aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSpp <spp@jorge.gr>2012-01-31 11:49:53 +0100
committerSpp <spp@jorge.gr>2012-01-31 11:49:53 +0100
commit37b66384f3d905fb8de506aae48237900a1b6065 (patch)
treef6c36187e06f76704d7a661179857916b18b6469 /src
parentfdbb3e52bcbaa236a26bd2bf8293a5deccb34a01 (diff)
parentd4670a558dd40fc03c9b143dcffa763c834ab966 (diff)
Merge branch 'master' into 4.x
Conflicts: src/server/authserver/Server/AuthSocket.cpp src/server/game/Entities/Object/Object.cpp src/server/game/Entities/Player/Player.cpp src/server/game/Entities/Unit/Unit.cpp src/server/game/Handlers/AuctionHouseHandler.cpp src/server/game/Handlers/CharacterHandler.cpp src/server/game/Handlers/MovementHandler.cpp src/server/game/Miscellaneous/SharedDefines.h src/server/game/Spells/Spell.cpp src/server/game/Spells/SpellEffects.cpp
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/server/CMakeLists.txt2
-rwxr-xr-xsrc/server/authserver/Server/AuthSocket.cpp43
-rwxr-xr-xsrc/server/authserver/Server/RealmSocket.cpp14
-rwxr-xr-xsrc/server/authserver/Server/RealmSocket.h7
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h1
-rwxr-xr-xsrc/server/game/AI/CoreAI/GuardAI.cpp4
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp9
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAI.cpp5
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp5
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp4
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedGossip.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp28
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp289
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h1
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp4
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h24
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp18
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.h4
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAB.cpp3
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAB.h2
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAV.cpp3
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundAV.h2
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundEY.cpp4
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundEY.h2
-rw-r--r--src/server/game/CMakeLists.txt8
-rwxr-xr-xsrc/server/game/Chat/Commands/Level2.cpp19
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp61
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp206
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.h28
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp117
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.h8
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp74
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h4
-rwxr-xr-xsrc/server/game/Entities/Creature/CreatureGroups.cpp6
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp14
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.h5
-rwxr-xr-xsrc/server/game/Entities/Object/Object.cpp130
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h3
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp191
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h11
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp289
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h126
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp2
-rwxr-xr-xsrc/server/game/Groups/Group.cpp128
-rwxr-xr-xsrc/server/game/Groups/Group.h3
-rw-r--r--src/server/game/Groups/GroupMgr.cpp8
-rwxr-xr-xsrc/server/game/Groups/GroupReference.cpp4
-rwxr-xr-xsrc/server/game/Handlers/AddonHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/AddonHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/AddonHandler.h (renamed from src/server/game/Server/Protocol/Handlers/AddonHandler.h)0
-rwxr-xr-xsrc/server/game/Handlers/ArenaTeamHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/AuctionHouseHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/AuthHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/AuthHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/BattleGroundHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/CalendarHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/CalendarHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/ChannelHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp)0
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp)18
-rwxr-xr-xsrc/server/game/Handlers/ChatHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/ChatHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/CombatHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/CombatHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/DuelHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/DuelHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/GroupHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/GroupHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/GuildHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/GuildHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/ItemHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/LFGHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/LFGHandler.cpp)3
-rwxr-xr-xsrc/server/game/Handlers/LootHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/LootHandler.cpp)2
-rwxr-xr-xsrc/server/game/Handlers/MailHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/MailHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/MiscHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/MiscHandler.cpp)8
-rwxr-xr-xsrc/server/game/Handlers/MovementHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/MovementHandler.cpp)13
-rwxr-xr-xsrc/server/game/Handlers/NPCHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/NPCHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/NPCHandler.h (renamed from src/server/game/Server/Protocol/Handlers/NPCHandler.h)0
-rwxr-xr-xsrc/server/game/Handlers/PetHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/PetHandler.cpp)1
-rwxr-xr-xsrc/server/game/Handlers/PetitionsHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/QueryHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/QueryHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/QuestHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/QuestHandler.cpp)0
-rw-r--r--src/server/game/Handlers/ReferAFriendHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/SkillHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/SkillHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/SpellHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/SpellHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/TaxiHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp)1
-rwxr-xr-xsrc/server/game/Handlers/TicketHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/TicketHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/TradeHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/TradeHandler.cpp)0
-rw-r--r--src/server/game/Handlers/VehicleHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp)0
-rwxr-xr-xsrc/server/game/Handlers/VoiceChatHandler.cpp (renamed from src/server/game/Server/Protocol/Handlers/VoiceChatHandler.cpp)0
-rwxr-xr-xsrc/server/game/Instances/InstanceSaveMgr.cpp4
-rwxr-xr-xsrc/server/game/Instances/InstanceScript.cpp18
-rwxr-xr-xsrc/server/game/Maps/Map.cpp18
-rwxr-xr-xsrc/server/game/Maps/Map.h2
-rwxr-xr-xsrc/server/game/Maps/MapManager.cpp1
-rwxr-xr-xsrc/server/game/Miscellaneous/Language.h12
-rwxr-xr-xsrc/server/game/Movement/DestinationHolder.cpp20
-rwxr-xr-xsrc/server/game/Movement/DestinationHolder.h65
-rwxr-xr-xsrc/server/game/Movement/DestinationHolderImp.h215
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.cpp168
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.h17
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.cpp1
-rwxr-xr-xsrc/server/game/Movement/MovementGenerator.h2
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp125
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h13
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp123
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h7
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp57
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/HomeMovementGenerator.h12
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp105
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.h30
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp188
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/RandomMovementGenerator.h12
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp370
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h91
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp417
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h90
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp316
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.h127
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h143
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp118
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h170
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h67
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp188
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.h37
-rw-r--r--src/server/game/Movement/Spline/MovementTypedefs.h81
-rw-r--r--src/server/game/Movement/Spline/MovementUtil.cpp208
-rw-r--r--src/server/game/Movement/Spline/Spline.cpp307
-rw-r--r--src/server/game/Movement/Spline/Spline.h212
-rw-r--r--src/server/game/Movement/Spline/SplineImpl.h97
-rwxr-xr-xsrc/server/game/Movement/Traveller.h152
-rwxr-xr-xsrc/server/game/Quests/QuestDef.h2
-rwxr-xr-xsrc/server/game/Scripting/MapScripts.cpp10
-rwxr-xr-xsrc/server/game/Scripting/ScriptLoader.cpp2
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp2
-rwxr-xr-xsrc/server/game/Server/WorldSession.h1
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp6
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp14
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.h3
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp7
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp53
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp19
-rw-r--r--src/server/scripts/CMakeLists.txt4
-rw-r--r--src/server/scripts/Commands/cs_account.cpp5
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp3
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp2
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp9
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp211
-rw-r--r--src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp9
-rw-r--r--src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp20
-rw-r--r--src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp23
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp30
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp7
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp3
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp17
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp91
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp25
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp71
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp80
-rw-r--r--src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp1
-rw-r--r--src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/MoltenCore/molten_core.cpp22
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp12
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp25
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp15
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp162
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp49
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp22
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp15
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp188
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp30
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp24
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h19
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/arathi_highlands.cpp40
-rw-r--r--src/server/scripts/EasternKingdoms/duskwood.cpp16
-rw-r--r--src/server/scripts/EasternKingdoms/eversong_woods.cpp16
-rw-r--r--src/server/scripts/EasternKingdoms/ghostlands.cpp40
-rw-r--r--src/server/scripts/EasternKingdoms/silverpine_forest.cpp71
-rw-r--r--src/server/scripts/EasternKingdoms/stormwind_city.cpp74
-rw-r--r--src/server/scripts/EasternKingdoms/undercity.cpp4
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp47
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp15
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp15
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp25
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp163
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp40
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp21
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp21
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp23
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp30
-rw-r--r--src/server/scripts/Kalimdor/ashenvale.cpp46
-rw-r--r--src/server/scripts/Kalimdor/moonglade.cpp146
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp115
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp16
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp2
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp4
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp31
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp10
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp23
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp204
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp118
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp4
-rw-r--r--src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp20
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp4
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp150
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp427
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp2
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp771
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp9
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h2
-rw-r--r--src/server/scripts/Northrend/dalaran.cpp13
-rw-r--r--src/server/scripts/Northrend/grizzly_hills.cpp107
-rw-r--r--src/server/scripts/Northrend/icecrown.cpp93
-rw-r--r--src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp2
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp2
-rw-r--r--src/server/scripts/Outland/CMakeLists.txt1
-rw-r--r--src/server/scripts/Outland/GruulsLair/boss_gruul.cpp2
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp4
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp102
-rw-r--r--src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp93
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp909
-rw-r--r--src/server/scripts/Spells/spell_item.cpp46
-rwxr-xr-xsrc/server/scripts/World/achievement_scripts.cpp12
-rw-r--r--src/server/scripts/World/guards.cpp2
-rw-r--r--src/server/scripts/World/npcs_special.cpp281
-rwxr-xr-xsrc/server/shared/Cryptography/HMACSHA1.cpp1
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp8
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h3
-rwxr-xr-xsrc/server/shared/Utilities/Timer.h2
-rw-r--r--src/server/worldserver/CMakeLists.txt4
-rw-r--r--src/tools/CMakeLists.txt2
-rw-r--r--src/tools/map_extractor/CMakeLists.txt2
-rw-r--r--src/tools/vmap3_assembler/CMakeLists.txt2
-rw-r--r--src/tools/vmap3_extractor/CMakeLists.txt2
237 files changed, 7959 insertions, 4227 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c372d12418b..7c2ebe9906c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 561ee50f439..2b6c553e10b 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
diff --git a/src/server/authserver/Server/AuthSocket.cpp b/src/server/authserver/Server/AuthSocket.cpp
index 1ebbd0b0c85..e6da5eeb996 100755
--- a/src/server/authserver/Server/AuthSocket.cpp
+++ b/src/server/authserver/Server/AuthSocket.cpp
@@ -209,7 +209,7 @@ AuthSocket::~AuthSocket(void) {}
// Accept the connection and set the s random value for SRP6
void AuthSocket::OnAccept(void)
{
- sLog->outBasic("Accepting connection from '%s'", socket().get_remote_address().c_str());
+ sLog->outBasic("'%s:%d' Accepting connection", socket().getRemoteAddress().c_str(), socket().getRemotePort());
}
void AuthSocket::OnClose(void)
@@ -247,7 +247,7 @@ void AuthSocket::OnRead()
// Report unknown packets in the error log
if (i == AUTH_TOTAL_COMMANDS)
{
- sLog->outError("[Auth] got unknown packet from '%s'", socket().get_remote_address().c_str());
+ sLog->outError("[Auth] got unknown packet from '%s'", socket().getRemoteAddress().c_str());
socket().shutdown();
return;
}
@@ -349,14 +349,14 @@ bool AuthSocket::_HandleLogonChallenge()
// Verify that this IP is not in the ip_banned table
LoginDatabase.Execute(LoginDatabase.GetPreparedStatement(LOGIN_DEL_EXPIRED_IP_BANS));
- const std::string& ip_address = socket().get_remote_address();
+ const std::string& ip_address = socket().getRemoteAddress();
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_IP_BANNED);
stmt->setString(0, ip_address);
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (result)
{
- pkt << uint8(WOW_FAIL_BANNED);
- sLog->outBasic("[AuthChallenge] Banned ip %s tried to login!", ip_address.c_str());
+ pkt << (uint8)WOW_FAIL_BANNED;
+ sLog->outBasic("'%s:%d' [AuthChallenge] Banned ip tries to login!",socket().getRemoteAddress().c_str(), socket().getRemotePort());
}
else
{
@@ -402,13 +402,13 @@ bool AuthSocket::_HandleLogonChallenge()
{
if ((*banresult)[0].GetUInt64() == (*banresult)[1].GetUInt64())
{
- pkt << uint8(WOW_FAIL_BANNED);
- sLog->outBasic("[AuthChallenge] Banned account %s tried to login!", _login.c_str());
+ pkt << (uint8)WOW_FAIL_BANNED;
+ sLog->outBasic("'%s:%d' [AuthChallenge] Banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ());
}
else
{
- pkt << uint8(WOW_FAIL_SUSPENDED);
- sLog->outBasic("[AuthChallenge] Temporarily banned account %s tried to login!", _login.c_str());
+ pkt << (uint8)WOW_FAIL_SUSPENDED;
+ sLog->outBasic("'%s:%d' [AuthChallenge] Temporarily banned account %s tried to login!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ());
}
}
else
@@ -483,7 +483,9 @@ bool AuthSocket::_HandleLogonChallenge()
for (int i = 0; i < 4; ++i)
_localizationName[i] = ch->country[4-i-1];
- sLog->outBasic("[AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName));
+ sLog->outBasic("'%s:%d' [AuthChallenge] account %s is using '%c%c%c%c' locale (%u)", socket().getRemoteAddress().c_str(), socket().getRemotePort(),
+ _login.c_str (), ch->country[3], ch->country[2], ch->country[1], ch->country[0], GetLocaleByName(_localizationName)
+ );
}
}
}
@@ -584,7 +586,7 @@ bool AuthSocket::_HandleLogonProof()
// Check if SRP6 results match (password is correct), else send an error
if (!memcmp(M.AsByteArray(), lp.M1, 20))
{
- sLog->outBasic("User '%s' successfully authenticated", _login.c_str());
+ sLog->outBasic("'%s:%d' User '%s' successfully authenticated", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
// Update the sessionkey, last_ip, last login time and reset number of failed logins in the account table for this account
// No SQL injection (escaped user name) and IP address as received by socket
@@ -592,7 +594,7 @@ bool AuthSocket::_HandleLogonProof()
PreparedStatement *stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_LOGONPROOF);
stmt->setString(0, K_hex);
- stmt->setString(1, socket().get_remote_address().c_str());
+ stmt->setString(1, socket().getRemoteAddress().c_str());
stmt->setUInt32(2, GetLocaleByName(_localizationName));
stmt->setString(3, _login);
LoginDatabase.Execute(stmt);
@@ -620,7 +622,7 @@ bool AuthSocket::_HandleLogonProof()
char data[4] = { AUTH_LOGON_PROOF, WOW_FAIL_UNKNOWN_ACCOUNT, 3, 0 };
socket().send(data, sizeof(data));
- sLog->outBasic("[AuthChallenge] account %s tried to login with wrong password!", _login.c_str());
+ sLog->outBasic("'%s:%d' [AuthChallenge] account %s tried to login with invalid password!", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str ());
uint32 MaxWrongPassCount = ConfigMgr::GetIntDefault("WrongPass.MaxCount", 0);
if (MaxWrongPassCount > 0)
@@ -650,17 +652,18 @@ bool AuthSocket::_HandleLogonProof()
stmt->setUInt32(1, WrongPassBanTime);
LoginDatabase.Execute(stmt);
- sLog->outBasic("[AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
- _login.c_str(), WrongPassBanTime, failed_logins);
+ sLog->outBasic("'%s:%d' [AuthChallenge] account %s got banned for '%u' seconds because it failed to authenticate '%u' times",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str(), WrongPassBanTime, failed_logins);
}
else
{
stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_IP_AUTO_BANNED);
- stmt->setString(0, socket().get_remote_address());
+ stmt->setString(0, socket().getRemoteAddress());
stmt->setUInt32(1, WrongPassBanTime);
LoginDatabase.Execute(stmt);
- sLog->outBasic("[AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times", socket().get_remote_address().c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
+ sLog->outBasic("'%s:%d' [AuthChallenge] IP %s got banned for '%u' seconds because account %s failed to authenticate '%u' times",
+ socket().getRemoteAddress().c_str(), socket().getRemotePort(), socket().getRemoteAddress().c_str(), WrongPassBanTime, _login.c_str(), failed_logins);
}
}
}
@@ -712,7 +715,7 @@ bool AuthSocket::_HandleReconnectChallenge()
// Stop if the account is not found
if (!result)
{
- sLog->outError("[ERROR] user %s tried to login and we cannot find his session key in the database.", _login.c_str());
+ sLog->outError("'%s:%d' [ERROR] user %s tried to login and we cannot find his session key in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
socket().shutdown();
return false;
}
@@ -771,7 +774,7 @@ bool AuthSocket::_HandleReconnectProof()
}
else
{
- sLog->outError("[ERROR] user %s tried to login, but session invalid.", _login.c_str());
+ sLog->outError("'%s:%d' [ERROR] user %s tried to login, but session is invalid.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
socket().shutdown();
return false;
}
@@ -793,7 +796,7 @@ bool AuthSocket::_HandleRealmList()
PreparedQueryResult result = LoginDatabase.Query(stmt);
if (!result)
{
- sLog->outError("[ERROR] user %s tried to login and we cannot find him in the database.", _login.c_str());
+ sLog->outError("'%s:%d' [ERROR] user %s tried to login but we cannot find him in the database.", socket().getRemoteAddress().c_str(), socket().getRemotePort(), _login.c_str());
socket().shutdown();
return false;
}
diff --git a/src/server/authserver/Server/RealmSocket.cpp b/src/server/authserver/Server/RealmSocket.cpp
index a796daae17d..72c36fc6646 100755
--- a/src/server/authserver/Server/RealmSocket.cpp
+++ b/src/server/authserver/Server/RealmSocket.cpp
@@ -31,7 +31,7 @@ RealmSocket::Session::Session(void) {}
RealmSocket::Session::~Session(void) { }
-RealmSocket::RealmSocket(void) : input_buffer_(4096), session_(NULL), remote_address_()
+RealmSocket::RealmSocket(void) : input_buffer_(4096), session_(NULL), _remoteAddress()
{
reference_counting_policy().value(ACE_Event_Handler::Reference_Counting_Policy::ENABLED);
@@ -63,7 +63,8 @@ int RealmSocket::open(void * arg)
return -1;
}
- remote_address_ = addr.get_host_addr();
+ _remoteAddress = addr.get_host_addr();
+ _remotePort = addr.get_port_number();
// Register with ACE Reactor
if (Base::open(arg) == -1)
@@ -89,9 +90,14 @@ int RealmSocket::close(int)
return 0;
}
-const std::string& RealmSocket::get_remote_address(void) const
+const std::string& RealmSocket::getRemoteAddress(void) const
{
- return remote_address_;
+ return _remoteAddress;
+}
+
+const uint16 RealmSocket::getRemotePort(void) const
+{
+ return _remotePort;
}
size_t RealmSocket::recv_len(void) const
diff --git a/src/server/authserver/Server/RealmSocket.h b/src/server/authserver/Server/RealmSocket.h
index c532f016dcb..9682b5e4559 100755
--- a/src/server/authserver/Server/RealmSocket.h
+++ b/src/server/authserver/Server/RealmSocket.h
@@ -52,7 +52,9 @@ public:
bool send(const char *buf, size_t len);
- const std::string& get_remote_address(void) const;
+ const std::string& getRemoteAddress(void) const;
+
+ const uint16 getRemotePort(void) const;
virtual int open(void *);
@@ -70,7 +72,8 @@ private:
ACE_Message_Block input_buffer_;
Session* session_;
- std::string remote_address_;
+ std::string _remoteAddress;
+ uint16 _remotePort;
};
#endif /* __REALMSOCKET_H__ */
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index 0b91b6e8ddb..b9d385ba675 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -50,6 +50,7 @@ class GameObjectAI
virtual void Destroyed(Player* /*player*/, uint32 /*eventId*/) {}
virtual void SetData(uint32 /*id*/, uint32 /*value*/) {}
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {}
+ virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { }
};
class NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp
index 54061274408..b78fec7c142 100755
--- a/src/server/game/AI/CoreAI/GuardAI.cpp
+++ b/src/server/game/AI/CoreAI/GuardAI.cpp
@@ -115,8 +115,8 @@ void GuardAI::EnterEvadeMode()
me->CombatStop(true);
i_state = STATE_NORMAL;
- // Remove TargetedMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ // Remove ChaseMovementGenerator from MotionMaster stack list, and add HomeMovementGenerator instead
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MoveTargetedHome();
}
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 60151e4865a..015e20415b1 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -417,10 +417,9 @@ void PetAI::MovementInform(uint32 moveType, uint32 data)
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
}
+ break;
}
- break;
-
- case TARGETED_MOTION_TYPE:
+ case FOLLOW_MOTION_TYPE:
{
// If data is owner's GUIDLow then we've reached follow point,
// otherwise we're probably chasing a creature
@@ -430,11 +429,9 @@ void PetAI::MovementInform(uint32 moveType, uint32 data)
me->GetCharmInfo()->SetIsReturning(false);
me->GetCharmInfo()->SetIsFollowing(true);
me->GetCharmInfo()->SetIsCommandAttack(false);
- me->AddUnitState(UNIT_STAT_FOLLOW);
}
+ break;
}
- break;
-
default:
break;
}
diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp
index 4029f5e8180..9703757ca7a 100755
--- a/src/server/game/AI/EventAI/CreatureEventAI.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp
@@ -475,7 +475,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
//Melee current victim if flag not set
if (!(action.cast.castFlags & CAST_NO_MELEE_IF_OOM))
{
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
{
m_AttackDistance = 0.0f;
m_AttackAngle = 0.0f;
@@ -483,7 +483,6 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
me->GetMotionMaster()->MoveChase(me->getVictim(), m_AttackDistance, m_AttackAngle);
}
}
-
}
else
{
@@ -595,7 +594,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
me->ClearUnitState(UNIT_STAT_MELEE_ATTACKING);
me->SendMeleeAttackStop(victim);
}
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MoveIdle();
}
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index e9a9c1fdcf2..ff432abcc82 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
@@ -298,7 +298,8 @@ void ScriptedAI::DoModifyThreatPercent(Unit* unit, int32 pct)
void ScriptedAI::DoTeleportTo(float x, float y, float z, uint32 time)
{
me->Relocate(x, y, z);
- me->SendMonsterMove(x, y, z, time);
+ float speed = me->GetDistance(x, y, z) / ((float)time * 0.001f);
+ me->MonsterMoveWithSpeed(x, y, z, speed);
}
void ScriptedAI::DoTeleportTo(const float position[4])
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 1e0b212dd45..53747d0c799 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -167,7 +167,7 @@ void FollowerAI::EnterEvadeMode()
{
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI left combat, returning to CombatStartPosition.");
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
{
float fPosX, fPosY, fPosZ;
me->GetPosition(fPosX, fPosY, fPosZ);
@@ -176,7 +176,7 @@ void FollowerAI::EnterEvadeMode()
}
else
{
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MoveTargetedHome();
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedGossip.h b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
index 5d376be888e..34300ff406c 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedGossip.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedGossip.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+/* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
*
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index b5fdf38a4b6..d4b2a9746be 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -46,7 +46,7 @@ SmartAI::SmartAI(Creature* c) : CreatureAI(c)
// spawn in run mode
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
- mRun = true;
+ mRun = false;
me->GetPosition(&mLastOOCPos);
@@ -89,7 +89,7 @@ void SmartAI::UpdateDespawn(const uint32 diff)
void SmartAI::Reset()
{
if (!HasEscortState(SMART_ESCORT_ESCORTING))//dont mess up escort movement after combat
- SetRun(true);
+ SetRun(mRun);
GetScript()->OnReset();
}
@@ -433,24 +433,13 @@ void SmartAI::MovementInform(uint32 MovementType, uint32 Data)
void SmartAI::RemoveAuras()
{
+ // Only loop throught the applied auras, because here is where all auras on the current unit are stored
Unit::AuraApplicationMap appliedAuras = me->GetAppliedAuras();
- for (Unit::AuraApplicationMap::iterator iter = appliedAuras.begin(); iter != appliedAuras.end();)
+ for (Unit::AuraApplicationMap::iterator iter = appliedAuras.begin(); iter != appliedAuras.end(); ++iter)
{
Aura const* aura = iter->second->GetBase();
- if (!aura->GetSpellInfo()->HasAura(SPELL_AURA_CONTROL_VEHICLE) && !(iter->second->GetTarget() == me && aura->GetCaster() == me))
- me->_UnapplyAura(iter, AURA_REMOVE_BY_DEFAULT);
- else
- ++iter;
- }
-
- Unit::AuraMap ownedAuras = me->GetOwnedAuras();
- for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
- {
- Aura* aura = iter->second;
- if (!aura->GetSpellInfo()->HasAura(SPELL_AURA_CONTROL_VEHICLE))
- me->RemoveOwnedAura(iter, AURA_REMOVE_BY_DEFAULT);
- else
- ++iter;
+ if (!aura->GetSpellInfo()->IsPassive() && !aura->GetSpellInfo()->HasAura(SPELL_AURA_CONTROL_VEHICLE) && aura->GetCaster() != me)
+ me->RemoveAurasDueToSpell(aura->GetId());
}
}
@@ -948,6 +937,11 @@ void SmartGameObjectAI::OnGameEvent(bool start, uint16 eventId)
GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId);
}
+void SmartGameObjectAI::OnStateChanged(uint32 state, Unit* unit)
+{
+ GetScript()->ProcessEventsFor(SMART_EVENT_GO_STATE_CHANGED, unit, state);
+}
+
class SmartTrigger : public AreaTriggerScript
{
public:
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index b33bfebf912..0576612a155 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -253,6 +253,7 @@ public:
void SetData(uint32 id, uint32 value);
void SetScript9(SmartScriptHolder& e, uint32 entry, Unit* invoker);
void OnGameEvent(bool start, uint16 eventId);
+ void OnStateChanged(uint32 state, Unit* unit);
protected:
GameObject* const go;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index a2e70e9cbf2..3c0bdfcade7 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -51,7 +51,6 @@ SmartScript::SmartScript()
mTemplate = SMARTAI_TEMPLATE_BASIC;
meOrigGUID = 0;
goOrigGUID = 0;
- mResumeActionList = true;
mLastInvoker = 0;
}
@@ -78,22 +77,6 @@ void SmartScript::OnReset()
void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
{
- if (e == SMART_EVENT_AGGRO)
- {
- if (!mResumeActionList)
- mTimedActionList.clear();//clear action list if it is not resumable
- else
- {
- for (SmartAIEventList::iterator itr = mTimedActionList.begin(); itr != mTimedActionList.end(); ++itr)
- {
- if (itr->enableTimed)
- {
- InitTimer((*itr));//re-init the currently enabled timer, so it restarts the timer when resumed
- break;
- }
- }
- }
- }
for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i)
{
SMART_EVENT eventType = SMART_EVENT((*i).GetEventType());
@@ -101,7 +84,20 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
continue;
if (eventType == e/* && (!(*i).event.event_phase_mask || IsInPhase((*i).event.event_phase_mask)) && !((*i).event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && (*i).runOnce)*/)
- ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
+ {
+ bool meets = true;
+ if (unit)
+ {
+ if (Player* player = unit->ToPlayer())
+ {
+ ConditionList conds = sConditionMgr->GetConditionsForSmartEvent((*i).entryOrGuid, (*i).event_id, (*i).source_type);
+ meets = sConditionMgr->IsPlayerMeetToConditions(player, conds);
+ }
+ }
+
+ if (meets)
+ ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
+ }
}
}
@@ -119,15 +115,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (unit)
mLastInvoker = unit->GetGUID();
- if (e.link && e.link != e.event_id)
- {
- SmartScriptHolder linked = FindLinkedEvent(e.link);
- if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
- ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
- else
- sLog->outErrorDb("SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
- }
-
if (Unit* tempInvoker = GetLastInvoker())
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName(), tempInvoker->GetGUIDLow());
@@ -136,7 +123,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_TALK:
{
if (!me)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
Creature* talker = me;
@@ -274,7 +261,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -317,7 +304,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -336,7 +323,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -357,7 +344,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_REACT_STATE:
{
if (!me)
- return;
+ break;
me->SetReactState(ReactStates(e.action.react.state));
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_REACT_STATE: Creature guidLow %u set reactstate %u",
@@ -368,7 +355,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
uint32 emotes[SMART_ACTION_PARAM_COUNT];
emotes[0] = e.action.randomEmote.emote1;
@@ -405,7 +392,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_THREAT_ALL_PCT:
{
if (!me)
- return;
+ break;
std::list<HostileReference*> const& threatList = me->getThreatManager().getThreatList();
for (std::list<HostileReference*>::const_iterator i = threatList.begin(); i != threatList.end(); ++i)
@@ -422,11 +409,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_THREAT_SINGLE_PCT:
{
if (!me)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -445,7 +432,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -463,11 +450,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SEND_CASTCREATUREORGO:
{
if (!GetBaseObject())
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -485,11 +472,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_CAST:
{
if (!me)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -511,11 +498,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
Unit* tempLastInvoker = GetLastInvoker();
if (!tempLastInvoker)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -537,7 +524,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -556,7 +543,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -564,7 +551,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
// Activate
(*itr)->ToGameObject()->SetLootState(GO_READY);
- (*itr)->ToGameObject()->UseDoorOrButton();
+ (*itr)->ToGameObject()->UseDoorOrButton(0, false, unit);
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject %u (entry: %u) activated",
(*itr)->GetGUIDLow(), (*itr)->GetEntry());
}
@@ -577,7 +564,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -596,7 +583,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -615,7 +602,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -634,7 +621,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -652,7 +639,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_AUTO_ATTACK:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack ? true : false);
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u",
@@ -662,7 +649,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_ALLOW_COMBAT_MOVEMENT:
{
if (!IsSmart())
- return;
+ break;
bool move = e.action.combatMove.move ? true : false;
CAST_AI(SmartAI, me->AI())->SetCombatMove(move);
@@ -673,7 +660,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_EVENT_PHASE:
{
if (!GetBaseObject())
- return;
+ break;
SetPhase(e.action.setEventPhase.phase);
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: Creature %u set event phase %u",
@@ -683,7 +670,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_INC_EVENT_PHASE:
{
if (!GetBaseObject())
- return;
+ break;
IncPhase(e.action.incEventPhase.inc);
DecPhase(e.action.incEventPhase.dec);
@@ -694,7 +681,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_EVADE:
{
if (!me)
- return;
+ break;
me->AI()->EnterEvadeMode();
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_EVADE: Creature %u EnterEvadeMode", me->GetGUIDLow());
@@ -703,7 +690,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_FLEE_FOR_ASSIST:
{
if (!me)
- return;
+ break;
me->DoFleeToGetAssistance();
if (e.action.flee.withEmote)
@@ -724,11 +711,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_CALL_CASTEDCREATUREORGO:
{
if (!GetBaseObject())
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -747,7 +734,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -765,11 +752,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_FOLLOW:
{
if (!IsSmart())
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -788,7 +775,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_RANDOM_PHASE:
{
if (!GetBaseObject())
- return;
+ break;
uint32 phases[SMART_ACTION_PARAM_COUNT];
phases[0] = e.action.randomPhase.phase1;
@@ -817,7 +804,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_RANDOM_PHASE_RANGE:
{
if (!GetBaseObject())
- return;
+ break;
uint32 phase = urand(e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax);
SetPhase(phase);
@@ -837,7 +824,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -866,13 +853,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
obj = unit;
if (!obj)
- return;
+ break;
InstanceScript* instance = obj->GetInstanceScript();
if (!instance)
{
sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid);
- return;
+ break;
}
instance->SetData(e.action.setInstanceData.field, e.action.setInstanceData.data);
@@ -887,18 +874,18 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
obj = unit;
if (!obj)
- return;
+ break;
InstanceScript* instance = obj->GetInstanceScript();
if (!instance)
{
sLog->outErrorDb("SmartScript: Event %u attempt to set instance data without instance script. EntryOrGuid %d", e.GetEventType(), e.entryOrGuid);
- return;
+ break;
}
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
instance->SetData64(e.action.setInstanceData64.field, targets->front()->GetGUID());
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_SET_INST_DATA64: Field: %u, data: "UI64FMTD,
@@ -910,7 +897,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_UPDATE_TEMPLATE:
{
if (!me || me->GetEntry() == e.action.updateTemplate.creature)
- return;
+ break;
me->UpdateEntry(e.action.updateTemplate.creature, e.action.updateTemplate.team ? HORDE : ALLIANCE);
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_UPDATE_TEMPLATE: Creature %u, Template: %u, Team: %u",
@@ -957,7 +944,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_FORCE_DESPAWN:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1);//next tick
CAST_AI(SmartAI, me->AI())->StartDespawn();
@@ -973,7 +960,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1003,7 +990,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL:
{
if (!me)
- return;
+ break;
if (e.action.invincHP.percent)
mInvinceabilityHpLevel = me->CountPctFromMaxHealth(e.action.invincHP.percent);
@@ -1015,7 +1002,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1031,7 +1018,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_MOVE_FORWARD:
{
if (!me)
- return;
+ break;
float x, y, z;
me->GetClosePoint(x, y, z, me->GetObjectSize() / 3, (float)e.action.moveRandom.distance);
@@ -1053,11 +1040,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_ATTACK_START:
{
if (!me)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1092,7 +1079,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
if (e.GetTargetType() != SMART_TARGET_POSITION)
- return;
+ break;
if (Creature* summon = GetBaseObject()->SummonCreature(e.action.summonCreature.creature, e.target.x, e.target.y, e.target.z, e.target.o, (TempSummonType)e.action.summonCreature.type, e.action.summonCreature.duration))
if (unit && e.action.summonCreature.attackInvoker)
@@ -1102,7 +1089,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SUMMON_GO:
{
if (!GetBaseObject())
- return;
+ break;
float x, y, z, o;
ObjectList* targets = GetTargets(e, unit);
@@ -1121,7 +1108,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
}
if (e.GetTargetType() != SMART_TARGET_POSITION)
- return;
+ break;
GetBaseObject()->SummonGameObject(e.action.summonGO.entry, e.target.x, e.target.y, e.target.z, e.target.o, 0, 0, 0, 0, e.action.summonGO.despawnTime);
break;
@@ -1130,7 +1117,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1152,7 +1139,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1169,7 +1156,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1199,7 +1186,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1215,7 +1202,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_FLY:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->SetFly(e.action.setFly.fly ? true : false);
break;
@@ -1223,7 +1210,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_RUN:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->SetRun(e.action.setRun.run ? true : false);
break;
@@ -1231,7 +1218,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_SWIM:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->SetSwim(e.action.setSwim.swim ? true : false);
break;
@@ -1239,7 +1226,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_WP_START:
{
if (!IsSmart())
- return;
+ break;
bool run = e.action.wpStart.run ? true : false;
uint32 entry = e.action.wpStart.pathID;
@@ -1258,7 +1245,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_WP_PAUSE:
{
if (!IsSmart())
- return;
+ break;
uint32 delay = e.action.wpPause.delay;
CAST_AI(SmartAI, me->AI())->PausePath(delay, e.GetEventType() == SMART_EVENT_WAYPOINT_REACHED ? false : true);
@@ -1267,7 +1254,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_WP_STOP:
{
if (!IsSmart())
- return;
+ break;
uint32 DespawnTime = e.action.wpStop.despawnTime;
uint32 quest = e.action.wpStop.quest;
@@ -1278,7 +1265,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_WP_RESUME:
{
if (!IsSmart())
- return;
+ break;
CAST_AI(SmartAI, me->AI())->ResumePath();
break;
@@ -1286,15 +1273,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_SET_ORIENTATION:
{
if (!me)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (e.GetTargetType() == SMART_TARGET_SELF)
- me->SetFacing(me->GetHomePosition().GetOrientation(), NULL);
+ me->SetFacingTo(me->GetHomePosition().GetOrientation());
else if (e.GetTargetType() == SMART_TARGET_POSITION)
- me->SetFacing(e.target.o, NULL);
+ me->SetFacingTo(e.target.o);
else if (targets && !targets->empty())
- me->SetFacing(0, (*targets->begin()));
+ me->SetFacingToObject(*targets->begin());
delete targets;
break;
@@ -1303,7 +1290,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1319,7 +1306,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_MOVE_TO_POS:
{
if (!IsSmart())
- return;
+ break;
WorldObject* target = NULL;
@@ -1331,7 +1318,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
target = targets->front();
}
@@ -1346,7 +1333,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1363,7 +1350,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsPlayer(*itr))
@@ -1376,7 +1363,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1453,7 +1440,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1493,7 +1480,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
- return;
+ break;
}
ObjectList* targets = GetTargets(e, unit);
@@ -1521,7 +1508,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1534,7 +1521,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1547,7 +1534,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1560,13 +1547,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* casters = GetTargets(CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.cast.targetType, e.action.cast.targetParam1, e.action.cast.targetParam2, e.action.cast.targetParam3, 0), unit);
if (!casters)
- return;
+ break;
ObjectList* targets = GetTargets(e, unit);
if (!targets)
{
delete casters; // casters already validated, delete now
- return;
+ break;
}
for (ObjectList::const_iterator itr = casters->begin(); itr != casters->end(); ++itr)
@@ -1610,7 +1597,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
- return;
+ break;
}
ObjectList* targets = GetTargets(e, unit);
@@ -1640,7 +1627,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (e.GetTargetType() == SMART_TARGET_NONE)
{
sLog->outErrorDb("SmartScript: Entry %d SourceType %u Event %u Action %u is using TARGET_NONE(0) for Script9 target. Please correct target_type in database.", e.entryOrGuid, e.GetScriptType(), e.GetEventType(), e.GetActionType());
- return;
+ break;
}
ObjectList* targets = GetTargets(e, unit);
@@ -1668,7 +1655,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsPlayer(*itr))
@@ -1681,7 +1668,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
@@ -1701,7 +1688,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
(*itr)->ToUnit()->SetByteFlag(UNIT_FIELD_BYTES_1, 0, e.action.setunitByte.byte1);
@@ -1713,7 +1700,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1726,7 +1713,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1739,7 +1726,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsGameObject(*itr))
@@ -1752,7 +1739,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1765,7 +1752,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1778,7 +1765,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (IsUnit(*itr))
@@ -1790,24 +1777,65 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
case SMART_ACTION_JUMP_TO_POS:
{
if (!me)
- return;
+ break;
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveJump(e.target.x, e.target.y, e.target.z, (float)e.action.jump.speedxy, (float)e.action.jump.speedz);
// TODO: Resume path when reached jump location
break;
}
+ case SMART_ACTION_GO_SET_LOOT_STATE:
+ {
+ ObjectList* targets = GetTargets(e, unit);
+
+ if (!targets)
+ break;
+
+ for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ if (IsGameObject(*itr))
+ (*itr)->ToGameObject()->SetLootState((LootState)e.action.setGoLootState.state);
+
+ delete targets;
+ break;
+ }
+ case SMART_ACTION_SEND_TARGET_TO_TARGET:
+ {
+ ObjectList* targets = GetTargets(e, unit);
+ if (!targets)
+ break;
+
+ for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
+ {
+ if (IsCreature(*itr))
+ {
+ if (SmartAI* ai = CAST_AI(SmartAI, (*itr)->ToCreature()->AI()))
+ ai->GetScript()->StoreTargetList(GetTargetList(e.action.sendTargetToTarget.id), e.action.sendTargetToTarget.id);
+ else
+ sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartAI, skipping");
+ }
+ else if (IsGameObject(*itr))
+ {
+ if (SmartGameObjectAI* ai = CAST_AI(SmartGameObjectAI, (*itr)->ToGameObject()->AI()))
+ ai->GetScript()->StoreTargetList(GetTargetList(e.action.sendTargetToTarget.id), e.action.sendTargetToTarget.id);
+ else
+ sLog->outErrorDb("SmartScript: Action target for SMART_ACTION_SEND_TARGET_TO_TARGET is not using SmartGameObjectAI, skipping");
+ }
+ }
+
+ delete targets;
+ break;
+ }
case SMART_ACTION_SEND_GOSSIP_MENU:
{
if (!GetBaseObject())
- return;
+ break;
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction:: SMART_ACTION_SEND_GOSSIP_MENU: gossipMenuId %d, gossipNpcTextId %d",
e.action.sendGossipMenu.gossipMenuId, e.action.sendGossipMenu.gossipNpcTextId);
ObjectList* targets = GetTargets(e, unit);
if (!targets)
- return;
+ break;
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
if (Player* player = (*itr)->ToPlayer())
@@ -1827,6 +1855,15 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
sLog->outErrorDb("SmartScript::ProcessAction: Unhandled Action type %u", e.GetActionType());
break;
}
+
+ if (e.link && e.link != e.event_id)
+ {
+ SmartScriptHolder linked = FindLinkedEvent(e.link);
+ if (linked.GetActionType() && linked.GetEventType() == SMART_EVENT_LINK)
+ ProcessEvent(linked, unit, var0, var1, bvar, spell, gob);
+ else
+ sLog->outErrorDb("SmartScript::ProcessAction: Entry %d SourceType %u, Event %u, Link Event %u not found or invalid, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.link);
+ }
}
void SmartScript::InstallTemplate(SmartScriptHolder const& e)
@@ -2619,6 +2656,13 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
ProcessAction(e, NULL, var0);
break;
}
+ case SMART_EVENT_GO_STATE_CHANGED:
+ {
+ if (e.event.goStateChanged.state != var0)
+ return;
+ ProcessAction(e, unit, var0, var1);
+ break;
+ }
default:
sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
break;
@@ -3017,7 +3061,6 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry)
i->event.type = SMART_EVENT_UPDATE_IC;
else if (e.action.timedActionList.timerType > 1)
i->event.type = SMART_EVENT_UPDATE;
- mResumeActionList = e.action.timedActionList.dontResume ? false : true;
InitTimer((*i));
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 0193ac2bfb6..f55d91ed52f 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -228,7 +228,6 @@ class SmartScript
SmartAIEventList mEvents;
SmartAIEventList mInstallEvents;
SmartAIEventList mTimedActionList;
- bool mResumeActionList;
Creature* me;
uint64 meOrigGUID;
GameObject* go;
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index 63595b2439f..9a23d9e1390 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -282,6 +282,7 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e)
case SMART_TARGET_HOSTILE_RANDOM:
case SMART_TARGET_HOSTILE_RANDOM_NOT_TOP:
case SMART_TARGET_ACTION_INVOKER:
+ case SMART_TARGET_INVOKER_PARTY:
case SMART_TARGET_POSITION:
case SMART_TARGET_NONE:
case SMART_TARGET_ACTION_INVOKER_VEHICLE:
@@ -478,6 +479,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
}
+ case SMART_EVENT_GO_STATE_CHANGED:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_RELOCATE:
@@ -800,6 +802,8 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_ACTION_REMOVE_DYNAMIC_FLAG:
case SMART_ACTION_JUMP_TO_POS:
case SMART_ACTION_SEND_GOSSIP_MENU:
+ case SMART_ACTION_GO_SET_LOOT_STATE:
+ case SMART_ACTION_SEND_TARGET_TO_TARGET:
break;
default:
sLog->outErrorDb("SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id);
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index f56cf478bf8..123275ccc55 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -155,8 +155,9 @@ enum SMART_EVENT
SMART_EVENT_IS_BEHIND_TARGET = 67, //1 // cooldownMin, CooldownMax
SMART_EVENT_GAME_EVENT_START = 68, //1 // game_event.Entry
SMART_EVENT_GAME_EVENT_END = 69, //1 // game_event.Entry
+ SMART_EVENT_GO_STATE_CHANGED = 70, // go state
- SMART_EVENT_END = 70,
+ SMART_EVENT_END = 71,
};
struct SmartEvent
@@ -348,6 +349,11 @@ struct SmartEvent
struct
{
+ uint32 state;
+ } goStateChanged;
+
+ struct
+ {
uint32 param1;
uint32 param2;
uint32 param3;
@@ -467,8 +473,10 @@ enum SMART_ACTION
SMART_ACTION_REMOVE_DYNAMIC_FLAG = 96, // Flags
SMART_ACTION_JUMP_TO_POS = 97, // speedXY, speedZ, targetX, targetY, targetZ
SMART_ACTION_SEND_GOSSIP_MENU = 98, // menuId, optionId
+ SMART_ACTION_GO_SET_LOOT_STATE = 99, // state
+ SMART_ACTION_SEND_TARGET_TO_TARGET = 100, // id
- SMART_ACTION_END = 99,
+ SMART_ACTION_END = 101,
};
struct SmartAction
@@ -825,7 +833,6 @@ struct SmartAction
struct
{
uint32 id;
- uint32 dontResume;
uint32 timerType;
} timedActionList;
@@ -875,6 +882,16 @@ struct SmartAction
struct
{
+ uint32 state;
+ } setGoLootState;
+
+ struct
+ {
+ uint32 id;
+ } sendTargetToTarget;
+
+ struct
+ {
uint32 param1;
uint32 param2;
uint32 param3;
@@ -1139,6 +1156,7 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
{SMART_EVENT_IS_BEHIND_TARGET, SMART_SCRIPT_TYPE_MASK_CREATURE },
{SMART_EVENT_GAME_EVENT_START, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
{SMART_EVENT_GAME_EVENT_END, SMART_SCRIPT_TYPE_MASK_CREATURE + SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
+ {SMART_EVENT_GO_STATE_CHANGED, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
};
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 78fad4bfe02..159a986367c 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -771,6 +771,7 @@ void Battleground::EndBattleground(uint32 winner)
}
}
+ uint8 aliveWinners = GetAlivePlayersCountByTeam(winner);
for (BattlegroundPlayerMap::iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
{
uint32 team = itr->second.Team;
@@ -796,6 +797,10 @@ void Battleground::EndBattleground(uint32 winner)
if (player->HasAuraType(SPELL_AURA_SPIRIT_OF_REDEMPTION))
player->RemoveAurasByType(SPELL_AURA_MOD_SHAPESHIFT);
+ // Last standing - Rated 5v5 arena & be solely alive player
+ if (team == winner && isArena() && isRated() && GetArenaType() == ARENA_TYPE_5v5 && aliveWinners == 1 && player->isAlive())
+ player->CastSpell(player, SPELL_THE_LAST_STANDING, true);
+
if (!player->isAlive())
{
player->ResurrectPlayer(1.0f);
@@ -898,19 +903,6 @@ uint32 Battleground::GetBonusHonorFromKill(uint32 kills) const
return Trinity::Honor::hk_honor_at_level(maxLevel, float(kills));
}
-uint32 Battleground::GetBattlemasterEntry() const
-{
- switch (GetTypeID(true))
- {
- case BATTLEGROUND_AV: return 15972;
- case BATTLEGROUND_WS: return 14623;
- case BATTLEGROUND_AB: return 14879;
- case BATTLEGROUND_EY: return 22516;
- case BATTLEGROUND_NA: return 20200;
- default: return 0;
- }
-}
-
void Battleground::BlockMovement(Player* player)
{
player->SetClientControl(player, 0); // movement disabled NOTE: the effect will be automatically removed by client when the player is teleported from the battleground, so no need to send with uint8(1) in RemovePlayerAtLeave()
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index fcfc0c48cb4..6eb64a2caba 100755
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -98,7 +98,8 @@ enum BattlegroundSpells
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
+ 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
+ SPELL_THE_LAST_STANDING = 26549, // Arena achievement related
};
enum BattlegroundTimeIntervals
@@ -360,7 +361,6 @@ class Battleground
uint8 GetArenaType() const { return m_ArenaType; }
uint8 GetWinner() const { return m_Winner; }
uint32 GetScriptId() const { return ScriptId; }
- uint32 GetBattlemasterEntry() const;
uint32 GetBonusHonorFromKill(uint32 kills) const;
bool IsRandom() const { return m_IsRandom; }
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
index d64b2a9913d..5e529768c04 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp
@@ -202,6 +202,9 @@ void BattlegroundAB::StartingEventOpenDoors()
}
DoorOpen(BG_AB_OBJECT_GATE_A);
DoorOpen(BG_AB_OBJECT_GATE_H);
+
+ // Achievement: Let's Get This Done
+ StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, AB_EVENT_START_BATTLE);
}
void BattlegroundAB::AddPlayer(Player* player)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
index 38c8f4a21d4..c86076f0250 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h
@@ -181,6 +181,8 @@ enum BG_AB_Objectives
#define BG_AB_NotABBGWeekendReputationTicks 200
#define BG_AB_ABBGWeekendReputationTicks 150
+#define AB_EVENT_START_BATTLE 9158 // Achievement: Let's Get This Done
+
// x, y, z, o
const float BG_AB_NodePositions[BG_AB_DYNAMIC_NODES_COUNT][4] = {
{1166.785f, 1200.132f, -56.70859f, 0.9075713f}, // stables
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
index 01f62bfcf35..f2e8c2bf0af 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp
@@ -420,6 +420,9 @@ void BattlegroundAV::StartingEventOpenDoors()
DoorOpen(BG_AV_OBJECT_DOOR_H);
DoorOpen(BG_AV_OBJECT_DOOR_A);
+
+ // Achievement: The Alterac Blitz
+ StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, AV_EVENT_START_BATTLE);
}
void BattlegroundAV::AddPlayer(Player* player)
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
index e2902f8fd2d..82e231c63fa 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h
@@ -50,6 +50,8 @@ class Battleground;
#define BG_AV_KILL_SURVIVING_CAPTAIN 2
#define BG_AV_REP_SURVIVING_CAPTAIN 125
+#define AV_EVENT_START_BATTLE 9166 // Achievement: The Alterac Blitz
+
enum BG_AV_Sounds
{ //TODO: get out if there comes a sound when neutral team captures mine
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
index 4595a061e1a..cbc3ec85055 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp
@@ -120,6 +120,9 @@ void BattlegroundEY::StartingEventOpenDoors()
uint8 buff = urand(0, 2);
SpawnBGObject(BG_EY_OBJECT_SPEEDBUFF_FEL_REAVER + buff + i * 3, RESPAWN_IMMEDIATELY);
}
+
+ // Achievement: Flurry
+ StartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EY_EVENT_START_BATTLE);
}
void BattlegroundEY::AddPoints(uint32 Team, uint32 Points)
@@ -193,7 +196,6 @@ void BattlegroundEY::CheckSomeoneLeftPoint()
//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 (!player->CanCaptureTowerPoint() || !player->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
index 5f89e0d7021..baa9ca30cff 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h
@@ -220,6 +220,8 @@ enum EYBattlegroundObjectTypes
#define BG_EY_NotEYWeekendHonorTicks 330
#define BG_EY_EYWeekendHonorTicks 200
+#define EY_EVENT_START_BATTLE 13180 // Achievement: Flurry
+
enum BG_EY_Score
{
BG_EY_WARNING_NEAR_VICTORY_SCORE = 1400,
diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt
index 117a8f680ee..745e5962eb6 100644
--- a/src/server/game/CMakeLists.txt
+++ b/src/server/game/CMakeLists.txt
@@ -30,6 +30,7 @@ file(GLOB_RECURSE sources_Globals Globals/*.cpp Globals/*.h)
file(GLOB_RECURSE sources_Grids Grids/*.cpp Grids/*.h)
file(GLOB_RECURSE sources_Groups Groups/*.cpp Groups/*.h)
file(GLOB_RECURSE sources_Guilds Guilds/*.cpp Guilds/*.h)
+file(GLOB_RECURSE sources_Handlers Handlers/*.cpp Server/*.h)
file(GLOB_RECURSE sources_Instances Instances/*.cpp Instances/*.h)
file(GLOB_RECURSE sources_Loot Loot/*.cpp Loot/*.h)
file(GLOB_RECURSE sources_Mails Mails/*.cpp Mails/*.h)
@@ -79,6 +80,7 @@ set(game_STAT_SRCS
${sources_Grids}
${sources_Groups}
${sources_Guilds}
+ ${sources_Handlers}
${sources_Instances}
${sources_Loot}
${sources_Mails}
@@ -102,6 +104,7 @@ set(game_STAT_SRCS
include_directories(
${CMAKE_BINARY_DIR}
+ ${CMAKE_SOURCE_DIR}/dep/g3dlite/include
${CMAKE_SOURCE_DIR}/dep/mersennetwister
${CMAKE_SOURCE_DIR}/dep/SFMT
${CMAKE_SOURCE_DIR}/dep/zlib
@@ -114,12 +117,10 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/CountedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Policies
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_CURRENT_SOURCE_DIR}
@@ -164,12 +165,14 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Grids
${CMAKE_CURRENT_SOURCE_DIR}/Groups
${CMAKE_CURRENT_SOURCE_DIR}/Guilds
+ ${CMAKE_CURRENT_SOURCE_DIR}/Handlers
${CMAKE_CURRENT_SOURCE_DIR}/Instances
${CMAKE_CURRENT_SOURCE_DIR}/Loot
${CMAKE_CURRENT_SOURCE_DIR}/Mails
${CMAKE_CURRENT_SOURCE_DIR}/Maps
${CMAKE_CURRENT_SOURCE_DIR}/Miscellaneous
${CMAKE_CURRENT_SOURCE_DIR}/Movement
+ ${CMAKE_CURRENT_SOURCE_DIR}/Movement/Spline
${CMAKE_CURRENT_SOURCE_DIR}/Movement/MovementGenerators
${CMAKE_CURRENT_SOURCE_DIR}/Movement/Waypoints
${CMAKE_CURRENT_SOURCE_DIR}/OutdoorPvP
@@ -179,7 +182,6 @@ include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/Reputation
${CMAKE_CURRENT_SOURCE_DIR}/Scripting
${CMAKE_CURRENT_SOURCE_DIR}/Server/Protocol
- ${CMAKE_CURRENT_SOURCE_DIR}/Server/Protocol/Handlers
${CMAKE_CURRENT_SOURCE_DIR}/Server
${CMAKE_CURRENT_SOURCE_DIR}/Skills
${CMAKE_CURRENT_SOURCE_DIR}/Spells
diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp
index ef91d39e6cb..b0c0bbf6890 100755
--- a/src/server/game/Chat/Commands/Level2.cpp
+++ b/src/server/game/Chat/Commands/Level2.cpp
@@ -332,8 +332,8 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel, a.email, a.last_ip, a.last_login, a.mutetime "
"FROM account a "
"LEFT JOIN account_access aa "
- "ON (a.id = aa.id) "
- "WHERE a.id = '%u'", accId);
+ "ON (a.id = aa.id AND (aa.RealmID = -1 OR aa.RealmID = %u)) "
+ "WHERE a.id = '%u'", realmID, accId);
if (result)
{
Field* fields = result->Fetch();
@@ -714,19 +714,20 @@ bool ChatHandler::HandleLookupPlayerIpCommand(const char* args)
char* limit_str;
Player *chr = getSelectedPlayer();
- if (chr == NULL)
+ if (!*args)
{
- if (!*args)
+ // NULL only if used from console
+ if (!chr || chr == GetSession()->GetPlayer())
return false;
- ip = strtok ((char*)args, " ");
- limit_str = strtok (NULL, " ");
- limit = limit_str ? atoi (limit_str) : -1;
+ ip = chr->GetSession()->GetRemoteAddress();
+ limit = -1;
}
else
{
- ip = chr->GetSession()->GetRemoteAddress();
- limit = -1;
+ ip = strtok ((char*)args, " ");
+ limit_str = strtok (NULL, " ");
+ limit = limit_str ? atoi (limit_str) : -1;
}
LoginDatabase.EscapeString(ip);
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index df35a8ed906..1cb07fca4a8 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -3690,6 +3690,9 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
PSendSysMessage(LANG_MOVEGENS_LIST, (unit->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), unit->GetGUIDLow());
MotionMaster* mm = unit->GetMotionMaster();
+ float x,y,z;
+ mm->GetDestination(x,y,z);
+
for (uint8 i = 0; i < MAX_MOTION_SLOT; ++i)
{
MovementGenerator* mg = mm->GetMotionSlot(i);
@@ -3705,48 +3708,55 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
case WAYPOINT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_WAYPOINT); break;
case ANIMAL_RANDOM_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_ANIMAL_RANDOM); break;
case CONFUSED_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_CONFUSED); break;
- case TARGETED_MOTION_TYPE:
+ case CHASE_MOTION_TYPE:
{
+ Unit* target = NULL;
if (unit->GetTypeId() == TYPEID_PLAYER)
- {
- TargetedMovementGenerator<Player> const* mgen = static_cast<TargetedMovementGenerator<Player> const*>(mg);
- Unit* target = mgen->GetTarget();
- if (target)
- PSendSysMessage(LANG_MOVEGENS_TARGETED_PLAYER, target->GetName(), target->GetGUIDLow());
- else
- SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
- }
+ target = static_cast<ChaseMovementGenerator<Player> const*>(mg)->GetTarget();
else
- {
- TargetedMovementGenerator<Creature> const* mgen = static_cast<TargetedMovementGenerator<Creature> const*>(mg);
- Unit* target = mgen->GetTarget();
- if (target)
- PSendSysMessage(LANG_MOVEGENS_TARGETED_CREATURE, target->GetName(), target->GetGUIDLow());
- else
- SendSysMessage(LANG_MOVEGENS_TARGETED_NULL);
- }
+ target = static_cast<ChaseMovementGenerator<Creature> const*>(mg)->GetTarget();
+
+ if (!target)
+ SendSysMessage(LANG_MOVEGENS_CHASE_NULL);
+ else if (target->GetTypeId() == TYPEID_PLAYER)
+ PSendSysMessage(LANG_MOVEGENS_CHASE_PLAYER, target->GetName(), target->GetGUIDLow());
+ else
+ PSendSysMessage(LANG_MOVEGENS_CHASE_CREATURE, target->GetName(), target->GetGUIDLow());
break;
}
+ case FOLLOW_MOTION_TYPE:
+ {
+ Unit* target = NULL;
+ if (unit->GetTypeId() == TYPEID_PLAYER)
+ target = static_cast<FollowMovementGenerator<Player> const*>(mg)->GetTarget();
+ else
+ target = static_cast<FollowMovementGenerator<Creature> const*>(mg)->GetTarget();
+
+ if (!target)
+ SendSysMessage(LANG_MOVEGENS_FOLLOW_NULL);
+ else if (target->GetTypeId() == TYPEID_PLAYER)
+ PSendSysMessage(LANG_MOVEGENS_FOLLOW_PLAYER, target->GetName(), target->GetGUIDLow());
+ else
+ PSendSysMessage(LANG_MOVEGENS_FOLLOW_CREATURE, target->GetName(), target->GetGUIDLow());
+ break;
+ }
case HOME_MOTION_TYPE:
+ {
if (unit->GetTypeId() == TYPEID_UNIT)
- {
- float x, y, z;
- mg->GetDestination(x, y, z);
PSendSysMessage(LANG_MOVEGENS_HOME_CREATURE, x, y, z);
- }
else
SendSysMessage(LANG_MOVEGENS_HOME_PLAYER);
break;
+ }
case FLIGHT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FLIGHT); break;
case POINT_MOTION_TYPE:
{
- float x, y, z;
- mg->GetDestination(x, y, z);
PSendSysMessage(LANG_MOVEGENS_POINT, x, y, z);
break;
}
case FLEEING_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_FEAR); break;
case DISTRACT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_DISTRACT); break;
+ case EFFECT_MOTION_TYPE: SendSysMessage(LANG_MOVEGENS_EFFECT); break;
default:
PSendSysMessage(LANG_MOVEGENS_UNKNOWN, mg->GetMovementGeneratorType());
break;
@@ -4038,19 +4048,14 @@ bool ChatHandler::HandleComeToMeCommand(const char *args)
if (!newFlagStr)
return false;
- uint32 newFlags = (uint32)strtoul(newFlagStr, NULL, 0);
-
Creature* caster = getSelectedCreature();
if (!caster)
{
- m_session->GetPlayer()->SetUnitMovementFlags(newFlags);
SendSysMessage(LANG_SELECT_CREATURE);
SetSentErrorMessage(true);
return false;
}
- caster->SetUnitMovementFlags(newFlags);
-
Player* player = m_session->GetPlayer();
caster->GetMotionMaster()->MovePoint(0, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ());
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 0bcd1a7864b..a745c5a2f13 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -63,7 +63,7 @@ bool Condition::Meets(Player* player, Unit* invoker)
case CONDITION_REPUTATION_RANK:
{
if (FactionEntry const* faction = sFactionStore.LookupEntry(mConditionValue1))
- condMeets = uint32(player->GetReputationMgr().GetRank(faction)) == mConditionValue2;
+ condMeets = (mConditionValue2 & (1 << player->GetReputationMgr().GetRank(faction)));
break;
}
case CONDITION_ACHIEVEMENT:
@@ -73,10 +73,10 @@ bool Condition::Meets(Player* player, Unit* invoker)
condMeets = player->GetTeam() == mConditionValue1;
break;
case CONDITION_CLASS:
- condMeets = player->getClass() == mConditionValue1;
+ condMeets = player->getClassMask() & mConditionValue1;
break;
case CONDITION_RACE:
- condMeets = player->getRace() == mConditionValue1;
+ condMeets = player->getRaceMask() & mConditionValue1;
break;
case CONDITION_SKILL:
condMeets = player->HasSkill(mConditionValue1) && player->GetBaseSkillValue(mConditionValue1) >= mConditionValue2;
@@ -243,33 +243,33 @@ ConditionMgr::~ConditionMgr()
ConditionList ConditionMgr::GetConditionReferences(uint32 refId)
{
ConditionList conditions;
- ConditionReferenceMap::const_iterator ref = m_ConditionReferenceMap.find(refId);
- if (ref != m_ConditionReferenceMap.end())
+ ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(refId);
+ if (ref != ConditionReferenceStore.end())
conditions = (*ref).second;
return conditions;
}
bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList const& conditions, Unit* invoker /*= NULL*/)
{
- std::map<uint32, bool> ElseGroupMap;
+ std::map<uint32, bool> ElseGroupStore;
for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "ConditionMgr::IsPlayerMeetToConditionList condType: %u val1: %u", (*i)->mConditionType, (*i)->mConditionValue1);
if ((*i)->isLoaded())
{
- std::map<uint32, bool>::const_iterator itr = ElseGroupMap.find((*i)->mElseGroup);
- if (itr == ElseGroupMap.end())
- ElseGroupMap[(*i)->mElseGroup] = true;
+ std::map<uint32, bool>::const_iterator itr = ElseGroupStore.find((*i)->mElseGroup);
+ if (itr == ElseGroupStore.end())
+ ElseGroupStore[(*i)->mElseGroup] = true;
else if (!(*itr).second)
continue;
if ((*i)->mReferenceId)//handle reference
{
- ConditionReferenceMap::const_iterator ref = m_ConditionReferenceMap.find((*i)->mReferenceId);
- if (ref != m_ConditionReferenceMap.end())
+ ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->mReferenceId);
+ if (ref != ConditionReferenceStore.end())
{
if (!IsPlayerMeetToConditionList(player, (*ref).second, invoker))
- ElseGroupMap[(*i)->mElseGroup] = false;
+ ElseGroupStore[(*i)->mElseGroup] = false;
}
else
{
@@ -281,11 +281,11 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player, ConditionList con
else //handle normal condition
{
if (!(*i)->Meets(player, invoker))
- ElseGroupMap[(*i)->mElseGroup] = false;
+ ElseGroupStore[(*i)->mElseGroup] = false;
}
}
}
- for (std::map<uint32, bool>::const_iterator i = ElseGroupMap.begin(); i != ElseGroupMap.end(); ++i)
+ for (std::map<uint32, bool>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
if (i->second)
return true;
@@ -309,19 +309,19 @@ bool ConditionMgr::IsPlayerMeetToConditions(Player* player, ConditionList const&
return result;
}
-ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType sType, uint32 uEntry)
+ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry)
{
ConditionList spellCond;
- if (sType > CONDITION_SOURCE_TYPE_NONE && sType < CONDITION_SOURCE_TYPE_MAX)
+ if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
{
- ConditionMap::const_iterator itr = m_ConditionMap.find(sType);
- if (itr != m_ConditionMap.end())
+ ConditionContainer::const_iterator itr = ConditionStore.find(sourceType);
+ if (itr != ConditionStore.end())
{
- ConditionTypeMap::const_iterator i = (*itr).second.find(uEntry);
+ ConditionTypeContainer::const_iterator i = (*itr).second.find(entry);
if (i != (*itr).second.end())
{
spellCond = (*i).second;
- sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u", uint32(sType), uEntry);
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u", uint32(sourceType), entry);
}
}
}
@@ -331,10 +331,10 @@ ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType
ConditionList ConditionMgr::GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID)
{
ConditionList cond;
- VehicleSpellConditionMap::const_iterator itr = m_VehicleSpellConditions.find(creatureID);
- if (itr != m_VehicleSpellConditions.end())
+ VehicleSpellConditionContainer::const_iterator itr = VehicleSpellConditionStore.find(creatureID);
+ if (itr != VehicleSpellConditionStore.end())
{
- ConditionTypeMap::const_iterator i = (*itr).second.find(spellID);
+ ConditionTypeContainer::const_iterator i = (*itr).second.find(spellID);
if (i != (*itr).second.end())
{
cond = (*i).second;
@@ -344,6 +344,22 @@ ConditionList ConditionMgr::GetConditionsForVehicleSpell(uint32 creatureID, uint
return cond;
}
+ConditionList ConditionMgr::GetConditionsForSmartEvent(uint32 entry, uint32 eventId, uint32 sourceType)
+{
+ ConditionList cond;
+ SmartEventConditionContainer::const_iterator itr = SmartEventConditionStore.find(std::make_pair(entry, sourceType));
+ if (itr != SmartEventConditionStore.end())
+ {
+ ConditionTypeContainer::const_iterator i = (*itr).second.find(eventId + 1);
+ if (i != (*itr).second.end())
+ {
+ cond = (*i).second;
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForSmartEvent: found conditions for Smart Event entry %u event_id %u", entry, eventId);
+ }
+ }
+ return cond;
+}
+
void ConditionMgr::LoadConditions(bool isReload)
{
uint32 oldMSTime = getMSTime();
@@ -374,7 +390,7 @@ void ConditionMgr::LoadConditions(bool isReload)
sObjectMgr->LoadGossipMenuItems();
}
- QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, ElseGroup, ConditionTypeOrReference, "
+ QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, "
" ConditionValue1, ConditionValue2, ConditionValue3, ErrorTextId, ScriptName FROM conditions");
if (!result)
@@ -395,13 +411,14 @@ void ConditionMgr::LoadConditions(bool isReload)
int32 iSourceTypeOrReferenceId = fields[0].GetInt32();
cond->mSourceGroup = fields[1].GetUInt32();
cond->mSourceEntry = fields[2].GetUInt32();
- cond->mElseGroup = fields[3].GetUInt32();
- int32 iConditionTypeOrReference = fields[4].GetInt32();
- cond->mConditionValue1 = fields[5].GetUInt32();
- cond->mConditionValue2 = fields[6].GetUInt32();
- cond->mConditionValue3 = fields[7].GetUInt32();
- cond->ErrorTextd = fields[8].GetUInt32();
- cond->mScriptId = sObjectMgr->GetScriptId(fields[9].GetCString());
+ cond->mSourceId = fields[3].GetUInt32();
+ cond->mElseGroup = fields[4].GetUInt32();
+ int32 iConditionTypeOrReference = fields[5].GetInt32();
+ cond->mConditionValue1 = fields[6].GetUInt32();
+ cond->mConditionValue2 = fields[7].GetUInt32();
+ cond->mConditionValue3 = fields[8].GetUInt32();
+ cond->ErrorTextd = fields[9].GetUInt32();
+ cond->mScriptId = sObjectMgr->GetScriptId(fields[10].GetCString());
if (iConditionTypeOrReference >= 0)
cond->mConditionType = ConditionType(iConditionTypeOrReference);
@@ -440,12 +457,12 @@ void ConditionMgr::LoadConditions(bool isReload)
if (iSourceTypeOrReferenceId < 0)//it is a reference template
{
uint32 uRefId = abs(iSourceTypeOrReferenceId);
- if (m_ConditionReferenceMap.find(uRefId) == m_ConditionReferenceMap.end())//make sure we have a list for our conditions, based on reference id
+ if (ConditionReferenceStore.find(uRefId) == ConditionReferenceStore.end())//make sure we have a list for our conditions, based on reference id
{
ConditionList mCondList;
- m_ConditionReferenceMap[uRefId] = mCondList;
+ ConditionReferenceStore[uRefId] = mCondList;
}
- m_ConditionReferenceMap[uRefId].push_back(cond);//add to reference storage
+ ConditionReferenceStore[uRefId].push_back(cond);//add to reference storage
count++;
continue;
}//end of reference templates
@@ -468,83 +485,102 @@ void ConditionMgr::LoadConditions(bool isReload)
}
else if (cond->mSourceGroup)
{
- bool bIsDone = false;
+ bool valid = false;
//handle grouped conditions
switch (cond->mSourceType)
{
case CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Creature.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Creature.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Disenchant.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Disenchant.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Fishing.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Fishing.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Gameobject.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Gameobject.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Item.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Item.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Mail.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Mail.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Milling.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Milling.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Pickpocketing.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Pickpocketing.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Prospecting.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Prospecting.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Reference.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Reference.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Skinning.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Skinning.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE:
- bIsDone = addToLootTemplate(cond, LootTemplates_Spell.GetLootForConditionFill(cond->mSourceGroup));
+ valid = addToLootTemplate(cond, LootTemplates_Spell.GetLootForConditionFill(cond->mSourceGroup));
break;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
- bIsDone = addToGossipMenus(cond);
+ valid = addToGossipMenus(cond);
break;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
- bIsDone = addToGossipMenuItems(cond);
+ valid = addToGossipMenuItems(cond);
break;
case CONDITION_SOURCE_TYPE_VEHICLE_SPELL:
{
//if no list for vehicle create one
- if (m_VehicleSpellConditions.find(cond->mSourceGroup) == m_VehicleSpellConditions.end())
+ if (VehicleSpellConditionStore.find(cond->mSourceGroup) == VehicleSpellConditionStore.end())
{
- ConditionTypeMap cmap;
- m_VehicleSpellConditions[cond->mSourceGroup] = cmap;
+ ConditionTypeContainer cmap;
+ VehicleSpellConditionStore[cond->mSourceGroup] = cmap;
}
//if no list for vehicle's spell create one
- if (m_VehicleSpellConditions[cond->mSourceGroup].find(cond->mSourceEntry) == m_VehicleSpellConditions[cond->mSourceGroup].end())
+ if (VehicleSpellConditionStore[cond->mSourceGroup].find(cond->mSourceEntry) == VehicleSpellConditionStore[cond->mSourceGroup].end())
{
ConditionList clist;
- m_VehicleSpellConditions[cond->mSourceGroup][cond->mSourceEntry] = clist;
+ VehicleSpellConditionStore[cond->mSourceGroup][cond->mSourceEntry] = clist;
}
- m_VehicleSpellConditions[cond->mSourceGroup][cond->mSourceEntry].push_back(cond);
- bIsDone = true;
+ VehicleSpellConditionStore[cond->mSourceGroup][cond->mSourceEntry].push_back(cond);
+ valid = true;
++count;
continue; // do not add to m_AllocatedMemory to avoid double deleting
}
+ case CONDITION_SOURCE_TYPE_SMART_EVENT:
+ {
+ // If the entry does not exist, create a new list
+ std::pair<uint32, uint32> key = std::make_pair(cond->mSourceEntry, cond->mSourceId);
+ if (SmartEventConditionStore.find(key) == SmartEventConditionStore.end())
+ {
+ ConditionTypeContainer cmap;
+ SmartEventConditionStore[key] = cmap;
+ }
+ if (SmartEventConditionStore[key].find(cond->mSourceGroup) == SmartEventConditionStore[key].end())
+ {
+ ConditionList clist;
+ SmartEventConditionStore[key][cond->mSourceGroup] = clist;
+ }
+ SmartEventConditionStore[key][cond->mSourceGroup].push_back(cond);
+ valid = true;
+ ++count;
+ continue;
+ }
default:
break;
}
- if (!bIsDone)
+ if (!valid)
{
sLog->outErrorDb("Not handled grouped condition, SourceGroup %u", cond->mSourceGroup);
delete cond;
}
else
{
- m_AllocatedMemory.push_back(cond);
+ AllocatedMemoryStore.push_back(cond);
++count;
}
continue;
@@ -552,21 +588,21 @@ void ConditionMgr::LoadConditions(bool isReload)
//handle not grouped conditions
//make sure we have a storage list for our SourceType
- if (m_ConditionMap.find(cond->mSourceType) == m_ConditionMap.end())
+ if (ConditionStore.find(cond->mSourceType) == ConditionStore.end())
{
- ConditionTypeMap mTypeMap;
- m_ConditionMap[cond->mSourceType] = mTypeMap;//add new empty list for SourceType
+ ConditionTypeContainer mTypeMap;
+ ConditionStore[cond->mSourceType] = mTypeMap;//add new empty list for SourceType
}
//make sure we have a condition list for our SourceType's entry
- if (m_ConditionMap[cond->mSourceType].find(cond->mSourceEntry) == m_ConditionMap[cond->mSourceType].end())
+ if (ConditionStore[cond->mSourceType].find(cond->mSourceEntry) == ConditionStore[cond->mSourceType].end())
{
ConditionList mCondList;
- m_ConditionMap[cond->mSourceType][cond->mSourceEntry] = mCondList;
+ ConditionStore[cond->mSourceType][cond->mSourceEntry] = mCondList;
}
//add new Condition to storage based on Type/Entry
- m_ConditionMap[cond->mSourceType][cond->mSourceEntry].push_back(cond);
+ ConditionStore[cond->mSourceType][cond->mSourceEntry].push_back(cond);
++count;
}
while (result->NextRow());
@@ -1004,6 +1040,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
break;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
+ case CONDITION_SOURCE_TYPE_SMART_EVENT:
case CONDITION_SOURCE_TYPE_NONE:
default:
break;
@@ -1180,9 +1217,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
}
case CONDITION_CLASS:
{
- if (cond->mConditionValue1 >= MAX_CLASSES)
+ if (!(cond->mConditionValue1 & CLASSMASK_ALL_PLAYABLE))
{
- sLog->outErrorDb("Class condition has non existing class (%u), skipped", cond->mConditionValue1);
+ sLog->outErrorDb("Class condition has non existing classmask (%u), skipped", cond->mConditionValue1 & ~CLASSMASK_ALL_PLAYABLE);
return false;
}
@@ -1192,9 +1229,9 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
}
case CONDITION_RACE:
{
- if (cond->mConditionValue1 >= MAX_RACES)
+ if (!(cond->mConditionValue1 & RACEMASK_ALL_PLAYABLE))
{
- sLog->outErrorDb("Race condition has non existing race (%u), skipped", cond->mConditionValue1);
+ sLog->outErrorDb("Race condition has non existing racemask (%u), skipped", cond->mConditionValue1 & ~RACEMASK_ALL_PLAYABLE);
return false;
}
@@ -1375,18 +1412,31 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond)
void ConditionMgr::Clean()
{
- for (ConditionReferenceMap::iterator itr = m_ConditionReferenceMap.begin(); itr != m_ConditionReferenceMap.end(); ++itr)
+ for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
{
for (ConditionList::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
delete *it;
itr->second.clear();
}
- m_ConditionReferenceMap.clear();
+ ConditionReferenceStore.clear();
+
+ for (ConditionContainer::iterator itr = ConditionStore.begin(); itr != ConditionStore.end(); ++itr)
+ {
+ for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ {
+ for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ delete *i;
+ it->second.clear();
+ }
+ itr->second.clear();
+ }
+
+ ConditionStore.clear();
- for (ConditionMap::iterator itr = m_ConditionMap.begin(); itr != m_ConditionMap.end(); ++itr)
+ for (VehicleSpellConditionContainer::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
{
- for (ConditionTypeMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
{
for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
@@ -1395,11 +1445,11 @@ void ConditionMgr::Clean()
itr->second.clear();
}
- m_ConditionMap.clear();
+ VehicleSpellConditionStore.clear();
- for (VehicleSpellConditionMap::iterator itr = m_VehicleSpellConditions.begin(); itr != m_VehicleSpellConditions.end(); ++itr)
+ for (SmartEventConditionContainer::iterator itr = SmartEventConditionStore.begin(); itr != SmartEventConditionStore.end(); ++itr)
{
- for (ConditionTypeMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
{
for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
@@ -1408,11 +1458,11 @@ void ConditionMgr::Clean()
itr->second.clear();
}
- m_VehicleSpellConditions.clear();
+ SmartEventConditionStore.clear();
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
- for (std::list<Condition*>::const_iterator itr = m_AllocatedMemory.begin(); itr != m_AllocatedMemory.end(); ++itr)
+ for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
delete *itr;
- m_AllocatedMemory.clear();
+ AllocatedMemoryStore.clear();
}
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 7e11a9420e7..a9bb97251da 100755
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -96,7 +96,8 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_QUEST_ACCEPT = 19, //DONE
CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20, //DONE
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21, //DONE
- CONDITION_SOURCE_TYPE_MAX = 22//MAX
+ CONDITION_SOURCE_TYPE_SMART_EVENT = 22, //DONE
+ CONDITION_SOURCE_TYPE_MAX = 23 //MAX
};
struct Condition
@@ -104,6 +105,7 @@ struct Condition
ConditionSourceType mSourceType; //SourceTypeOrReferenceId
uint32 mSourceGroup;
uint32 mSourceEntry;
+ uint32 mSourceId; // So far, only used in CONDITION_SOURCE_TYPE_SMART_EVENT
uint32 mElseGroup;
ConditionType mConditionType; //ConditionTypeOrReference
uint32 mConditionValue1;
@@ -133,11 +135,12 @@ struct Condition
};
typedef std::list<Condition*> ConditionList;
-typedef std::map<uint32, ConditionList> ConditionTypeMap;
-typedef std::map<ConditionSourceType, ConditionTypeMap> ConditionMap;
-typedef std::map<uint32, ConditionTypeMap> VehicleSpellConditionMap;
+typedef std::map<uint32, ConditionList> ConditionTypeContainer;
+typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer;
+typedef std::map<uint32, ConditionTypeContainer> VehicleSpellConditionContainer;
+typedef std::map<std::pair<uint32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
-typedef std::map<uint32, ConditionList> ConditionReferenceMap;//only used for references
+typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
class ConditionMgr
{
@@ -153,7 +156,8 @@ class ConditionMgr
ConditionList GetConditionReferences(uint32 refId);
bool IsPlayerMeetToConditions(Player* player, ConditionList const& conditions, Unit* invoker = NULL);
- ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sType, uint32 uEntry);
+ ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
+ ConditionList GetConditionsForSmartEvent(uint32 entry, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureID, uint32 spellID);
private:
@@ -179,15 +183,17 @@ class ConditionMgr
sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU ||
sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION ||
- sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL);
+ sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
+ sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
}
void Clean(); // free up resources
- std::list<Condition*> m_AllocatedMemory; // some garbage collection :)
+ std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
- ConditionMap m_ConditionMap;
- ConditionReferenceMap m_ConditionReferenceMap;
- VehicleSpellConditionMap m_VehicleSpellConditions;
+ ConditionContainer ConditionStore;
+ ConditionReferenceContainer ConditionReferenceStore;
+ VehicleSpellConditionContainer VehicleSpellConditionStore;
+ SmartEventConditionContainer SmartEventConditionStore;
};
#define sConditionMgr ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index e0a16d4868b..ac7343e8f23 100755
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -72,6 +72,54 @@ LFGMgr::~LFGMgr()
delete it->second;
}
+void LFGMgr::_LoadFromDB(Field* fields, uint64 guid)
+{
+ if (!fields)
+ return;
+
+ if (!IS_GROUP(guid))
+ return;
+
+ uint32 dungeon = fields[16].GetUInt32();
+
+ uint8 state = fields[17].GetUInt8();
+
+ if (!dungeon || !state)
+ return;
+
+ SetDungeon(guid, dungeon);
+
+ switch (state)
+ {
+ case LFG_STATE_DUNGEON:
+ case LFG_STATE_FINISHED_DUNGEON:
+ SetState(guid, (LfgState)state);
+ break;
+ default:
+ break;
+ }
+}
+
+void LFGMgr::_SaveToDB(uint64 guid, uint32 db_guid)
+{
+ if (!IS_GROUP(guid))
+ return;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
+
+ stmt->setUInt32(0, db_guid);
+
+ CharacterDatabase.Execute(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_LFG_DATA);
+ stmt->setUInt32(0, db_guid);
+
+ stmt->setUInt32(1, GetDungeon(guid));
+ stmt->setUInt32(2, GetState(guid));
+
+ CharacterDatabase.Execute(stmt);
+}
+
/// Load rewards for completing dungeons
void LFGMgr::LoadRewards()
{
@@ -245,7 +293,8 @@ void LFGMgr::Update(uint32 diff)
UpdateProposal(m_lfgProposalId, guid, true);
}
else
- currentQueue.push_back(frontguid); // Lfg group not found, add this group to the queue.
+ if (std::find(currentQueue.begin(), currentQueue.end(), frontguid) == currentQueue.end()) //already in queue?
+ currentQueue.push_back(frontguid); // Lfg group not found, add this group to the queue.
firstNew.clear();
}
}
@@ -382,7 +431,10 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
else if (DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, dungeon->map, player))
locktype = LFG_LOCKSTATUS_RAID_LOCKED;
else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
- locktype = LFG_LOCKSTATUS_RAID_LOCKED;
+ {
+ if (!player->GetGroup() || !player->GetGroup()->isLFGGroup() || GetDungeon(player->GetGroup()->GetGUID(), true) != dungeon->ID || GetState(player->GetGroup()->GetGUID()) != LFG_STATE_DUNGEON)
+ locktype = LFG_LOCKSTATUS_RAID_LOCKED;
+ }
else if (dungeon->minlevel > level)
locktype = LFG_LOCKSTATUS_TOO_LOW_LEVEL;
else if (dungeon->maxlevel < level)
@@ -431,7 +483,7 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
void LFGMgr::Join(Player* player, uint8 roles, const LfgDungeonSet& selectedDungeons, const std::string& comment)
{
if (!player || !player->GetSession() || selectedDungeons.empty())
- return;
+ return;
Group* grp = player->GetGroup();
uint64 guid = player->GetGUID();
@@ -808,7 +860,7 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
{
uint64 guid = (*it);
LfgQueueInfoMap::iterator itQueue = m_QueueInfoMap.find(guid);
- if (itQueue == m_QueueInfoMap.end())
+ if (itQueue == m_QueueInfoMap.end() || GetState(guid) != LFG_STATE_QUEUED)
{
sLog->outError("LFGMgr::CheckCompatibility: [" UI64FMTD "] is not queued but listed as queued!", (*it));
RemoveFromQueue(guid);
@@ -923,6 +975,42 @@ bool LFGMgr::CheckCompatibility(LfgGuidList check, LfgProposal*& pProposal)
if (numPlayers != MAXGROUPSIZE)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::CheckCompatibility: (%s) Compatibles but not match. Players(%u)", strGuids.c_str(), numPlayers);
+ uint8 Tanks_Needed = LFG_TANKS_NEEDED;
+ uint8 Healers_Needed = LFG_HEALERS_NEEDED;
+ uint8 Dps_Needed = LFG_DPS_NEEDED;
+ for (LfgQueueInfoMap::const_iterator itQueue = pqInfoMap.begin(); itQueue != pqInfoMap.end(); ++itQueue)
+ {
+ LfgQueueInfo* queue = itQueue->second;
+ for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer)
+ {
+ uint8 roles = itPlayer->second;
+ if ((roles & ROLE_TANK) && Tanks_Needed > 0)
+ --Tanks_Needed;
+ else if ((roles & ROLE_HEALER) && Healers_Needed > 0)
+ --Healers_Needed;
+ else if ((roles & ROLE_DAMAGE) && Dps_Needed > 0)
+ --Dps_Needed;
+ }
+ }
+ for (PlayerSet::const_iterator itPlayers = players.begin(); itPlayers != players.end(); ++itPlayers)
+ {
+ for (LfgQueueInfoMap::const_iterator itQueue = pqInfoMap.begin(); itQueue != pqInfoMap.end(); ++itQueue)
+ {
+ LfgQueueInfo* queue = itQueue->second;
+ if (!queue)
+ continue;
+
+ for (LfgRolesMap::const_iterator itPlayer = queue->roles.begin(); itPlayer != queue->roles.end(); ++itPlayer)
+ {
+ if (*itPlayers == ObjectAccessor::FindPlayer(itPlayer->first))
+ {
+ queue->tanks = Tanks_Needed;
+ queue->healers = Healers_Needed;
+ queue->dps = Dps_Needed;
+ }
+ }
+ }
+ }
return true;
}
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::CheckCompatibility: (%s) MATCH! Group formed", strGuids.c_str());
@@ -1078,6 +1166,11 @@ void LFGMgr::UpdateRoleCheck(uint64 gguid, uint64 guid /* = 0 */, uint8 roles /*
}
m_QueueInfoMap[gguid] = pqInfo;
+ if(GetState(gguid) != LFG_STATE_NONE)
+ {
+ LfgGuidList& currentQueue = m_currentQueue[team];
+ currentQueue.push_front(gguid);
+ }
AddToQueue(gguid, team);
}
@@ -1384,6 +1477,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
break;
}
}
+ m_teleport.push_back(pguid);
grp->SetLfgRoles(pguid, pProposal->players[pguid]->role);
SetState(pguid, LFG_STATE_DUNGEON);
}
@@ -1395,6 +1489,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
uint64 gguid = grp->GetGUID();
SetDungeon(gguid, dungeon->Entry());
SetState(gguid, LFG_STATE_DUNGEON);
+ _SaveToDB(gguid, grp->GetDbStoreId());
// Remove players/groups from Queue
for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it)
@@ -1509,7 +1604,9 @@ void LFGMgr::RemoveProposal(LfgProposalMap::iterator itProposal, LfgUpdateType t
for (LfgGuidList::const_iterator it = pProposal->queues.begin(); it != pProposal->queues.end(); ++it)
{
uint64 guid = *it;
- AddToQueue(guid, team);
+ LfgGuidList& currentQueue = m_currentQueue[team];
+ currentQueue.push_front(guid); //Add GUID for high priority
+ AddToQueue(guid, team); //We have to add each GUID in newQueue to check for a new groups
}
delete pProposal;
@@ -1921,6 +2018,16 @@ const std::string& LFGMgr::GetComment(uint64 guid)
return m_Players[guid].GetComment();
}
+bool LFGMgr::IsTeleported(uint64 pguid)
+{
+ if (std::find(m_teleport.begin(), m_teleport.end(), pguid) != m_teleport.end())
+ {
+ m_teleport.remove(pguid);
+ return true;
+ }
+ return false;
+}
+
const LfgDungeonSet& LFGMgr::GetSelectedDungeons(uint64 guid)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::GetSelectedDungeons: [" UI64FMTD "]", guid);
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index 3e324f4b5f4..d10902b9553 100755
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -287,6 +287,9 @@ class LFGMgr
void InitializeLockedDungeons(Player* player);
+ void _LoadFromDB(Field* fields, uint64 guid);
+ void _SaveToDB(uint64 guid, uint32 db_guid);
+
void SetComment(uint64 guid, const std::string& comment);
const LfgLockMap& GetLockedDungeons(uint64 guid);
LfgState GetState(uint64 guid);
@@ -298,7 +301,9 @@ class LFGMgr
void RemoveGroupData(uint64 guid);
uint8 GetKicksLeft(uint64 gguid);
uint8 GetVotesNeeded(uint64 gguid);
+ bool IsTeleported(uint64 pguid);
void SetRoles(uint64 guid, uint8 roles);
+ void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
private:
@@ -306,10 +311,8 @@ class LFGMgr
const std::string& GetComment(uint64 gguid);
void RestoreState(uint64 guid);
void SetDungeon(uint64 guid, uint32 dungeon);
- void SetSelectedDungeons(uint64 guid, const LfgDungeonSet& dungeons);
void SetLockedDungeons(uint64 guid, const LfgLockMap& lock);
void DecreaseKicksLeft(uint64 guid);
- void NoExiste(uint8 lala);
// Queue
void AddToQueue(uint64 guid, uint8 queueId);
@@ -352,6 +355,7 @@ class LFGMgr
LfgGuidListMap m_currentQueue; ///< Ordered list. Used to find groups
LfgGuidListMap m_newToQueue; ///< New groups to add to queue
LfgCompatibleMap m_CompatibleMap; ///< Compatible dungeons
+ LfgGuidList m_teleport; ///< Players being teleported
// Rolecheck - Proposal - Vote Kicks
LfgRoleCheckMap m_RoleChecks; ///< Current Role checks
LfgProposalMap m_Proposals; ///< Current Proposals
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 2c6ba86ea8f..25682999f62 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -48,6 +48,8 @@
#include "Vehicle.h"
#include "SpellAuraEffects.h"
#include "Group.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
// apply implementation of the singletons
TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const
@@ -143,7 +145,7 @@ m_PlayerDamageReq(0), m_lootMoney(0), m_lootRecipient(0), m_lootRecipientGroup(0
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
-m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL)
+m_creatureInfo(NULL), m_creatureData(NULL), m_formation(NULL), m_path_id(0)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
@@ -332,6 +334,7 @@ bool Creature::InitEntry(uint32 Entry, uint32 /*team*/, const CreatureData* data
SetSpeed(MOVE_FLIGHT, 1.0f); // using 1.0 rate
SetFloatValue(OBJECT_FIELD_SCALE_X, cinfo->scale);
+ SetLevitate(canFly());
// checked at loading
m_defaultMovementType = MovementGeneratorType(cinfo->MovementType);
@@ -435,6 +438,17 @@ void Creature::Update(uint32 diff)
m_vehicleKit->Reset();
}
+ if (IsInWater())
+ {
+ if (canSwim())
+ AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ }
+ else
+ {
+ if (canWalk())
+ RemoveUnitMovementFlag(MOVEMENTFLAG_SWIMMING);
+ }
+
switch (m_deathState)
{
case JUST_ALIVED:
@@ -472,9 +486,7 @@ void Creature::Update(uint32 diff)
}
case CORPSE:
{
- m_Events.Update(diff);
- _UpdateSpells(diff);
-
+ Unit::Update(diff);
// deathstate changed on spells update, prevent problems
if (m_deathState != CORPSE)
break;
@@ -565,9 +577,6 @@ void Creature::Update(uint32 diff)
m_regenTimer = CREATURE_REGEN_INTERVAL;
break;
}
- case DEAD_FALLING:
- GetMotionMaster()->UpdateMotion(diff);
- break;
default:
break;
}
@@ -715,7 +724,7 @@ void Creature::Motion_Initialize()
i_motionMaster.Initialize();
}
else if (m_formation->isFormed())
- i_motionMaster.MoveIdle(MOTION_SLOT_IDLE); //wait the order of leader
+ i_motionMaster.MoveIdle(); //wait the order of leader
else
i_motionMaster.Initialize();
}
@@ -945,7 +954,8 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint3
m_startMove = getMSTime();
m_moveTime = time;*/
- SendMonsterMove(x, y, z, time);
+ float speed = GetDistance(x, y, z) / ((float)time * 0.001f);
+ MonsterMoveWithSpeed(x, y, z, speed);
}
Player* Creature::GetLootRecipient() const
@@ -1507,8 +1517,8 @@ void Creature::setDeathState(DeathState s)
if (m_formation && m_formation->getLeader() == this)
m_formation->FormationReset(true);
- if ((canFly() || IsFlying()) && FallGround())
- return;
+ if ((canFly() || IsFlying()))
+ i_motionMaster.MoveFall();
Unit::setDeathState(CORPSE);
}
@@ -1520,7 +1530,7 @@ void Creature::setDeathState(DeathState s)
SetLootRecipient(NULL);
ResetPlayerDamageReq();
CreatureTemplate const* cinfo = GetCreatureInfo();
- AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ SetWalk(true);
if (GetCreatureInfo()->InhabitType & INHABIT_AIR)
AddUnitMovementFlag(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING);
if (GetCreatureInfo()->InhabitType & INHABIT_WATER)
@@ -1536,24 +1546,6 @@ void Creature::setDeathState(DeathState s)
}
}
-bool Creature::FallGround()
-{
- // Let's abort after we called this function one time
- if (getDeathState() == DEAD_FALLING)
- return false;
-
- float x, y, z;
- GetPosition(x, y, z);
- // use larger distance for vmap height search than in most other cases
- float ground_Z = GetMap()->GetHeight(x, y, z, true, MAX_FALL_DISTANCE);
- if (fabs(ground_Z - z) < 0.1f)
- return false;
-
- GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND);
- Unit::setDeathState(DEAD_FALLING);
- return true;
-}
-
void Creature::Respawn(bool force)
{
DestroyForNearbyPlayers();
@@ -2417,3 +2409,25 @@ bool Creature::IsDungeonBoss() const
CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(GetEntry());
return cinfo && (cinfo->flags_extra & CREATURE_FLAG_EXTRA_DUNGEON_BOSS);
}
+
+void Creature::SetWalk(bool enable)
+{
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_WALK_MODE : SMSG_MOVE_SPLINE_SET_RUN_MODE, 9);
+ data.append(GetPackGUID());
+ SendMessageToSet(&data, true);
+}
+
+void Creature::SetLevitate(bool enable)
+{
+ if (enable)
+ AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ WorldPacket data(enable ? SMSG_MOVE_SPLINE_DISABLE_GRAVITY : SMSG_MOVE_SPLINE_ENABLE_GRAVITY, 9);
+ data.append(GetPackGUID());
+ SendMessageToSet(&data, true);
+}
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 017085fec04..908f2b7e312 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -522,6 +522,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type);
CreatureAI* AI() const { return (CreatureAI*)i_AI; }
+ void SetWalk(bool enable);
+ void SetLevitate(bool enable);
+
uint32 GetShieldBlockValue() const //dunno mob block value
{
return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20));
@@ -575,7 +578,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
const char* GetNameForLocaleIdx(LocaleConstant locale_idx) const;
void setDeathState(DeathState s); // override virtual Unit::setDeathState
- bool FallGround();
bool LoadFromDB(uint32 guid, Map* map) { return LoadCreatureFromDB(guid, map, false); }
bool LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap = true);
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 3a63c32fc1e..f440fd497fc 100755
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -203,7 +203,7 @@ void CreatureGroup::FormationReset(bool dismiss)
if (dismiss)
itr->first->GetMotionMaster()->Initialize();
else
- itr->first->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
+ itr->first->GetMotionMaster()->MoveIdle();
sLog->outDebug(LOG_FILTER_UNITS, "Set %s movement for member GUID: %u", dismiss ? "default" : "idle", itr->first->GetGUIDLow());
}
}
@@ -212,10 +212,12 @@ void CreatureGroup::FormationReset(bool dismiss)
void CreatureGroup::LeaderMoveTo(float x, float y, float z)
{
+ //! To do: This should probably get its own movement generator or use WaypointMovementGenerator.
+ //! If the leader's path is known, member's path can be plotted as well using formation offsets.
if (!m_leader)
return;
- float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
+ float pathangle = atan2(m_leader->GetPositionY() - y, m_leader->GetPositionX() - x);
for (CreatureGroupMemberType::iterator itr = m_members.begin(); itr != m_members.end(); ++itr)
{
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 10220c7bc89..64cc1bb325c 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -974,7 +974,7 @@ void GameObject::ResetDoorOrButton()
m_cooldownTime = 0;
}
-void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */)
+void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */, Unit* user /*=NULL*/)
{
if (m_lootState != GO_READY)
return;
@@ -983,7 +983,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f
time_to_restore = GetGOInfo()->GetAutoCloseTime();
SwitchDoorOrButton(true, alternative);
- SetLootState(GO_ACTIVATED);
+ SetLootState(GO_ACTIVATED, user);
m_cooldownTime = time(NULL) + time_to_restore;
}
@@ -1053,7 +1053,7 @@ void GameObject::Use(Unit* user)
case GAMEOBJECT_TYPE_DOOR: //0
case GAMEOBJECT_TYPE_BUTTON: //1
//doors/buttons never really despawn, only reset to default state/flags
- UseDoorOrButton();
+ UseDoorOrButton(0, false, user);
// activate script
GetMap()->ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this);
@@ -1206,7 +1206,7 @@ void GameObject::Use(Unit* user)
TriggeringLinkedGameObject(trapEntry, user);
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE);
- SetLootState(GO_ACTIVATED);
+ SetLootState(GO_ACTIVATED, user);
// this appear to be ok, however others exist in addition to this that should have custom (ex: 190510, 188692, 187389)
if (info->goober.customAnim)
@@ -1864,3 +1864,9 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
}
}
}
+
+void GameObject::SetLootState(LootState s, Unit* unit)
+{
+ m_lootState = s;
+ AI()->OnStateChanged(s, unit);
+}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 4daf73370f1..2329ed10e49 100755
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -714,7 +714,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>
void Use(Unit* user);
LootState getLootState() const { return m_lootState; }
- void SetLootState(LootState s) { m_lootState = s; }
+ // Note: unit is only used when s = GO_ACTIVATED
+ void SetLootState(LootState s, Unit* unit = NULL);
uint16 GetLootMode() { return m_LootMode; }
bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; }
@@ -748,7 +749,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
bool hasQuest(uint32 quest_id) const;
bool hasInvolvedQuest(uint32 quest_id) const;
bool ActivateToQuest(Player* target) const;
- void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false);
+ void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = NULL);
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index d4e48548aa0..d89849f7ccf 100755
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -45,6 +45,7 @@
#include "TemporarySummon.h"
#include "Totem.h"
#include "OutdoorPvPMgr.h"
+#include "MovementPacketBuilder.h"
uint32 GuidHigh2TypeId(uint32 guid_hi)
{
@@ -309,65 +310,9 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const
*data << self->GetSpeed(MOVE_TURN_RATE);
*data << self->GetSpeed(MOVE_PITCH_RATE);
- Player const* player = ToPlayer();
-
// 0x08000000
- if (player && player->isInFlight())
- {
- uint32 flags3 = SPLINEFLAG_GLIDE;
-
- *data << uint32(flags3); // splines flag
-
- if (flags3 & 0x00004000) // FinalOrientation
- {
- *data << (float)0;
- }
- else if (flags3 & 0x00001000) // FinalOrientation
- {
- *data << (float)0;
- *data << (float)0;
- *data << (float)0;
- }
- else if (flags3 & 0x00002000) // FinalTarget
- {
- *data << uint64(0);
- }
-
- FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(player->GetMotionMaster()->top());
- TaxiPathNodeList const& path = fmg->GetPath();
-
- float x, y, z;
- player->GetPosition(x, y, z);
-
- uint32 inflighttime = uint32(path.GetPassedLength(fmg->GetCurrentNode(), x, y, z) * 32);
- uint32 traveltime = uint32(path.GetTotalLength() * 32);
-
- *data << uint32(inflighttime); // passed move time?
- *data << uint32(traveltime); // full move time?
- *data << uint32(0); // ticks count?
-
- *data << float(0); // added in 3.1
- *data << float(0); // added in 3.1
- *data << float(0); // added in 3.1
-
- *data << uint32(0); // added in 3.1
-
- uint32 poscount = uint32(path.size());
- *data << uint32(poscount); // points count
-
- for (uint32 i = 0; i < poscount; ++i)
- {
- *data << float(path[i].x);
- *data << float(path[i].y);
- *data << float(path[i].z);
- }
-
- *data << uint8(0); // added in 3.0.8
-
- *data << float(path[poscount-1].x);
- *data << float(path[poscount-1].y);
- *data << float(path[poscount-1].z);
- }
+ if (self->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED))
+ Movement::PacketBuilder::WriteCreate(*self->movespline, *data);
}
else
{
@@ -1549,6 +1494,70 @@ void WorldObject::UpdateGroundPositionZ(float x, float y, float &z) const
z = new_z+ 0.05f; // just to be sure that we are not a few pixel under the surface
}
+void WorldObject::UpdateAllowedPositionZ(float x, float y, float &z) const
+{
+ switch (GetTypeId())
+ {
+ case TYPEID_UNIT:
+ {
+ // non fly unit don't must be in air
+ // non swim unit must be at ground (mostly speedup, because it don't must be in water and water level check less fast
+ if (!((Creature const*)this)->canFly())
+ {
+ bool canSwim = ((Creature const*)this)->canSwim();
+ float ground_z = z;
+ float max_z = canSwim
+ ? GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK))
+ : ((ground_z = GetBaseMap()->GetHeight(x, y, z, true)));
+ if (max_z > INVALID_HEIGHT)
+ {
+ if (z > max_z)
+ z = max_z;
+ else if (z < ground_z)
+ z = ground_z;
+ }
+ }
+ else
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if (z < ground_z)
+ z = ground_z;
+ }
+ break;
+ }
+ case TYPEID_PLAYER:
+ {
+ // for server controlled moves playr work same as creature (but it can always swim)
+ if (!((Player const*)this)->canFly())
+ {
+ float ground_z = z;
+ float max_z = GetBaseMap()->GetWaterOrGroundLevel(x, y, z, &ground_z, !((Unit const*)this)->HasAuraType(SPELL_AURA_WATER_WALK));
+ if (max_z > INVALID_HEIGHT)
+ {
+ if (z > max_z)
+ z = max_z;
+ else if (z < ground_z)
+ z = ground_z;
+ }
+ }
+ else
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if (z < ground_z)
+ z = ground_z;
+ }
+ break;
+ }
+ default:
+ {
+ float ground_z = GetBaseMap()->GetHeight(x, y, z, true);
+ if(ground_z > INVALID_HEIGHT)
+ z = ground_z;
+ break;
+ }
+ }
+}
+
bool Position::IsPositionValid() const
{
return Trinity::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation);
@@ -1987,7 +1996,8 @@ void Unit::BuildHeartBeatMsg(WorldPacket* data) const
void WorldObject::SendMessageToSet(WorldPacket* data, bool self)
{
- SendMessageToSetInRange(data, GetVisibilityRange(), self);
+ if (IsInWorld())
+ SendMessageToSetInRange(data, GetVisibilityRange(), self);
}
void WorldObject::SendMessageToSetInRange(WorldPacket* data, float dist, bool /*self*/)
@@ -2475,7 +2485,7 @@ void WorldObject::GetNearPoint(WorldObject const* /*searcher*/, float &x, float
{
GetNearPoint2D(x, y, distance2d+searcher_size, absAngle);
z = GetPositionZ();
- UpdateGroundPositionZ(x, y, z);
+ UpdateAllowedPositionZ(x, y, z);
/*
// if detection disabled, return first point
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index b421142bef1..666f71ffe68 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -497,7 +497,9 @@ struct MovementInfo
}
uint32 GetMovementFlags() { return flags; }
+ void SetMovementFlags(uint32 flag) { flags = flag; }
void AddMovementFlag(uint32 flag) { flags |= flag; }
+ void RemoveMovementFlag(uint32 flag) { flags &= ~flag; }
bool HasMovementFlag(uint32 flag) const { return flags & flag; }
uint16 GetExtraMovementFlags() { return flags2; }
@@ -615,6 +617,7 @@ class WorldObject : public Object, public WorldLocation
return (m_valuesCount > UNIT_FIELD_COMBATREACH) ? m_floatValues[UNIT_FIELD_COMBATREACH] : DEFAULT_WORLD_OBJECT_SIZE;
}
void UpdateGroundPositionZ(float x, float y, float &z) const;
+ void UpdateAllowedPositionZ(float x, float y, float &z) const;
void GetRandomPoint(const Position &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const;
void GetRandomPoint(const Position &srcPos, float distance, Position &pos) const
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index a211d848f59..8cf1413611b 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -297,15 +297,24 @@ Item* TradeData::GetItem(TradeSlots slot) const
return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : NULL;
}
-bool TradeData::HasItem(uint64 item_guid) const
+bool TradeData::HasItem(uint64 itemGuid) const
{
for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
- if (m_items[i] == item_guid)
+ if (m_items[i] == itemGuid)
return true;
return false;
}
+TradeSlots TradeData::GetTradeSlotForItem(uint64 itemGuid) const
+{
+ for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
+ if (m_items[i] == itemGuid)
+ return TradeSlots(i);
+
+ return TRADE_SLOT_INVALID;
+}
+
Item* TradeData::GetSpellCastItem() const
{
return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : NULL;
@@ -2179,6 +2188,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
// reset movement flags at teleport, because player will continue move with these flags after teleport
SetUnitMovementFlags(0);
+ DisableSpline();
if (m_transport)
{
@@ -2387,9 +2397,14 @@ bool Player::TeleportToBGEntryPoint()
if (m_bgData.joinPos.m_mapId == MAPID_INVALID)
return false;
+ Group* group = GetGroup();
+ if (group && group->isLFGGroup() && group->GetMembersCount() == 1)
+ group->Disband();
+ else
+ ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
+
ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE);
ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE);
- ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE);
return TeleportTo(m_bgData.joinPos);
}
@@ -5240,43 +5255,10 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
}
}
-/**
- * FallMode = 0 implies that the player is dying, or already dead, and the proper death state will be set.
- * = 1 simply causes the player to plummet towards the ground, and not suffer any damage.
- * = 2 causes the player to plummet towards the ground, and causes falling damage, regardless
- * of any auras that might of prevented fall damage.
- */
-bool Player::FallGround(uint8 FallMode)
-{
- // Let's abort after we called this function one time
- if (getDeathState() == DEAD_FALLING && FallMode == 0)
- return false;
-
- float x, y, z;
- GetPosition(x, y, z);
- float ground_Z = GetMap()->GetHeight(x, y, z);
- float z_diff = 0.0f;
- if ((z_diff = fabs(ground_Z - z)) < 0.1f)
- return false;
-
- GetMotionMaster()->MoveFall(ground_Z, EVENT_FALL_GROUND);
-
- // Below formula for falling damage is from Player::HandleFall
- if (FallMode == 2 && z_diff >= 14.57f)
- {
- uint32 damage = std::min(GetMaxHealth(), (uint32)((0.018f * z_diff - 0.2426f) * GetMaxHealth() * sWorld->getRate(RATE_DAMAGE_FALL)));
- if (damage)
- EnvironmentalDamage(DAMAGE_FALL, damage);
- }
- else if (FallMode == 0)
- Unit::setDeathState(DEAD_FALLING);
- return true;
-}
-
void Player::KillPlayer()
{
if (IsFlying() && !GetTransport())
- FallGround();
+ i_motionMaster.MoveFall();
SetMovement(MOVE_ROOT);
@@ -7614,6 +7596,22 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
SendInitWorldStates(newZone, newArea); // only if really enters to new zone, not just area change, works strange...
}
+ // group update
+ if (GetGroup())
+ {
+ SetGroupUpdateFlag(GROUP_UPDATE_FULL);
+ Group* grp = GetGroup();
+ if (GetSession() && grp->isLFGGroup() && sLFGMgr->IsTeleported(GetGUID()))
+ {
+ for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* tempplr = itr->getSource();
+ if (tempplr)
+ GetSession()->SendNameQueryOpcode(tempplr->GetGUID());
+ }
+ }
+ }
+
m_zoneUpdateId = newZone;
m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL;
@@ -7701,10 +7699,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
// recent client version not send leave/join channel packets for built-in local channels
UpdateLocalChannels(newZone);
- // group update
- if (GetGroup())
- SetGroupUpdateFlag(GROUP_UPDATE_FULL);
-
UpdateZoneDependentAuras(newZone);
}
@@ -8856,7 +8850,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
}
}
- go->SetLootState(GO_ACTIVATED);
+ go->SetLootState(GO_ACTIVATED, this);
}
if (go->getLootState() == GO_ACTIVATED)
@@ -11955,6 +11949,93 @@ InventoryResult Player::CanUseItem(ItemTemplate const* proto) const
return EQUIP_ERR_ITEM_NOT_FOUND;
}
+InventoryResult Player::CanRollForItemInLFG(ItemTemplate const* proto, WorldObject const* lootedObject) const
+{
+ LfgDungeonSet const& dungeons = sLFGMgr->GetSelectedDungeons(GetGUID());
+ if (dungeons.empty())
+ return EQUIP_ERR_OK; // not using LFG
+
+ if (!GetGroup() || !GetGroup()->isLFGGroup())
+ return EQUIP_ERR_OK; // not in LFG group
+
+ // check if looted object is inside the lfg dungeon
+ bool lootedObjectInDungeon = false;
+ Map const* map = lootedObject->GetMap();
+ if (uint32 dungeonId = sLFGMgr->GetDungeon(GetGroup()->GetGUID(), true))
+ if (LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(dungeonId))
+ if (dungeon->map == map->GetId() && dungeon->difficulty == map->GetDifficulty())
+ lootedObjectInDungeon = true;
+
+ if (!lootedObjectInDungeon)
+ return EQUIP_ERR_OK;
+
+ if (!proto)
+ return EQUIP_ERR_ITEM_NOT_FOUND;
+ // Used by group, function NeedBeforeGreed, to know if a prototype can be used by a player
+
+ const static uint32 item_weapon_skills[MAX_ITEM_SUBCLASS_WEAPON] =
+ {
+ SKILL_AXES, SKILL_2H_AXES, SKILL_BOWS, SKILL_GUNS, SKILL_MACES,
+ SKILL_2H_MACES, SKILL_POLEARMS, SKILL_SWORDS, SKILL_2H_SWORDS, 0,
+ SKILL_STAVES, 0, 0, SKILL_FIST_WEAPONS, 0,
+ SKILL_DAGGERS, SKILL_THROWN, SKILL_ASSASSINATION, SKILL_CROSSBOWS, SKILL_WANDS,
+ SKILL_FISHING
+ }; //Copy from function Item::GetSkill()
+
+ if ((proto->AllowableClass & getClassMask()) == 0 || (proto->AllowableRace & getRaceMask()) == 0)
+ return EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM;
+
+ if (proto->RequiredSpell != 0 && !HasSpell(proto->RequiredSpell))
+ return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+
+ if (proto->RequiredSkill != 0)
+ {
+ if (!GetSkillValue(proto->RequiredSkill))
+ return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+ else if (GetSkillValue(proto->RequiredSkill) < proto->RequiredSkillRank)
+ return EQUIP_ERR_CANT_EQUIP_SKILL;
+ }
+
+ uint8 _class = getClass();
+
+ if (proto->Class == ITEM_CLASS_WEAPON && GetSkillValue(item_weapon_skills[proto->SubClass]) == 0)
+ return EQUIP_ERR_NO_REQUIRED_PROFICIENCY;
+
+ if (proto->Class == ITEM_CLASS_ARMOR && proto->SubClass > ITEM_SUBCLASS_ARMOR_MISCELLANEOUS && proto->SubClass < ITEM_SUBCLASS_ARMOR_BUCKLER && proto->InventoryType != INVTYPE_CLOAK)
+ {
+ if (_class == CLASS_WARRIOR || _class == CLASS_PALADIN || _class == CLASS_DEATH_KNIGHT)
+ {
+ if (getLevel() < 40)
+ {
+ if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_PLATE)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ else if (_class == CLASS_HUNTER || _class == CLASS_SHAMAN)
+ {
+ if (getLevel() < 40)
+ {
+ if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+ else if (proto->SubClass != ITEM_SUBCLASS_ARMOR_MAIL)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+
+ if (_class == CLASS_ROGUE || _class == CLASS_DRUID)
+ if (proto->SubClass != ITEM_SUBCLASS_ARMOR_LEATHER)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+
+ if (_class == CLASS_MAGE || _class == CLASS_PRIEST || _class == CLASS_WARLOCK)
+ if (proto->SubClass != ITEM_SUBCLASS_ARMOR_CLOTH)
+ return EQUIP_ERR_CANT_DO_RIGHT_NOW;
+ }
+
+ return EQUIP_ERR_OK;
+}
+
Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update, int32 randomPropertyId)
{
AllowedLooterSet allowedLooters;
@@ -12797,6 +12878,14 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
return;
}
+ //! If trading
+ if (TradeData* tradeData = GetTradeData())
+ {
+ //! If current item is in trade window (only possible with packet spoofing - silent return)
+ if (tradeData->GetTradeSlotForItem(pSrcItem->GetGUID()) != TRADE_SLOT_INVALID)
+ return;
+ }
+
sLog->outDebug(LOG_FILTER_PLAYER_ITEMS, "STORAGE: SplitItem bag = %u, slot = %u, item = %u, count = %u", dstbag, dstslot, pSrcItem->GetEntry(), count);
Item* pNewItem = pSrcItem->CloneItem(count, this);
if (!pNewItem)
@@ -12825,7 +12914,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
pSrcItem->SetState(ITEM_CHANGED, this);
StoreItem(dest, pNewItem, true);
}
- else if (IsBankPos (dst))
+ else if (IsBankPos(dst))
{
// change item amount before check (for unique max count check)
pSrcItem->SetCount(pSrcItem->GetCount() - count);
@@ -12845,7 +12934,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count)
pSrcItem->SetState(ITEM_CHANGED, this);
BankItem(dest, pNewItem, true);
}
- else if (IsEquipmentPos (dst))
+ else if (IsEquipmentPos(dst))
{
// change item amount before check (for unique max count check), provide space for splitted items
pSrcItem->SetCount(pSrcItem->GetCount() - count);
@@ -14055,6 +14144,10 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
PrepareQuestMenu(source->GetGUID());
}
+ if (source->GetTypeId() == TYPEID_GAMEOBJECT)
+ if (source->ToGameObject()->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
+ PrepareQuestMenu(source->GetGUID());
+
for (GossipMenuItemsMap::const_iterator itr = menuItemBounds.first; itr != menuItemBounds.second; ++itr)
{
bool canTalk = true;
@@ -14140,11 +14233,6 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool
switch (itr->second.OptionType)
{
- case GOSSIP_OPTION_QUESTGIVER:
- if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
- PrepareQuestMenu(source->GetGUID());
- canTalk = false;
- break;
case GOSSIP_OPTION_GOSSIP:
if (go->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER && go->GetGoType() != GAMEOBJECT_TYPE_GOOBER)
canTalk = false;
@@ -16751,6 +16839,7 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
_LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES));
_LoadBGData(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADBGDATA));
+ GetSession()->SetPlayer(this);
MapEntry const* mapEntry = sMapStore.LookupEntry(mapId);
if (!mapEntry || !IsPositionValid())
{
@@ -21577,8 +21666,6 @@ void Player::SendInitialVisiblePackets(Unit* target)
SendAurasForTarget(target);
if (target->isAlive())
{
- if (target->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
- target->SendMonsterMoveWithSpeedToCurrentDestination(this);
if (target->HasUnitState(UNIT_STAT_MELEE_ATTACKING) && target->getVictim())
target->SendMeleeAttackStart(target->getVictim());
}
@@ -21836,7 +21923,9 @@ void Player::SendInitialPacketsBeforeAddToMap()
// SMSG_PET_GUIDS
// SMSG_UPDATE_WORLD_STATE
// SMSG_POWER_UPDATE
+
SendCurrencies();
+ SetMover(this);
}
void Player::SendInitialPacketsAfterAddToMap()
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 21027402e84..f462f5af48f 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -290,13 +290,14 @@ struct PvPInfo
struct DuelInfo
{
- DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0) {}
+ DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0), isMounted(false) {}
Player* initiator;
Player* opponent;
time_t startTimer;
time_t startTime;
time_t outOfBound;
+ bool isMounted;
};
struct Areas
@@ -702,7 +703,8 @@ enum TradeSlots
{
TRADE_SLOT_COUNT = 7,
TRADE_SLOT_TRADED_COUNT = 6,
- TRADE_SLOT_NONTRADED = 6
+ TRADE_SLOT_NONTRADED = 6,
+ TRADE_SLOT_INVALID = -1,
};
enum TransferAbortReason
@@ -1013,7 +1015,8 @@ class TradeData
TradeData* GetTraderData() const;
Item* GetItem(TradeSlots slot) const;
- bool HasItem(uint64 item_guid) const;
+ bool HasItem(uint64 itemGuid) const;
+ TradeSlots GetTradeSlotForItem(uint64 itemGuid) const;
void SetItem(TradeSlots slot, Item* item);
uint32 GetSpell() const { return m_spell; }
@@ -1333,6 +1336,7 @@ class Player : public Unit, public GridObject<Player>
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem) const;
InventoryResult CanUseAmmo(uint32 item) const;
+ InventoryResult CanRollForItemInLFG(ItemTemplate const* item, WorldObject const* lootedObject) const;
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId = 0);
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId, AllowedLooterSet &allowedLooters);
Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update);
@@ -2046,7 +2050,6 @@ class Player : public Unit, public GridObject<Player>
Corpse* GetCorpse() const;
void SpawnCorpseBones();
void CreateCorpse();
- bool FallGround(uint8 FallMode = 0);
void KillPlayer();
uint32 GetResurrectionSpellId();
void ResurrectPlayer(float restore_percent, bool applySickness = false);
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 430b6adb6ec..103e42a9da9 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -45,16 +45,16 @@
#include "InstanceSaveMgr.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
-#include "Path.h"
#include "CreatureGroups.h"
#include "PetAI.h"
#include "PassiveAI.h"
-#include "Traveller.h"
#include "TemporarySummon.h"
#include "Vehicle.h"
#include "Transport.h"
#include "InstanceScript.h"
#include "SpellInfo.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
#include <math.h>
@@ -62,9 +62,9 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
{
2.5f, // MOVE_WALK
7.0f, // MOVE_RUN
- 2.5f, // MOVE_RUN_BACK
+ 4.5f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM
- 4.5f, // MOVE_SWIM_BACK
+ 2.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
@@ -73,9 +73,9 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =
float playerBaseMoveSpeed[MAX_MOVE_TYPE] = {
2.5f, // MOVE_WALK
7.0f, // MOVE_RUN
- 2.5f, // MOVE_RUN_BACK
+ 4.5f, // MOVE_RUN_BACK
4.722222f, // MOVE_SWIM
- 4.5f, // MOVE_SWIM_BACK
+ 2.5f, // MOVE_SWIM_BACK
3.141594f, // MOVE_TURN_RATE
7.0f, // MOVE_FLIGHT
4.5f, // MOVE_FLIGHT_BACK
@@ -148,7 +148,7 @@ Unit::Unit(bool isWorldObject): WorldObject(isWorldObject),
m_movedPlayer(NULL), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false),
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
-m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
+m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this), movespline(new Movement::MoveSpline())
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -280,6 +280,7 @@ Unit::~Unit()
delete m_charmInfo;
delete m_vehicleKit;
+ delete movespline;
ASSERT(!m_duringRemoveFromWorld);
ASSERT(!m_attacking);
@@ -346,6 +347,7 @@ void Unit::Update(uint32 p_time)
ModifyAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, HealthAbovePct(75));
}
+ UpdateSplineMovement(p_time);
i_motionMaster.UpdateMotion(p_time);
}
@@ -357,151 +359,46 @@ bool Unit::haveOffhandWeapon() const
return m_canDualWield;
}
-void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player)
+void Unit::MonsterMoveWithSpeed(float x, float y, float z, float speed)
{
- float x, y, z;
- if (GetMotionMaster()->GetDestination(x, y, z))
- SendMonsterMoveWithSpeed(x, y, z, 0, player);
-}
-
-void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player)
-{
- if (!transitTime)
- {
- if (GetTypeId() == TYPEID_PLAYER)
- {
- Traveller<Player> traveller(*(Player*)this);
- transitTime = traveller.GetTotalTrevelTimeTo(x, y, z);
- }
- else
- {
- Traveller<Creature> traveller(*ToCreature());
- transitTime = traveller.GetTotalTrevelTimeTo(x, y, z);
- }
- }
- //float orientation = (float)atan2((double)dy, (double)dx);
- SendMonsterMove(x, y, z, transitTime, player);
-}
-
-void Unit::SetFacing(float ori, WorldObject* obj)
-{
- SetOrientation(obj ? GetAngle(obj) : ori);
-
- WorldPacket data(SMSG_MONSTER_MOVE, (1+12+4+1+(obj ? 8 : 4)+4+4+4+12+GetPackGUID().size()));
- data.append(GetPackGUID());
- data << uint8(0); // unk
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
- if (obj)
- {
- data << uint8(SPLINETYPE_FACING_TARGET);
- data << uint64(obj->GetGUID());
- }
- else
- {
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << ori;
- }
- data << uint32(SPLINEFLAG_NONE);
- data << uint32(0); // move time 0
- data << uint32(1); // one point
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendMonsterStop(bool on_death)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, (17 + GetPackGUID().size()));
- data.append(GetPackGUID());
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- if (on_death == true)
- {
- data << uint8(0);
- data << uint32((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) ? SPLINEFLAG_FLYING : SPLINEFLAG_WALKING);
- data << uint32(0); // Time in between points
- data << uint32(1); // 1 single waypoint
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- }
- else
- data << uint8(1);
-
- SendMessageToSet(&data, true);
-
- ClearUnitState(UNIT_STAT_MOVE);
+ Movement::MoveSplineInit init(*this);
+ init.MoveTo(x,y,z);
+ init.SetVelocity(speed);
+ init.Launch();
}
-void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player)
+void Unit::UpdateSplineMovement(uint32 t_diff)
{
- WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
- data.append(GetPackGUID());
-
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- data << uint8(0);
- data << uint32((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) ? SPLINEFLAG_FLYING : SPLINEFLAG_WALKING);
- data << Time; // Time in between points
- data << uint32(1); // 1 single waypoint
- data << NewPosX << NewPosY << NewPosZ; // the single waypoint Point B
-
- if (player)
- player->GetSession()->SendPacket(&data);
- else
- SendMessageToSet(&data, true);
-
- AddUnitState(UNIT_STAT_MOVE);
-}
+ enum{
+ POSITION_UPDATE_DELAY = 400,
+ };
-void Unit::SendMonsterMove(MonsterMoveData const& moveData, Player* player)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, GetPackGUID().size() + 1 + 12 + 4 + 1 + 4 + 8 + 4 + 4 + 12);
- data.append(GetPackGUID());
+ if (movespline->Finalized())
+ return;
- data << uint8(0); // new in 3.1
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
+ movespline->updateState(t_diff);
+ bool arrived = movespline->Finalized();
- data << uint8(0);
- data << moveData.SplineFlag;
+ if (arrived)
+ DisableSpline();
- if (moveData.SplineFlag & SPLINEFLAG_ANIMATIONTIER)
+ m_movesplineTimer.Update(t_diff);
+ if (m_movesplineTimer.Passed() || arrived)
{
- data << uint8(moveData.AnimationState);
- data << uint32(0);
- }
+ m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);
+ Movement::Location loc = movespline->ComputePosition();
- data << moveData.Time;
-
- if (moveData.SplineFlag & SPLINEFLAG_TRAJECTORY)
- {
- data << moveData.SpeedZ;
- data << uint32(0); // walk time after jump
+ if (GetTypeId() == TYPEID_PLAYER)
+ ((Player*)this)->UpdatePosition(loc.x,loc.y,loc.z,loc.orientation);
+ else
+ GetMap()->CreatureRelocation((Creature*)this,loc.x,loc.y,loc.z,loc.orientation);
}
-
- data << uint32(1); // waypoint count
- data << moveData.DestLocation.GetPositionX();
- data << moveData.DestLocation.GetPositionY();
- data << moveData.DestLocation.GetPositionZ();
-
- if (player)
- player->GetSession()->SendPacket(&data);
- else
- SendMessageToSet(&data, true);
}
-void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player)
+void Unit::DisableSpline()
{
- MonsterMoveData data;
- data.DestLocation.Relocate(NewPosX, NewPosY, NewPosZ);
- data.SplineFlag = MoveFlags;
- data.Time = time;
- data.SpeedZ = speedZ;
-
- SendMonsterMove(data, player);
+ m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD));
+ movespline->_Interrupt();
}
void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
@@ -731,6 +628,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
// duel ends when player has 1 or less hp
bool duel_hasEnded = false;
+ bool duel_wasMounted = false;
if (victim->GetTypeId() == TYPEID_PLAYER && victim->ToPlayer()->duel && damage >= (health-1))
{
// prevent kill only if killed in duel and killed by opponent or opponent controlled creature
@@ -739,6 +637,20 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
duel_hasEnded = true;
}
+ else if (victim->IsVehicle() && damage >= (health-1) && victim->GetCharmer() && victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER)
+ {
+ Player* victimRider = victim->GetCharmer()->ToPlayer();
+
+ if (victimRider && victimRider->duel && victimRider->duel->isMounted)
+ {
+ // prevent kill only if killed in duel and killed by opponent or opponent controlled creature
+ if (victimRider->duel->opponent == this || victimRider->duel->opponent->GetGUID() == GetCharmerGUID())
+ damage = health - 1;
+
+ duel_wasMounted = true;
+ duel_hasEnded = true;
+ }
+ }
if (GetTypeId() == TYPEID_PLAYER && this != victim)
{
@@ -848,8 +760,18 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam
// last damage from duel opponent
if (duel_hasEnded)
{
- ASSERT(victim->GetTypeId() == TYPEID_PLAYER);
- Player* he = victim->ToPlayer();
+ Player* he;
+
+ if (duel_wasMounted)
+ {
+ ASSERT(victim->GetCharmer()->GetTypeId() == TYPEID_PLAYER);
+ he = victim->GetCharmer()->ToPlayer();
+ }
+ else
+ {
+ ASSERT(victim->GetTypeId() == TYPEID_PLAYER);
+ he = victim->ToPlayer();
+ }
ASSERT(he->duel);
@@ -2226,12 +2148,12 @@ void Unit::SendMeleeAttackStart(Unit* victim)
void Unit::SendMeleeAttackStop(Unit* victim)
{
- WorldPacket data(SMSG_ATTACKSTOP, (8+8+4)); // we guess size
+ WorldPacket data(SMSG_ATTACKSTOP, (8+8+4));
data.append(GetPackGUID());
data.append(victim ? victim->GetPackGUID() : 0); // can be 0x00...
data << uint32(0); // can be 0x1
SendMessageToSet(&data, true);
- sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTART");
+ sLog->outStaticDebug("WORLD: Sent SMSG_ATTACKSTOP");
if (victim)
sLog->outDetail("%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUIDLow());
@@ -3115,17 +3037,6 @@ bool Unit::isInBackInMap(Unit const* target, float distance, float arc) const
return IsWithinDistInMap(target, distance) && !HasInArc(2 * M_PI - arc, target);
}
-void Unit::SetFacingToObject(WorldObject* pObject)
-{
- // update orientation at server
- SetOrientation(GetAngle(pObject));
-
- // and client
- WorldPacket data;
- BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
-}
-
bool Unit::isInAccessiblePlaceFor(Creature const* c) const
{
if (IsInWater())
@@ -7191,6 +7102,8 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
return false;
basepoints0 = CalculatePctN(int32(damage), triggerAmount);
triggered_spell_id = 58879;
+ // Cast on spirit wolf
+ CastCustomSpell(this, triggered_spell_id, &basepoints0, NULL, NULL, true, NULL, triggeredByAura);
break;
}
// Shaman T8 Elemental 4P Bonus
@@ -8947,18 +8860,17 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
// Maelstrom Weapon
case 53817:
{
- // Item - Shaman T10 Enhancement 4P Bonus
- if (AuraEffect const* aurEff = GetAuraEffect(70832, 0))
- if (Aura const* maelstrom = GetAura(53817))
- if ((maelstrom->GetStackAmount() == maelstrom->GetSpellInfo()->StackAmount) && roll_chance_i(aurEff->GetAmount()))
- CastSpell(this, 70831, true, castItem, triggeredByAura);
-
// has rank dependant proc chance, ignore too often cases
// PPM = 2.5 * (rank of talent),
uint32 rank = auraSpellInfo->GetRank();
// 5 rank -> 100% 4 rank -> 80% and etc from full rate
if (!roll_chance_i(20*rank))
return false;
+ // Item - Shaman T10 Enhancement 4P Bonus
+ if (AuraEffect const* aurEff = GetAuraEffect(70832, 0))
+ if (Aura const* maelstrom = GetAura(53817))
+ if ((maelstrom->GetStackAmount() == maelstrom->GetSpellInfo()->StackAmount - 1) && roll_chance_i(aurEff->GetAmount()))
+ CastSpell(this, 70831, true, castItem, triggeredByAura);
break;
}
// Astral Shift
@@ -13150,7 +13062,7 @@ void Unit::setDeathState(DeathState s)
ClearDiminishings();
GetMotionMaster()->Clear(false);
GetMotionMaster()->MoveIdle();
- SendMonsterStop(true);
+ StopMoving();
// without this when removing IncreaseMaxHealth aura player may stuck with 1 hp
// do not why since in IncreaseMaxHealth currenthealth is checked
SetHealth(0);
@@ -13969,7 +13881,7 @@ void Unit::SetHealth(uint32 val)
{
if (getDeathState() == JUST_DIED)
val = 0;
- else if (GetTypeId() == TYPEID_PLAYER && (getDeathState() == DEAD || getDeathState() == DEAD_FALLING))
+ else if (GetTypeId() == TYPEID_PLAYER && getDeathState() == DEAD)
val = 1;
else
{
@@ -15145,22 +15057,20 @@ void Unit::StopMoving()
{
ClearUnitState(UNIT_STAT_MOVING);
- // send explicit stop packet
- // rely on vmaps here because for example stormwind is in air
- //float z = sMapMgr->GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true);
- //if (fabs(GetPositionZ() - z) < 2.0f)
- // Relocate(GetPositionX(), GetPositionY(), z);
- //Relocate(GetPositionX(), GetPositionY(), GetPositionZ());
+ // not need send any packets if not in world
+ if (!IsInWorld())
+ return;
- if (!(GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT))
- SendMonsterStop();
+ Movement::MoveSplineInit init(*this);
+ init.SetFacing(GetOrientation());
+ init.Launch();
}
void Unit::SendMovementFlagUpdate()
{
WorldPacket data;
BuildHeartBeatMsg(&data);
- SendMessageToSet(&data, false);
+ SendMessageToSet(&data, true);
}
bool Unit::IsSitState() const
@@ -16426,6 +16336,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
case CHARM_TYPE_VEHICLE:
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
charmer->ToPlayer()->SetClientControl(this, 1);
+ charmer->ToPlayer()->SetMover(this);
charmer->ToPlayer()->SetViewpoint(this, true);
charmer->ToPlayer()->VehicleSpellInitialize();
break;
@@ -16434,6 +16345,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED);
charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
charmer->ToPlayer()->SetClientControl(this, 1);
+ charmer->ToPlayer()->SetMover(this);
charmer->ToPlayer()->SetViewpoint(this, true);
charmer->ToPlayer()->PossessSpellInitialize();
break;
@@ -16724,7 +16636,7 @@ void Unit::GetRaidMember(std::list<Unit*> &nearMembers, float radius)
if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
nearMembers.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
- if (pet->isAlive() && (pet == this && IsWithinDistInMap(pet, radius)))
+ if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius)))
nearMembers.push_back(pet);
}
}
@@ -16761,7 +16673,7 @@ void Unit::GetPartyMemberInDist(std::list<Unit*> &TagUnitMap, float radius)
if (owner->isAlive() && (owner == this || IsWithinDistInMap(owner, radius)))
TagUnitMap.push_back(owner);
if (Guardian* pet = owner->GetGuardianPet())
- if (pet->isAlive() && (pet == this && IsWithinDistInMap(pet, radius)))
+ if (pet->isAlive() && (pet == this || IsWithinDistInMap(pet, radius)))
TagUnitMap.push_back(pet);
}
}
@@ -17568,6 +17480,10 @@ void Unit::_ExitVehicle(Position const* exitPosition)
m_vehicle->RemovePassenger(this);
+ // If player is on mouted duel and exits the mount should immediatly lose the duel
+ if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->duel && ToPlayer()->duel->isMounted)
+ ToPlayer()->DuelComplete(DUEL_FLED);
+
// This should be done before dismiss, because there may be some aura removal
Vehicle* vehicle = m_vehicle;
m_vehicle = NULL;
@@ -17599,7 +17515,7 @@ void Unit::_ExitVehicle(Position const* exitPosition)
WorldPacket data2;
BuildHeartBeatMsg(&data2);
- SendMessageToSet(&data2, false);
+ SendMessageToSet(&data2, true);
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
@@ -17729,13 +17645,13 @@ void Unit::SetFlying(bool apply)
void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool casting /*= false*/)
{
+ DisableSpline();
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->TeleportTo(GetMapId(), x, y, z, orientation, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0));
else
{
- // FIXME: this interrupts spell visual
- DestroyForNearbyPlayers();
UpdatePosition(x, y, z, orientation, true);
+ SendMovementFlagUpdate();
}
}
@@ -18017,3 +17933,26 @@ bool CharmInfo::IsReturning()
{
return m_isReturning;
}
+
+void Unit::SetInFront(Unit const* target)
+{
+ if (!HasUnitState(UNIT_STAT_CANNOT_TURN))
+ SetOrientation(GetAngle(target));
+}
+
+void Unit::SetFacingTo(float ori)
+{
+ Movement::MoveSplineInit init(*this);
+ init.SetFacing(ori);
+ init.Launch();
+}
+
+void Unit::SetFacingToObject(WorldObject* pObject)
+{
+ // never face when already moving
+ if (!IsStopped())
+ return;
+
+ // TODO: figure out under what conditions creature will move towards object instead of facing it where it currently is.
+ SetFacingTo(GetAngle(pObject));
+}
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 21dcb4bf3fe..c50cba080c7 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -465,7 +465,6 @@ enum DeathState
CORPSE = 2,
DEAD = 3,
JUST_ALIVED = 4,
- DEAD_FALLING= 5
};
enum UnitState
@@ -493,13 +492,22 @@ enum UnitState
UNIT_STAT_MOVE = 0x00100000,
UNIT_STAT_ROTATING = 0x00200000,
UNIT_STAT_EVADE = 0x00400000,
+ UNIT_STAT_ROAMING_MOVE = 0x00800000,
+ UNIT_STAT_CONFUSED_MOVE = 0x01000000,
+ UNIT_STAT_FLEEING_MOVE = 0x02000000,
+ UNIT_STAT_CHASE_MOVE = 0x04000000,
+ UNIT_STAT_FOLLOW_MOVE = 0x08000000,
UNIT_STAT_UNATTACKABLE = (UNIT_STAT_IN_FLIGHT | UNIT_STAT_ONVEHICLE),
- UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
+ //UNIT_STAT_MOVING = (UNIT_STAT_ROAMING | UNIT_STAT_CHASE),
+ // for real move using movegen check and stop (except unstoppable flight)
+ UNIT_STAT_MOVING = UNIT_STAT_ROAMING_MOVE | UNIT_STAT_CONFUSED_MOVE | UNIT_STAT_FLEEING_MOVE| UNIT_STAT_CHASE_MOVE | UNIT_STAT_FOLLOW_MOVE ,
UNIT_STAT_CONTROLLED = (UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING),
UNIT_STAT_LOST_CONTROL = (UNIT_STAT_CONTROLLED | UNIT_STAT_JUMPING | UNIT_STAT_CHARGING),
UNIT_STAT_SIGHTLESS = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_EVADE),
UNIT_STAT_CANNOT_AUTOATTACK = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_CASTING),
UNIT_STAT_CANNOT_TURN = (UNIT_STAT_LOST_CONTROL | UNIT_STAT_ROTATING),
+ // stay by different reasons
+ UNIT_STAT_NOT_MOVE = UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DIED | UNIT_STAT_DISTRACTED,
UNIT_STAT_ALL_STATE = 0xffffffff //(UNIT_STAT_STOPPED | UNIT_STAT_MOVING | UNIT_STAT_IN_COMBAT | UNIT_STAT_IN_FLIGHT)
};
@@ -719,59 +727,18 @@ enum MovementFlags2
MOVEMENTFLAG2_UNK15 = 0x00004000,
MOVEMENTFLAG2_UNK16 = 0x00008000,
};
+
enum SplineFlags
{
- SPLINEFLAG_NONE = 0x00000000,
- SPLINEFLAG_FORWARD = 0x00000001,
- SPLINEFLAG_BACKWARD = 0x00000002,
- SPLINEFLAG_STRAFE_LEFT = 0x00000004,
- SPLINEFLAG_STRAFE_RIGHT = 0x00000008,
- SPLINEFLAG_LEFT = 0x00000010,
- SPLINEFLAG_RIGHT = 0x00000020,
- SPLINEFLAG_PITCH_UP = 0x00000040,
- SPLINEFLAG_PITCH_DOWN = 0x00000080,
- SPLINEFLAG_DONE = 0x00000100,
- SPLINEFLAG_FALLING = 0x00000200,
- SPLINEFLAG_NO_SPLINE = 0x00000400,
- SPLINEFLAG_TRAJECTORY = 0x00000800,
- SPLINEFLAG_WALKING = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_KNOCKBACK = 0x00004000,
- SPLINEFLAG_FINAL_POINT = 0x00008000,
- SPLINEFLAG_FINAL_TARGET = 0x00010000,
- SPLINEFLAG_FINAL_FACING = 0x00020000,
- SPLINEFLAG_CATMULL_ROM = 0x00040000,
- SPLINEFLAG_UNKNOWN20 = 0x00080000,
- SPLINEFLAG_UNKNOWN21 = 0x00100000,
- SPLINEFLAG_ANIMATIONTIER = 0x00200000,
- SPLINEFLAG_UNKNOWN23 = 0x00400000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
- SPLINEFLAG_UNKNOWN26 = 0x02000000,
- SPLINEFLAG_UNKNOWN27 = 0x04000000,
- SPLINEFLAG_UNKNOWN28 = 0x08000000,
- SPLINEFLAG_UNKNOWN29 = 0x10000000,
- SPLINEFLAG_ANIMATION = 0x20000000,
- SPLINEFLAG_UNKNOWN31 = 0x40000000,
- SPLINEFLAG_UNKNOWN32 = 0x80000000,
-
- SPLINEFLAG_GLIDE = SPLINEFLAG_WALKING | SPLINEFLAG_FLYING,
-};
-
-enum SplineMode
-{
- SPLINEMODE_LINEAR = 0,
- SPLINEMODE_CATMULL_ROM = 1,
- SPLINEMODE_BEZIER3 = 2
+ SPLINEFLAG_WALKMODE = 0x00001000,
+ SPLINEFLAG_FLYING = 0x00002000,
+ SPLINEFLAG_TRANSPORT = 0x00800000,
+ SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
};
enum SplineType
{
- SPLINETYPE_NORMAL = 0,
- SPLINETYPE_STOP = 1,
- SPLINETYPE_FACING_SPOT = 2,
- SPLINETYPE_FACING_TARGET = 3,
- SPLINETYPE_FACING_ANGLE = 4
+ SPLINETYPE_FACING_ANGLE = 4,
};
enum UnitTypeMask
@@ -789,6 +756,10 @@ enum UnitTypeMask
UNIT_MASK_ACCESSORY = 0x00000200,
};
+namespace Movement{
+ class MoveSpline;
+}
+
enum DiminishingLevels
{
DIMINISHING_LEVEL_1 = 0,
@@ -1631,20 +1602,18 @@ class Unit : public WorldObject
void JumpTo(float speedXY, float speedZ, bool forward = true);
void JumpTo(WorldObject* obj, float speedZ);
- void SetFacing(float ori, WorldObject* obj = NULL);
- void SendMonsterStop(bool on_death = false);
- void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL);
- void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player* player = NULL);
- void SendMonsterMove(MonsterMoveData const& moveData, Player* receiver = NULL);
+ void MonsterMoveWithSpeed(float x, float y, float z, float speed);
+ //void SetFacing(float ori, WorldObject* obj = NULL);
void SendMonsterMoveExitVehicle(Position const* newPos);
//void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL);
void SendMonsterMoveTransport(Unit* vehicleOwner);
- void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL);
- void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL);
void SendMovementFlagUpdate();
+ bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_LEVITATING);}
+ bool IsWalking() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);}
- template<typename PathElem, typename PathNode>
- void SendMonsterMoveByPath(Path<PathElem, PathNode> const& path, uint32 start, uint32 end);
+ void SetInFront(Unit const* target);
+ void SetFacingTo(float ori);
+ void SetFacingToObject(WorldObject* pObject);
void SendChangeCurrentVictimOpcode(HostileReference* pHostileReference);
void SendClearThreatListOpcode();
@@ -1954,13 +1923,7 @@ class Unit : public WorldObject
void SetBaseWeaponDamage(WeaponAttackType attType, WeaponDamageRange damageRange, float value) { m_weaponDamage[attType][damageRange] = value; }
bool isInFrontInMap(Unit const* target, float distance, float arc = M_PI) const;
- void SetInFront(Unit const* target)
- {
- if (!HasUnitState(UNIT_STAT_CANNOT_TURN))
- SetOrientation(GetAngle(target));
- }
bool isInBackInMap(Unit const* target, float distance, float arc = M_PI) const;
- void SetFacingToObject(WorldObject* pObject);
// Visibility system
bool IsVisible() const { return (m_serverSideVisibility.GetValue(SERVERSIDE_VISIBILITY_GM) > SEC_PLAYER) ? false : true; }
@@ -2235,6 +2198,9 @@ class Unit : public WorldObject
SetUInt64Value(UNIT_FIELD_TARGET, 0);
}
+ // Movement info
+ Movement::MoveSpline * movespline;
+
protected:
explicit Unit (bool isWorldObject);
@@ -2306,6 +2272,8 @@ class Unit : public WorldObject
bool IsAlwaysVisibleFor(WorldObject const* seer) const;
bool IsAlwaysDetectableFor(WorldObject const* seer) const;
+
+ void DisableSpline();
private:
bool IsTriggeredAtSpellProcEvent(Unit* pVictim, Aura* aura, SpellInfo const* procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const* & spellProcEvent);
bool HandleDummyAuraProc(Unit* pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellInfo const* procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
@@ -2319,6 +2287,8 @@ class Unit : public WorldObject
bool HandleAuraRaidProcFromChargeWithValue(AuraEffect* triggeredByAura);
bool HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura);
+ void UpdateSplineMovement(uint32 t_diff);
+
// player or player's pet
float GetCombatRatingReduction(CombatRating cr) const;
uint32 GetCombatRatingDamageReduction(CombatRating cr, float rate, float cap, uint32 damage) const;
@@ -2333,6 +2303,7 @@ class Unit : public WorldObject
uint32 m_state; // Even derived shouldn't modify
uint32 m_CombatTimer;
uint32 m_lastManaUse; // msecs
+ TimeTrackerSmall m_movesplineTimer;
Diminishing m_Diminishing;
// Manage all Units that are threatened by us
@@ -2385,31 +2356,4 @@ namespace Trinity
const bool m_ascending;
};
}
-
-template<typename Elem, typename Node>
-inline void Unit::SendMonsterMoveByPath(Path<Elem, Node> const& path, uint32 start, uint32 end)
-{
- uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32);
- uint32 pathSize = end - start;
- WorldPacket data(SMSG_MONSTER_MOVE, (GetPackGUID().size()+1+4+4+4+4+1+4+4+4+pathSize*4*3));
- data.append(GetPackGUID());
- data << uint8(0);
- data << GetPositionX();
- data << GetPositionY();
- data << GetPositionZ();
- data << uint32(getMSTime());
- data << uint8(0);
- data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight()) ? (SPLINEFLAG_FLYING|SPLINEFLAG_WALKING) : SPLINEFLAG_WALKING);
- data << uint32(traveltime);
- data << uint32(pathSize);
-
- for (uint32 i = start; i < end; ++i)
- {
- data << float(path[i].x);
- data << float(path[i].y);
- data << float(path[i].z);
- }
-
- SendMessageToSet(&data, true);
-}
#endif
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 6d9fbbc435d..30e0efc15a2 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -8762,7 +8762,7 @@ void ObjectMgr::CheckScripts(ScriptsType type, std::set<int32>& ids)
case SCRIPT_COMMAND_TALK:
{
if (!GetTrinityStringLocale (itrM->second.Talk.TextID))
- sLog->outErrorDb("Table `db_script_string` not has string id %u used db script (ID: %u)", itrM->second.Talk.TextID, itrMM->first);
+ sLog->outErrorDb("Table `%s` references invalid text id %u from `db_script_string`, script id: %u.", GetScriptsTableNameByType(type).c_str(), itrM->second.Talk.TextID, itrMM->first);
if (ids.find(itrM->second.Talk.TextID) != ids.end())
ids.erase(itrM->second.Talk.TextID);
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 0411d8854ad..fd5b40f8031 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -190,6 +190,9 @@ void Group::LoadGroupFromDB(Field* fields)
m_raidDifficulty = RAID_DIFFICULTY_10MAN_NORMAL;
else
m_raidDifficulty = Difficulty(r_diff);
+
+ if (m_groupType & GROUPTYPE_LFG)
+ sLFGMgr->_LoadFromDB(fields, GetGUID());
}
void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles)
@@ -200,7 +203,9 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup,
// skip non-existed member
if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name))
{
- CharacterDatabase.PQuery("DELETE FROM group_member WHERE memberGuid=%u", guidLow);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GROUP_MEMBER);
+ stmt->setUInt32(0, guidLow);
+ CharacterDatabase.Execute(stmt);
return;
}
@@ -211,6 +216,14 @@ void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup,
m_memberSlots.push_back(member);
SubGroupCounterIncrease(subgroup);
+
+ if (isLFGGroup())
+ {
+ LfgDungeonSet Dungeons;
+ Dungeons.insert(sLFGMgr->GetDungeon(GetGUID()));
+ sLFGMgr->SetSelectedDungeons(member.guid, Dungeons);
+ sLFGMgr->SetState(member.guid, sLFGMgr->GetState(GetGUID()));
+ }
}
void Group::ConvertToLFG()
@@ -472,7 +485,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
return m_memberSlots.size();
// remove member and change leader (if need) only if strong more 2 members _before_ member remove (BG allow 1 member group)
- if (GetMembersCount() > (isBGGroup() ? 1u : 2u))
+ if (GetMembersCount() > ((isBGGroup() || isLFGGroup()) ? 1u : 2u))
{
Player* player = ObjectAccessor::FindPlayer(guid);
if (player)
@@ -516,6 +529,8 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
CharacterDatabase.Execute(stmt);
+ DelinkMember(guid);
+
// Reevaluate group enchanter if the leaving player had enchanting skill or the player is offline
if ((player && player->GetSkillValue(SKILL_ENCHANTING)) || !player)
ResetMaxEnchantingLevel();
@@ -566,6 +581,20 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
SendUpdate();
+ if (isLFGGroup() && GetMembersCount() == 1)
+ {
+ Player* Leader = ObjectAccessor::FindPlayer(GetLeaderGUID());
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(sLFGMgr->GetDungeon(GetGUID()));
+ if ((Leader && dungeon && Leader->isAlive() && Leader->GetMapId() != dungeon->map) || !dungeon)
+ {
+ Disband();
+ return false;
+ }
+ }
+
+ if (m_memberMgr.getSize() < ((isLFGGroup() || isBGGroup()) ? 1u : 2u))
+ Disband();
+
return true;
}
// If group size before player removal <= 2 then disband it
@@ -705,6 +734,10 @@ void Group::Disband(bool hideDestroy /* = false */)
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL);
ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA);
+ stmt->setUInt32(0, m_dbStoreId);
+ CharacterDatabase.Execute(stmt);
+
sGroupMgr->FreeGroupDbStoreId(this);
}
@@ -741,6 +774,28 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
}
}
+void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r)
+{
+ if (!p || !p->GetSession())
+ return;
+
+ WorldPacket data(SMSG_LOOT_START_ROLL, (8 + 4 + 4 + 4 + 4 + 4 + 4 + 1 ));
+ data << uint64(r.itemGUID); // guid of rolled item
+ data << uint32(mapId); // 3.3.3 mapid
+ data << uint32(r.totalPlayersRolling); // maybe the number of players rolling for it???
+ data << uint32(r.itemid); // the itemEntryId for the item that shall be rolled for
+ data << uint32(r.itemRandomSuffix); // randomSuffix
+ data << uint32(r.itemRandomPropId); // item random property ID
+ data << uint32(r.itemCount); // items in stack
+ data << uint32(countDown); // the countdown time to choose "need" or "greed"
+ uint8 voteMask = r.rollVoteMask;
+ if (!canNeed)
+ voteMask &= ~ROLL_FLAG_TYPE_NEED;
+ data << uint8(voteMask); // roll type mask
+
+ p->GetSession()->SendPacket(&data);
+}
+
void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
{
WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1));
@@ -919,11 +974,11 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject)
}
}
-void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
+void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject)
{
ItemTemplate const* item;
uint8 itemSlot = 0;
- for (std::vector<LootItem>::iterator i=loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
+ for (std::vector<LootItem>::iterator i = loot->items.begin(); i != loot->items.end(); ++i, ++itemSlot)
{
if (i->freeforall)
continue;
@@ -934,7 +989,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
if (item->Quality >= uint32(m_lootThreshold))
{
uint64 newitemGUID = MAKE_NEW_GUID(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), 0, HIGHGUID_ITEM);
- Roll* r=new Roll(newitemGUID, *i);
+ Roll* r = new Roll(newitemGUID, *i);
for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
@@ -943,21 +998,17 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
continue;
bool allowedForPlayer = i->AllowedForPlayer(playerToRoll);
- if (playerToRoll->CanUseItem(item) == EQUIP_ERR_OK && allowedForPlayer)
+ if (allowedForPlayer && playerToRoll->IsWithinDistInMap(lootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
{
- if (playerToRoll->IsWithinDistInMap(pLootedObject, sWorld->getFloatConfig(CONFIG_GROUP_XP_DISTANCE), false))
+ r->totalPlayersRolling++;
+ if (playerToRoll->GetPassOnGroupLoot())
{
- r->totalPlayersRolling++;
-
- if (playerToRoll->GetPassOnGroupLoot())
- {
- r->playerVote[playerToRoll->GetGUID()] = PASS;
- r->totalPass++;
- // can't broadcast the pass now. need to wait until all rolling players are known.
- }
- else
- r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
+ r->playerVote[playerToRoll->GetGUID()] = PASS;
+ r->totalPass++;
+ // can't broadcast the pass now. need to wait until all rolling players are known.
}
+ else
+ r->playerVote[playerToRoll->GetGUID()] = NOT_EMITED_YET;
}
}
@@ -973,29 +1024,31 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject)
loot->items[itemSlot].is_blocked = true;
- // If there is any "auto pass", broadcast the pass now.
- if (r->totalPass)
+ //Broadcast Pass and Send Rollstart
+ for (Roll::PlayerVote::const_iterator itr = r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
{
- for (Roll::PlayerVote::const_iterator itr=r->playerVote.begin(); itr != r->playerVote.end(); ++itr)
- {
- Player* p = ObjectAccessor::FindPlayer(itr->first);
- if (!p || !p->GetSession())
- continue;
+ Player* p = ObjectAccessor::FindPlayer(itr->first);
+ if (!p || !p->GetSession())
+ continue;
- if (itr->second == PASS)
- SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
- }
+ if (itr->second == PASS)
+ SendLootRoll(newitemGUID, p->GetGUID(), 128, ROLL_PASS, *r);
+ else
+ SendLootStartRollToPlayer(60000, lootedObject->GetMapId(), p, p->CanRollForItemInLFG(item, lootedObject) == EQUIP_ERR_OK, *r);
}
- SendLootStartRoll(60000, pLootedObject->GetMapId(), *r);
-
RollId.push_back(r);
- if (Creature* creature = pLootedObject->ToCreature())
+ if (Creature* creature = lootedObject->ToCreature())
{
creature->m_groupLootTimer = 60000;
creature->lootingGroupLowGUID = GetLowGUID();
}
+ else if (GameObject* go = lootedObject->ToGameObject())
+ {
+ go->m_groupLootTimer = 60000;
+ go->lootingGroupLowGUID = GetLowGUID();
+ }
}
else
delete r;
@@ -1274,9 +1327,7 @@ void Group::SendTargetIconList(WorldSession* session)
void Group::SendUpdate()
{
for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr)
- {
SendUpdateToPlayer(witr->guid, &(*witr));
- }
}
void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot)
@@ -2149,8 +2200,19 @@ void Group::LinkMember(GroupReference* pRef)
m_memberMgr.insertFirst(pRef);
}
-void Group::DelinkMember(GroupReference* /*pRef*/) const
+void Group::DelinkMember(uint64 guid)
{
+ GroupReference* ref = m_memberMgr.getFirst();
+ while (ref)
+ {
+ GroupReference* nextRef = ref->next();
+ if (ref->getSource()->GetGUID() == guid)
+ {
+ ref->unlink();
+ break;
+ }
+ ref = nextRef;
+ }
}
Group::BoundInstancesMap& Group::GetBoundInstances(Difficulty difficulty)
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 63c89069f52..08246614627 100755
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -276,6 +276,7 @@ class Group
bool isRollLootActive() const;
void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r);
+ void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r);
void SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r);
void SendLootAllPassed(uint32 NumberOfPlayers, const Roll &r);
@@ -292,7 +293,7 @@ class Group
void ResetMaxEnchantingLevel();
void LinkMember(GroupReference* pRef);
- void DelinkMember(GroupReference* /*pRef*/) const;
+ void DelinkMember(uint64 guid);
InstanceGroupBind* BindToInstance(InstanceSave* save, bool permanent, bool load = false);
void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false);
diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp
index 412814a60d2..ae400852c73 100644
--- a/src/server/game/Groups/GroupMgr.cpp
+++ b/src/server/game/Groups/GroupMgr.cpp
@@ -119,10 +119,10 @@ void GroupMgr::LoadGroups()
// Delete all groups with less than 2 members
CharacterDatabase.DirectExecute("DELETE FROM groups WHERE guid NOT IN (SELECT guid FROM group_member GROUP BY guid HAVING COUNT(guid) > 1)");
- // 0 1 2 3 4 5 6 7 8 9
- QueryResult result = CharacterDatabase.PQuery("SELECT leaderGuid, lootMethod, looterGuid, lootThreshold, icon1, icon2, icon3, icon4, icon5, icon6"
- // 10 11 12 13 14 15
- ", icon7, icon8, groupType, difficulty, raiddifficulty, guid FROM groups ORDER BY guid ASC");
+ // 0 1 2 3 4 5 6 7 8 9
+ QueryResult result = CharacterDatabase.PQuery("SELECT g.leaderGuid, g.lootMethod, g.looterGuid, g.lootThreshold, g.icon1, g.icon2, g.icon3, g.icon4, g.icon5, g.icon6"
+ // 10 11 12 13 14 15 16 17
+ ", g.icon7, g.icon8, g.groupType, g.difficulty, g.raiddifficulty, g.guid, lfg.dungeon, lfg.state FROM groups g LEFT JOIN lfg_data lfg ON lfg.guid = g.guid ORDER BY g.guid ASC");
if (!result)
{
sLog->outString(">> Loaded 0 group definitions. DB table `groups` is empty!");
diff --git a/src/server/game/Groups/GroupReference.cpp b/src/server/game/Groups/GroupReference.cpp
index 4d5890aa4e6..68d85c5bce9 100755
--- a/src/server/game/Groups/GroupReference.cpp
+++ b/src/server/game/Groups/GroupReference.cpp
@@ -28,12 +28,12 @@ void GroupReference::targetObjectBuildLink()
void GroupReference::targetObjectDestroyLink()
{
// called from unlink()
- getTarget()->DelinkMember(this);
+ //getTarget()->DelinkMember(this);
}
void GroupReference::sourceObjectDestroyLink()
{
// called from invalidate()
- getTarget()->DelinkMember(this);
+ //getTarget()->DelinkMember(this);
}
diff --git a/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp b/src/server/game/Handlers/AddonHandler.cpp
index ef537cb6198..ef537cb6198 100755
--- a/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp
+++ b/src/server/game/Handlers/AddonHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/AddonHandler.h b/src/server/game/Handlers/AddonHandler.h
index 36cb19e5698..36cb19e5698 100755
--- a/src/server/game/Server/Protocol/Handlers/AddonHandler.h
+++ b/src/server/game/Handlers/AddonHandler.h
diff --git a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp
index 8fb820713ce..8fb820713ce 100755
--- a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp
+++ b/src/server/game/Handlers/ArenaTeamHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 845f3279356..845f3279356 100755
--- a/src/server/game/Server/Protocol/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/AuthHandler.cpp b/src/server/game/Handlers/AuthHandler.cpp
index c5dbcb4f946..c5dbcb4f946 100755
--- a/src/server/game/Server/Protocol/Handlers/AuthHandler.cpp
+++ b/src/server/game/Handlers/AuthHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp
index 00f18217eed..00f18217eed 100755
--- a/src/server/game/Server/Protocol/Handlers/BattleGroundHandler.cpp
+++ b/src/server/game/Handlers/BattleGroundHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp
index be547c84b19..be547c84b19 100755
--- a/src/server/game/Server/Protocol/Handlers/CalendarHandler.cpp
+++ b/src/server/game/Handlers/CalendarHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp
index efa2d54a65d..efa2d54a65d 100755
--- a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp
+++ b/src/server/game/Handlers/ChannelHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 62b9fe0b582..ee68a15c301 100644
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -43,6 +43,7 @@
#include "Battleground.h"
#include "AccountMgr.h"
#include "DBCStores.h"
+#include "LFGMgr.h"
class LoginQueryHolder : public SQLQueryHolder
{
@@ -196,7 +197,7 @@ bool LoginQueryHolder::Initialize()
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES);
stmt->setUInt32(0, m_accountId);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADINSTANCELOCKTIMES, stmt);
-
+
return res;
}
@@ -872,6 +873,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
// "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools)
if (!pCurrChar->LoadFromDB(GUID_LOPART(playerGuid), holder))
{
+ SetPlayer(NULL);
KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick
delete pCurrChar; // delete it manually
delete holder; // delete all unprocessed queries
@@ -880,9 +882,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
}
pCurrChar->GetMotionMaster()->Initialize();
-
- SetPlayer(pCurrChar);
-
pCurrChar->SendDungeonDifficulty(false);
WorldPacket data(SMSG_LOGIN_VERIFY_WORLD, 20);
@@ -992,6 +991,17 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
}
}
+ if (Group* group = pCurrChar->GetGroup())
+ {
+ if (group->isLFGGroup())
+ {
+ LfgDungeonSet Dungeons;
+ Dungeons.insert(sLFGMgr->GetDungeon(group->GetGUID()));
+ sLFGMgr->SetSelectedDungeons(pCurrChar->GetGUID(), Dungeons);
+ sLFGMgr->SetState(pCurrChar->GetGUID(), sLFGMgr->GetState(group->GetGUID()));
+ }
+ }
+
if (!pCurrChar->GetMap()->AddPlayerToMap(pCurrChar) || !pCurrChar->CheckInstanceLoginValid())
{
AreaTrigger const* at = sObjectMgr->GetGoBackTrigger(pCurrChar->GetMapId());
diff --git a/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index 3a47f214099..3a47f214099 100755
--- a/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp
index 6693cdfca27..6693cdfca27 100755
--- a/src/server/game/Server/Protocol/Handlers/CombatHandler.cpp
+++ b/src/server/game/Handlers/CombatHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/DuelHandler.cpp b/src/server/game/Handlers/DuelHandler.cpp
index 8afd9f3b978..8afd9f3b978 100755
--- a/src/server/game/Server/Protocol/Handlers/DuelHandler.cpp
+++ b/src/server/game/Handlers/DuelHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index 7d99213acf0..7d99213acf0 100755
--- a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp
index fff068a0a04..fff068a0a04 100755
--- a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp
+++ b/src/server/game/Handlers/GuildHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 2146b8a89bb..2146b8a89bb 100755
--- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index 7d4e4ec28ae..842e19cf510 100755
--- a/src/server/game/Server/Protocol/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -50,7 +50,8 @@ void BuildPartyLockDungeonBlock(WorldPacket& data, const LfgLockPartyMap& lockMa
void WorldSession::HandleLfgJoinOpcode(WorldPacket& recv_data)
{
if (!sWorld->getBoolConfig(CONFIG_DUNGEON_FINDER_ENABLE) ||
- (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID()))
+ (GetPlayer()->GetGroup() && GetPlayer()->GetGroup()->GetLeaderGUID() != GetPlayer()->GetGUID() &&
+ (GetPlayer()->GetGroup()->GetMembersCount() == MAXGROUPSIZE || !GetPlayer()->GetGroup()->isLFGGroup())))
{
recv_data.rfinish();
return;
diff --git a/src/server/game/Server/Protocol/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index b17817e196f..6508f08dc22 100755
--- a/src/server/game/Server/Protocol/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -324,7 +324,7 @@ void WorldSession::DoLootRelease(uint64 lguid)
else
{
// not fully looted object
- go->SetLootState(GO_ACTIVATED);
+ go->SetLootState(GO_ACTIVATED, player);
// if the round robin player release, reset it.
if (player->GetGUID() == loot->roundRobinPlayer)
diff --git a/src/server/game/Server/Protocol/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 95459bae0fa..95459bae0fa 100755
--- a/src/server/game/Server/Protocol/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 843aa8fd6c0..0b3a675e762 100755
--- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -160,7 +160,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket & recv_data)
else
{
go->AI()->GossipSelect(_player, menuId, gossipListId);
- sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
+ if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
+ _player->OnGossipSelect(go, gossipListId, menuId);
}
}
}
@@ -169,6 +170,11 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd CMSG_WHO Message");
+ time_t now = time(NULL);
+ if (now - timeLastWhoCommand < 5)
+ return;
+ else timeLastWhoCommand = now;
+
uint32 matchcount = 0;
uint32 level_min, level_max, racemask, classmask, zones_count, str_count;
diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 71dfc670145..5cac0b99c77 100755
--- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -479,19 +479,8 @@ void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)
if (GetPlayer()->IsInWorld())
{
- if (Unit* mover = ObjectAccessor::GetUnit(*GetPlayer(), guid))
- {
- GetPlayer()->SetMover(mover);
- if (mover != GetPlayer() && mover->canFly())
- {
- GetPlayer()->SendSetFlyPacket(true);
- }
- }
- else
- {
+ if (_player->m_mover->GetGUID() != guid)
sLog->outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " UI64FMTD " (%s - Entry: %u) and should be " UI64FMTD, guid, GetLogNameForGuid(guid), GUID_ENPART(guid), _player->m_mover->GetGUID());
- GetPlayer()->SetMover(GetPlayer());
- }
}
}
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp
index c1b59b41ebb..c1b59b41ebb 100755
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp
+++ b/src/server/game/Handlers/NPCHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h
index af84b71a74f..af84b71a74f 100755
--- a/src/server/game/Server/Protocol/Handlers/NPCHandler.h
+++ b/src/server/game/Handlers/NPCHandler.h
diff --git a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 90cda17d477..00a19adc8ae 100755
--- a/src/server/game/Server/Protocol/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -160,6 +160,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
case COMMAND_STAY: //flat=1792 //STAY
pet->AttackStop();
pet->InterruptNonMeleeSpells(false);
+ pet->GetMotionMaster()->Clear(false);
pet->GetMotionMaster()->MoveIdle();
charmInfo->SetCommandState(COMMAND_STAY);
diff --git a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp
index dce5e0f78ba..dce5e0f78ba 100755
--- a/src/server/game/Server/Protocol/Handlers/PetitionsHandler.cpp
+++ b/src/server/game/Handlers/PetitionsHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index abb62fb0185..abb62fb0185 100755
--- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index a3debe82ac1..a3debe82ac1 100755
--- a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp
index 58d425ddf98..58d425ddf98 100644
--- a/src/server/game/Server/Protocol/Handlers/ReferAFriendHandler.cpp
+++ b/src/server/game/Handlers/ReferAFriendHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp
index 2e4ef5cb40d..2e4ef5cb40d 100755
--- a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp
+++ b/src/server/game/Handlers/SkillHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index 09ba46654ee..09ba46654ee 100755
--- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp
index 81481bdef31..3533b153bd8 100755
--- a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp
+++ b/src/server/game/Handlers/TaxiHandler.cpp
@@ -27,7 +27,6 @@
#include "UpdateMask.h"
#include "Path.h"
#include "WaypointMovementGenerator.h"
-#include "DestinationHolderImp.h"
void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket & recv_data)
{
diff --git a/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp
index a270d42b000..a270d42b000 100755
--- a/src/server/game/Server/Protocol/Handlers/TicketHandler.cpp
+++ b/src/server/game/Handlers/TicketHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 900f036df0a..900f036df0a 100755
--- a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp
index ce4f6ccb8fe..ce4f6ccb8fe 100644
--- a/src/server/game/Server/Protocol/Handlers/VehicleHandler.cpp
+++ b/src/server/game/Handlers/VehicleHandler.cpp
diff --git a/src/server/game/Server/Protocol/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp
index 34ad5ac3eae..34ad5ac3eae 100755
--- a/src/server/game/Server/Protocol/Handlers/VoiceChatHandler.cpp
+++ b/src/server/game/Handlers/VoiceChatHandler.cpp
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 9fb2fdf1c25..722b7089a17 100755
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -532,8 +532,8 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)
if (iMap && iMap->IsDungeon())
((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
- else
- sObjectMgr->DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded
+
+ sObjectMgr->DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded
// Free up the instance id and allow it to be reused
sMapMgr->FreeInstanceId(instanceId);
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index dd9abbed372..1869a21c738 100755
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -302,21 +302,21 @@ void InstanceScript::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData)
}
// Send Notify to all players in instance
-void InstanceScript::DoSendNotifyToInstance(const char *format, ...)
+void InstanceScript::DoSendNotifyToInstance(char const* format, ...)
{
- InstanceMap::PlayerList const &PlayerList = instance->GetPlayers();
+ InstanceMap::PlayerList const& players = instance->GetPlayers();
- if (!PlayerList.isEmpty())
+ if (!players.isEmpty())
{
va_list ap;
va_start(ap, format);
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- {
- if (Player* player = i->getSource())
- if (WorldSession* pSession = player->GetSession())
- pSession->SendNotification(format, ap);
- }
+ char buff[1024];
+ vsnprintf(buff, 1024, format, ap);
va_end(ap);
+ for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
+ if (Player* player = i->getSource())
+ if (WorldSession* session = player->GetSession())
+ session->SendNotification(buff);
}
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index bbe349d76df..ec362cf1a83 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1539,6 +1539,24 @@ inline GridMap* Map::GetGrid(float x, float y)
return GridMaps[gx][gy];
}
+float Map::GetWaterOrGroundLevel(float x, float y, float z, float* ground /*= NULL*/, bool swim /*= false*/) const
+{
+ if (const_cast<Map*>(this)->GetGrid(x, y))
+ {
+ // we need ground level (including grid height version) for proper return water level in point
+ float ground_z = GetHeight(x, y, z, true, 50.0f);
+ if (ground)
+ *ground = ground_z;
+
+ LiquidData liquid_status;
+
+ ZLiquidStatus res = getLiquidStatus(x, y, ground_z, MAP_ALL_LIQUIDS, &liquid_status);
+ return res ? ( swim ? liquid_status.level - 2.0f : liquid_status.level) : ground_z;
+ }
+
+ return VMAP_INVALID_HEIGHT_VALUE;
+}
+
float Map::GetHeight(float x, float y, float z, bool checkVMap /*= true*/, float maxSearchDist /*= DEFAULT_HEIGHT_SEARCH*/) const
{
// find raw .map surface under Z coordinates
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 9f6b936541e..f3b45bd8f37 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -424,6 +424,8 @@ class Map : public GridRefManager<NGridType>
InstanceMap* ToInstanceMap(){ if (IsDungeon()) return reinterpret_cast<InstanceMap*>(this); else return NULL; }
const InstanceMap* ToInstanceMap() const { if (IsDungeon()) return (const InstanceMap*)((InstanceMap*)this); else return NULL; }
+ float GetWaterOrGroundLevel(float x, float y, float z, float* ground = NULL, bool swim = false) const;
+
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index 62520cf2ace..6890ec8ac2e 100755
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -25,7 +25,6 @@
#include "GridDefines.h"
#include "MapInstanced.h"
#include "InstanceScript.h"
-#include "DestinationHolderImp.h"
#include "Config.h"
#include "World.h"
#include "CellImpl.h"
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index 66610adc1f0..e751dbf92fe 100755
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -492,9 +492,9 @@ enum TrinityStrings
LANG_MOVEGENS_WAYPOINT = 529,
LANG_MOVEGENS_ANIMAL_RANDOM = 530,
LANG_MOVEGENS_CONFUSED = 531,
- LANG_MOVEGENS_TARGETED_PLAYER = 532,
- LANG_MOVEGENS_TARGETED_CREATURE = 533,
- LANG_MOVEGENS_TARGETED_NULL = 534,
+ LANG_MOVEGENS_CHASE_PLAYER = 532,
+ LANG_MOVEGENS_CHASE_CREATURE = 533,
+ LANG_MOVEGENS_CHASE_NULL = 534,
LANG_MOVEGENS_HOME_CREATURE = 535,
LANG_MOVEGENS_HOME_PLAYER = 536,
LANG_MOVEGENS_FLIGHT = 537,
@@ -807,7 +807,11 @@ enum TrinityStrings
LANG_CHAR_NOT_BANNED = 1136,
LANG_DEV_ON = 1137,
LANG_DEV_OFF = 1138,
- // Room for more level 3 1139-1199 not used
+ LANG_MOVEGENS_FOLLOW_PLAYER = 1139,
+ LANG_MOVEGENS_FOLLOW_CREATURE = 1140,
+ LANG_MOVEGENS_FOLLOW_NULL = 1141,
+ LANG_MOVEGENS_EFFECT = 1142,
+ // Room for more level 3 1143-1199 not used
// Debug commands
LANG_CINEMATIC_NOT_EXIST = 1200,
diff --git a/src/server/game/Movement/DestinationHolder.cpp b/src/server/game/Movement/DestinationHolder.cpp
deleted file mode 100755
index 4b763112968..00000000000
--- a/src/server/game/Movement/DestinationHolder.cpp
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "DestinationHolder.h"
-
diff --git a/src/server/game/Movement/DestinationHolder.h b/src/server/game/Movement/DestinationHolder.h
deleted file mode 100755
index 5ae4ee88ce3..00000000000
--- a/src/server/game/Movement/DestinationHolder.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_DESTINATION_HOLDER_H
-#define TRINITY_DESTINATION_HOLDER_H
-
-#include "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
-
diff --git a/src/server/game/Movement/DestinationHolderImp.h b/src/server/game/Movement/DestinationHolderImp.h
deleted file mode 100755
index 4d6e6f0c741..00000000000
--- a/src/server/game/Movement/DestinationHolderImp.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef 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 = (float)((i_destX - i_fromX) * percent_passed);
- const float distanceY = (float)((i_destY - i_fromY) * percent_passed);
- const float distanceZ = (float)((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 = (float)(i_fromX + ((i_destX - i_fromX) * percent_passed));
- y = (float)(i_fromY + ((i_destY - i_fromY) * percent_passed));
- z = (float)(i_fromZ + ((i_destZ - i_fromZ) * percent_passed));
- }
-}
-
-#endif
-
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 51725c118ce..8975a2d7d7b 100755
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -19,7 +19,6 @@
#include "MotionMaster.h"
#include "CreatureAISelector.h"
#include "Creature.h"
-#include "Traveller.h"
#include "ConfusedMovementGenerator.h"
#include "FleeingMovementGenerator.h"
@@ -29,7 +28,8 @@
#include "TargetedMovementGenerator.h"
#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
-
+#include "MoveSpline.h"
+#include "MoveSplineInit.h"
#include <cassert>
inline bool isStatic(MovementGenerator *mv)
@@ -175,12 +175,11 @@ void MotionMaster::DelayedExpire()
--i_top;
}
-void MotionMaster::MoveIdle(MovementSlot slot)
+void MotionMaster::MoveIdle()
{
- //if (empty() || !isStatic(top()))
- // push(&si_idleMovement);
- if (!isStatic(Impl[slot]))
- Mutate(&si_idleMovement, slot);
+ //! Should be preceded by MovementExpired or Clear if there's an overlying movementgenerator active
+ if (empty() || !isStatic(top()))
+ Mutate(&si_idleMovement, MOTION_SLOT_IDLE);
}
void MotionMaster::MoveRandom(float spawndist)
@@ -194,16 +193,23 @@ void MotionMaster::MoveRandom(float spawndist)
void MotionMaster::MoveTargetedHome()
{
- //if (i_owner->HasUnitState(UNIT_STAT_FLEEING))
- // return;
-
Clear(false);
- if (i_owner->GetTypeId() == TYPEID_UNIT)
+ if (i_owner->GetTypeId()==TYPEID_UNIT && !((Creature*)i_owner)->GetCharmerOrOwnerGUID())
{
sLog->outStaticDebug("Creature (Entry: %u GUID: %u) targeted home", i_owner->GetEntry(), i_owner->GetGUIDLow());
Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE);
}
+ else if (i_owner->GetTypeId()==TYPEID_UNIT && ((Creature*)i_owner)->GetCharmerOrOwnerGUID())
+ {
+ sLog->outStaticDebug("Pet or controlled creature (Entry: %u GUID: %u) targeting home", i_owner->GetEntry(), i_owner->GetGUIDLow() );
+ Unit *target = ((Creature*)i_owner)->GetCharmerOrOwner();
+ if (target)
+ {
+ sLog->outStaticDebug("Following %s (GUID: %u)", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow() );
+ Mutate(new FollowMovementGenerator<Creature>(*target,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE);
+ }
+ }
else
{
sLog->outError("Player (GUID: %u) attempt targeted home", i_owner->GetGUIDLow());
@@ -231,14 +237,14 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle)
if (!target || target == i_owner || i_owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
return;
- i_owner->ClearUnitState(UNIT_STAT_FOLLOW);
+ //i_owner->ClearUnitState(UNIT_STAT_FOLLOW);
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
sLog->outStaticDebug("Player (GUID: %u) chase to %s (GUID: %u)",
i_owner->GetGUIDLow(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
- Mutate(new TargetedMovementGenerator<Player>(*target, dist, angle), MOTION_SLOT_ACTIVE);
+ Mutate(new ChaseMovementGenerator<Player>(*target,dist,angle), MOTION_SLOT_ACTIVE);
}
else
{
@@ -246,7 +252,7 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle)
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
- Mutate(new TargetedMovementGenerator<Creature>(*target, dist, angle), MOTION_SLOT_ACTIVE);
+ Mutate(new ChaseMovementGenerator<Creature>(*target,dist,angle), MOTION_SLOT_ACTIVE);
}
}
@@ -256,13 +262,13 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo
if (!target || target == i_owner || i_owner->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE))
return;
- i_owner->AddUnitState(UNIT_STAT_FOLLOW);
+ //i_owner->AddUnitState(UNIT_STAT_FOLLOW);
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
sLog->outStaticDebug("Player (GUID: %u) follow to %s (GUID: %u)", i_owner->GetGUIDLow(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
- Mutate(new TargetedMovementGenerator<Player>(*target, dist, angle), slot);
+ Mutate(new FollowMovementGenerator<Player>(*target,dist,angle), slot);
}
else
{
@@ -270,7 +276,7 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo
i_owner->GetEntry(), i_owner->GetGUIDLow(),
target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature",
target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow());
- Mutate(new TargetedMovementGenerator<Creature>(*target, dist, angle), slot);
+ Mutate(new FollowMovementGenerator<Creature>(*target,dist,angle), slot);
}
}
@@ -291,54 +297,32 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z)
void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
{
- if (i_owner->GetTypeId() != TYPEID_UNIT)
- return;
-
- uint32 moveFlag = SPLINEFLAG_FLYING | SPLINEFLAG_ANIMATIONTIER;
- uint32 moveTime = uint32(i_owner->GetExactDist(&pos) / speed) * IN_MILLISECONDS;
-
- // CHARGING state makes the unit use m_TempSpeed and JUMPING prevents sending movement packet in PointMovementGenerator
- i_owner->AddUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
- i_owner->m_TempSpeed = speed;
-
float x, y, z;
pos.GetPosition(x, y, z);
- sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
- Mutate(new PointMovementGenerator<Creature>(id, x, y, z), MOTION_SLOT_ACTIVE);
- MonsterMoveData data;
- data.DestLocation.Relocate(pos);
- data.SplineFlag = moveFlag;
- data.Time = moveTime;
- data.AnimationState = ANIMATION_ON_GROUND;
+ sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
- i_owner->SendMonsterMove(data);
+ Movement::MoveSplineInit init(*i_owner);
+ init.MoveTo(x,y,z);
+ init.SetVelocity(speed);
+ init.SetAnimation(Movement::ToGround);
+ init.Launch();
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
}
void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
{
- if (i_owner->GetTypeId() != TYPEID_UNIT)
- return;
-
- uint32 moveFlag = SPLINEFLAG_FLYING | SPLINEFLAG_ANIMATIONTIER;
- uint32 moveTime = uint32(i_owner->GetExactDist(&pos) / speed) * IN_MILLISECONDS;
-
- // CHARGING state makes the unit use m_TempSpeed and JUMPING prevents sending movement packet in PointMovementGenerator
- i_owner->AddUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
- i_owner->m_TempSpeed = speed;
-
float x, y, z;
pos.GetPosition(x, y, z);
- sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
- Mutate(new PointMovementGenerator<Creature>(id, x, y, z), MOTION_SLOT_ACTIVE);
- MonsterMoveData data;
- data.DestLocation.Relocate(pos);
- data.SplineFlag = moveFlag;
- data.Time = moveTime;
- data.AnimationState = ANIMATION_FLYING;
+ sLog->outStaticDebug("Creature (Entry: %u) landing point (ID: %u X: %f Y: %f Z: %f)", i_owner->GetEntry(), id, x, y, z);
- i_owner->SendMonsterMove(data);
+ Movement::MoveSplineInit init(*i_owner);
+ init.MoveTo(x,y,z);
+ init.SetVelocity(speed);
+ init.SetAnimation(Movement::ToFly);
+ init.Launch();
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
}
void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ)
@@ -348,7 +332,9 @@ void MotionMaster::MoveKnockbackFrom(float srcX, float srcY, float speedXY, floa
return;
float x, y, z;
- float dist = speedXY * speedZ * 0.1f;
+ float moveTimeHalf = speedZ / Movement::gravity;
+ float dist = 2 * moveTimeHalf * speedXY;
+
i_owner->GetNearPoint(i_owner, x, y, z, i_owner->GetObjectSize(), dist, i_owner->GetAngle(srcX, srcY) + M_PI);
MoveJump(x, y, z, speedXY, speedZ);
}
@@ -360,35 +346,51 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ)
return;
float x, y, z;
- float dist = speedXY * speedZ * 0.1f;
+
+ float moveTimeHalf = speedZ / Movement::gravity;
+ float dist = 2 * moveTimeHalf * speedXY;
i_owner->GetClosePoint(x, y, z, i_owner->GetObjectSize(), dist, angle);
MoveJump(x, y, z, speedXY, speedZ);
}
-void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ)
+void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id)
{
- uint32 moveFlag = SPLINEFLAG_TRAJECTORY | SPLINEFLAG_WALKING;
- uint32 time = uint32(speedZ * 100);
+ sLog->outStaticDebug("Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z);
- // Instantly interrupt non melee spells being casted
- if (i_owner->IsNonMeleeSpellCasted(true))
- i_owner->InterruptNonMeleeSpells(true);
+ float moveTimeHalf = speedZ / Movement::gravity;
+ float max_height = -Movement::computeFallElevation(moveTimeHalf,false,-speedZ);
- i_owner->AddUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
- i_owner->m_TempSpeed = speedXY;
+ Movement::MoveSplineInit init(*i_owner);
+ init.MoveTo(x,y,z);
+ init.SetParabolic(max_height,0);
+ init.SetVelocity(speedXY);
+ init.Launch();
if (i_owner->GetTypeId() == TYPEID_PLAYER)
- {
- sLog->outStaticDebug("Player (GUID: %u) jump to point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z);
- Mutate(new PointMovementGenerator<Player>(0, x, y, z), MOTION_SLOT_CONTROLLED);
- }
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
else
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
+}
+
+void MotionMaster::MoveFall(uint32 id/*=0*/)
+{
+ // use larger distance for vmap height search than in most other cases
+ float tz = i_owner->GetMap()->GetHeight(i_owner->GetPositionX(), i_owner->GetPositionY(), i_owner->GetPositionZ(), true, MAX_FALL_DISTANCE);
+ if (tz <= INVALID_HEIGHT)
{
- sLog->outStaticDebug("Creature (Entry: %u GUID: %u) jump to point (X: %f Y: %f Z: %f)",
- i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z);
- Mutate(new PointMovementGenerator<Creature>(0, x, y, z), MOTION_SLOT_CONTROLLED);
+ sLog->outStaticDebug("MotionMaster::MoveFall: unable retrive a proper height at map %u (x: %f, y: %f, z: %f).",
+ i_owner->GetMap()->GetId(), i_owner->GetPositionX(), i_owner->GetPositionX(), i_owner->GetPositionZ());
+ return;
}
- i_owner->SendMonsterMove(x, y, z, moveFlag, time, speedZ);
+ // Abort too if the ground is very near
+ if (fabs(i_owner->GetPositionZ() - tz) < 0.1f)
+ return;
+
+ Movement::MoveSplineInit init(*i_owner);
+ init.MoveTo(i_owner->GetPositionX(),i_owner->GetPositionY(),tz);
+ init.SetFall();
+ init.Launch();
+ Mutate(new EffectMovementGenerator(id), MOTION_SLOT_CONTROLLED);
}
void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id)
@@ -396,29 +398,19 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed, uint32 id)
if (Impl[MOTION_SLOT_CONTROLLED] && Impl[MOTION_SLOT_CONTROLLED]->GetMovementGeneratorType() != DISTRACT_MOTION_TYPE)
return;
- i_owner->AddUnitState(UNIT_STAT_CHARGING);
- i_owner->m_TempSpeed = speed;
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
sLog->outStaticDebug("Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", i_owner->GetGUIDLow(), x, y, z);
- Mutate(new PointMovementGenerator<Player>(id, x, y, z), MOTION_SLOT_CONTROLLED);
+ Mutate(new PointMovementGenerator<Player>(id, x, y, z, speed), MOTION_SLOT_CONTROLLED);
}
else
{
sLog->outStaticDebug("Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)",
i_owner->GetEntry(), i_owner->GetGUIDLow(), x, y, z);
- Mutate(new PointMovementGenerator<Creature>(id, x, y, z), MOTION_SLOT_CONTROLLED);
+ Mutate(new PointMovementGenerator<Creature>(id, x, y, z, speed), MOTION_SLOT_CONTROLLED);
}
}
-void MotionMaster::MoveFall(float z, uint32 id)
-{
- i_owner->SetFlying(false);
- i_owner->SendMovementFlagUpdate();
- //AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
- MoveCharge(i_owner->GetPositionX(), i_owner->GetPositionY(), z, SPEED_CHARGE, id);
-}
-
void MotionMaster::MoveSeekAssistance(float x, float y, float z)
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
@@ -562,7 +554,7 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable)
//i_owner->GetTypeId() == TYPEID_PLAYER ?
//Mutate(new WaypointMovementGenerator<Player>(path_id, repeatable)):
- Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE);
+ Mutate(new WaypointMovementGenerator<Creature>(path_id, repeatable), MOTION_SLOT_IDLE);
sLog->outStaticDebug("%s (GUID: %u) start moving over path(Id:%u, repeatable: %s)",
i_owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature",
@@ -633,8 +625,12 @@ void MotionMaster::DelayedDelete(_Ty curr)
bool MotionMaster::GetDestination(float &x, float &y, float &z)
{
- if (empty())
+ if (i_owner->movespline->Finalized())
return false;
- return top()->GetDestination(x, y, z);
+ const G3D::Vector3& dest = i_owner->movespline->FinalDestination();
+ x = dest.x;
+ y = dest.y;
+ z = dest.z;
+ return true;
}
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index 64026ea7b80..a5bd0861b04 100755
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -39,7 +39,7 @@ enum MovementGeneratorType
MAX_DB_MOTION_TYPE = 3, // *** this and below motion types can't be set in DB.
ANIMAL_RANDOM_MOTION_TYPE = MAX_DB_MOTION_TYPE, // AnimalRandomMovementGenerator.h
CONFUSED_MOTION_TYPE = 4, // ConfusedMovementGenerator.h
- TARGETED_MOTION_TYPE = 5, // TargetedMovementGenerator.h
+ CHASE_MOTION_TYPE = 5, // TargetedMovementGenerator.h
HOME_MOTION_TYPE = 6, // HomeMovementGenerator.h
FLIGHT_MOTION_TYPE = 7, // WaypointMovementGenerator.h
POINT_MOTION_TYPE = 8, // PointMovementGenerator.h
@@ -48,8 +48,10 @@ enum MovementGeneratorType
ASSISTANCE_MOTION_TYPE= 11, // PointMovementGenerator.h (first part of flee for assistance)
ASSISTANCE_DISTRACT_MOTION_TYPE = 12, // IdleMovementGenerator.h (second part of flee for assistance)
TIMED_FLEEING_MOTION_TYPE = 13, // FleeingMovementGenerator.h (alt.second part of flee for assistance)
- ROTATE_MOTION_TYPE = 14,
- NULL_MOTION_TYPE = 15,
+ FOLLOW_MOTION_TYPE = 14,
+ ROTATE_MOTION_TYPE = 15,
+ EFFECT_MOTION_TYPE = 16,
+ NULL_MOTION_TYPE = 17,
};
enum MovementSlot
@@ -86,7 +88,6 @@ class MotionMaster //: private std::stack<MovementGenerator *>
typedef std::vector<_Ty> ExpireList;
int i_top;
- bool empty() const { return (i_top < 0); }
void pop() { Impl[i_top] = NULL; --i_top; }
void push(_Ty _Val) { ++i_top; Impl[i_top] = _Val; }
@@ -107,6 +108,7 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void Initialize();
void InitDefault();
+ bool empty() const { return (i_top < 0); }
int size() const { return i_top + 1; }
_Ty top() const { return Impl[i_top]; }
_Ty GetMotionSlot(int slot) const { return Impl[slot]; }
@@ -142,7 +144,7 @@ class MotionMaster //: private std::stack<MovementGenerator *>
DirectExpire(reset);
}
- void MoveIdle(MovementSlot slot = MOTION_SLOT_ACTIVE);
+ void MoveIdle();
void MoveTargetedHome();
void MoveRandom(float spawndist = 0.0f);
void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE);
@@ -158,10 +160,11 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MoveTakeoff(uint32 id, Position const& pos, float speed);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
- void MoveFall(float z, uint32 id = 0);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
void MoveJumpTo(float angle, float speedXY, float speedZ);
- void MoveJump(float x, float y, float z, float speedXY, float speedZ);
+ void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = 0);
+ void MoveFall(uint32 id = 0);
+
void MoveSeekAssistance(float x, float y, float z);
void MoveSeekAssistanceDistract(uint32 timer);
void MoveTaxiFlight(uint32 path, uint32 pathnode);
diff --git a/src/server/game/Movement/MovementGenerator.cpp b/src/server/game/Movement/MovementGenerator.cpp
index 103b8876959..73921ea86ff 100755
--- a/src/server/game/Movement/MovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerator.cpp
@@ -21,4 +21,3 @@
MovementGenerator::~MovementGenerator()
{
}
-
diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h
index 06450d938ae..dd9ba32f337 100755
--- a/src/server/game/Movement/MovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerator.h
@@ -43,8 +43,6 @@ class MovementGenerator
virtual MovementGeneratorType GetMovementGeneratorType() = 0;
virtual void unitSpeedChanged() { }
-
- virtual bool GetDestination(float& /*x*/, float& /*y*/, float& /*z*/) const { return false; }
};
template<class T, class D>
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
index bf5c8bafc49..94608d85420 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp
@@ -18,10 +18,11 @@
#include "Creature.h"
#include "MapManager.h"
-#include "Opcodes.h"
#include "ConfusedMovementGenerator.h"
-#include "DestinationHolderImp.h"
#include "VMapFactory.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "Player.h"
#ifdef MAP_BASED_RAND_GEN
#define rand_norm() unit.rand_norm()
@@ -31,8 +32,8 @@
template<class T>
void ConfusedMovementGenerator<T>::Initialize(T &unit)
{
- float const wanderDistance = 4;
- float x, y, z;
+ const float wander_distance=4;
+ float x,y,z;
x = unit.GetPositionX();
y = unit.GetPositionY();
z = unit.GetPositionZ();
@@ -44,52 +45,33 @@ void ConfusedMovementGenerator<T>::Initialize(T &unit)
bool is_water_ok, is_land_ok;
_InitSpecific(unit, is_water_ok, is_land_ok);
- for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx)
+ for (uint8 idx = 0; idx < MAX_CONF_WAYPOINTS + 1; ++idx)
{
- float wanderX = x + wanderDistance * (float)rand_norm() - wanderDistance/2;
- float wanderY = y + wanderDistance * (float)rand_norm() - wanderDistance/2;
- Trinity::NormalizeMapCoord(wanderX);
- Trinity::NormalizeMapCoord(wanderY);
+ const float wanderX=wander_distance*(float)rand_norm() - wander_distance/2;
+ const float wanderY=wander_distance*(float)rand_norm() - wander_distance/2;
- float new_z = map->GetHeight(wanderX, wanderY, z, true);
- if (new_z > INVALID_HEIGHT && unit.IsWithinLOS(wanderX, wanderY, new_z))
- {
- // Don't move in water if we're not already in
- // Don't move on land if we're not already on it either
- bool is_water_now = map->IsInWater(x, y, z);
- bool is_water_next = map->IsInWater(wanderX, wanderY, new_z);
- if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok))
- {
- i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; // Back to previous location
- i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y;
- i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z;
- continue;
- }
-
- // Taken from FleeingMovementGenerator
- if (!(new_z - z) || wanderDistance / fabs(new_z - z) > 1.0f)
- {
- i_waypoints[idx][0] = wanderX;
- i_waypoints[idx][1] = wanderY;
- i_waypoints[idx][2] = new_z;
- continue;
- }
- }
- else // Back to previous location
+ i_waypoints[idx][0] = x + wanderX;
+ i_waypoints[idx][1] = y + wanderY;
+
+ // 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;
- i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z;
- continue;
}
+
+ unit.UpdateAllowedPositionZ(i_waypoints[idx][0], i_waypoints[idx][1], z);
+ i_waypoints[idx][2] = z;
}
- unit.SetTarget(0);
- unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
- unit.CastStop();
unit.StopMoving();
- unit.AddUnitMovementFlag(MOVEMENTFLAG_WALKING); // Should actually be splineflag
- unit.AddUnitState(UNIT_STAT_CONFUSED);
+ unit.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
+ unit.AddUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
}
template<>
@@ -111,69 +93,70 @@ void ConfusedMovementGenerator<T>::Reset(T &unit)
{
i_nextMove = 1;
i_nextMoveTime.Reset(0);
- i_destinationHolder.ResetUpdate();
unit.StopMoving();
+ unit.AddUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
}
template<class T>
-bool ConfusedMovementGenerator<T>::Update(T &unit, const uint32 diff)
+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))
+ unit.AddUnitState(UNIT_STAT_CONFUSED_MOVE);
+
+ if (unit.movespline->Finalized())
{
- 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(100, 1000));
- }
+ 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())
+ 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);
+ unit.AddUnitState(UNIT_STAT_CONFUSED_MOVE);
+
+ ASSERT( i_nextMove <= MAX_CONF_WAYPOINTS );
+ float x = i_waypoints[i_nextMove][0];
+ float y = i_waypoints[i_nextMove][1];
+ float z = i_waypoints[i_nextMove][2];
+ Movement::MoveSplineInit init(unit);
+ init.MoveTo(x, y, z);
+ init.SetWalk(true);
+ init.Launch();
}
}
+
return true;
}
-template<class T>
-void ConfusedMovementGenerator<T>::Finalize(T &unit)
+template<>
+void ConfusedMovementGenerator<Player>::Finalize(Player &unit)
{
unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
- unit.ClearUnitState(UNIT_STAT_CONFUSED);
+ unit.ClearUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
+}
- if (unit.GetTypeId() == TYPEID_UNIT && unit.getVictim())
+template<>
+void ConfusedMovementGenerator<Creature>::Finalize(Creature &unit)
+{
+ unit.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED);
+ unit.ClearUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_CONFUSED_MOVE);
+ if (unit.getVictim())
unit.SetTarget(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);
+template bool ConfusedMovementGenerator<Player>::Update(Player &player, const uint32 &diff);
+template bool ConfusedMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff);
diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
index d3981ee2dcf..b9f96bb785d 100755
--- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h
@@ -20,8 +20,7 @@
#define TRINITY_CONFUSEDGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
+#include "Timer.h"
#define MAX_CONF_WAYPOINTS 24
@@ -35,21 +34,13 @@ class ConfusedMovementGenerator
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;
- }
+ bool Update(T &, const uint32 &);
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
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
index d2b3fcee384..458e6f9a62c 100755
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.cpp
@@ -20,8 +20,9 @@
#include "CreatureAI.h"
#include "MapManager.h"
#include "FleeingMovementGenerator.h"
-#include "DestinationHolderImp.h"
#include "ObjectAccessor.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
#define MIN_QUIET_DISTANCE 28.0f
#define MAX_QUIET_DISTANCE 43.0f
@@ -43,25 +44,12 @@ FleeingMovementGenerator<T>::_setTargetLocation(T &owner)
if (!_getPoint(owner, x, y, z))
return;
- owner.AddUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
- Traveller<T> traveller(owner);
- i_destinationHolder.SetDestination(traveller, x, y, z);
-}
-
-template<>
-bool FleeingMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) const
-{
- if (i_destinationHolder.HasArrived())
- return false;
+ owner.AddUnitState(UNIT_STAT_FLEEING_MOVE);
- i_destinationHolder.GetDestination(x, y, z);
- return true;
-}
-
-template<>
-bool FleeingMovementGenerator<Player>::GetDestination(float & /*x*/, float & /*y*/, float & /*z*/) const
-{
- return false;
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(x,y,z);
+ init.SetWalk(false);
+ init.Launch();
}
template<class T>
@@ -75,10 +63,10 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
y = owner.GetPositionY();
z = owner.GetPositionZ();
- float temp_x, temp_y, angle = 0;
+ float temp_x, temp_y, angle;
const Map* _map = owner.GetBaseMap();
//primitive path-finding
- for (uint8 i = 0; i < 18; ++i)
+ for(uint8 i = 0; i < 18; ++i)
{
if (i_only_forward && i > 2)
break;
@@ -143,11 +131,11 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
distance /= 4;
break;
case 15:
- angle = i_cur_angle + static_cast<float>(M_PI*3/4);
+ angle = i_cur_angle + static_cast<float>(3*M_PI/4);
distance /= 2;
break;
case 16:
- angle = i_cur_angle - static_cast<float>(M_PI*3/4);
+ angle = i_cur_angle - static_cast<float>(3*M_PI/4);
distance /= 2;
break;
case 17:
@@ -161,9 +149,9 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
Trinity::NormalizeMapCoord(temp_y);
if (owner.IsWithinLOS(temp_x, temp_y, z))
{
- bool is_water_now = _map->IsInWater(x, y, z);
+ bool is_water_now = _map->IsInWater(x,y,z);
- if (is_water_now && _map->IsInWater(temp_x, temp_y, z))
+ if (is_water_now && _map->IsInWater(temp_x,temp_y,z))
{
x = temp_x;
y = temp_y;
@@ -181,8 +169,8 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
if (!(new_z - z) || distance / fabs(new_z - z) > 1.0f)
{
- float new_z_left = _map->GetHeight(temp_x + (float)(cos(angle+M_PI/2)), temp_y + (float)(sin(angle+M_PI/2)), z, true);
- float new_z_right = _map->GetHeight(temp_x + (float)(cos(angle-M_PI/2)), temp_y + (float)(sin(angle-M_PI/2)), z, true);
+ float new_z_left = _map->GetHeight(temp_x + 1.0f*cos(angle+static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle+static_cast<float>(M_PI/2)),z,true);
+ float new_z_right = _map->GetHeight(temp_x + 1.0f*cos(angle-static_cast<float>(M_PI/2)),temp_y + 1.0f*sin(angle-static_cast<float>(M_PI/2)),z,true);
if (fabs(new_z_left - new_z) < 1.2f && fabs(new_z_right - new_z) < 1.2f)
{
x = temp_x;
@@ -194,7 +182,7 @@ FleeingMovementGenerator<T>::_getPoint(T &owner, float &x, float &y, float &z)
}
}
i_to_distance_from_caster = 0.0f;
- i_nextCheckTime.Reset(urand(500, 1000));
+ i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
@@ -213,12 +201,12 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
(i_last_distance_from_caster < i_to_distance_from_caster && cur_dist_xyz > i_to_distance_from_caster) ||
// if we reach bigger distance
(cur_dist_xyz > MAX_QUIET_DISTANCE) || // if we are too far
- (i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE))
+ (i_last_distance_from_caster > MIN_QUIET_DISTANCE && cur_dist_xyz < MIN_QUIET_DISTANCE) )
// if we leave 'quiet zone'
{
// we are very far or too close, stopping
i_to_distance_from_caster = 0.0f;
- i_nextCheckTime.Reset(urand(500, 1000));
+ i_nextCheckTime.Reset( urand(500,1000) );
return false;
}
else
@@ -232,9 +220,7 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
float cur_dist;
float angle_to_caster;
- Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGUID);
-
- if (fright)
+ if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
{
cur_dist = fright->GetDistance(&owner);
if (cur_dist < cur_dist_xyz)
@@ -284,7 +270,7 @@ FleeingMovementGenerator<T>::_setMoveData(T &owner)
i_to_distance_from_caster = MIN_QUIET_DISTANCE + 2.5f + (float)rand_norm()*(MAX_QUIET_DISTANCE - MIN_QUIET_DISTANCE - 2.5f);
}
- int8 sign = rand_norm() > 0.5f ? 1 : -1;
+ int8 sign = (float)rand_norm() > 0.5f ? 1 : -1;
i_cur_angle = sign*angle + angle_to_caster;
// current distance
@@ -300,14 +286,12 @@ FleeingMovementGenerator<T>::Initialize(T &owner)
if (!&owner)
return;
- _Init(owner);
- owner.CastStop();
- owner.AddUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
owner.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner.SetTarget(0);
- owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ owner.AddUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
- if (Unit* fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
+ _Init(owner);
+
+ if (Unit *fright = ObjectAccessor::GetUnit(owner, i_frightGUID))
{
i_caster_x = fright->GetPositionX();
i_caster_y = fright->GetPositionY();
@@ -334,6 +318,7 @@ FleeingMovementGenerator<Creature>::_Init(Creature &owner)
if (!&owner)
return;
+ //owner.SetTargetGuid(ObjectGuid());
is_water_ok = owner.canSwim();
is_land_ok = owner.canWalk();
}
@@ -346,51 +331,44 @@ FleeingMovementGenerator<Player>::_Init(Player &)
is_land_ok = true;
}
-template<class T>
-void
-FleeingMovementGenerator<T>::Finalize(T &owner)
+template<>
+void FleeingMovementGenerator<Player>::Finalize(Player &owner)
+{
+ owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
+ owner.ClearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
+}
+
+template<>
+void FleeingMovementGenerator<Creature>::Finalize(Creature &owner)
{
owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner.ClearUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
- if (owner.GetTypeId() == TYPEID_UNIT && owner.getVictim())
+ owner.ClearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
+ if (owner.getVictim())
owner.SetTarget(owner.getVictim()->GetGUID());
}
template<class T>
-void
-FleeingMovementGenerator<T>::Reset(T &owner)
+void FleeingMovementGenerator<T>::Reset(T &owner)
{
Initialize(owner);
}
template<class T>
bool
-FleeingMovementGenerator<T>::Update(T &owner, const uint32 time_diff)
+FleeingMovementGenerator<T>::Update(T &owner, const uint32 &time_diff)
{
if (!&owner || !owner.isAlive())
return false;
if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
+ {
+ owner.ClearUnitState(UNIT_STAT_FLEEING_MOVE);
return true;
-
- Traveller<T> traveller(owner);
+ }
i_nextCheckTime.Update(time_diff);
-
- if ((owner.IsStopped() && !i_destinationHolder.HasArrived()) || !i_destinationHolder.HasDestination())
- {
+ if (i_nextCheckTime.Passed() && owner.movespline->Finalized())
_setTargetLocation(owner);
- return true;
- }
- if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
- {
- i_destinationHolder.ResetUpdate(50);
- if (i_nextCheckTime.Passed() && i_destinationHolder.HasArrived())
- {
- _setTargetLocation(owner);
- return true;
- }
- }
return true;
}
@@ -402,17 +380,15 @@ template bool FleeingMovementGenerator<Player>::_getPoint(Player &, float &, flo
template bool FleeingMovementGenerator<Creature>::_getPoint(Creature &, float &, float &, float &);
template void FleeingMovementGenerator<Player>::_setTargetLocation(Player &);
template void FleeingMovementGenerator<Creature>::_setTargetLocation(Creature &);
-template void FleeingMovementGenerator<Player>::Finalize(Player &);
-template void FleeingMovementGenerator<Creature>::Finalize(Creature &);
template void FleeingMovementGenerator<Player>::Reset(Player &);
template void FleeingMovementGenerator<Creature>::Reset(Creature &);
-template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32);
-template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32);
+template bool FleeingMovementGenerator<Player>::Update(Player &, const uint32 &);
+template bool FleeingMovementGenerator<Creature>::Update(Creature &, const uint32 &);
void TimedFleeingMovementGenerator::Finalize(Unit &owner)
{
owner.RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_FLEEING);
- owner.ClearUnitState(UNIT_STAT_FLEEING | UNIT_STAT_ROAMING);
+ owner.ClearUnitState(UNIT_STAT_FLEEING|UNIT_STAT_FLEEING_MOVE);
if (Unit* victim = owner.getVictim())
{
if (owner.isAlive())
@@ -429,13 +405,20 @@ bool TimedFleeingMovementGenerator::Update(Unit & owner, const uint32 time_diff)
return false;
if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
+ {
+ owner.ClearUnitState(UNIT_STAT_FLEEING_MOVE);
return true;
+ }
+
+ i_totalFleeTime.Update(time_diff);
+ if (i_totalFleeTime.Passed())
+ return false;
i_totalFleeTime.Update(time_diff);
if (i_totalFleeTime.Passed())
return false;
- // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32) version
+ // This calls grant-parent Update method hiden by FleeingMovementGenerator::Update(Creature &, const uint32 &) version
// This is done instead of casting Unit& to Creature& and call parent method, then we can use Unit directly
return MovementGeneratorMedium< Creature, FleeingMovementGenerator<Creature> >::Update(owner, time_diff);
}
diff --git a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
index 4d4631fe932..750db52bb5a 100755
--- a/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/FleeingMovementGenerator.h
@@ -20,8 +20,6 @@
#define TRINITY_FLEEINGMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
template<class T>
class FleeingMovementGenerator
@@ -33,8 +31,7 @@ class FleeingMovementGenerator
void Initialize(T &);
void Finalize(T &);
void Reset(T &);
- bool Update(T &, const uint32);
- bool GetDestination(float &x, float &y, float &z) const;
+ bool Update(T &, const uint32 &);
MovementGeneratorType GetMovementGeneratorType() { return FLEEING_MOTION_TYPE; }
@@ -56,8 +53,6 @@ class FleeingMovementGenerator
float i_cur_angle;
uint64 i_frightGUID;
TimeTracker i_nextCheckTime;
-
- DestinationHolder< Traveller<T> > i_destinationHolder;
};
class TimedFleeingMovementGenerator
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
index 16153dd6ccb..84997d6d1ae 100755
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
@@ -19,22 +19,16 @@
#include "HomeMovementGenerator.h"
#include "Creature.h"
#include "CreatureAI.h"
-#include "Traveller.h"
-#include "DestinationHolderImp.h"
#include "WorldPacket.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
void HomeMovementGenerator<Creature>::Initialize(Creature & owner)
{
- owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
owner.AddUnitState(UNIT_STAT_EVADE);
_setTargetLocation(owner);
}
-void HomeMovementGenerator<Creature>::Finalize(Creature & owner)
-{
- owner.ClearUnitState(UNIT_STAT_EVADE);
-}
-
void HomeMovementGenerator<Creature>::Reset(Creature &)
{
}
@@ -47,42 +41,35 @@ void HomeMovementGenerator<Creature>::_setTargetLocation(Creature & owner)
if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
return;
- float x, y, z;
- owner.GetHomePosition(x, y, z, ori);
+ Movement::MoveSplineInit init(owner);
+ float x, y, z, o;
+ // at apply we can select more nice return points base at current movegen
+ //if (owner.GetMotionMaster()->empty() || !owner.GetMotionMaster()->top()->GetResetPosition(owner,x,y,z))
+ //{
+ owner.GetHomePosition(x, y, z, o);
+ init.SetFacing(o);
+ //}
+ init.MoveTo(x,y,z);
+ init.SetWalk(false);
+ init.Launch();
- CreatureTraveller traveller(owner);
-
- uint32 travel_time = i_destinationHolder.SetDestination(traveller, x, y, z);
- modifyTravelTime(travel_time);
- owner.ClearUnitState(uint32(UNIT_STAT_ALL_STATE & ~UNIT_STAT_EVADE));
+ arrived = false;
+ owner.ClearUnitState(UNIT_STAT_ALL_STATE & ~UNIT_STAT_EVADE);
}
bool HomeMovementGenerator<Creature>::Update(Creature &owner, const uint32 time_diff)
{
- CreatureTraveller traveller(owner);
- i_destinationHolder.UpdateTraveller(traveller, time_diff);
+ arrived = owner.movespline->Finalized();
+ return !arrived;
+}
- if (time_diff > i_travel_timer)
+void HomeMovementGenerator<Creature>::Finalize(Creature& owner)
+{
+ if (arrived)
{
- owner.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
-
- // restore orientation of not moving creature at returning to home
- if (owner.GetDefaultMovementType() == IDLE_MOTION_TYPE)
- {
- //sLog->outDebug("Entering HomeMovement::GetDestination(z, y, z)");
- owner.SetOrientation(ori);
- WorldPacket packet;
- owner.BuildHeartBeatMsg(&packet);
- owner.SendMessageToSet(&packet, false);
- }
-
owner.ClearUnitState(UNIT_STAT_EVADE);
+ owner.SetWalk(true);
owner.LoadCreaturesAddon(true);
owner.AI()->JustReachedHome();
- return false;
}
-
- i_travel_timer -= time_diff;
-
- return true;
}
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
index ba34899dee5..c724edc91ff 100755
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.h
@@ -20,8 +20,6 @@
#define TRINITY_HOMEMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
class Creature;
@@ -34,24 +32,18 @@ class HomeMovementGenerator<Creature>
{
public:
- HomeMovementGenerator() {}
+ HomeMovementGenerator() : arrived(false) {}
~HomeMovementGenerator() {}
void Initialize(Creature &);
void Finalize(Creature &);
void Reset(Creature &);
bool Update(Creature &, const uint32);
- void modifyTravelTime(uint32 travel_time) { i_travel_timer = travel_time; }
MovementGeneratorType GetMovementGeneratorType() { return HOME_MOTION_TYPE; }
- bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x, y, z); return true; }
-
private:
void _setTargetLocation(Creature &);
- DestinationHolder< Traveller<Creature> > i_destinationHolder;
-
- float ori;
- uint32 i_travel_timer;
+ bool arrived;
};
#endif
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index af2207ae141..88465017dc2 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -20,84 +20,84 @@
#include "Errors.h"
#include "Creature.h"
#include "CreatureAI.h"
-#include "DestinationHolderImp.h"
#include "World.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "Player.h"
//----- Point Movement Generator
template<class T>
void PointMovementGenerator<T>::Initialize(T &unit)
{
- unit.StopMoving();
- Traveller<T> traveller(unit);
- // OLD: knockback effect has UNIT_STAT_JUMPING set, so if here we disable sentmonstermove there will be creature position sync problem between client and server
- // NEW: reactivated this check - UNIT_STAT_JUMPING is only used in MoveJump, which sends its own packet
- i_destinationHolder.SetDestination(traveller, i_x, i_y, i_z, /*true*/ !unit.HasUnitState(UNIT_STAT_JUMPING));
+ if (!unit.IsStopped())
+ unit.StopMoving();
+
+ unit.AddUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+ Movement::MoveSplineInit init(unit);
+ init.MoveTo(i_x, i_y, i_z);
+ if (speed > 0.0f)
+ init.SetVelocity(speed);
+ init.Launch();
}
template<class T>
-bool PointMovementGenerator<T>::Update(T &unit, const uint32 diff)
+bool PointMovementGenerator<T>::Update(T &unit, const uint32 &diff)
{
if (!&unit)
return false;
- if (unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
+ if(unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED))
{
- if (unit.HasUnitState(UNIT_STAT_CHARGING))
- return false;
- else
- return true;
+ unit.ClearUnitState(UNIT_STAT_ROAMING_MOVE);
+ return true;
}
- Traveller<T> traveller(unit);
-
- i_destinationHolder.UpdateTraveller(traveller, diff);
-
- if (i_destinationHolder.HasArrived())
- {
- unit.ClearUnitState(UNIT_STAT_MOVE);
- arrived = true;
- return false;
- }
- else if (!unit.HasUnitState(UNIT_STAT_MOVE) && !unit.HasUnitState(UNIT_STAT_JUMPING))
- {
- i_destinationHolder.StartTravel(traveller);
- }
-
- return true;
+ unit.AddUnitState(UNIT_STAT_ROAMING_MOVE);
+ return !unit.movespline->Finalized();
}
template<class T>
void PointMovementGenerator<T>:: Finalize(T &unit)
{
- if (unit.HasUnitState(UNIT_STAT_CHARGING))
- unit.ClearUnitState(UNIT_STAT_CHARGING | UNIT_STAT_JUMPING);
- if (arrived) // without this crash!
+ unit.ClearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+
+ if (unit.movespline->Finalized())
MovementInform(unit);
}
template<class T>
+void PointMovementGenerator<T>::Reset(T &unit)
+{
+ if (!unit.IsStopped())
+ unit.StopMoving();
+
+ unit.AddUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+}
+
+template<class T>
void PointMovementGenerator<T>::MovementInform(T & /*unit*/)
{
}
template <> void PointMovementGenerator<Creature>::MovementInform(Creature &unit)
{
- if (id == EVENT_FALL_GROUND)
- {
- unit.setDeathState(JUST_DIED);
- unit.SetFlying(true);
- }
- unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
+ //if (id == EVENT_FALL_GROUND)
+ //{
+ // unit.setDeathState(JUST_DIED);
+ // unit.SetFlying(true);
+ //}
+ if (unit.AI())
+ unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
}
template void PointMovementGenerator<Player>::Initialize(Player&);
-template bool PointMovementGenerator<Player>::Update(Player &, const uint32 diff);
-template void PointMovementGenerator<Player>::MovementInform(Player&);
-template void PointMovementGenerator<Player>::Finalize(Player&);
-
template void PointMovementGenerator<Creature>::Initialize(Creature&);
-template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 diff);
+template void PointMovementGenerator<Player>::Finalize(Player&);
template void PointMovementGenerator<Creature>::Finalize(Creature&);
+template void PointMovementGenerator<Player>::Reset(Player&);
+template void PointMovementGenerator<Creature>::Reset(Creature&);
+template bool PointMovementGenerator<Player>::Update(Player &, const uint32 &);
+template bool PointMovementGenerator<Creature>::Update(Creature&, const uint32 &);
void AssistanceMovementGenerator::Finalize(Unit &unit)
{
@@ -107,3 +107,24 @@ void AssistanceMovementGenerator::Finalize(Unit &unit)
unit.GetMotionMaster()->MoveSeekAssistanceDistract(sWorld->getIntConfig(CONFIG_CREATURE_FAMILY_ASSISTANCE_DELAY));
}
+bool EffectMovementGenerator::Update(Unit &unit, const uint32)
+{
+ return !unit.movespline->Finalized();
+}
+
+void EffectMovementGenerator::Finalize(Unit &unit)
+{
+ if (unit.GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if (((Creature&)unit).AI() && unit.movespline->Finalized())
+ ((Creature&)unit).AI()->MovementInform(EFFECT_MOTION_TYPE, m_Id);
+ // Need restore previous movement since we have no proper states system
+ //if (unit.isAlive() && !unit.HasUnitState(UNIT_STAT_CONFUSED|UNIT_STAT_FLEEING))
+ //{
+ // if (Unit * victim = unit.getVictim())
+ // unit.GetMotionMaster()->MoveChase(victim);
+ // else
+ // unit.GetMotionMaster()->Initialize();
+ //}
+}
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
index 2504f1a38e3..e47f3d93450 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
@@ -20,8 +20,6 @@
#define TRINITY_POINTMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
#include "FollowerReference.h"
template<class T>
@@ -29,13 +27,13 @@ class PointMovementGenerator
: public MovementGeneratorMedium< T, PointMovementGenerator<T> >
{
public:
- PointMovementGenerator(uint32 _id, float _x, float _y, float _z) : id(_id),
- i_x(_x), i_y(_y), i_z(_z), i_nextMoveTime(0), arrived(false) {}
+ PointMovementGenerator(uint32 _id, float _x, float _y, float _z, float _speed = 0.0f) : id(_id),
+ i_x(_x), i_y(_y), i_z(_z), speed(_speed) {}
void Initialize(T &);
- void Finalize(T &unit);
- void Reset(T &unit){unit.StopMoving();}
- bool Update(T &, const uint32 diff);
+ void Finalize(T &);
+ void Reset(T &);
+ bool Update(T &, const uint32 &);
void MovementInform(T &);
@@ -45,9 +43,7 @@ class PointMovementGenerator
private:
uint32 id;
float i_x, i_y, i_z;
- TimeTracker i_nextMoveTime;
- DestinationHolder< Traveller<T> > i_destinationHolder;
- bool arrived;
+ float speed;
};
class AssistanceMovementGenerator
@@ -61,5 +57,19 @@ class AssistanceMovementGenerator
void Finalize(Unit &);
};
+// Does almost nothing - just doesn't allows previous movegen interrupt current effect.
+class EffectMovementGenerator : public MovementGenerator
+{
+ public:
+ explicit EffectMovementGenerator(uint32 Id) : m_Id(Id) {}
+ void Initialize(Unit &) {}
+ void Finalize(Unit &unit);
+ void Reset(Unit &) {}
+ bool Update(Unit &u, const uint32);
+ MovementGeneratorType GetMovementGeneratorType() { return EFFECT_MOTION_TYPE; }
+ private:
+ uint32 m_Id;
+};
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
index 981ec031cf9..0205b734058 100755
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp
@@ -19,123 +19,103 @@
#include "Creature.h"
#include "MapManager.h"
#include "RandomMovementGenerator.h"
-#include "Traveller.h"
#include "ObjectAccessor.h"
-#include "DestinationHolderImp.h"
#include "Map.h"
#include "Util.h"
#include "CreatureGroups.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
#define RUNNING_CHANCE_RANDOMMV 20 //will be "1 / RUNNING_CHANCE_RANDOMMV"
-template<>
-bool
-RandomMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) const
-{
- if (i_destinationHolder.HasArrived())
- return false;
-
- i_destinationHolder.GetDestination(x, y, z);
- return true;
-}
-
#ifdef MAP_BASED_RAND_GEN
#define rand_norm() creature.rand_norm()
#endif
template<>
-void
-RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
+void RandomMovementGenerator<Creature>::_setRandomLocation(Creature &creature)
{
- float X, Y, Z, nx, ny, nz, ori, dist;
-
- creature.GetHomePosition(X, Y, Z, ori);
-
+ float respX, respY, respZ, respO, currZ, destX, destY, destZ, travelDistZ;
+ creature.GetHomePosition(respX, respY, respZ, respO);
+ currZ = creature.GetPositionZ();
Map const* map = creature.GetBaseMap();
// For 2D/3D system selection
- //bool is_land_ok = creature.canWalk();
- //bool is_water_ok = creature.canSwim();
- bool is_air_ok = creature.canFly();
+ //bool is_land_ok = creature.CanWalk(); // not used?
+ //bool is_water_ok = creature.CanSwim(); // not used?
+ bool is_air_ok = creature.canFly();
- for (uint32 i = 0; ; ++i)
- {
- const float angle = (float)rand_norm()*static_cast<float>(M_PI*2);
- const float range = (float)rand_norm()*wander_distance;
- const float distanceX = range * cos(angle);
- const float distanceY = range * sin(angle);
+ const float angle = float(rand_norm()) * static_cast<float>(M_PI*2.0f);
+ const float range = float(rand_norm()) * wander_distance;
+ const float distanceX = range * cos(angle);
+ const float distanceY = range * sin(angle);
- nx = X + distanceX;
- ny = Y + distanceY;
+ destX = respX + distanceX;
+ destY = respY + distanceY;
- // prevent invalid coordinates generation
- Trinity::NormalizeMapCoord(nx);
- Trinity::NormalizeMapCoord(ny);
+ // prevent invalid coordinates generation
+ Trinity::NormalizeMapCoord(destX);
+ Trinity::NormalizeMapCoord(destY);
- dist = (nx - X)*(nx - X) + (ny - Y)*(ny - Y);
+ travelDistZ = distanceX*distanceX + distanceY*distanceY;
- if (i == 5)
- {
- nz = Z;
- break;
- }
+ if (is_air_ok) // 3D system above ground and above water (flying mode)
+ {
+ // Limit height change
+ const float distanceZ = float(rand_norm()) * sqrtf(travelDistZ)/2.0f;
+ destZ = respZ + distanceZ;
+ float levelZ = map->GetWaterOrGroundLevel(destX, destY, destZ-2.0f);
+
+ // Problem here, we must fly above the ground and water, not under. Let's try on next tick
+ if (levelZ >= destZ)
+ return;
+ }
+ //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
+ else // 2D only
+ {
+ // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
+ travelDistZ = travelDistZ >= 100.0f ? 10.0f : sqrtf(travelDistZ);
- if (is_air_ok) // 3D system above ground and above water (flying mode)
- {
- const float distanceZ = (float)(rand_norm()) * sqrtf(dist)/2; // Limit height change
- nz = Z + distanceZ;
- float tz = map->GetHeight(nx, ny, nz-2.0f, false); // Map check only, vmap needed here but need to alter vmaps checks for height.
- float wz = map->GetWaterLevel(nx, ny);
- if (tz >= nz || wz >= nz)
- continue; // Problem here, we must fly above the ground and water, not under. Let's try on next tick
- }
- //else if (is_water_ok) // 3D system under water and above ground (swimming mode)
- else // 2D only
+ // The fastest way to get an accurate result 90% of the time.
+ // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
+ destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, false);
+
+ if (fabs(destZ - respZ) > travelDistZ) // Map check
{
- dist = dist >= 100.0f ? 10.0f : sqrtf(dist); // 10.0 is the max that vmap high can check (MAX_CAN_FALL_DISTANCE)
+ // Vmap Horizontal or above
+ destZ = map->GetHeight(destX, destY, respZ - 2.0f, true);
- // The fastest way to get an accurate result 90% of the time.
- // Better result can be obtained like 99% accuracy with a ray light, but the cost is too high and the code is too long.
- nz = map->GetHeight(nx, ny, Z+dist-2.0f, false); // Map check
- if (fabs(nz-Z)>dist)
+ if (fabs(destZ - respZ) > travelDistZ)
{
- nz = map->GetHeight(nx, ny, Z-2.0f, true); // Vmap Horizontal or above
- if (fabs(nz-Z)>dist)
- {
- nz = map->GetHeight(nx, ny, Z+dist-2.0f, true); // Vmap Higher
- if (fabs(nz-Z)>dist)
- continue; // let's forget this bad coords where a z cannot be find and retry at next tick
- }
+ // Vmap Higher
+ destZ = map->GetHeight(destX, destY, respZ+travelDistZ-2.0f, true);
+
+ // let's forget this bad coords where a z cannot be find and retry at next tick
+ if (fabs(destZ - respZ) > travelDistZ)
+ return;
}
}
- break;
}
- Traveller<Creature> traveller(creature);
- creature.SetOrientation(creature.GetAngle(nx, ny));
- i_destinationHolder.SetDestination(traveller, nx, ny, nz);
- creature.AddUnitState(UNIT_STAT_ROAMING);
if (is_air_ok)
- {
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- }
- //else if (is_water_ok) // Swimming mode to be done with more than this check
+ i_nextMoveTime.Reset(0);
else
- {
- i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(), 5000+i_destinationHolder.GetTotalTravelTime()));
- creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
- }
+ i_nextMoveTime.Reset(urand(500, 10000));
+
+ creature.AddUnitState(UNIT_STAT_ROAMING_MOVE);
+
+ Movement::MoveSplineInit init(creature);
+ init.MoveTo(destX, destY, destZ);
+ init.SetWalk(true);
+ init.Launch();
//Call for creature group update
if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature)
- {
- creature.GetFormation()->LeaderMoveTo(nx, ny, nz);
- }
+ creature.GetFormation()->LeaderMoveTo(destX, destY, destZ);
}
template<>
-void
-RandomMovementGenerator<Creature>::Initialize(Creature &creature)
+void RandomMovementGenerator<Creature>::Initialize(Creature &creature)
{
if (!creature.isAlive())
return;
@@ -143,8 +123,7 @@ RandomMovementGenerator<Creature>::Initialize(Creature &creature)
if (!wander_distance)
wander_distance = creature.GetRespawnRadius();
- if (irand(0, RUNNING_CHANCE_RANDOMMV) > 0)
- creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ creature.AddUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
_setRandomLocation(creature);
}
@@ -156,8 +135,11 @@ RandomMovementGenerator<Creature>::Reset(Creature &creature)
}
template<>
-void
-RandomMovementGenerator<Creature>::Finalize(Creature & /*creature*/){}
+void RandomMovementGenerator<Creature>::Finalize(Creature &creature)
+{
+ creature.ClearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+ creature.SetWalk(false);
+}
template<>
bool
@@ -165,35 +147,29 @@ RandomMovementGenerator<Creature>::Update(Creature &creature, const uint32 diff)
{
if (creature.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
{
- i_nextMoveTime.Update(i_nextMoveTime.GetExpiry()); // Expire the timer
- creature.ClearUnitState(UNIT_STAT_ROAMING);
+ i_nextMoveTime.Reset(0); // Expire the timer
+ creature.ClearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
}
- i_nextMoveTime.Update(diff);
-
- if (i_destinationHolder.HasArrived() && !creature.IsStopped() && !creature.canFly())
- creature.ClearUnitState(UNIT_STAT_ROAMING | UNIT_STAT_MOVE);
-
- if (!i_destinationHolder.HasArrived() && creature.IsStopped())
- creature.AddUnitState(UNIT_STAT_ROAMING);
-
- CreatureTraveller traveller(creature);
-
- if (i_destinationHolder.UpdateTraveller(traveller, diff, true))
+ if (creature.movespline->Finalized())
{
+ i_nextMoveTime.Update(diff);
if (i_nextMoveTime.Passed())
- {
- if (irand(0, RUNNING_CHANCE_RANDOMMV) > 0)
- creature.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
_setRandomLocation(creature);
- }
- else if (creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(), PET_FOLLOW_DIST+2.5f))
- {
- creature.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
- _setRandomLocation(creature);
- }
}
return true;
}
+template<>
+bool RandomMovementGenerator<Creature>::GetResetPosition(Creature &creature, float& x, float& y, float& z)
+{
+ float radius;
+ creature.GetRespawnPosition(x, y, z, NULL, &radius);
+
+ // use current if in range
+ if (creature.IsWithinDist2d(x,y,radius))
+ creature.GetPosition(x,y,z);
+
+ return true;
+}
diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
index 816e325f3b1..67161b6fc29 100755
--- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h
@@ -20,15 +20,12 @@
#define TRINITY_RANDOMMOTIONGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
template<class T>
class RandomMovementGenerator
: public MovementGeneratorMedium< T, RandomMovementGenerator<T> >
{
public:
- // Wander dist is related on db spawn dist. So what if we wanna set eandom movement on summoned creature?!
RandomMovementGenerator(float spawn_dist = 0.0f) : i_nextMoveTime(0), wander_distance(spawn_dist) {}
void _setRandomLocation(T &);
@@ -36,18 +33,13 @@ class RandomMovementGenerator
void Finalize(T &);
void Reset(T &);
bool Update(T &, const uint32);
- bool GetDestination(float &x, float &y, float &z) const;
- void UpdateMapPosition(uint32 mapid, float &x, float &y, float &z)
- {
- i_destinationHolder.GetLocationNow(mapid, x, y, z);
- }
+ bool GetResetPosition(T&, float& x, float& y, float& z);
MovementGeneratorType GetMovementGeneratorType() { return RANDOM_MOTION_TYPE; }
private:
TimeTrackerSmall i_nextMoveTime;
- DestinationHolder< Traveller<T> > i_destinationHolder;
- float wander_distance;
uint32 i_nextMove;
+ float wander_distance;
};
#endif
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
index e0ca5231000..0d2982ab6b7 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp
@@ -21,106 +21,43 @@
#include "Errors.h"
#include "Creature.h"
#include "CreatureAI.h"
-#include "DestinationHolderImp.h"
#include "World.h"
-
-#define SMALL_ALPHA 0.05f
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "Player.h"
#include <cmath>
-/*
-struct StackCleaner
-{
- Creature &i_creature;
- StackCleaner(Creature &creature) : i_creature(creature) {}
- void Done(void) { i_creature.StopMoving(); }
- ~StackCleaner()
- {
- i_creature->Clear();
- }
-};
-*/
-template<class T>
-TargetedMovementGenerator<T>::TargetedMovementGenerator(Unit &target, float offset, float angle)
-: TargetedMovementGeneratorBase(target)
-, i_offset(offset), i_angle(angle), i_recalculateTravel(false)
-{
- target.GetPosition(i_targetX, i_targetY, i_targetZ);
-}
-
-template<class T>
-bool
-TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
+template<class T, typename D>
+void TargetedMovementGeneratorMedium<T,D>::_setTargetLocation(T &owner)
{
if (!i_target.isValid() || !i_target->IsInWorld())
- return false;
+ return;
- if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
- return false;
+ if (owner.HasUnitState(UNIT_STAT_NOT_MOVE))
+ return;
float x, y, z;
- Traveller<T> traveller(owner);
- if (i_destinationHolder.HasDestination())
+
+ if (i_offset && i_target->IsWithinDistInMap(&owner,2*i_offset))
{
- if (i_destinationHolder.HasArrived())
- {
- // prevent redundant micro-movement
- if (!i_offset)
- {
- if (i_target->IsWithinMeleeRange(&owner))
- return false;
- }
- else if (!i_angle && !owner.HasUnitState(UNIT_STAT_FOLLOW))
- {
- if (i_target->IsWithinDistInMap(&owner, i_offset))
- return false;
- }
- else
- {
- if (i_target->IsWithinDistInMap(&owner, i_offset + 1.0f))
- return false;
- }
- }
- else
- {
- bool stop = false;
- if (!i_offset)
- {
- if (i_target->IsWithinMeleeRange(&owner, 0))
- stop = true;
- }
- else if (!i_angle && !owner.HasUnitState(UNIT_STAT_FOLLOW))
- {
- if (i_target->IsWithinDist(&owner, i_offset * 0.8f))
- stop = true;
- }
-
- if (stop)
- {
- owner.GetPosition(x, y, z);
- i_destinationHolder.SetDestination(traveller, x, y, z);
- i_destinationHolder.StartTravel(traveller, false);
- owner.StopMoving();
- return false;
- }
- }
+ if (!owner.movespline->Finalized())
+ return;
- if (i_target->GetExactDistSq(i_targetX, i_targetY, i_targetZ) < 0.01f)
- return false;
+ owner.GetPosition(x, y, z);
}
-
- if (!i_offset)
+ else if (!i_offset)
{
+ if (i_target->IsWithinMeleeRange(&owner))
+ return;
+
// to nearest random contact position
i_target->GetRandomContactPoint(&owner, x, y, z, 0, MELEE_RANGE - 0.5f);
}
- else if (!i_angle && !owner.HasUnitState(UNIT_STAT_FOLLOW))
- {
- // caster chase
- i_target->GetContactPoint(&owner, x, y, z, i_offset * urand(80, 95) * 0.01f);
- }
else
{
+ if (i_target->IsWithinDistInMap(&owner, i_offset + 1.0f))
+ return;
// to at i_offset distance from target and i_angle from target facing
i_target->GetClosePoint(x, y, z, owner.GetObjectSize(), i_offset, i_angle);
}
@@ -137,55 +74,65 @@ TargetedMovementGenerator<T>::_setTargetLocation(T &owner)
ralf
//We don't update Mob Movement, if the difference between New destination and last destination is < BothObjectSize
- float bothObjectSize = i_target->GetObjectSize() + owner.GetObjectSize() + CONTACT_DISTANCE;
- if (i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x, y, z) < bothObjectSize)
+ float bothObjectSize = i_target->GetObjectBoundingRadius() + owner.GetObjectBoundingRadius() + CONTACT_DISTANCE;
+ if( i_destinationHolder.HasDestination() && i_destinationHolder.GetDestinationDiff(x,y,z) < bothObjectSize )
return;
*/
- i_destinationHolder.SetDestination(traveller, x, y, z);
- owner.AddUnitState(UNIT_STAT_CHASE);
- i_destinationHolder.StartTravel(traveller);
- return true;
+
+
+ D::_addUnitStateMove(owner);
+ i_targetReached = false;
+ i_recalculateTravel = false;
+
+ Movement::MoveSplineInit init(owner);
+ init.MoveTo(x,y,z);
+ init.SetWalk(((D*)this)->EnableWalking());
+ init.Launch();
}
-template<class T>
-void
-TargetedMovementGenerator<T>::Initialize(T &owner)
+template<>
+void TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::UpdateFinalDistance(float /*fDistance*/)
{
- if (owner.isInCombat())
- owner.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ // nothing to do for Player
+}
- _setTargetLocation(owner);
+template<>
+void TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::UpdateFinalDistance(float /*fDistance*/)
+{
+ // nothing to do for Player
}
-template<class T>
-void
-TargetedMovementGenerator<T>::Finalize(T &owner)
+template<>
+void TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::UpdateFinalDistance(float fDistance)
{
- owner.ClearUnitState(UNIT_STAT_CHASE);
+ i_offset = fDistance;
+ i_recalculateTravel = true;
}
-template<class T>
-void
-TargetedMovementGenerator<T>::Reset(T &owner)
+template<>
+void TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::UpdateFinalDistance(float fDistance)
{
- Initialize(owner);
+ i_offset = fDistance;
+ i_recalculateTravel = true;
}
-template<class T>
-bool
-TargetedMovementGenerator<T>::Update(T &owner, const uint32 time_diff)
+template<class T, typename D>
+bool TargetedMovementGeneratorMedium<T,D>::Update(T &owner, const uint32 & time_diff)
{
if (!i_target.isValid() || !i_target->IsInWorld())
return false;
- if (!&owner || !owner.isAlive())
+ if (!owner.isAlive())
return true;
- if (owner.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING | UNIT_STAT_DISTRACTED))
+ if (owner.HasUnitState(UNIT_STAT_NOT_MOVE))
+ {
+ D::_clearUnitStateMove(owner);
return true;
+ }
// prevent movement while casting spells with cast time or channel time
- if (owner.HasUnitState(UNIT_STAT_CASTING))
+ if (owner.IsNonMeleeSpellCasted(false, false, true))
{
if (!owner.IsStopped())
owner.StopMoving();
@@ -193,85 +140,184 @@ TargetedMovementGenerator<T>::Update(T &owner, const uint32 time_diff)
}
// prevent crash after creature killed pet
- if (!owner.HasUnitState(UNIT_STAT_FOLLOW) && owner.getVictim() != i_target.getTarget())
+ if (static_cast<D*>(this)->_lostTarget(owner))
+ {
+ D::_clearUnitStateMove(owner);
return true;
+ }
- Traveller<T> traveller(owner);
-
- if (!i_destinationHolder.HasDestination())
- _setTargetLocation(owner);
- else if (owner.IsStopped() && !i_destinationHolder.HasArrived())
+ i_recheckDistance.Update(time_diff);
+ if (i_recheckDistance.Passed())
{
- owner.AddUnitState(UNIT_STAT_CHASE);
- i_destinationHolder.StartTravel(traveller);
- return true;
+ i_recheckDistance.Reset(50);
+ //More distance let have better performance, less distance let have more sensitive reaction at target move.
+ float allowed_dist = i_target->GetObjectSize() + owner.GetObjectSize() + MELEE_RANGE - 0.5f;
+ float dist = (owner.movespline->FinalDestination() - G3D::Vector3(i_target->GetPositionX(),i_target->GetPositionY(),i_target->GetPositionZ())).squaredLength();
+ if (dist >= allowed_dist * allowed_dist)
+ _setTargetLocation(owner);
}
- if (i_destinationHolder.UpdateTraveller(traveller, time_diff))
+ if (owner.movespline->Finalized())
{
- // put targeted movement generators on a higher priority
- //if (owner.GetObjectSize())
- //i_destinationHolder.ResetUpdate(50);
+ static_cast<D*>(this)->MovementInform(owner);
+ if (i_angle == 0.f && !owner.HasInArc(0.01f, i_target.getTarget()))
+ owner.SetInFront(i_target.getTarget());
- // target moved
- if (i_targetX != i_target->GetPositionX() || i_targetY != i_target->GetPositionY()
- || i_targetZ != i_target->GetPositionZ())
+ if (!i_targetReached)
{
- if (_setTargetLocation(owner) || !owner.HasUnitState(UNIT_STAT_FOLLOW))
- owner.SetInFront(i_target.getTarget());
- i_target->GetPosition(i_targetX, i_targetY, i_targetZ);
+ i_targetReached = true;
+ static_cast<D*>(this)->_reachTarget(owner);
}
+ }
+ else
+ {
+ if (i_recalculateTravel)
+ _setTargetLocation(owner);
+ }
+ return true;
+}
- if ((owner.IsStopped() && !i_destinationHolder.HasArrived()) || i_recalculateTravel)
- {
- i_recalculateTravel = false;
- //Angle update will take place into owner.StopMoving()
- owner.SetInFront(i_target.getTarget());
+//-----------------------------------------------//
+template<class T>
+void ChaseMovementGenerator<T>::_reachTarget(T &owner)
+{
+ if (owner.IsWithinMeleeRange(this->i_target.getTarget()))
+ owner.Attack(this->i_target.getTarget(),true);
+}
- owner.StopMoving();
- if (owner.IsWithinMeleeRange(i_target.getTarget()) && !owner.HasUnitState(UNIT_STAT_FOLLOW))
- owner.Attack(i_target.getTarget(), true);
- }
- }
+template<>
+void ChaseMovementGenerator<Player>::Initialize(Player &owner)
+{
+ owner.AddUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
+ _setTargetLocation(owner);
+}
- // Implemented for PetAI to handle resetting flags when pet owner reached
- if (i_destinationHolder.HasArrived())
- MovementInform(owner);
+template<>
+void ChaseMovementGenerator<Creature>::Initialize(Creature &owner)
+{
+ owner.SetWalk(false);
+ owner.AddUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
+ _setTargetLocation(owner);
+}
- return true;
+template<class T>
+void ChaseMovementGenerator<T>::Finalize(T &owner)
+{
+ owner.ClearUnitState(UNIT_STAT_CHASE|UNIT_STAT_CHASE_MOVE);
}
template<class T>
-Unit*
-TargetedMovementGenerator<T>::GetTarget() const
+void ChaseMovementGenerator<T>::Reset(T &owner)
{
- return i_target.getTarget();
+ Initialize(owner);
}
template<class T>
-void TargetedMovementGenerator<T>::MovementInform(T & /*unit*/)
+void ChaseMovementGenerator<T>::MovementInform(T & /*unit*/)
{
}
-template <> void TargetedMovementGenerator<Creature>::MovementInform(Creature &unit)
+template<>
+void ChaseMovementGenerator<Creature>::MovementInform(Creature &unit)
{
// Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
- unit.AI()->MovementInform(TARGETED_MOTION_TYPE, i_target.getTarget()->GetGUIDLow());
+ if (unit.AI())
+ unit.AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUIDLow());
+}
+
+//-----------------------------------------------//
+template<>
+bool FollowMovementGenerator<Creature>::EnableWalking() const
+{
+ return i_target.isValid() && i_target->IsWalking();
+}
+
+template<>
+bool FollowMovementGenerator<Player>::EnableWalking() const
+{
+ return false;
+}
+
+template<>
+void FollowMovementGenerator<Player>::_updateSpeed(Player &/*u*/)
+{
+ // nothing to do for Player
+}
+
+template<>
+void FollowMovementGenerator<Creature>::_updateSpeed(Creature &u)
+{
+ // pet only sync speed with owner
+ if (!((Creature&)u).isPet() || !i_target.isValid() || i_target->GetGUID() != u.GetOwnerGUID())
+ return;
+
+ u.UpdateSpeed(MOVE_RUN,true);
+ u.UpdateSpeed(MOVE_WALK,true);
+ u.UpdateSpeed(MOVE_SWIM,true);
+}
+
+template<>
+void FollowMovementGenerator<Player>::Initialize(Player &owner)
+{
+ owner.AddUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
+ _updateSpeed(owner);
+ _setTargetLocation(owner);
+}
+
+template<>
+void FollowMovementGenerator<Creature>::Initialize(Creature &owner)
+{
+ owner.AddUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
+ _updateSpeed(owner);
+ _setTargetLocation(owner);
+}
+
+template<class T>
+void FollowMovementGenerator<T>::Finalize(T &owner)
+{
+ owner.ClearUnitState(UNIT_STAT_FOLLOW|UNIT_STAT_FOLLOW_MOVE);
+ _updateSpeed(owner);
}
-template void TargetedMovementGenerator<Player>::MovementInform(Player&); // Not implemented for players
-template TargetedMovementGenerator<Player>::TargetedMovementGenerator(Unit &target, float offset, float angle);
-template TargetedMovementGenerator<Creature>::TargetedMovementGenerator(Unit &target, float offset, float angle);
-template bool TargetedMovementGenerator<Player>::_setTargetLocation(Player &);
-template bool TargetedMovementGenerator<Creature>::_setTargetLocation(Creature &);
-template void TargetedMovementGenerator<Player>::Initialize(Player &);
-template void TargetedMovementGenerator<Creature>::Initialize(Creature &);
-template void TargetedMovementGenerator<Player>::Finalize(Player &);
-template void TargetedMovementGenerator<Creature>::Finalize(Creature &);
-template void TargetedMovementGenerator<Player>::Reset(Player &);
-template void TargetedMovementGenerator<Creature>::Reset(Creature &);
-template bool TargetedMovementGenerator<Player>::Update(Player &, const uint32);
-template bool TargetedMovementGenerator<Creature>::Update(Creature &, const uint32);
-template Unit* TargetedMovementGenerator<Player>::GetTarget() const;
-template Unit* TargetedMovementGenerator<Creature>::GetTarget() const;
+template<class T>
+void FollowMovementGenerator<T>::Reset(T &owner)
+{
+ Initialize(owner);
+}
+
+template<class T>
+void FollowMovementGenerator<T>::MovementInform(T & /*unit*/)
+{
+}
+
+template<>
+void FollowMovementGenerator<Creature>::MovementInform(Creature &unit)
+{
+ // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle
+ if (unit.AI())
+ unit.AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUIDLow());
+}
+//-----------------------------------------------//
+template void TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::_setTargetLocation(Player &);
+template void TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::_setTargetLocation(Player &);
+template void TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::_setTargetLocation(Creature &);
+template void TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::_setTargetLocation(Creature &);
+template bool TargetedMovementGeneratorMedium<Player,ChaseMovementGenerator<Player> >::Update(Player &, const uint32 &);
+template bool TargetedMovementGeneratorMedium<Player,FollowMovementGenerator<Player> >::Update(Player &, const uint32 &);
+template bool TargetedMovementGeneratorMedium<Creature,ChaseMovementGenerator<Creature> >::Update(Creature &, const uint32 &);
+template bool TargetedMovementGeneratorMedium<Creature,FollowMovementGenerator<Creature> >::Update(Creature &, const uint32 &);
+
+template void ChaseMovementGenerator<Player>::_reachTarget(Player &);
+template void ChaseMovementGenerator<Creature>::_reachTarget(Creature &);
+template void ChaseMovementGenerator<Player>::Finalize(Player &);
+template void ChaseMovementGenerator<Creature>::Finalize(Creature &);
+template void ChaseMovementGenerator<Player>::Reset(Player &);
+template void ChaseMovementGenerator<Creature>::Reset(Creature &);
+template void ChaseMovementGenerator<Player>::MovementInform(Player &unit);
+
+template void FollowMovementGenerator<Player>::Finalize(Player &);
+template void FollowMovementGenerator<Creature>::Finalize(Creature &);
+template void FollowMovementGenerator<Player>::Reset(Player &);
+template void FollowMovementGenerator<Creature>::Reset(Creature &);
+template void FollowMovementGenerator<Player>::MovementInform(Player &unit);
diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
index edb4fca8fce..696c99e1460 100755
--- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.h
@@ -20,9 +20,9 @@
#define TRINITY_TARGETEDMOVEMENTGENERATOR_H
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
-#include "Traveller.h"
#include "FollowerReference.h"
+#include "Timer.h"
+#include "Unit.h"
class TargetedMovementGeneratorBase
{
@@ -33,41 +33,84 @@ class TargetedMovementGeneratorBase
FollowerReference i_target;
};
+template<class T, typename D>
+class TargetedMovementGeneratorMedium
+: public MovementGeneratorMedium< T, D >, public TargetedMovementGeneratorBase
+{
+ protected:
+ TargetedMovementGeneratorMedium(Unit &target, float offset, float angle) :
+ TargetedMovementGeneratorBase(target), i_offset(offset), i_angle(angle),
+ i_recalculateTravel(false), i_targetReached(false), i_recheckDistance(0)
+ {
+ }
+ ~TargetedMovementGeneratorMedium() {}
+
+ public:
+ bool Update(T &, const uint32 &);
+ Unit* GetTarget() const { return i_target.getTarget(); }
+
+ void unitSpeedChanged() { i_recalculateTravel=true; }
+ void UpdateFinalDistance(float fDistance);
+
+ protected:
+ void _setTargetLocation(T &);
+
+ TimeTrackerSmall i_recheckDistance;
+ float i_offset;
+ float i_angle;
+ bool i_recalculateTravel : 1;
+ bool i_targetReached : 1;
+};
+
template<class T>
-class TargetedMovementGenerator
-: public MovementGeneratorMedium< T, TargetedMovementGenerator<T> >, public TargetedMovementGeneratorBase
+class ChaseMovementGenerator : public TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >
{
public:
- TargetedMovementGenerator(Unit &target, float offset = 0, float angle = 0);
- ~TargetedMovementGenerator() {}
+ ChaseMovementGenerator(Unit &target)
+ : TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target) {}
+ ChaseMovementGenerator(Unit &target, float offset, float angle)
+ : TargetedMovementGeneratorMedium<T, ChaseMovementGenerator<T> >(target, offset, angle) {}
+ ~ChaseMovementGenerator() {}
+
+ MovementGeneratorType GetMovementGeneratorType() { return CHASE_MOTION_TYPE; }
void Initialize(T &);
void Finalize(T &);
void Reset(T &);
- bool Update(T &, const uint32);
- MovementGeneratorType GetMovementGeneratorType() { return TARGETED_MOTION_TYPE; }
-
void MovementInform(T &);
- Unit* GetTarget() const;
+ static void _clearUnitStateMove(T &u) { u.ClearUnitState(UNIT_STAT_CHASE_MOVE); }
+ static void _addUnitStateMove(T &u) { u.AddUnitState(UNIT_STAT_CHASE_MOVE); }
+ bool EnableWalking() const { return false;}
+ bool _lostTarget(T &u) const { return u.getVictim() != this->GetTarget(); }
+ void _reachTarget(T &);
+};
- bool GetDestination(float &x, float &y, float &z) const
- {
- if (i_destinationHolder.HasArrived() || !i_destinationHolder.HasDestination()) return false;
- i_destinationHolder.GetDestination(x, y, z);
- return true;
- }
+template<class T>
+class FollowMovementGenerator : public TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >
+{
+ public:
+ FollowMovementGenerator(Unit &target)
+ : TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >(target){}
+ FollowMovementGenerator(Unit &target, float offset, float angle)
+ : TargetedMovementGeneratorMedium<T, FollowMovementGenerator<T> >(target, offset, angle) {}
+ ~FollowMovementGenerator() {}
- void unitSpeedChanged() { i_recalculateTravel=true; }
- private:
+ MovementGeneratorType GetMovementGeneratorType() { return FOLLOW_MOTION_TYPE; }
- bool _setTargetLocation(T &);
+ void Initialize(T &);
+ void Finalize(T &);
+ void Reset(T &);
+ void MovementInform(T &);
- float i_offset;
- float i_angle;
- DestinationHolder< Traveller<T> > i_destinationHolder;
- bool i_recalculateTravel;
- float i_targetX, i_targetY, i_targetZ;
+ static void _clearUnitStateMove(T &u) { u.ClearUnitState(UNIT_STAT_FOLLOW_MOVE); }
+ static void _addUnitStateMove(T &u) { u.AddUnitState(UNIT_STAT_FOLLOW_MOVE); }
+ bool EnableWalking() const;
+ bool _lostTarget(T &) const { return false; }
+ void _reachTarget(T &) {}
+ private:
+ void _updateSpeed(T &u);
};
+
#endif
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
index f88ed249aca..ce8628af1ca 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp
@@ -17,222 +17,166 @@
*/
//Basic headers
#include "WaypointMovementGenerator.h"
-#include "DestinationHolderImp.h"
//Extended headers
#include "ObjectMgr.h"
#include "World.h"
-#include "MapManager.h" // for flightmaster grid preloading
+//Flightmaster grid preloading
+#include "MapManager.h"
//Creature-specific headers
#include "Creature.h"
#include "CreatureAI.h"
#include "CreatureGroups.h"
//Player-specific
#include "Player.h"
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
-template<class T>
-void
-WaypointMovementGenerator<T>::Initialize(T & /*u*/){}
-
-template<>
-void
-WaypointMovementGenerator<Creature>::Finalize(Creature & /*u*/){}
+void WaypointMovementGenerator<Creature>::LoadPath(Creature &creature)
+{
+ if (!path_id)
+ path_id = creature.GetWaypointPath();
-template<>
-void
-WaypointMovementGenerator<Player>::Finalize(Player & /*u*/){}
+ i_path = sWaypointMgr->GetPath(path_id);
-template<class T>
-void
-WaypointMovementGenerator<T>::MovementInform(T & /*unit*/){}
+ if (!i_path)
+ {
+ // No movement found for entry
+ sLog->outErrorDb("WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u) doesn't have waypoint path id: %u", creature.GetName(), creature.GetEntry(), creature.GetGUIDLow(), path_id);
+ return;
+ }
-template<>
-void WaypointMovementGenerator<Creature>::MovementInform(Creature &unit)
-{
- unit.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
+ StartMoveNow(creature);
}
-template<>
-bool WaypointMovementGenerator<Creature>::GetDestination(float &x, float &y, float &z) const
+void WaypointMovementGenerator<Creature>::Initialize(Creature &creature)
{
- if (i_destinationHolder.HasArrived())
- return false;
-
- i_destinationHolder.GetDestination(x, y, z);
- return true;
+ LoadPath(creature);
+ creature.AddUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
}
-template<>
-bool WaypointMovementGenerator<Player>::GetDestination(float & /*x*/, float & /*y*/, float & /*z*/) const
+void WaypointMovementGenerator<Creature>::Finalize(Creature &creature)
{
- return false;
+ creature.ClearUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+ creature.SetWalk(false);
}
-template<>
-void WaypointMovementGenerator<Creature>::Reset(Creature & /*unit*/)
+void WaypointMovementGenerator<Creature>::Reset(Creature &creature)
{
- StopedByPlayer = true;
- i_nextMoveTime.Reset(0);
+ creature.AddUnitState(UNIT_STAT_ROAMING|UNIT_STAT_ROAMING_MOVE);
+ StartMoveNow(creature);
}
-template<>
-void WaypointMovementGenerator<Player>::Reset(Player & /*unit*/){}
-
-template<>
-void WaypointMovementGenerator<Creature>::InitTraveller(Creature &unit, const WaypointData &node)
+void WaypointMovementGenerator<Creature>::OnArrived(Creature& creature)
{
- node.run ? unit.RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING):
- unit.AddUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ if (!i_path || i_path->empty())
+ return;
+ if (m_isArrivalDone)
+ return;
- unit.SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
- unit.SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ creature.ClearUnitState(UNIT_STAT_ROAMING_MOVE);
+ m_isArrivalDone = true;
- // TODO: make this part of waypoint node, so that creature can walk when desired?
- if (unit.canFly())
- unit.SetByteFlag(UNIT_FIELD_BYTES_1, 3, 0x02);
+ if (i_path->at(i_currentNode)->event_id && urand(0, 99) < i_path->at(i_currentNode)->event_chance)
+ {
+ sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Creature movement start script %u at point %u for %u.", i_path->at(i_currentNode)->event_id, i_currentNode, creature.GetGUID());
+ creature.GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, &creature, NULL/*, false*/);
+ }
- unit.AddUnitState(UNIT_STAT_ROAMING);
+ // Inform script
+ MovementInform(creature);
+ creature.UpdateWaypointID(i_currentNode);
+ Stop(i_path->at(i_currentNode)->delay);
}
-template<>
-void
-WaypointMovementGenerator<Creature>::Initialize(Creature &u)
+bool WaypointMovementGenerator<Creature>::StartMove(Creature &creature)
{
- u.StopMoving();
- //i_currentNode = -1; // uint32, become 0 in the first update
- //i_nextMoveTime.Reset(0);
- StopedByPlayer = false;
- if (!path_id)
- path_id = u.GetWaypointPath();
- waypoints = sWaypointMgr->GetPath(path_id);
- i_currentNode = 0;
- if (waypoints && waypoints->size())
+ if (!i_path || i_path->empty())
+ return false;
+ if (Stopped())
+ return true;
+
+ if (m_isArrivalDone)
{
- node = waypoints->front();
- Traveller<Creature> traveller(u);
- InitTraveller(u, *node);
- i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
-
- //Call for creature group update
- if (u.GetFormation() && u.GetFormation()->getLeader() == &u)
- u.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
+ if ((i_currentNode == i_path->size() - 1) && !repeating) // If that's our last waypoint
+ {
+ creature.SetHomePosition(i_path->at(i_currentNode)->x, i_path->at(i_currentNode)->y, i_path->at(i_currentNode)->z, creature.GetOrientation());
+ creature.GetMotionMaster()->Initialize();
+ return false;
+ }
+
+ i_currentNode = (i_currentNode+1) % i_path->size();
}
- else
- node = NULL;
-}
-template<>
-void WaypointMovementGenerator<Player>::InitTraveller(Player & /*unit*/, const WaypointData & /*node*/){}
+ const WaypointData *node = i_path->at(i_currentNode);
-template<class T>
-bool
-WaypointMovementGenerator<T>::Update(T & /*unit*/, const uint32 /*diff*/)
-{
- return false;
-}
+ m_isArrivalDone = false;
-template<>
-bool
-WaypointMovementGenerator<Creature>::Update(Creature &unit, const uint32 diff)
-{
- if (!&unit)
- return true;
+ creature.AddUnitState(UNIT_STAT_ROAMING_MOVE);
+
+ Movement::MoveSplineInit init(creature);
+ init.MoveTo(node->x, node->y, node->z);
- if (!path_id)
- return false;
+ if (node->orientation != 100 && node->delay != 0)
+ init.SetFacing(node->orientation);
+
+ init.SetWalk(!node->run);
+ init.Launch();
+
+ //Call for creature group update
+ if (creature.GetFormation() && creature.GetFormation()->getLeader() == &creature)
+ creature.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
+
+ return true;
+}
+bool WaypointMovementGenerator<Creature>::Update(Creature &creature, const uint32 &diff)
+{
// Waypoint movement can be switched on/off
// This is quite handy for escort quests and other stuff
- if (unit.HasUnitState(UNIT_STAT_ROOT | UNIT_STAT_STUNNED | UNIT_STAT_DISTRACTED))
+ if (creature.HasUnitState(UNIT_STAT_NOT_MOVE))
+ {
+ creature.ClearUnitState(UNIT_STAT_ROAMING_MOVE);
return true;
-
- // Clear the generator if the path doesn't exist
- if (!waypoints || !waypoints->size())
+ }
+ // prevent a crash at empty waypoint path.
+ if (!i_path || i_path->empty())
return false;
- Traveller<Creature> traveller(unit);
-
- i_nextMoveTime.Update(diff);
- i_destinationHolder.UpdateTraveller(traveller, diff, true);
-
- if (i_nextMoveTime.GetExpiry() < TIMEDIFF_NEXT_WP)
+ if (Stopped())
{
- if (unit.IsStopped())
- {
- if (StopedByPlayer)
- {
- ASSERT(node);
- InitTraveller(unit, *node);
- i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
- StopedByPlayer = false;
- return true;
- }
-
- if (i_currentNode == waypoints->size() - 1) // If that's our last waypoint
- {
- if (repeating) // If the movement is repeating
- i_currentNode = 0; // Start moving all over again
- else
- {
- unit.SetHomePosition(node->x, node->y, node->z, unit.GetOrientation());
- unit.GetMotionMaster()->Initialize();
- return false; // Clear the waypoint movement
- }
- }
- else
- ++i_currentNode;
-
- node = waypoints->at(i_currentNode);
- InitTraveller(unit, *node);
- i_destinationHolder.SetDestination(traveller, node->x, node->y, node->z);
- i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime());
-
- //Call for creature group update
- if (unit.GetFormation() && unit.GetFormation()->getLeader() == &unit)
- unit.GetFormation()->LeaderMoveTo(node->x, node->y, node->z);
- }
- else
- {
- //Determine waittime
- if (node->delay)
- i_nextMoveTime.Reset(node->delay);
-
- //note: disable "start" for mtmap
- if (node->event_id && urand(0, 99) < node->event_chance)
- unit.GetMap()->ScriptsStart(sWaypointScripts, node->event_id, &unit, NULL/*, false*/);
-
- i_destinationHolder.ResetTravelTime();
- MovementInform(unit);
- unit.UpdateWaypointID(i_currentNode);
- unit.ClearUnitState(UNIT_STAT_ROAMING);
- if (node->orientation)
- {
- unit.Relocate(node->x, node->y, node->z, node->orientation);
- unit.SetFacing(node->orientation, NULL);
- }
- else
- unit.Relocate(node->x, node->y, node->z);
- }
+ if (CanMove(diff))
+ return StartMove(creature);
}
- else
+ else
{
- if (unit.IsStopped() && !i_destinationHolder.HasArrived())
+ if (creature.IsStopped())
+ Stop(STOP_TIME_FOR_PLAYER);
+ else if (creature.movespline->Finalized())
{
- if (!StopedByPlayer)
- {
- i_destinationHolder.IncreaseTravelTime(STOP_TIME_FOR_PLAYER);
- i_nextMoveTime.Reset(STOP_TIME_FOR_PLAYER);
- StopedByPlayer = true;
- }
- }
+ OnArrived(creature);
+ return StartMove(creature);
+ }
}
+ return true;
+ }
+
+void WaypointMovementGenerator<Creature>::MovementInform(Creature &creature)
+{
+ if (creature.AI())
+ creature.AI()->MovementInform(WAYPOINT_MOTION_TYPE, i_currentNode);
+}
+
+bool WaypointMovementGenerator<Creature>::GetResetPosition(Creature&, float& x, float& y, float& z)
+{
+ // prevent a crash at empty waypoint path.
+ if (!i_path || i_path->empty())
+ return false;
+
+ const WaypointData* node = i_path->at(i_currentNode);
+ x = node->x; y = node->y; z = node->z;
return true;
}
-template void WaypointMovementGenerator<Player>::Initialize(Player &);
-template bool WaypointMovementGenerator<Player>::Update(Player &, const uint32);
-template void WaypointMovementGenerator<Player>::MovementInform(Player &);
//----------------------------------------------------//
@@ -253,71 +197,72 @@ uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const
void FlightPathMovementGenerator::Initialize(Player &player)
{
- player.getHostileRefManager().setOnlineOfflineState(false);
- player.AddUnitState(UNIT_STAT_IN_FLIGHT);
- player.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
- Traveller<Player> traveller(player);
- // do not send movement, it was sent already
- i_destinationHolder.SetDestination(traveller, (*i_path)[i_currentNode].x, (*i_path)[i_currentNode].y, (*i_path)[i_currentNode].z, false);
- // For preloading end grid
+ Reset(player);
InitEndGridInfo();
- player.SendMonsterMoveByPath(GetPath(), GetCurrentNode(), GetPathAtMapEnd());
}
void FlightPathMovementGenerator::Finalize(Player & player)
{
+ // remove flag to prevent send object build movement packets for flight state and crash (movement generator already not at top of stack)
player.ClearUnitState(UNIT_STAT_IN_FLIGHT);
- float x = 0;
- float y = 0;
- float z = 0;
- i_destinationHolder.GetLocationNow(player.GetBaseMap(), x, y, z);
- player.UpdatePosition(x, y, z, player.GetOrientation());
+ player.Dismount();
+ player.RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
+ if(player.m_taxi.empty())
+ {
+ player.getHostileRefManager().setOnlineOfflineState(true);
+ if(player.pvpInfo.inHostileArea)
+ player.CastSpell(&player, 2479, true);
+
+ // update z position to ground and orientation for landing point
+ // this prevent cheating with landing point at lags
+ // when client side flight end early in comparison server side
+ player.StopMoving();
+ }
+}
+
+#define PLAYER_FLIGHT_SPEED 32.0f
+
+void FlightPathMovementGenerator::Reset(Player & player)
+{
+ player.getHostileRefManager().setOnlineOfflineState(false);
+ player.AddUnitState(UNIT_STAT_IN_FLIGHT);
+ player.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT);
+
+ Movement::MoveSplineInit init(player);
+ uint32 end = GetPathAtMapEnd();
+ for (uint32 i = GetCurrentNode(); i != end; ++i)
+ {
+ G3D::Vector3 vertice((*i_path)[i].x,(*i_path)[i].y,(*i_path)[i].z);
+ init.Path().push_back(vertice);
+ }
+ init.SetFirstPointId(GetCurrentNode());
+ init.SetFly();
+ init.SetVelocity(PLAYER_FLIGHT_SPEED);
+ init.Launch();
}
bool FlightPathMovementGenerator::Update(Player &player, const uint32 diff)
{
- if (MovementInProgress())
+ uint32 pointId = (uint32)player.movespline->currentPathIdx();
+ if (pointId > i_currentNode)
{
- Traveller<Player> traveller(player);
- if (i_destinationHolder.UpdateTraveller(traveller, diff))
+ bool departureEvent = true;
+ do
{
- i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE);
- if (i_destinationHolder.HasArrived())
- {
- DoEventIfAny(player, (*i_path)[i_currentNode], false);
-
- uint32 curMap = (*i_path)[i_currentNode].mapid;
- ++i_currentNode;
- if (MovementInProgress())
- {
- DoEventIfAny(player, (*i_path)[i_currentNode], true);
-
- sLog->outStaticDebug("loading node %u for player %s", i_currentNode, player.GetName());
- if ((*i_path)[i_currentNode].mapid == curMap)
- {
- // do not send movement, it was sent already
- i_destinationHolder.SetDestination(traveller, (*i_path)[i_currentNode].x, (*i_path)[i_currentNode].y, (*i_path)[i_currentNode].z, false);
- }
-
- // check if it's time to preload the flightmaster grid at path end
- if (i_currentNode == m_preloadTargetNode)
- PreloadEndGrid();
-
- return true;
- }
- //else HasArrived()
- }
- else
- return true;
+ DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent);
+ if (pointId == i_currentNode)
+ break;
+ if (i_currentNode == _preloadTargetNode)
+ PreloadEndGrid();
+ i_currentNode += (uint32)departureEvent;
+ departureEvent = !departureEvent;
}
- else
- return true;
+ while (true);
}
- // we have arrived at the end of the path
- return false;
+ return i_currentNode < (i_path->size()-1);
}
void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
@@ -336,42 +281,48 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport()
}
}
+void FlightPathMovementGenerator::DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure)
+{
+ if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID)
+ {
+ sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player.GetName());
+ player.GetMap()->ScriptsStart(sEventScripts, eventid, &player, &player);
+ }
+}
+
+bool FlightPathMovementGenerator::GetResetPosition(Player&, float& x, float& y, float& z)
+{
+ const TaxiPathNodeEntry& node = (*i_path)[i_currentNode];
+ x = node.x; y = node.y; z = node.z;
+ return true;
+}
+
void FlightPathMovementGenerator::InitEndGridInfo()
{
- // Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
- // be reinitialized for each flightmaster at the end of each spline (or stop) in the flight.
-
- uint32 nodeCount = (*i_path).size(); // Get the number of nodes in the path.
- m_endMapId = (*i_path)[nodeCount -1].mapid; // Get the map ID from the last node
- m_preloadTargetNode = nodeCount - 3; // 2 nodes before the final node, we pre-load the grid
- m_endGridX = (*i_path)[nodeCount -1].x; // Get the X position from the last node
- m_endGridY = (*i_path)[nodeCount -1].y; // Get the Y position from the last node
+ /*! Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will
+ be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. */
+ uint32 nodeCount = (*i_path).size(); //! Number of nodes in path.
+ _endMapId = (*i_path)[nodeCount - 1].mapid; //! MapId of last node
+ _preloadTargetNode = nodeCount - 3;
+ _endGridX = (*i_path)[nodeCount - 1].x;
+ _endGridY = (*i_path)[nodeCount - 1].y;
}
void FlightPathMovementGenerator::PreloadEndGrid()
{
// used to preload the final grid where the flightmaster is
- Map* endMap = sMapMgr->FindBaseNonInstanceMap(m_endMapId);
+ Map* endMap = sMapMgr->FindBaseNonInstanceMap(_endMapId);
// Load the grid
if (endMap)
{
- sLog->outDetail("Preloading flightmaster at grid (%f, %f) for map %u", m_endGridX, m_endGridY, m_endMapId);
- endMap->LoadGrid(m_endGridX, m_endGridY);
+ sLog->outDetail("Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1));
+ endMap->LoadGrid(_endGridX, _endGridY);
}
else
sLog->outDetail("Unable to determine map to preload flightmaster grid");
}
-void FlightPathMovementGenerator::DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure)
-{
- if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID)
- {
- sLog->outDebug(LOG_FILTER_MAPSCRIPTS, "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player.GetName());
- player.GetMap()->ScriptsStart(sEventScripts, eventid, &player, &player);
- }
-}
-
//
// Unique1's ASTAR Pathfinding Code... For future use & reference...
diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
index 230630936ff..aa6d327db3b 100755
--- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h
@@ -26,10 +26,8 @@
*/
#include "MovementGenerator.h"
-#include "DestinationHolder.h"
#include "WaypointManager.h"
#include "Path.h"
-#include "Traveller.h"
#include "Player.h"
@@ -44,49 +42,68 @@ template<class T, class P>
class PathMovementBase
{
public:
- PathMovementBase() : i_currentNode(0) {}
+ PathMovementBase() : i_currentNode(0), i_path(NULL) {}
virtual ~PathMovementBase() {};
- bool MovementInProgress(void) const { return i_currentNode < i_path->size(); }
-
+ // template pattern, not defined .. override required
void LoadPath(T &);
- void ReloadPath(T &);
uint32 GetCurrentNode() const { return i_currentNode; }
- bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x, y, z); return true; }
- bool GetPosition(float& x, float& y, float& z) const { i_destinationHolder.GetLocationNowNoMicroMovement(x, y, z); return true; }
-
protected:
- uint32 i_currentNode;
- DestinationHolder< Traveller<T> > i_destinationHolder;
P i_path;
+ uint32 i_currentNode;
};
template<class T>
+class WaypointMovementGenerator;
-class WaypointMovementGenerator
- : public MovementGeneratorMedium< T, WaypointMovementGenerator<T> >, public PathMovementBase<T, WaypointPath const*>
+template<>
+class WaypointMovementGenerator<Creature>
+: public MovementGeneratorMedium< Creature, WaypointMovementGenerator<Creature> >,
+public PathMovementBase<Creature, WaypointPath const*>
{
public:
- WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) :
- node(NULL), path_id(_path_id), i_nextMoveTime(0), repeating(_repeating), StopedByPlayer(false) {}
-
- void Initialize(T &);
- void Finalize(T &);
- void MovementInform(T &);
- void InitTraveller(T &, const WaypointData &);
- void GeneratePathId(T &);
- void Reset(T &unit);
- bool Update(T &, const uint32);
- bool GetDestination(float &x, float &y, float &z) const;
+ WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) : i_nextMoveTime(0), path_id(_path_id), m_isArrivalDone(false), repeating(_repeating) {}
+ ~WaypointMovementGenerator() { i_path = NULL; }
+ void Initialize(Creature &);
+ void Finalize(Creature &);
+ void Reset(Creature &);
+ bool Update(Creature &, const uint32 &diff);
+
+ void MovementInform(Creature &);
+
MovementGeneratorType GetMovementGeneratorType() { return WAYPOINT_MOTION_TYPE; }
+ // now path movement implmementation
+ void LoadPath(Creature &c);
+
+ bool GetResetPosition(Creature&, float& x, float& y, float& z);
+
private:
- WaypointData* node;
- uint32 path_id;
+
+ void Stop(int32 time) { i_nextMoveTime.Reset(time);}
+
+ bool Stopped() { return !i_nextMoveTime.Passed();}
+
+ bool CanMove(int32 diff)
+ {
+ i_nextMoveTime.Update(diff);
+ return i_nextMoveTime.Passed();
+ }
+
+ void OnArrived(Creature&);
+ bool StartMove(Creature&);
+
+ void StartMoveNow(Creature& creature)
+ {
+ i_nextMoveTime.Reset(0);
+ StartMove(creature);
+ }
+
TimeTrackerSmall i_nextMoveTime;
- WaypointPath const* waypoints;
- bool repeating, StopedByPlayer;
+ bool m_isArrivalDone;
+ uint32 path_id;
+ bool repeating;
};
/** FlightPathMovementGenerator generates movement of the player for the paths
@@ -103,7 +120,7 @@ public PathMovementBase<Player, TaxiPathNodeList const*>
i_currentNode = startNode;
}
void Initialize(Player &);
- void Reset(Player & /*u*/){};
+ void Reset(Player &);
void Finalize(Player &);
bool Update(Player &, const uint32);
MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; }
@@ -115,17 +132,16 @@ public PathMovementBase<Player, TaxiPathNodeList const*>
void SkipCurrentNode() { ++i_currentNode; }
void DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure);
- bool GetDestination(float& x, float& y, float& z) const { return PathMovementBase<Player, TaxiPathNodeList const*>::GetDestination(x, y, z); }
+ bool GetResetPosition(Player&, float& x, float& y, float& z);
- void PreloadEndGrid();
void InitEndGridInfo();
+ void PreloadEndGrid();
+
private:
- // storage for preloading the flightmaster grid at end
- // before reaching final waypoint
- uint32 m_endMapId;
- uint32 m_preloadTargetNode;
- float m_endGridX;
- float m_endGridY;
+ float _endGridX; //! X coord of last node location
+ float _endGridY; //! Y coord of last node location
+ uint32 _endMapId; //! map Id of last node location
+ uint32 _preloadTargetNode; //! node index where preloading starts
};
#endif
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
new file mode 100644
index 00000000000..4eaa6b57b36
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MoveSpline.h"
+#include <sstream>
+#include "Log.h"
+
+namespace Movement{
+
+extern float computeFallTime(float path_length, bool isSafeFall);
+extern float computeFallElevation(float time_passed, bool isSafeFall, float start_velocy);
+extern float computeFallElevation(float time_passed);
+
+Location MoveSpline::ComputePosition() const
+{
+ ASSERT(Initialized());
+
+ float u = 1.f;
+ int32 seg_time = spline.length(point_Idx,point_Idx+1);
+ if (seg_time > 0)
+ u = (time_passed - spline.length(point_Idx)) / (float)seg_time;
+ Location c;
+ c.orientation = initialOrientation;
+ spline.evaluate_percent(point_Idx, u, c);
+
+ if (splineflags.animation)
+ ;// MoveSplineFlag::Animation disables falling or parabolic movement
+ else if (splineflags.parabolic)
+ computeParabolicElevation(c.z);
+ else if (splineflags.falling)
+ computeFallElevation(c.z);
+
+ if (splineflags.done && splineflags.isFacing())
+ {
+ if (splineflags.final_angle)
+ c.orientation = facing.angle;
+ else if (splineflags.final_point)
+ c.orientation = atan2(facing.f.y-c.y, facing.f.x-c.x);
+ //nothing to do for MoveSplineFlag::Final_Target flag
+ }
+ else
+ {
+ if (!splineflags.hasFlag(MoveSplineFlag::OrientationFixed|MoveSplineFlag::Falling))
+ {
+ Vector3 hermite;
+ spline.evaluate_derivative(point_Idx,u,hermite);
+ c.orientation = atan2(hermite.y, hermite.x);
+ }
+
+ if (splineflags.orientationInversed)
+ c.orientation = -c.orientation;
+ }
+ return c;
+}
+
+void MoveSpline::computeParabolicElevation(float& el) const
+{
+ if (time_passed > effect_start_time)
+ {
+ float t_passedf = MSToSec(time_passed - effect_start_time);
+ float t_durationf = MSToSec(Duration() - effect_start_time); //client use not modified duration here
+
+ // -a*x*x + bx + c:
+ //(dur * v3->z_acceleration * dt)/2 - (v3->z_acceleration * dt * dt)/2 + Z;
+ el += (t_durationf - t_passedf) * 0.5f * vertical_acceleration * t_passedf;
+ }
+}
+
+void MoveSpline::computeFallElevation(float& el) const
+{
+ float z_now = spline.getPoint(spline.first()).z - Movement::computeFallElevation(MSToSec(time_passed));
+ float final_z = FinalDestination().z;
+ if (z_now < final_z)
+ el = final_z;
+ else
+ el = z_now;
+}
+
+inline uint32 computeDuration(float length, float velocity)
+{
+ return SecToMS(length / velocity);
+}
+
+struct FallInitializer
+{
+ FallInitializer(float _start_elevation) : start_elevation(_start_elevation) {}
+ float start_elevation;
+ inline int32 operator()(Spline<int32>& s, int32 i)
+ {
+ return Movement::computeFallTime(start_elevation - s.getPoint(i+1).z,false) * 1000.f;
+ }
+};
+
+enum{
+ minimal_duration = 1,
+};
+
+struct CommonInitializer
+{
+ CommonInitializer(float _velocity) : velocityInv(1000.f/_velocity), time(minimal_duration) {}
+ float velocityInv;
+ int32 time;
+ inline int32 operator()(Spline<int32>& s, int32 i)
+ {
+ time += (s.SegLength(i) * velocityInv);
+ return time;
+ }
+};
+
+void MoveSpline::init_spline(const MoveSplineInitArgs& args)
+{
+ const SplineBase::EvaluationMode modes[2] = {SplineBase::ModeLinear,SplineBase::ModeCatmullrom};
+ if (args.flags.cyclic)
+ {
+ uint32 cyclic_point = 0;
+ // MoveSplineFlag::Enter_Cycle support dropped
+ //if (splineflags & SPLINEFLAG_ENTER_CYCLE)
+ //cyclic_point = 1; // shouldn't be modified, came from client
+ spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point);
+ }
+ else
+ {
+ spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()]);
+ }
+
+ // init spline timestamps
+ if (splineflags.falling)
+ {
+ FallInitializer init(spline.getPoint(spline.first()).z);
+ spline.initLengths(init);
+ }
+ else
+ {
+ CommonInitializer init(args.velocity);
+ spline.initLengths(init);
+ }
+
+ // TODO: what to do in such cases? problem is in input data (all points are at same coords)
+ if (spline.length() < minimal_duration)
+ {
+ sLog->outError("MoveSpline::init_spline: zero length spline, wrong input data?");
+ spline.set_length(spline.last(), spline.isCyclic() ? 1000 : 1);
+ }
+ point_Idx = spline.first();
+}
+
+void MoveSpline::Initialize(const MoveSplineInitArgs& args)
+{
+ splineflags = args.flags;
+ facing = args.facing;
+ m_Id = args.splineId;
+ point_Idx_offset = args.path_Idx_offset;
+ initialOrientation = args.initialOrientation;
+
+ time_passed = 0;
+ vertical_acceleration = 0.f;
+ effect_start_time = 0;
+
+ init_spline(args);
+
+ // init parabolic / animation
+ // spline initialized, duration known and i able to compute parabolic acceleration
+ if (args.flags & (MoveSplineFlag::Parabolic | MoveSplineFlag::Animation))
+ {
+ effect_start_time = Duration() * args.time_perc;
+ if (args.flags.parabolic && effect_start_time < Duration())
+ {
+ float f_duration = MSToSec(Duration() - effect_start_time);
+ vertical_acceleration = args.parabolic_amplitude * 8.f / (f_duration * f_duration);
+ }
+ }
+}
+
+MoveSpline::MoveSpline() : m_Id(0), time_passed(0),
+ vertical_acceleration(0.f), effect_start_time(0), point_Idx(0), point_Idx_offset(0), initialOrientation(0.f)
+{
+ splineflags.done = true;
+}
+
+/// ============================================================================================
+
+bool MoveSplineInitArgs::Validate() const
+{
+#define CHECK(exp) \
+ if (!(exp))\
+ {\
+ sLog->outError("MoveSplineInitArgs::Validate: expression '%s' failed", #exp);\
+ return false;\
+ }
+ CHECK(path.size() > 1);
+ CHECK(velocity > 0.f);
+ CHECK(time_perc >= 0.f && time_perc <= 1.f);
+ //CHECK(_checkPathBounds());
+ return true;
+#undef CHECK
+}
+
+// MONSTER_MOVE packet format limitation for not CatmullRom movement:
+// each vertex offset packed into 11 bytes
+bool MoveSplineInitArgs::_checkPathBounds() const
+{
+ if (!(flags & MoveSplineFlag::Mask_CatmullRom) && path.size() > 2)
+ {
+ enum{
+ MAX_OFFSET = (1 << 11) / 2,
+ };
+ Vector3 middle = (path.front()+path.back()) / 2;
+ Vector3 offset;
+ for (uint32 i = 1; i < path.size()-1; ++i)
+ {
+ offset = path[i] - middle;
+ if (fabs(offset.x) >= MAX_OFFSET || fabs(offset.y) >= MAX_OFFSET || fabs(offset.z) >= MAX_OFFSET)
+ {
+ sLog->outError("MoveSplineInitArgs::_checkPathBounds check failed");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+/// ============================================================================================
+
+MoveSpline::UpdateResult MoveSpline::_updateState(int32& ms_time_diff)
+{
+ if (Finalized())
+ {
+ ms_time_diff = 0;
+ return Result_Arrived;
+ }
+
+ UpdateResult result = Result_None;
+
+ int32 minimal_diff = std::min(ms_time_diff, segment_time_elapsed());
+ ASSERT(minimal_diff >= 0);
+ time_passed += minimal_diff;
+ ms_time_diff -= minimal_diff;
+
+ if (time_passed >= next_timestamp())
+ {
+ ++point_Idx;
+ if (point_Idx < spline.last())
+ {
+ result = Result_NextSegment;
+ }
+ else
+ {
+ if (spline.isCyclic())
+ {
+ point_Idx = spline.first();
+ time_passed = time_passed % Duration();
+ result = Result_NextSegment;
+ }
+ else
+ {
+ _Finalize();
+ ms_time_diff = 0;
+ result = Result_Arrived;
+ }
+ }
+ }
+
+ return result;
+}
+
+std::string MoveSpline::ToString() const
+{
+ std::stringstream str;
+ str << "MoveSpline" << std::endl;
+ str << "spline Id: " << GetId() << std::endl;
+ str << "flags: " << splineflags.ToString() << std::endl;
+ if (splineflags.final_angle)
+ str << "facing angle: " << facing.angle;
+ else if (splineflags.final_target)
+ str << "facing target: " << facing.target;
+ else if(splineflags.final_point)
+ str << "facing point: " << facing.f.x << " " << facing.f.y << " " << facing.f.z;
+ str << std::endl;
+ str << "time passed: " << time_passed << std::endl;
+ str << "total time: " << Duration() << std::endl;
+ str << "spline point Id: " << point_Idx << std::endl;
+ str << "path point Id: " << currentPathIdx() << std::endl;
+ str << spline.ToString();
+ return str.str();
+}
+
+void MoveSpline::_Finalize()
+{
+ splineflags.done = true;
+ point_Idx = spline.last() - 1;
+ time_passed = Duration();
+}
+
+int32 MoveSpline::currentPathIdx() const
+{
+ int32 point = point_Idx_offset + point_Idx - spline.first() + (int)Finalized();
+ if (isCyclic())
+ point = point % (spline.last()-spline.first());
+ return point;
+}
+}
diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h
new file mode 100644
index 00000000000..4b8dbcc8ee3
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSpline.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_MOVEPLINE_H
+#define TRINITYSERVER_MOVEPLINE_H
+
+#include "Spline.h"
+#include "MoveSplineInitArgs.h"
+
+namespace Movement
+{
+ struct Location : public Vector3
+ {
+ Location() : orientation(0) {}
+ Location(float x, float y, float z, float o) : Vector3(x,y,z), orientation(o) {}
+ Location(const Vector3& v) : Vector3(v), orientation(0) {}
+ Location(const Vector3& v, float o) : Vector3(v), orientation(o) {}
+
+ float orientation;
+ };
+
+ // MoveSpline represents smooth catmullrom or linear curve and point that moves belong it
+ // curve can be cyclic - in this case movement will be cyclic
+ // point can have vertical acceleration motion componemt(used in fall, parabolic movement)
+ class MoveSpline
+ {
+ public:
+ typedef Spline<int32> MySpline;
+ enum UpdateResult{
+ Result_None = 0x01,
+ Result_Arrived = 0x02,
+ Result_NextCycle = 0x04,
+ Result_NextSegment = 0x08,
+ };
+ #pragma region fields
+ friend class PacketBuilder;
+ protected:
+ MySpline spline;
+
+ FacingInfo facing;
+
+ uint32 m_Id;
+
+ MoveSplineFlag splineflags;
+
+ int32 time_passed;
+ // currently duration mods are unused, but its _currently_
+ //float duration_mod;
+ //float duration_mod_next;
+ float vertical_acceleration;
+ float initialOrientation;
+ int32 effect_start_time;
+ int32 point_Idx;
+ int32 point_Idx_offset;
+
+ void init_spline(const MoveSplineInitArgs& args);
+ protected:
+
+ const MySpline::ControlArray& getPath() const { return spline.getPoints();}
+ void computeParabolicElevation(float& el) const;
+ void computeFallElevation(float& el) const;
+
+ UpdateResult _updateState(int32& ms_time_diff);
+ int32 next_timestamp() const { return spline.length(point_Idx+1);}
+ int32 segment_time_elapsed() const { return next_timestamp()-time_passed;}
+ int32 Duration() const { return spline.length();}
+ int32 timeElapsed() const { return Duration() - time_passed;}
+ int32 timePassed() const { return time_passed;}
+
+ public:
+ const MySpline& _Spline() const { return spline;}
+ int32 _currentSplineIdx() const { return point_Idx;}
+ void _Finalize();
+ void _Interrupt() { splineflags.done = true;}
+
+ #pragma endregion
+ public:
+
+ void Initialize(const MoveSplineInitArgs&);
+ bool Initialized() const { return !spline.empty();}
+
+ explicit MoveSpline();
+
+ template<class UpdateHandler>
+ void updateState(int32 difftime, UpdateHandler& handler)
+ {
+ ASSERT(Initialized());
+ do
+ handler(_updateState(difftime));
+ while(difftime > 0);
+ }
+
+ void updateState(int32 difftime)
+ {
+ ASSERT(Initialized());
+ do _updateState(difftime);
+ while(difftime > 0);
+ }
+
+ Location ComputePosition() const;
+
+ uint32 GetId() const { return m_Id;}
+ bool Finalized() const { return splineflags.done; }
+ bool isCyclic() const { return splineflags.cyclic;}
+ const Vector3 FinalDestination() const { return Initialized() ? spline.getPoint(spline.last()) : Vector3();}
+ const Vector3 CurrentDestination() const { return Initialized() ? spline.getPoint(point_Idx+1) : Vector3();}
+ int32 currentPathIdx() const;
+
+ std::string ToString() const;
+ };
+}
+#endif // TRINITYSERVER_MOVEPLINE_H
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
new file mode 100644
index 00000000000..de91f63c30a
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_MOVESPLINEFLAG_H
+#define TRINITYSERVER_MOVESPLINEFLAG_H
+#include "MovementTypedefs.h"
+
+#include <string>
+
+namespace Movement
+{
+#if defined( __GNUC__ )
+#pragma pack(1)
+#else
+#pragma pack(push,1)
+#endif
+
+ class MoveSplineFlag
+ {
+ public:
+ enum eFlags{
+ None = 0x00000000,
+ // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
+ Done = 0x00000100,
+ Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
+ No_Spline = 0x00000400,
+ Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
+ Walkmode = 0x00001000,
+ Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
+ OrientationFixed = 0x00004000, // Model orientation fixed
+ Final_Point = 0x00008000,
+ Final_Target = 0x00010000,
+ Final_Angle = 0x00020000,
+ Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
+ Cyclic = 0x00080000, // Movement by cycled spline
+ Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
+ Animation = 0x00200000, // Plays animation after some time passed
+ Frozen = 0x00400000, // Will never arrive
+ Unknown5 = 0x00800000,
+ Unknown6 = 0x01000000,
+ Unknown7 = 0x02000000,
+ Unknown8 = 0x04000000,
+ OrientationInversed = 0x08000000,
+ Unknown10 = 0x10000000,
+ Unknown11 = 0x20000000,
+ Unknown12 = 0x40000000,
+ Unknown13 = 0x80000000,
+
+ // Masks
+ Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
+ // animation ids stored here, see AnimType enum, used with Animation flag
+ Mask_Animations = 0xFF,
+ // flags that shouldn't be appended into SMSG_MONSTER_MOVE\SMSG_MONSTER_MOVE_TRANSPORT packet, should be more probably
+ Mask_No_Monster_Move = Mask_Final_Facing | Mask_Animations | Done,
+ // CatmullRom interpolation mode used
+ Mask_CatmullRom = Flying | Catmullrom,
+ // Unused, not suported flags
+ Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown5|Unknown6|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,
+ };
+
+ inline uint32& raw() { return (uint32&)*this;}
+ inline const uint32& raw() const { return (const uint32&)*this;}
+
+ MoveSplineFlag() { raw() = 0; }
+ MoveSplineFlag(uint32 f) { raw() = f; }
+ MoveSplineFlag(const MoveSplineFlag& f) { raw() = f.raw(); }
+
+ // Constant interface
+
+ bool isSmooth() const { return raw() & Mask_CatmullRom;}
+ bool isLinear() const { return !isSmooth();}
+ bool isFacing() const { return raw() & Mask_Final_Facing;}
+
+ uint8 getAnimationId() const { return animId;}
+ bool hasAllFlags(uint32 f) const { return (raw() & f) == f;}
+ bool hasFlag(uint32 f) const { return (raw() & f) != 0;}
+ uint32 operator & (uint32 f) const { return (raw() & f);}
+ uint32 operator | (uint32 f) const { return (raw() | f);}
+ std::string ToString() const;
+
+ // Not constant interface
+
+ void operator &= (uint32 f) { raw() &= f;}
+ void operator |= (uint32 f) { raw() |= f;}
+
+ void EnableAnimation(uint8 anim) { raw() = raw() & ~(Mask_Animations|Falling|Parabolic) | Animation|anim;}
+ void EnableParabolic() { raw() = raw() & ~(Mask_Animations|Falling|Animation) | Parabolic;}
+ void EnableFalling() { raw() = raw() & ~(Mask_Animations|Parabolic|Animation) | Falling;}
+ void EnableFlying() { raw() = raw() & ~Catmullrom | Flying; }
+ void EnableCatmullRom() { raw() = raw() & ~Flying | Catmullrom; }
+ void EnableFacingPoint() { raw() = raw() & ~Mask_Final_Facing | Final_Point;}
+ void EnableFacingAngle() { raw() = raw() & ~Mask_Final_Facing | Final_Angle;}
+ void EnableFacingTarget() { raw() = raw() & ~Mask_Final_Facing | Final_Target;}
+
+ uint8 animId : 8;
+ bool done : 1;
+ bool falling : 1;
+ bool no_spline : 1;
+ bool parabolic : 1;
+ bool walkmode : 1;
+ bool flying : 1;
+ bool orientationFixed : 1;
+ bool final_point : 1;
+ bool final_target : 1;
+ bool final_angle : 1;
+ bool catmullrom : 1;
+ bool cyclic : 1;
+ bool enter_cycle : 1;
+ bool animation : 1;
+ bool frozen : 1;
+ bool unknown5 : 1;
+ bool unknown6 : 1;
+ bool unknown7 : 1;
+ bool unknown8 : 1;
+ bool orientationInversed : 1;
+ bool unknown10 : 1;
+ bool unknown11 : 1;
+ bool unknown12 : 1;
+ bool unknown13 : 1;
+ };
+#if defined( __GNUC__ )
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+}
+
+#endif // TRINITYSERVER_MOVESPLINEFLAG_H
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
new file mode 100644
index 00000000000..b5ae923dc32
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MoveSplineInit.h"
+#include "MoveSpline.h"
+#include "MovementPacketBuilder.h"
+#include "Unit.h"
+
+namespace Movement
+{
+ UnitMoveType SelectSpeedType(uint32 moveFlags)
+ {
+ if (moveFlags & MOVEMENTFLAG_FLYING)
+ {
+ if ( moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.flight >= speed_obj.flight_back*/ )
+ return MOVE_FLIGHT_BACK;
+ else
+ return MOVE_FLIGHT;
+ }
+ else if (moveFlags & MOVEMENTFLAG_SWIMMING)
+ {
+ if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.swim >= speed_obj.swim_back*/)
+ return MOVE_SWIM_BACK;
+ else
+ return MOVE_SWIM;
+ }
+ else if (moveFlags & MOVEMENTFLAG_WALKING)
+ {
+ //if ( speed_obj.run > speed_obj.walk )
+ return MOVE_WALK;
+ }
+ else if (moveFlags & MOVEMENTFLAG_BACKWARD /*&& speed_obj.run >= speed_obj.run_back*/)
+ return MOVE_RUN_BACK;
+
+ return MOVE_RUN;
+ }
+
+ void MoveSplineInit::Launch()
+ {
+ MoveSpline& move_spline = *unit.movespline;
+
+ Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZ(),unit.GetOrientation());
+ // there is a big chane that current position is unknown if current state is not finalized, need compute it
+ // this also allows calculate spline position and update map position in much greater intervals
+ if (!move_spline.Finalized())
+ real_position = move_spline.ComputePosition();
+
+ if (args.path.empty())
+ {
+ // should i do the things that user should do?
+ MoveTo(real_position);
+ }
+
+ // corrent first vertex
+ args.path[0] = real_position;
+ args.initialOrientation = real_position.orientation;
+
+ uint32 moveFlags = unit.m_movementInfo.GetMovementFlags();
+ if (args.flags.walkmode)
+ moveFlags |= MOVEMENTFLAG_WALKING;
+ else
+ moveFlags &= ~MOVEMENTFLAG_WALKING;
+
+ moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD);
+
+ if (args.velocity == 0.f)
+ args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));
+
+ if (!args.Validate())
+ return;
+
+ if (moveFlags & MOVEMENTFLAG_ROOT)
+ moveFlags &= ~MOVEMENTFLAG_MASK_MOVING;
+
+ unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags);
+ move_spline.Initialize(args);
+
+ WorldPacket data(SMSG_MONSTER_MOVE, 64);
+ data.append(unit.GetPackGUID());
+ PacketBuilder::WriteMonsterMove(move_spline, data);
+ unit.SendMessageToSet(&data,true);
+ }
+
+ MoveSplineInit::MoveSplineInit(Unit& m) : unit(m)
+ {
+ // mix existing state into new
+ args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
+ args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_FLYING|MOVEMENTFLAG_LEVITATING));
+ }
+
+ void MoveSplineInit::SetFacing(const Unit * target)
+ {
+ args.flags.EnableFacingTarget();
+ //args.facing.target = target->GetObjectGuid().GetRawValue();
+ args.facing.target = target->GetUInt64Value(OBJECT_FIELD_GUID);
+ }
+
+ void MoveSplineInit::SetFacing(float angle)
+ {
+ args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
+ args.flags.EnableFacingAngle();
+ }
+}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
new file mode 100644
index 00000000000..7ef6cd7a120
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_MOVESPLINEINIT_H
+#define TRINITYSERVER_MOVESPLINEINIT_H
+
+#include "MoveSplineInitArgs.h"
+
+class Unit;
+
+namespace Movement
+{
+ enum AnimType
+ {
+ ToGround = 0, // 460 = ToGround, index of AnimationData.dbc
+ FlyToFly = 1, // 461 = FlyToFly?
+ ToFly = 2, // 458 = ToFly
+ FlyToGround = 3, // 463 = FlyToGround
+ };
+
+ /* Initializes and launches spline movement
+ */
+ class MoveSplineInit
+ {
+ public:
+
+ explicit MoveSplineInit(Unit& m);
+
+ /* Final pass of initialization that launches spline movement.
+ */
+ void Launch();
+
+ /* Adds movement by parabolic trajectory
+ * @param amplitude - the maximum height of parabola, value could be negative and positive
+ * @param start_time - delay between movement starting time and beginning to move by parabolic trajectory
+ * can't be combined with final animation
+ */
+ void SetParabolic(float amplitude, float start_time);
+ /* Plays animation after movement done
+ * can't be combined with parabolic movement
+ */
+ void SetAnimation(AnimType anim);
+
+ /* Adds final facing animation
+ * sets unit's facing to specified point/angle after all path done
+ * you can have only one final facing: previous will be overriden
+ */
+ void SetFacing(float angle);
+ void SetFacing(Vector3 const& point);
+ void SetFacing(const Unit * target);
+
+ /* Initializes movement by path
+ * @param path - array of points, shouldn't be empty
+ * @param pointId - Id of fisrt point of the path. Example: when third path point will be done it will notify that pointId + 3 done
+ */
+ void MovebyPath(const PointsArray& path, int32 pointId = 0);
+
+ /* Initializes simple A to B mition, A is current unit's position, B is destination
+ */
+ void MoveTo(const Vector3& destination);
+ void MoveTo(float x, float y, float z);
+
+ /* Sets Id of fisrt point of the path. When N-th path point will be done ILisener will notify that pointId + N done
+ * Needed for waypoint movement where path splitten into parts
+ */
+ void SetFirstPointId(int32 pointId) { args.path_Idx_offset = pointId; }
+
+ /* Enables CatmullRom spline interpolation mode(makes path smooth)
+ * if not enabled linear spline mode will be choosen. Disabled by default
+ */
+ void SetSmooth();
+ /* Enables CatmullRom spline interpolation mode, enables flying animation. Disabled by default
+ */
+ void SetFly();
+ /* Enables walk mode. Disabled by default
+ */
+ void SetWalk(bool enable);
+ /* Makes movement cyclic. Disabled by default
+ */
+ void SetCyclic();
+ /* Enables falling mode. Disabled by default
+ */
+ void SetFall();
+ /* Inverses unit model orientation. Disabled by default
+ */
+ void SetOrientationInversed();
+ /* Fixes unit's model rotation. Disabled by default
+ */
+ void SetOrientationFixed(bool enable);
+
+ /* Sets the velocity (in case you want to have custom movement velocity)
+ * if no set, speed will be selected based on unit's speeds and current movement mode
+ * Has no effect if falling mode enabled
+ * velocity shouldn't be negative
+ */
+ void SetVelocity(float velocity);
+
+ PointsArray& Path() { return args.path; }
+
+ protected:
+
+ MoveSplineInitArgs args;
+ Unit& unit;
+ };
+
+ inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();}
+ inline void MoveSplineInit::SetWalk(bool enable) { args.flags.walkmode = enable;}
+ inline void MoveSplineInit::SetSmooth() { args.flags.EnableCatmullRom();}
+ inline void MoveSplineInit::SetCyclic() { args.flags.cyclic = true;}
+ inline void MoveSplineInit::SetFall() { args.flags.EnableFalling();}
+ inline void MoveSplineInit::SetVelocity(float vel){ args.velocity = vel;}
+ inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
+ inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable;}
+
+ inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset)
+ {
+ args.path_Idx_offset = path_offset;
+ args.path.assign(controls.begin(),controls.end());
+ }
+
+ inline void MoveSplineInit::MoveTo(float x, float y, float z)
+ {
+ Vector3 v(x,y,z);
+ MoveTo(v);
+ }
+
+ inline void MoveSplineInit::MoveTo(const Vector3& dest)
+ {
+ args.path_Idx_offset = 0;
+ args.path.resize(2);
+ args.path[1] = dest;
+ }
+
+ inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift)
+ {
+ args.time_perc = time_shift;
+ args.parabolic_amplitude = amplitude;
+ args.flags.EnableParabolic();
+ }
+
+ inline void MoveSplineInit::SetAnimation(AnimType anim)
+ {
+ args.time_perc = 0.f;
+ args.flags.EnableAnimation((uint8)anim);
+ }
+
+ inline void MoveSplineInit::SetFacing(Vector3 const& spot)
+ {
+ args.facing.f.x = spot.x;
+ args.facing.f.y = spot.y;
+ args.facing.f.z = spot.z;
+ args.flags.EnableFacingPoint();
+ }
+}
+#endif // TRINITYSERVER_MOVESPLINEINIT_H
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
new file mode 100644
index 00000000000..26fbbdd0fcc
--- /dev/null
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_MOVESPLINEINIT_ARGS_H
+#define TRINITYSERVER_MOVESPLINEINIT_ARGS_H
+
+#include "MoveSplineFlag.h"
+#include <G3D/Vector3.h>
+
+namespace Movement
+{
+ typedef std::vector<Vector3> PointsArray;
+
+ union FacingInfo
+ {
+ struct{
+ float x,y,z;
+ }f;
+ uint64 target;
+ float angle;
+
+ FacingInfo(float o) : angle(o) {}
+ FacingInfo(uint64 t) : target(t) {}
+ FacingInfo() {}
+ };
+
+ struct MoveSplineInitArgs
+ {
+ MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0),
+ velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f)
+ {
+ path.reserve(path_capacity);
+ }
+
+ PointsArray path;
+ FacingInfo facing;
+ MoveSplineFlag flags;
+ int32 path_Idx_offset;
+ float velocity;
+ float parabolic_amplitude;
+ float time_perc;
+ uint32 splineId;
+ float initialOrientation;
+
+ /** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
+ bool Validate() const;
+ private:
+ bool _checkPathBounds() const;
+ };
+}
+
+#endif // TRINITYSERVER_MOVESPLINEINIT_ARGS_H
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
new file mode 100644
index 00000000000..73fdbf4c2f6
--- /dev/null
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -0,0 +1,188 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MovementPacketBuilder.h"
+#include "MoveSpline.h"
+#include "WorldPacket.h"
+
+namespace Movement
+{
+ inline void operator << (ByteBuffer& b, const Vector3& v)
+ {
+ b << v.x << v.y << v.z;
+ }
+
+ inline void operator >> (ByteBuffer& b, Vector3& v)
+ {
+ b >> v.x >> v.y >> v.z;
+ }
+
+ enum MonsterMoveType
+ {
+ MonsterMoveNormal = 0,
+ MonsterMoveStop = 1,
+ MonsterMoveFacingSpot = 2,
+ MonsterMoveFacingTarget = 3,
+ MonsterMoveFacingAngle = 4
+ };
+
+ void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
+ {
+ MoveSplineFlag splineflags = move_spline.splineflags;
+ /*if (mov.IsBoarded())
+ {
+ data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
+ data << mov.GetTransport()->Owner.GetPackGUID();
+ data << int8(mov.m_unused.transport_seat);
+ }*/
+
+ data << uint8(0);
+ data << move_spline.spline.getPoint(move_spline.spline.first());
+ data << move_spline.GetId();
+
+ switch(splineflags & MoveSplineFlag::Mask_Final_Facing)
+ {
+ default:
+ data << uint8(MonsterMoveNormal);
+ break;
+ case MoveSplineFlag::Final_Target:
+ data << uint8(MonsterMoveFacingTarget);
+ data << move_spline.facing.target;
+ break;
+ case MoveSplineFlag::Final_Angle:
+ data << uint8(MonsterMoveFacingAngle);
+ data << move_spline.facing.angle;
+ break;
+ case MoveSplineFlag::Final_Point:
+ data << uint8(MonsterMoveFacingSpot);
+ data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
+ break;
+ }
+
+ // add fake Enter_Cycle flag - needed for client-side cyclic movement (client will erase first spline vertex after first cycle done)
+ splineflags.enter_cycle = move_spline.isCyclic();
+ data << uint32(splineflags & ~MoveSplineFlag::Mask_No_Monster_Move);
+
+ if (splineflags.animation)
+ {
+ data << splineflags.getAnimationId();
+ data << move_spline.effect_start_time;
+ }
+
+ data << move_spline.Duration();
+
+ if (splineflags.parabolic)
+ {
+ data << move_spline.vertical_acceleration;
+ data << move_spline.effect_start_time;
+ }
+ }
+
+ void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data)
+ {
+ uint32 last_idx = spline.getPointCount() - 3;
+ const Vector3 * real_path = &spline.getPoint(1);
+
+ data << last_idx;
+ data << real_path[last_idx]; // destination
+ if (last_idx > 1)
+ {
+ Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f;
+ Vector3 offset;
+ // first and last points already appended
+ for(uint32 i = 1; i < last_idx; ++i)
+ {
+ offset = middle - real_path[i];
+ data.appendPackXYZ(offset.x, offset.y, offset.z);
+ }
+ }
+ }
+
+ void WriteCatmullRomPath(const Spline<int32>& spline, ByteBuffer& data)
+ {
+ uint32 count = spline.getPointCount() - 3;
+ data << count;
+ data.append<Vector3>(&spline.getPoint(2), count);
+ }
+
+ void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data)
+ {
+ uint32 count = spline.getPointCount() - 3;
+ data << uint32(count + 1);
+ data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done
+ data.append<Vector3>(&spline.getPoint(1), count);
+ }
+
+ void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, WorldPacket& data)
+ {
+ WriteCommonMonsterMovePart(move_spline, data);
+
+ const Spline<int32>& spline = move_spline.spline;
+ MoveSplineFlag splineflags = move_spline.splineflags;
+ if (splineflags & MoveSplineFlag::Mask_CatmullRom)
+ {
+ if (splineflags.cyclic)
+ WriteCatmullRomCyclicPath(spline, data);
+ else
+ WriteCatmullRomPath(spline, data);
+ }
+ else
+ WriteLinearPath(spline, data);
+ }
+
+ void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data)
+ {
+ //WriteClientStatus(mov,data);
+ //data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount);
+ //if (mov.SplineEnabled())
+ {
+ MoveSplineFlag splineFlags = move_spline.splineflags;
+
+ data << splineFlags.raw();
+
+ if (splineFlags.final_angle)
+ {
+ data << move_spline.facing.angle;
+ }
+ else if (splineFlags.final_target)
+ {
+ data << move_spline.facing.target;
+ }
+ else if(splineFlags.final_point)
+ {
+ data << move_spline.facing.f.x << move_spline.facing.f.y << move_spline.facing.f.z;
+ }
+
+ data << move_spline.timePassed();
+ data << move_spline.Duration();
+ data << move_spline.GetId();
+
+ data << float(1.f); // splineInfo.duration_mod; added in 3.1
+ data << float(1.f); // splineInfo.duration_mod_next; added in 3.1
+
+ data << move_spline.vertical_acceleration; // added in 3.1
+ data << move_spline.effect_start_time; // added in 3.1
+
+ uint32 nodes = move_spline.getPath().size();
+ data << nodes;
+ data.append<Vector3>(&move_spline.getPath()[0], nodes);
+ data << uint8(move_spline.spline.mode()); // added in 3.1
+ data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination());
+ }
+ }
+}
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h
new file mode 100644
index 00000000000..92a414e9b3b
--- /dev/null
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_PACKET_BUILDER_H
+#define TRINITYSERVER_PACKET_BUILDER_H
+
+class ByteBuffer;
+class WorldPacket;
+
+namespace Movement
+{
+ class MoveSpline;
+ class PacketBuilder
+ {
+ static void WriteCommonMonsterMovePart(const MoveSpline& mov, WorldPacket& data);
+ public:
+
+ static void WriteMonsterMove(const MoveSpline& mov, WorldPacket& data);
+ static void WriteCreate(const MoveSpline& mov, ByteBuffer& data);
+ };
+}
+#endif // TRINITYSERVER_PACKET_BUILDER_H
diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h
new file mode 100644
index 00000000000..01c8a5b7e7b
--- /dev/null
+++ b/src/server/game/Movement/Spline/MovementTypedefs.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_TYPEDEFS_H
+#define TRINITYSERVER_TYPEDEFS_H
+
+#include "Common.h"
+
+namespace G3D
+{
+ class Vector2;
+ class Vector3;
+ class Vector4;
+}
+
+namespace Movement
+{
+ using G3D::Vector2;
+ using G3D::Vector3;
+ using G3D::Vector4;
+
+ inline uint32 SecToMS(float sec)
+ {
+ return static_cast<uint32>(sec * 1000.f);
+ }
+
+ inline float MSToSec(uint32 ms)
+ {
+ return ms / 1000.f;
+ }
+
+#ifndef static_assert
+ #define CONCAT(x, y) CONCAT1 (x, y)
+ #define CONCAT1(x, y) x##y
+ #define static_assert(expr, msg) typedef char CONCAT(static_assert_failed_at_line_, __LINE__) [(expr) ? 1 : -1]
+#endif
+
+ template<class T, T limit>
+ class counter
+ {
+ public:
+ counter() { init();}
+
+ void Increase()
+ {
+ if (m_counter == limit)
+ init();
+ else
+ ++m_counter;
+ }
+
+ T NewId() { Increase(); return m_counter;}
+ T getCurrent() const { return m_counter;}
+
+ private:
+ void init() { m_counter = 0; }
+ T m_counter;
+ };
+
+ typedef counter<uint32, 0xFFFFFFFF> UInt32Counter;
+
+ extern double gravity;
+ extern float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity);
+}
+
+#endif // TRINITYSERVER_TYPEDEFS_H
diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp
new file mode 100644
index 00000000000..f0ed01c4676
--- /dev/null
+++ b/src/server/game/Movement/Spline/MovementUtil.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MoveSplineFlag.h"
+#include <math.h>
+#include <string>
+
+namespace Movement
+{
+ double gravity = 19.29110527038574;
+
+ /// Velocity bounds that makes fall speed limited
+ float terminalVelocity = 60.148003f;
+ float terminalSavefallVelocity = 7.f;
+
+ const float terminal_length = float(terminalVelocity * terminalVelocity) / (2.f * gravity);
+ const float terminal_savefall_length = (terminalSavefallVelocity * terminalSavefallVelocity) / (2.f * gravity);
+ const float terminalFallTime = float(terminalVelocity/gravity); // the time that needed to reach terminalVelocity
+
+ float computeFallTime(float path_length, bool isSafeFall)
+ {
+ if (path_length < 0.f)
+ return 0.f;
+
+ float time;
+ if ( isSafeFall )
+ {
+ if (path_length >= terminal_savefall_length)
+ time = (path_length - terminal_savefall_length)/terminalSavefallVelocity + terminalSavefallVelocity/gravity;
+ else
+ time = sqrtf(2.f * path_length/gravity);
+ }
+ else
+ {
+ if (path_length >= terminal_length)
+ time = (path_length - terminal_length)/terminalVelocity + terminalFallTime;
+ else
+ time = sqrtf(2.f * path_length/gravity);
+ }
+
+ return time;
+ }
+
+ float computeFallElevation(float t_passed, bool isSafeFall, float start_velocity)
+ {
+ float termVel;
+ float result;
+
+ if ( isSafeFall )
+ termVel = terminalSavefallVelocity;
+ else
+ termVel = terminalVelocity;
+
+ if ( start_velocity > termVel )
+ start_velocity = termVel;
+
+ float terminal_time = terminalFallTime - start_velocity / gravity; // the time that needed to reach terminalVelocity
+
+ if ( t_passed > terminal_time )
+ {
+ result = terminalVelocity*(t_passed - terminal_time) +
+ start_velocity*terminal_time + gravity*terminal_time*terminal_time*0.5f;
+ }
+ else
+ result = t_passed * (start_velocity + t_passed * gravity * 0.5f);
+
+ return result;
+ }
+
+ float computeFallElevation(float t_passed)
+ {
+ float result;
+
+ if (t_passed > terminalFallTime)
+ {
+ //result = terminalVelocity * (t_passed - terminal_time) + gravity*terminal_time*terminal_time*0.5f;
+ // simplified view:
+ result = terminalVelocity * (t_passed - terminalFallTime) + terminal_length;
+ }
+ else
+ result = t_passed * t_passed * gravity * 0.5f;
+
+ return result;
+ }
+
+ #define STR(x) #x
+
+ const char * g_MovementFlag_names[]=
+ {
+ STR(Forward ),// 0x00000001,
+ STR(Backward ),// 0x00000002,
+ STR(Strafe_Left ),// 0x00000004,
+ STR(Strafe_Right ),// 0x00000008,
+ STR(Turn_Left ),// 0x00000010,
+ STR(Turn_Right ),// 0x00000020,
+ STR(Pitch_Up ),// 0x00000040,
+ STR(Pitch_Down ),// 0x00000080,
+
+ STR(Walk ),// 0x00000100, // Walking
+ STR(Ontransport ),// 0x00000200,
+ STR(Levitation ),// 0x00000400,
+ STR(Root ),// 0x00000800,
+ STR(Falling ),// 0x00001000,
+ STR(Fallingfar ),// 0x00002000,
+ STR(Pendingstop ),// 0x00004000,
+ STR(PendingSTRafestop ),// 0x00008000,
+ STR(Pendingforward ),// 0x00010000,
+ STR(Pendingbackward ),// 0x00020000,
+ STR(PendingSTRafeleft ),// 0x00040000,
+ STR(PendingSTRaferight ),// 0x00080000,
+ STR(Pendingroot ),// 0x00100000,
+ STR(Swimming ),// 0x00200000, // Appears With Fly Flag Also
+ STR(Ascending ),// 0x00400000, // Swim Up Also
+ STR(Descending ),// 0x00800000, // Swim Down Also
+ STR(Can_Fly ),// 0x01000000, // Can Fly In 3.3?
+ STR(Flying ),// 0x02000000, // Actual Flying Mode
+ STR(Spline_Elevation ),// 0x04000000, // Used For Flight Paths
+ STR(Spline_Enabled ),// 0x08000000, // Used For Flight Paths
+ STR(Waterwalking ),// 0x10000000, // Prevent Unit From Falling Through Water
+ STR(Safe_Fall ),// 0x20000000, // Active Rogue Safe Fall Spell (Passive)
+ STR(Hover ),// 0x40000000
+ STR(Unknown13 ),// 0x80000000
+ STR(Unk1 ),
+ STR(Unk2 ),
+ STR(Unk3 ),
+ STR(Fullspeedturning ),
+ STR(Fullspeedpitching ),
+ STR(Allow_Pitching ),
+ STR(Unk4 ),
+ STR(Unk5 ),
+ STR(Unk6 ),
+ STR(Unk7 ),
+ STR(Interp_Move ),
+ STR(Interp_Turning ),
+ STR(Interp_Pitching ),
+ STR(Unk8 ),
+ STR(Unk9 ),
+ STR(Unk10 ),
+ };
+
+ const char * g_SplineFlag_names[32]=
+ {
+ STR(AnimBit1 ),// 0x00000001,
+ STR(AnimBit2 ),// 0x00000002,
+ STR(AnimBit3 ),// 0x00000004,
+ STR(AnimBit4 ),// 0x00000008,
+ STR(AnimBit5 ),// 0x00000010,
+ STR(AnimBit6 ),// 0x00000020,
+ STR(AnimBit7 ),// 0x00000040,
+ STR(AnimBit8 ),// 0x00000080,
+ STR(Done ),// 0x00000100,
+ STR(Falling ),// 0x00000200, // Not Compartible With Trajectory Movement
+ STR(No_Spline ),// 0x00000400,
+ STR(Trajectory ),// 0x00000800, // Not Compartible With Fall Movement
+ STR(Walkmode ),// 0x00001000,
+ STR(Flying ),// 0x00002000, // Smooth Movement(Catmullrom Interpolation Mode), Flying Animation
+ STR(Knockback ),// 0x00004000, // Model Orientation Fixed
+ STR(Final_Point ),// 0x00008000,
+ STR(Final_Target ),// 0x00010000,
+ STR(Final_Angle ),// 0x00020000,
+ STR(Catmullrom ),// 0x00040000, // Used Catmullrom Interpolation Mode
+ STR(Cyclic ),// 0x00080000, // Movement By Cycled Spline
+ STR(Enter_Cycle ),// 0x00100000, // Everytime Appears With Cyclic Flag In Monster Move Packet
+ STR(Animation ),// 0x00200000, // Animationid (0...3), Uint32 Time, Not Compartible With Trajectory And Fall Movement
+ STR(Unknown4 ),// 0x00400000, // Disables Movement By Path
+ STR(Unknown5 ),// 0x00800000,
+ STR(Unknown6 ),// 0x01000000,
+ STR(Unknown7 ),// 0x02000000,
+ STR(Unknown8 ),// 0x04000000,
+ STR(OrientationInversed ),// 0x08000000, // Appears With Runmode Flag, Nodes ),// 1, Handles Orientation
+ STR(Unknown10 ),// 0x10000000,
+ STR(Unknown11 ),// 0x20000000,
+ STR(Unknown12 ),// 0x40000000,
+ STR(Unknown13 ),// 0x80000000,
+ };
+
+ template<class Flags, int N>
+ void print_flags(Flags t, const char* (&names)[N], std::string& str)
+ {
+ for (int i = 0; i < N; ++i)
+ {
+ if ((t & (Flags)(1 << i)) && names[i] != NULL)
+ str.append(" ").append(names[i]);
+ }
+ }
+
+ std::string MoveSplineFlag::ToString() const
+ {
+ std::string str;
+ print_flags(raw(),g_SplineFlag_names,str);
+ return str;
+ }
+}
diff --git a/src/server/game/Movement/Spline/Spline.cpp b/src/server/game/Movement/Spline/Spline.cpp
new file mode 100644
index 00000000000..14c1bd0c117
--- /dev/null
+++ b/src/server/game/Movement/Spline/Spline.cpp
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "Spline.h"
+#include <sstream>
+#include <G3D/Matrix4.h>
+
+namespace Movement{
+
+SplineBase::EvaluationMethtod SplineBase::evaluators[SplineBase::ModesEnd] =
+{
+ &SplineBase::EvaluateLinear,
+ &SplineBase::EvaluateCatmullRom,
+ &SplineBase::EvaluateBezier3,
+ (EvaluationMethtod)&SplineBase::UninitializedSpline,
+};
+
+SplineBase::EvaluationMethtod SplineBase::derivative_evaluators[SplineBase::ModesEnd] =
+{
+ &SplineBase::EvaluateDerivativeLinear,
+ &SplineBase::EvaluateDerivativeCatmullRom,
+ &SplineBase::EvaluateDerivativeBezier3,
+ (EvaluationMethtod)&SplineBase::UninitializedSpline,
+};
+
+SplineBase::SegLenghtMethtod SplineBase::seglengths[SplineBase::ModesEnd] =
+{
+ &SplineBase::SegLengthLinear,
+ &SplineBase::SegLengthCatmullRom,
+ &SplineBase::SegLengthBezier3,
+ (SegLenghtMethtod)&SplineBase::UninitializedSpline,
+};
+
+SplineBase::InitMethtod SplineBase::initializers[SplineBase::ModesEnd] =
+{
+ //&SplineBase::InitLinear,
+ &SplineBase::InitCatmullRom, // we should use catmullrom initializer even for linear mode! (client's internal structure limitation)
+ &SplineBase::InitCatmullRom,
+ &SplineBase::InitBezier3,
+ (InitMethtod)&SplineBase::UninitializedSpline,
+};
+
+///////////
+#pragma region evaluation methtods
+
+using G3D::Matrix4;
+static const Matrix4 s_catmullRomCoeffs(
+ -0.5f, 1.5f,-1.5f, 0.5f,
+ 1.f, -2.5f, 2.f, -0.5f,
+ -0.5f, 0.f, 0.5f, 0.f,
+ 0.f, 1.f, 0.f, 0.f);
+
+static const Matrix4 s_Bezier3Coeffs(
+ -1.f, 3.f, -3.f, 1.f,
+ 3.f, -6.f, 3.f, 0.f,
+ -3.f, 3.f, 0.f, 0.f,
+ 1.f, 0.f, 0.f, 0.f);
+
+/* classic view:
+inline void C_Evaluate(const Vector3 *vertice, float t, const float (&matrix)[4][4], Vector3 &position)
+{
+ Vector3 tvec(t*t*t, t*t, t);
+ int i = 0;
+ double c;
+ double x = 0, y = 0, z = 0;
+ while ( i < 4 )
+ {
+ c = matrix[0][i]*tvec.x + matrix[1][i]*tvec.y + matrix[2][i]*tvec.z + matrix[3][i];
+
+ x += c * vertice->x;
+ y += c * vertice->y;
+ z += c * vertice->z;
+
+ ++i;
+ ++vertice;
+ }
+
+ position.x = x;
+ position.y = y;
+ position.z = z;
+}*/
+
+inline void C_Evaluate(const Vector3 *vertice, float t, const Matrix4& matr, Vector3 &result)
+{
+ Vector4 tvec(t*t*t, t*t, t, 1.f);
+ Vector4 weights(tvec * matr);
+
+ result = vertice[0] * weights[0] + vertice[1] * weights[1]
+ + vertice[2] * weights[2] + vertice[3] * weights[3];
+}
+
+inline void C_Evaluate_Derivative(const Vector3 *vertice, float t, const Matrix4& matr, Vector3 &result)
+{
+ Vector4 tvec(3.f*t*t, 2.f*t, 1.f, 0.f);
+ Vector4 weights(tvec * matr);
+
+ result = vertice[0] * weights[0] + vertice[1] * weights[1]
+ + vertice[2] * weights[2] + vertice[3] * weights[3];
+}
+
+void SplineBase::EvaluateLinear(index_type index, float u, Vector3& result) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+ result = points[index] + (points[index+1] - points[index]) * u;
+}
+
+void SplineBase::EvaluateCatmullRom( index_type index, float t, Vector3& result) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+ C_Evaluate(&points[index - 1], t, s_catmullRomCoeffs, result);
+}
+
+void SplineBase::EvaluateBezier3(index_type index, float t, Vector3& result) const
+{
+ index *= 3u;
+ ASSERT(index >= index_lo && index < index_hi);
+ C_Evaluate(&points[index], t, s_Bezier3Coeffs, result);
+}
+
+void SplineBase::EvaluateDerivativeLinear(index_type index, float, Vector3& result) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+ result = points[index+1] - points[index];
+}
+
+void SplineBase::EvaluateDerivativeCatmullRom(index_type index, float t, Vector3& result) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+ C_Evaluate_Derivative(&points[index - 1], t, s_catmullRomCoeffs, result);
+}
+
+void SplineBase::EvaluateDerivativeBezier3(index_type index, float t, Vector3& result) const
+{
+ index *= 3u;
+ ASSERT(index >= index_lo && index < index_hi);
+ C_Evaluate_Derivative(&points[index], t, s_Bezier3Coeffs, result);
+}
+
+float SplineBase::SegLengthLinear(index_type index) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+ return (points[index] - points[index+1]).length();
+}
+
+float SplineBase::SegLengthCatmullRom( index_type index ) const
+{
+ ASSERT(index >= index_lo && index < index_hi);
+
+ Vector3 curPos, nextPos;
+ const Vector3 * p = &points[index - 1];
+ curPos = nextPos = p[1];
+
+ index_type i = 1;
+ double length = 0;
+ while (i <= STEPS_PER_SEGMENT)
+ {
+ C_Evaluate(p, float(i) / float(STEPS_PER_SEGMENT), s_catmullRomCoeffs, nextPos);
+ length += (nextPos - curPos).length();
+ curPos = nextPos;
+ ++i;
+ }
+ return length;
+}
+
+float SplineBase::SegLengthBezier3(index_type index) const
+{
+ index *= 3u;
+ ASSERT(index >= index_lo && index < index_hi);
+
+ Vector3 curPos, nextPos;
+ const Vector3 * p = &points[index];
+
+ C_Evaluate(p, 0.f, s_Bezier3Coeffs, nextPos);
+ curPos = nextPos;
+
+ index_type i = 1;
+ double length = 0;
+ while (i <= STEPS_PER_SEGMENT)
+ {
+ C_Evaluate(p, float(i) / float(STEPS_PER_SEGMENT), s_Bezier3Coeffs, nextPos);
+ length += (nextPos - curPos).length();
+ curPos = nextPos;
+ ++i;
+ }
+ return length;
+}
+#pragma endregion
+
+void SplineBase::init_spline(const Vector3 * controls, index_type count, EvaluationMode m)
+{
+ m_mode = m;
+ cyclic = false;
+
+ (this->*initializers[m_mode])(controls, count, cyclic, 0);
+}
+
+void SplineBase::init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point)
+{
+ m_mode = m;
+ cyclic = true;
+
+ (this->*initializers[m_mode])(controls, count, cyclic, cyclic_point);
+}
+
+void SplineBase::InitLinear(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point)
+{
+ ASSERT(count >= 2);
+ const int real_size = count + 1;
+
+ points.resize(real_size);
+
+ memcpy(&points[0],controls, sizeof(Vector3) * count);
+
+ // first and last two indexes are space for special 'virtual points'
+ // these points are required for proper C_Evaluate and C_Evaluate_Derivative methtod work
+ if (cyclic)
+ points[count] = controls[cyclic_point];
+ else
+ points[count] = controls[count-1];
+
+ index_lo = 0;
+ index_hi = cyclic ? count : (count - 1);
+}
+
+void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, bool cyclic, index_type cyclic_point)
+{
+ const int real_size = count + (cyclic ? (1+2) : (1+1));
+
+ points.resize(real_size);
+
+ int lo_index = 1;
+ int high_index = lo_index + count - 1;
+
+ memcpy(&points[lo_index],controls, sizeof(Vector3) * count);
+
+ // first and last two indexes are space for special 'virtual points'
+ // these points are required for proper C_Evaluate and C_Evaluate_Derivative methtod work
+ if (cyclic)
+ {
+ if (cyclic_point == 0)
+ points[0] = controls[count-1];
+ else
+ points[0] = controls[0].lerp(controls[1], -1);
+
+ points[high_index+1] = controls[cyclic_point];
+ points[high_index+2] = controls[cyclic_point+1];
+ }
+ else
+ {
+ points[0] = controls[0].lerp(controls[1], -1);
+ points[high_index+1] = controls[count-1];
+ }
+
+ index_lo = lo_index;
+ index_hi = high_index + (cyclic ? 1 : 0);
+}
+
+void SplineBase::InitBezier3(const Vector3* controls, index_type count, bool /*cyclic*/, index_type /*cyclic_point*/)
+{
+ index_type c = count / 3u * 3u;
+ index_type t = c / 3u;
+
+ points.resize(c);
+ memcpy(&points[0],controls, sizeof(Vector3) * c);
+
+ index_lo = 0;
+ index_hi = t-1;
+ //mov_assert(points.size() % 3 == 0);
+}
+
+void SplineBase::clear()
+{
+ index_lo = 0;
+ index_hi = 0;
+ points.clear();
+}
+
+std::string SplineBase::ToString() const
+{
+ std::stringstream str;
+ const char * mode_str[ModesEnd] = {"Linear", "CatmullRom", "Bezier3", "Uninitialized"};
+
+ index_type count = this->points.size();
+ str << "mode: " << mode_str[mode()] << std::endl;
+ str << "points count: " << count << std::endl;
+ for (index_type i = 0; i < count; ++i)
+ str << "point " << i << " : " << points[i].toString() << std::endl;
+
+ return str.str();
+}
+
+}
diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h
new file mode 100644
index 00000000000..28876b220d4
--- /dev/null
+++ b/src/server/game/Movement/Spline/Spline.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef TRINITYSERVER_SPLINE_H
+#define TRINITYSERVER_SPLINE_H
+
+#include "MovementTypedefs.h"
+#include <G3D/Vector3.h>
+
+namespace Movement {
+
+class SplineBase
+{
+public:
+ typedef int index_type;
+ typedef std::vector<Vector3> ControlArray;
+
+ enum EvaluationMode
+ {
+ ModeLinear,
+ ModeCatmullrom,
+ ModeBezier3_Unused,
+ UninitializedMode,
+ ModesEnd
+ };
+
+ #pragma region fields
+protected:
+ ControlArray points;
+
+ index_type index_lo;
+ index_type index_hi;
+
+ uint8 m_mode;
+ bool cyclic;
+
+ enum{
+ // could be modified, affects segment length evaluation precision
+ // lesser value saves more performance in cost of lover precision
+ // minimal value is 1
+ // client's value is 20, blizzs use 2-3 steps to compute length
+ STEPS_PER_SEGMENT = 3,
+ };
+ static_assert(STEPS_PER_SEGMENT > 0, "shouldn't be lesser than 1");
+
+protected:
+ void EvaluateLinear(index_type, float, Vector3&) const;
+ void EvaluateCatmullRom(index_type, float, Vector3&) const;
+ void EvaluateBezier3(index_type, float, Vector3&) const;
+ typedef void (SplineBase::*EvaluationMethtod)(index_type,float,Vector3&) const;
+ static EvaluationMethtod evaluators[ModesEnd];
+
+ void EvaluateDerivativeLinear(index_type, float, Vector3&) const;
+ void EvaluateDerivativeCatmullRom(index_type, float, Vector3&) const;
+ void EvaluateDerivativeBezier3(index_type, float, Vector3&) const;
+ static EvaluationMethtod derivative_evaluators[ModesEnd];
+
+ float SegLengthLinear(index_type) const;
+ float SegLengthCatmullRom(index_type) const;
+ float SegLengthBezier3(index_type) const;
+ typedef float (SplineBase::*SegLenghtMethtod)(index_type) const;
+ static SegLenghtMethtod seglengths[ModesEnd];
+
+ void InitLinear(const Vector3*, index_type, bool, index_type);
+ void InitCatmullRom(const Vector3*, index_type, bool, index_type);
+ void InitBezier3(const Vector3*, index_type, bool, index_type);
+ typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, bool, index_type);
+ static InitMethtod initializers[ModesEnd];
+
+ void UninitializedSpline() const { ASSERT(false);}
+
+ #pragma endregion
+public:
+
+ explicit SplineBase() : m_mode(UninitializedMode), index_lo(0), index_hi(0), cyclic(false) {}
+
+ /** Caclulates the position for given segment Idx, and percent of segment length t
+ @param t - percent of segment length, assumes that t in range [0, 1]
+ @param Idx - spline segment index, should be in range [first, last)
+ */
+ void evaluate_percent(index_type Idx, float u, Vector3& c) const {(this->*evaluators[m_mode])(Idx,u,c);}
+
+ /** Caclulates derivation in index Idx, and percent of segment length t
+ @param Idx - spline segment index, should be in range [first, last)
+ @param t - percent of spline segment length, assumes that t in range [0, 1]
+ */
+ void evaluate_derivative(index_type Idx, float u, Vector3& hermite) const {(this->*derivative_evaluators[m_mode])(Idx,u,hermite);}
+
+ /** Bounds for spline indexes. All indexes should be in range [first, last). */
+ index_type first() const { return index_lo;}
+ index_type last() const { return index_hi;}
+
+ bool empty() const { return index_lo == index_hi;}
+ EvaluationMode mode() const { return (EvaluationMode)m_mode;}
+ bool isCyclic() const { return cyclic;}
+
+ const ControlArray& getPoints() const { return points;}
+ index_type getPointCount() const { return points.size();}
+ const Vector3& getPoint(index_type i) const { return points[i];}
+
+ /** Initializes spline. Don't call other methods while spline not initialized. */
+ void init_spline(const Vector3 * controls, index_type count, EvaluationMode m);
+ void init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point);
+
+ /** As i can see there are a lot of ways how spline can be initialized
+ would be no harm to have some custom initializers. */
+ template<class Init> inline void init_spline(Init& initializer)
+ {
+ initializer(m_mode,cyclic,points,index_lo,index_hi);
+ }
+
+ void clear();
+
+ /** Calculates distance between [i; i+1] points, assumes that index i is in bounds. */
+ float SegLength(index_type i) const { return (this->*seglengths[m_mode])(i);}
+
+ std::string ToString() const;
+};
+
+template<typename length_type>
+class Spline : public SplineBase
+{
+public:
+ typedef length_type LengthType;
+ typedef std::vector<length_type> LengthArray;
+ #pragma region fields
+protected:
+
+ LengthArray lengths;
+
+ index_type computeIndexInBounds(length_type length) const;
+ #pragma endregion
+public:
+
+ explicit Spline(){}
+
+ /** Calculates the position for given t
+ @param t - percent of spline's length, assumes that t in range [0, 1]. */
+ void evaluate_percent(float t, Vector3 & c) const;
+
+ /** Calculates derivation for given t
+ @param t - percent of spline's length, assumes that t in range [0, 1]. */
+ void evaluate_derivative(float t, Vector3& hermite) const;
+
+ /** Calculates the position for given segment Idx, and percent of segment length t
+ @param t = partial_segment_length / whole_segment_length
+ @param Idx - spline segment index, should be in range [first, last). */
+ void evaluate_percent(index_type Idx, float u, Vector3& c) const { SplineBase::evaluate_percent(Idx,u,c);}
+
+ /** Caclulates derivation for index Idx, and percent of segment length t
+ @param Idx - spline segment index, should be in range [first, last)
+ @param t - percent of spline segment length, assumes that t in range [0, 1]. */
+ void evaluate_derivative(index_type Idx, float u, Vector3& c) const { SplineBase::evaluate_derivative(Idx,u,c);}
+
+ // Assumes that t in range [0, 1]
+ index_type computeIndexInBounds(float t) const;
+ void computeIndex(float t, index_type& out_idx, float& out_u) const;
+
+ /** Initializes spline. Don't call other methods while spline not initialized. */
+ void init_spline(const Vector3 * controls, index_type count, EvaluationMode m) { SplineBase::init_spline(controls,count,m);}
+ void init_cyclic_spline(const Vector3 * controls, index_type count, EvaluationMode m, index_type cyclic_point) { SplineBase::init_cyclic_spline(controls,count,m,cyclic_point);}
+
+ /** Initializes lengths with SplineBase::SegLength method. */
+ void initLengths();
+
+ /** Initializes lengths in some custom way
+ Note that value returned by cacher must be greater or equal to previous value. */
+ template<class T> inline void initLengths(T& cacher)
+ {
+ index_type i = index_lo;
+ lengths.resize(index_hi+1);
+ length_type prev_length = 0, new_length = 0;
+ while(i < index_hi)
+ {
+ new_length = cacher(*this, i);
+ lengths[++i] = new_length;
+
+ ASSERT(prev_length <= new_length);
+ prev_length = new_length;
+ }
+ }
+
+ /** Returns length of the whole spline. */
+ length_type length() const { return lengths[index_hi];}
+ /** Returns length between given nodes. */
+ length_type length(index_type first, index_type last) const { return lengths[last]-lengths[first];}
+ length_type length(index_type Idx) const { return lengths[Idx];}
+
+ void set_length(index_type i, length_type length) { lengths[i] = length;}
+ void clear();
+};
+
+}
+
+#include "SplineImpl.h"
+
+#endif // TRINITYSERVER_SPLINE_H
diff --git a/src/server/game/Movement/Spline/SplineImpl.h b/src/server/game/Movement/Spline/SplineImpl.h
new file mode 100644
index 00000000000..eded2d8c903
--- /dev/null
+++ b/src/server/game/Movement/Spline/SplineImpl.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+namespace Movement
+{
+template<typename length_type> void Spline<length_type>::evaluate_percent( float t, Vector3 & c ) const
+{
+ index_type Index;
+ float u;
+ computeIndex(t, Index, u);
+ evaluate_percent(Index, u, c);
+}
+
+template<typename length_type> void Spline<length_type>::evaluate_derivative(float t, Vector3& hermite) const
+{
+ index_type Index;
+ float u;
+ computeIndex(t, Index, u);
+ evaluate_derivative(Index, u, hermite);
+}
+
+template<typename length_type> SplineBase::index_type Spline<length_type>::computeIndexInBounds(length_type length_) const
+{
+// Temporary disabled: causes infinite loop with t = 1.f
+/*
+ index_type hi = index_hi;
+ index_type lo = index_lo;
+
+ index_type i = lo + (float)(hi - lo) * t;
+
+ while ((lengths[i] > length) || (lengths[i + 1] <= length))
+ {
+ if (lengths[i] > length)
+ hi = i - 1; // too big
+ else if (lengths[i + 1] <= length)
+ lo = i + 1; // too small
+
+ i = (hi + lo) / 2;
+ }*/
+
+ index_type i = index_lo;
+ index_type N = index_hi;
+ while (i+1 < N && lengths[i+1] < length_)
+ ++i;
+
+ return i;
+}
+
+template<typename length_type> void Spline<length_type>::computeIndex(float t, index_type& index, float& u) const
+{
+ ASSERT(t >= 0.f && t <= 1.f);
+ length_type length_ = t * length();
+ index = computeIndexInBounds(length_);
+ ASSERT(index < index_hi);
+ u = (length_ - length(index)) / (float)length(index, index+1);
+}
+
+template<typename length_type> SplineBase::index_type Spline<length_type>::computeIndexInBounds( float t ) const
+{
+ ASSERT(t >= 0.f && t <= 1.f);
+ return computeIndexInBounds(t * length());
+}
+
+template<typename length_type> void Spline<length_type>::initLengths()
+{
+ index_type i = index_lo;
+ length_type length = 0;
+ lengths.resize(index_hi+1);
+ while(i < index_hi )
+ {
+ length += SegLength(i);
+ lengths[++i] = length;
+ }
+}
+
+template<typename length_type> void Spline<length_type>::clear()
+{
+ SplineBase::clear();
+ lengths.clear();
+}
+
+}
diff --git a/src/server/game/Movement/Traveller.h b/src/server/game/Movement/Traveller.h
deleted file mode 100755
index 641278ee37a..00000000000
--- a/src/server/game/Movement/Traveller.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef TRINITY_TRAVELLER_H
-#define TRINITY_TRAVELLER_H
-
-#include "Creature.h"
-#include "Player.h"
-#include <cassert>
-
-/** Traveller is a wrapper for units (creatures or players) that
- * travel from point A to point B using the destination holder.
- */
-#define PLAYER_FLIGHT_SPEED 32.0f
-
-template<class T>
-struct Traveller
-{
- T &i_traveller;
- Traveller(T &t) : i_traveller(t) {}
- Traveller(const Traveller &obj) : i_traveller(obj) {}
- Traveller& operator=(const Traveller &obj)
- {
- this.i_traveller = obj.i_traveller;
- return *this;
- }
-
- operator T&(void) { return i_traveller; }
- operator const T&(void) { return i_traveller; }
- float GetPositionX() const { return i_traveller.GetPositionX(); }
- float GetPositionY() const { return i_traveller.GetPositionY(); }
- float GetPositionZ() const { return i_traveller.GetPositionZ(); }
- T& GetTraveller(void) { return i_traveller; }
-
- float Speed(void) { ASSERT(false); return 0.0f; }
- float GetMoveDestinationTo(float x, float y, float z);
- uint32 GetTotalTrevelTimeTo(float x, float y, float z);
-
- void Relocation(float x, float y, float z, float orientation) {}
- void Relocation(float x, float y, float z) { Relocation(x, y, z, i_traveller.GetOrientation()); }
- void MoveTo(float x, float y, float z, uint32 t) {}
-};
-
-template<class T>
-inline uint32 Traveller<T>::GetTotalTrevelTimeTo(float x, float y, float z)
-{
- float dist = GetMoveDestinationTo(x, y, z);
- float speed = Speed();
- if (speed < 0.0f)
- return 0xfffffffe; // almost infinity-unit should stop
- else
- speed *= 0.001f; // speed is in seconds so convert from second to millisecond
- return static_cast<uint32>(dist/speed);
-}
-
-// specialization for creatures
-template<>
-inline float Traveller<Creature>::Speed()
-{
- if (i_traveller.HasUnitState(UNIT_STAT_CHARGING))
- return i_traveller.m_TempSpeed;
- else if (i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_WALKING))
- return i_traveller.GetSpeed(MOVE_WALK);
- else if (i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
- return i_traveller.GetSpeed(MOVE_FLIGHT);
- else
- return i_traveller.GetSpeed(MOVE_RUN);
-}
-
-template<>
-inline void Traveller<Creature>::Relocation(float x, float y, float z, float orientation)
-{
- i_traveller.UpdatePosition(x, y, z, orientation);
-}
-
-template<>
-inline float Traveller<Creature>::GetMoveDestinationTo(float x, float y, float z)
-{
- float dx = x - GetPositionX();
- float dy = y - GetPositionY();
- float dz = z - GetPositionZ();
-
- //if (i_traveller.HasUnitMovementFlag(MOVEMENTFLAG_FLYING))
- return sqrt((dx*dx) + (dy*dy) + (dz*dz));
- //else //Walking on the ground
- // return sqrt((dx*dx) + (dy*dy));
-}
-
-template<>
-inline void Traveller<Creature>::MoveTo(float x, float y, float z, uint32 t)
-{
- //i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0);
- i_traveller.SendMonsterMove(x, y, z, t);
-}
-
-// specialization for players
-template<>
-inline float Traveller<Player>::Speed()
-{
- if (i_traveller.HasUnitState(UNIT_STAT_CHARGING))
- return i_traveller.m_TempSpeed;
- else if (i_traveller.isInFlight())
- return PLAYER_FLIGHT_SPEED;
- else
- return i_traveller.GetSpeed(i_traveller.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING) ? MOVE_WALK : MOVE_RUN);
-}
-
-template<>
-inline float Traveller<Player>::GetMoveDestinationTo(float x, float y, float z)
-{
- float dx = x - GetPositionX();
- float dy = y - GetPositionY();
- float dz = z - GetPositionZ();
-
- //if (i_traveller.isInFlight())
- return sqrt((dx*dx) + (dy*dy) + (dz*dz));
- //else //Walking on the ground
- // return sqrt((dx*dx) + (dy*dy));
-}
-
-template<>
-inline void Traveller<Player>::Relocation(float x, float y, float z, float orientation)
-{
- i_traveller.UpdatePosition(x, y, z, orientation);
-}
-
-template<>
-inline void Traveller<Player>::MoveTo(float x, float y, float z, uint32 t)
-{
- //Only send MOVEMENTFLAG_WALKING, client has strange issues with other move flags
- i_traveller.SendMonsterMove(x, y, z, t);
-}
-
-typedef Traveller<Creature> CreatureTraveller;
-typedef Traveller<Player> PlayerTraveller;
-#endif
-
diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h
index 2cca2506f4a..0edd44328f1 100755
--- a/src/server/game/Quests/QuestDef.h
+++ b/src/server/game/Quests/QuestDef.h
@@ -271,7 +271,7 @@ class Quest
uint32 GetQuestTurnInPortrait() const { return QuestTurnInPortrait; }
bool IsDaily() const { return Flags & QUEST_FLAGS_DAILY; }
bool IsWeekly() const { return Flags & QUEST_FLAGS_WEEKLY; }
- bool IsSeasonal() const { return ZoneOrSort == -QUEST_SORT_SEASONAL; }
+ bool IsSeasonal() const { return (ZoneOrSort == -QUEST_SORT_SEASONAL || ZoneOrSort == -QUEST_SORT_SPECIAL || ZoneOrSort == -QUEST_SORT_LUNAR_FESTIVAL || ZoneOrSort == -QUEST_SORT_MIDSUMMER || ZoneOrSort == -QUEST_SORT_BREWFEST || ZoneOrSort == -QUEST_SORT_LOVE_IS_IN_THE_AIR || ZoneOrSort == -QUEST_SORT_NOBLEGARDEN); }
bool IsDailyOrWeekly() const { return Flags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); }
bool IsAutoAccept() const { return Flags & QUEST_FLAGS_AUTO_ACCEPT; }
bool IsRaidQuest() const { return Type == QUEST_TYPE_RAID || Type == QUEST_TYPE_RAID_10 || Type == QUEST_TYPE_RAID_25; }
diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp
index 71195538256..7757e1a1a35 100755
--- a/src/server/game/Scripting/MapScripts.cpp
+++ b/src/server/game/Scripting/MapScripts.cpp
@@ -475,8 +475,14 @@ void Map::ScriptsProcess()
// Source or target must be Creature.
if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
{
- cSource->SendMonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, step.script->MoveTo.TravelTime);
- cSource->GetMap()->CreatureRelocation(cSource, step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, 0);
+ Unit * unit = (Unit*)cSource;
+ if (step.script->MoveTo.TravelTime != 0)
+ {
+ float speed = unit->GetDistance(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ) / ((float)step.script->MoveTo.TravelTime * 0.001f);
+ unit->MonsterMoveWithSpeed(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, speed);
+ }
+ else
+ unit->NearTeleportTo(step.script->MoveTo.DestX, step.script->MoveTo.DestY, step.script->MoveTo.DestZ, unit->GetOrientation());
}
break;
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index 6322151e792..c46721db6cd 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -570,6 +570,7 @@ void AddSC_the_eye();
void AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
void AddSC_boss_nethermancer_sepethrea();
void AddSC_boss_pathaleon_the_calculator();
+void AddSC_boss_mechano_lord_capacitus();
void AddSC_instance_mechanar();
void AddSC_blades_edge_mountains();
@@ -1030,6 +1031,7 @@ void AddOutlandScripts()
AddSC_boss_gatewatcher_iron_hand(); //TK The Mechanar
AddSC_boss_nethermancer_sepethrea();
AddSC_boss_pathaleon_the_calculator();
+ AddSC_boss_mechano_lord_capacitus();
AddSC_instance_mechanar();
AddSC_blades_edge_mountains();
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 84ccc3e574b..978f33c88aa 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -96,7 +96,7 @@ m_playerRecentlyLogout(false), m_playerSave(false),
m_sessionDbcLocale(sWorld->GetAvailableDbcLocale(locale)),
m_sessionDbLocaleIndex(locale),
m_latency(0), m_TutorialsChanged(false), recruiterId(recruiter),
-isRecruiter(isARecruiter)
+isRecruiter(isARecruiter), timeLastWhoCommand(0)
{
if (sock)
{
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index ff07164e7b2..d4cf3119257 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -964,6 +964,7 @@ class WorldSession
uint32 recruiterId;
bool isRecruiter;
ACE_Based::LockedQueue<WorldPacket*, ACE_Thread_Mutex> _recvQueue;
+ time_t timeLastWhoCommand;
};
#endif
/// @}
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index c1fcfc6d244..2c28eb4216c 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -4789,11 +4789,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
case 46361: // Reinforced Net
if (caster)
- {
- float currentGroundLevel = target->GetBaseMap()->GetHeight(target->GetPositionX(), target->GetPositionY(), MAX_HEIGHT);
- if (target->GetPositionZ() > currentGroundLevel)
- target->GetMotionMaster()->MoveFall(currentGroundLevel);
- }
+ target->GetMotionMaster()->MoveFall();
break;
case 49028:
if (caster)
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index aac93ad78a3..a577a8678ea 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1978,6 +1978,13 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
if (!sSpellMgr->CanSpellTriggerProcOnEvent(*procEntry, eventInfo))
return false;
+ // TODO:
+ // - do checks using conditions table for eventInfo->GetActor() and eventInfo->GetActionTarget()
+ // - add DoCheckProc() AuraScript hook
+ // to allow additional requirements for procs
+ // this is needed because this is the last moment in which you can prevent aura charge drop on proc
+ // and possibly a way to prevent default checks (if there're going to be any)
+
// Check if current equipment meets aura requirements
// do that only for passive spells
// TODO: this needs to be unified for all kinds of auras
@@ -2038,11 +2045,14 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event
void Aura::TriggerProcOnEvent(AuraApplication* aurApp, ProcEventInfo& eventInfo)
{
- // TODO: script hooks here (allowing prevention of selected effects)
+ // TODO: OnProc hook here
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (aurApp->HasEffect(i))
+ // TODO: OnEffectProc hook here (allowing prevention of selected effects)
GetEffect(i)->HandleProc(aurApp, eventInfo);
- // TODO: script hooks here
+ // TODO: AfterEffectProc hook here
+
+ // TODO: AfterProc hook here
// Remove aura if we've used last charge to proc
if (IsUsingCharges() && !GetCharges())
diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h
index 8c9cde37c15..de743eb2991 100755
--- a/src/server/game/Spells/Auras/SpellAuras.h
+++ b/src/server/game/Spells/Auras/SpellAuras.h
@@ -186,6 +186,9 @@ class Aura
bool CanStackWith(Aura const* existingAura) const;
// Proc system
+ // this subsystem is not yet in use - the core of it is functional, but still some research has to be done
+ // and some dependant problems fixed before it can replace old proc system (for example cooldown handling)
+ // currently proc system functionality is implemented in Unit::ProcDamageAndSpell
bool IsProcOnCooldown() const;
void AddProcCooldown(uint32 msec);
bool IsUsingCharges() const { return m_isUsingCharges; }
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index e8872deb152..a36bd7361b4 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -3858,6 +3858,9 @@ void Spell::SendSpellGo()
castFlags |= CAST_FLAG_UNKNOWN_19; // same as in SMSG_SPELL_START
}
+ if (m_targets.HasTraj())
+ castFlags |= CAST_FLAG_ADJUST_MISSILE;
+
WorldPacket data(SMSG_SPELL_GO, 50); // guess size
if (m_CastItem)
@@ -3897,8 +3900,8 @@ void Spell::SendSpellGo()
if (castFlags & CAST_FLAG_ADJUST_MISSILE)
{
- data << float(0);
- data << uint32(0);
+ data << m_targets.GetElevation();
+ data << uint32(m_delayMoment);
}
if (castFlags & CAST_FLAG_PROJECTILE)
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index d932b536a78..cd4f2324d9b 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -346,38 +346,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
switch (m_spellInfo->Id) // better way to check unknown
{
- // Positive/Negative Charge
- case 28062:
- case 28085:
- case 39090:
- case 39093:
- if (!m_triggeredByAuraSpell)
- break;
- if (unitTarget == m_caster)
- {
- uint8 count = 0;
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
- if (ihit->targetGUID != m_caster->GetGUID())
- if (Player* target = ObjectAccessor::GetPlayer(*m_caster, ihit->targetGUID))
- if (target->HasAura(m_triggeredByAuraSpell->Id))
- ++count;
- if (count)
- {
- uint32 spellId = 0;
- switch (m_spellInfo->Id)
- {
- case 28062: spellId = 29659; break;
- case 28085: spellId = 29660; break;
- case 39090: spellId = 39089; break;
- case 39093: spellId = 39092; break;
- }
- m_caster->SetAuraStack(spellId, m_caster, count);
- }
- }
-
- if (unitTarget->HasAura(m_triggeredByAuraSpell->Id))
- damage = 0;
- break;
// Consumption
case 28865:
damage = (((InstanceMap*)m_caster->GetMap())->GetDifficulty() == REGULAR_DIFFICULTY ? 2750 : 4250);
@@ -2795,7 +2763,7 @@ void Spell::SendLoot(uint64 guid, LootType loottype)
{
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
- gameObjTarget->UseDoorOrButton();
+ gameObjTarget->UseDoorOrButton(0, false, player);
player->GetMap()->ScriptsStart(sGameObjectScripts, gameObjTarget->GetDBTableGUIDLow(), player, gameObjTarget);
return;
@@ -3408,22 +3376,11 @@ void Spell::EffectDistract(SpellEffIndex /*effIndex*/)
if (unitTarget->HasUnitState(UNIT_STAT_CONFUSED | UNIT_STAT_STUNNED | UNIT_STAT_FLEEING))
return;
- float angle = unitTarget->GetAngle(m_targets.GetDst());
+ unitTarget->SetFacingTo(unitTarget->GetAngle(m_targets.GetDst()));
+ unitTarget->ClearUnitState(UNIT_STAT_MOVING);
- if (unitTarget->GetTypeId() == TYPEID_PLAYER)
- {
- // For players just turn them
- unitTarget->ToPlayer()->UpdatePosition(unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), angle, false);
- //unitTarget->ToPlayer()->SendTeleportAckPacket(); TODO!
- }
- else
- {
- // Set creature Distracted, Stop it, And turn it
- unitTarget->SetOrientation(angle);
- unitTarget->StopMoving();
+ if (unitTarget->GetTypeId() == TYPEID_UNIT)
unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILLISECONDS);
- unitTarget->SendMovementFlagUpdate();
- }
}
void Spell::EffectPickPocket(SpellEffIndex /*effIndex*/)
@@ -5608,6 +5565,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
duel->opponent = target;
duel->startTime = 0;
duel->startTimer = 0;
+ duel->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel
caster->duel = duel;
DuelInfo* duel2 = new DuelInfo;
@@ -5615,6 +5573,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex)
duel2->opponent = caster;
duel2->startTime = 0;
duel2->startTimer = 0;
+ duel2->isMounted = (GetSpellInfo()->Id == 62875); // Mounted Duel
target->duel = duel2;
caster->SetUInt64Value(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 2e2199db794..a5bea319fee 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2889,6 +2889,22 @@ void SpellMgr::LoadSpellCustomAttr()
case 69293: // Wing Buffet
case 74439: // Machine Gun
case 63278: // Mark of the Faceless (General Vezax)
+ case 62544: // Thrust (Argent Tournament)
+ case 64588: // Thrust (Argent Tournament)
+ case 66479: // Thrust (Argent Tournament)
+ case 68505: // Thrust (Argent Tournament)
+ case 62626: // Break-Shield (Argent Tournament, Player)
+ case 64590: // Break-Shield (Argent Tournament, Player)
+ case 64342: // Break-Shield (Argent Tournament, NPC)
+ case 64686: // Break-Shield (Argent Tournament, NPC)
+ case 65147: // Break-Shield (Argent Tournament, NPC)
+ case 68504: // Break-Shield (Argent Tournament, NPC)
+ case 62874: // Charge (Argent Tournament, Player)
+ case 68498: // Charge (Argent Tournament, Player)
+ case 64591: // Charge (Argent Tournament, Player)
+ case 63003: // Charge (Argent Tournament, NPC)
+ case 63010: // Charge (Argent Tournament, NPC)
+ case 68321: // Charge (Argent Tournament, NPC)
case 72255: // Mark of the Fallen Champion (Deathbringer Saurfang)
case 72444: // Mark of the Fallen Champion (Deathbringer Saurfang)
case 72445: // Mark of the Fallen Champion (Deathbringer Saurfang)
@@ -2972,6 +2988,7 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_TARGET_ENEMY;
spellInfo->EffectImplicitTargetB[0] = 0;
break;
+ case 63665: // Charge (Argent Tournament emote on riders)
case 31447: // Mark of Kaz'rogal (needs target selection script)
case 31298: // Sleep (needs target selection script)
case 51904: // Summon Ghouls On Scarlet Crusade (this should use conditions table, script for this spell needs to be fixed)
@@ -3041,6 +3058,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 42611: // Shoot
case 61588: // Blazing Harpoon
case 52479: // Gift of the Harvester
+ case 48246: // Ball of Flame
spellInfo->MaxAffectedTargets = 1;
break;
case 41376: // Spite
@@ -3383,6 +3401,7 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->AreaGroupId = 0; // originally, these require area 4522, which is... outside of Icecrown Citadel
break;
case 70602: // Corruption
+ case 48278: // Paralyze
spellInfo->AttributesEx3 |= SPELL_ATTR3_STACK_FOR_DIFF_CASTERS;
break;
case 70715: // Column of Frost (visual marker)
diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt
index d34b1b8c3c3..56e63af5bbf 100644
--- a/src/server/scripts/CMakeLists.txt
+++ b/src/server/scripts/CMakeLists.txt
@@ -61,12 +61,10 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/CountedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Policies
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/collision
@@ -112,6 +110,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Grids/Notifiers
${CMAKE_SOURCE_DIR}/src/server/game/Groups
${CMAKE_SOURCE_DIR}/src/server/game/Guilds
+ ${CMAKE_SOURCE_DIR}/src/server/game/Handlers
${CMAKE_SOURCE_DIR}/src/server/game/Instances
${CMAKE_SOURCE_DIR}/src/server/game/LookingForGroup
${CMAKE_SOURCE_DIR}/src/server/game/Loot
@@ -130,7 +129,6 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Scripting
${CMAKE_SOURCE_DIR}/src/server/game/Server
${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol
- ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol/Handlers
${CMAKE_SOURCE_DIR}/src/server/game/Skills
${CMAKE_SOURCE_DIR}/src/server/game/Spells
${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index bd415c0f79f..7372c92c4dd 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -109,7 +109,8 @@ public:
{
case AOR_OK:
handler->PSendSysMessage(LANG_ACCOUNT_CREATED, accountName);
- sLog->outChar("Account: %d (IP: %s) Character:[%s] (GUID: %u) Change Password.", handler->GetSession()->GetAccountId(),handler->GetSession()->GetRemoteAddress().c_str(), handler->GetSession()->GetPlayer()->GetName(), handler->GetSession()->GetPlayer()->GetGUIDLow());
+ if (handler->GetSession())
+ sLog->outChar("Account: %d (IP: %s) Character:[%s] (GUID: %u) Change Password.", handler->GetSession()->GetAccountId(),handler->GetSession()->GetRemoteAddress().c_str(), handler->GetSession()->GetPlayer()->GetName(), handler->GetSession()->GetPlayer()->GetGUIDLow());
break;
case AOR_NAME_TOO_LONG:
handler->SendSysMessage(LANG_ACCOUNT_TOO_LONG);
@@ -509,7 +510,7 @@ public:
stmt->setUInt32(0, targetAccountId);
stmt->setUInt8(1, uint8(gm));
- stmt->setUInt32(2, gmRealmID);
+ stmt->setInt32(2, gmRealmID);
LoginDatabase.Execute(stmt);
}
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index ac57d9c9425..0dcb6995cb1 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -26,6 +26,7 @@ EndScriptData */
#include "ObjectMgr.h"
#include "Chat.h"
#include "AccountMgr.h"
+#include "World.h"
class gm_commandscript : public CommandScript
{
@@ -152,7 +153,7 @@ public:
static bool HandleGMListFullCommand(ChatHandler* handler, char const* /*args*/)
{
///- Get the accounts with GM Level >0
- QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= %u", SEC_MODERATOR);
+ QueryResult result = LoginDatabase.PQuery("SELECT a.username, aa.gmlevel FROM account a, account_access aa WHERE a.id=aa.id AND aa.gmlevel >= %u AND (aa.realmid = -1 OR aa.realmid = %u)", SEC_MODERATOR, realmID);
if (result)
{
handler->SendSysMessage(LANG_GMLIST);
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index 2fb6c3f0d10..74b8272201b 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -97,7 +97,7 @@ public:
// Activate
object->SetLootState(GO_READY);
- object->UseDoorOrButton(10000);
+ object->UseDoorOrButton(10000, false, handler->GetSession()->GetPlayer());
handler->PSendSysMessage("Object activated!");
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 54dac404f03..57932ef56c6 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -130,7 +130,7 @@ public:
{
uint32 tguid = chr->GetTransport()->AddNPCPassenger(0, id, chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
if (tguid > 0)
- WorldDatabase.PQuery("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
+ WorldDatabase.PExecute("INSERT INTO creature_transport (guid, npc_entry, transport_entry, TransOffsetX, TransOffsetY, TransOffsetZ, TransOffsetO) values (%u, %u, %f, %f, %f, %f, %u)", tguid, id, chr->GetTransport()->GetEntry(), chr->GetTransOffsetX(), chr->GetTransOffsetY(), chr->GetTransOffsetZ(), chr->GetTransOffsetO());
return true;
}
@@ -679,7 +679,7 @@ public:
if (target->GetTransport())
if (target->GetGUIDTransport())
- WorldDatabase.PQuery("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport());
+ WorldDatabase.PExecute("UPDATE creature_transport SET emote=%u WHERE transport_entry=%u AND guid=%u", emote, target->GetTransport()->GetEntry(), target->GetGUIDTransport());
target->SetUInt32Value(UNIT_NPC_EMOTESTATE, emote);
@@ -1036,15 +1036,14 @@ public:
}
if (/*creature->GetMotionMaster()->empty() ||*/
- creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != TARGETED_MOTION_TYPE)
+ creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != FOLLOW_MOTION_TYPE)
{
handler->PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName());
handler->SetSentErrorMessage(true);
return false;
}
- TargetedMovementGenerator<Creature> const* mgen
- = static_cast<TargetedMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
+ FollowMovementGenerator<Creature> const* mgen = static_cast<FollowMovementGenerator<Creature> const*>((creature->GetMotionMaster()->top()));
if (mgen->GetTarget() != player)
{
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index 4d8ce4ef4ed..363f7645f6f 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -404,113 +404,116 @@ public:
if (!*args)
return false;
- uint32 entry = (uint32) atoi((char*)args);
- QueryResult result = WorldDatabase.PQuery("SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = %u", entry);
- if (!result)
- {
- handler->PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry);
- if (!cInfo)
- {
- handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry);
- handler->SetSentErrorMessage(true);
- return false;
- }
+ Tokens entries(std::string(args), ' ');
- sLog->outString("Reloading creature template entry %u", entry);
-
- Field* fields = result->Fetch();
-
- const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString();
- const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString();
- const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString();
- const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32();
-
- for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
+ for (Tokens::const_iterator itr = entries.begin(); itr != entries.end(); ++itr)
{
- const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32();
+ uint32 entry = uint32(atoi(*itr));
+ QueryResult result = WorldDatabase.PQuery("SELECT difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction_A, faction_H, npcflag, speed_walk, speed_run, scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, type_flags, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, Health_mod, Mana_mod, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, questItem6, movementId, RegenHealth, equipment_id, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = %u", entry);
+ if (!result)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_CREATURETEMPLATE_NOTFOUND, entry);
+ continue;
+ }
+
+ CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(entry);
+ if (!cInfo)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_CREATURESTORAGE_NOTFOUND, entry);
+ continue;
+ }
+
+ sLog->outString("Reloading creature template entry %u", entry);
+
+ Field* fields = result->Fetch();
+
+ const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[0] = fields[0].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[1] = fields[1].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->DifficultyEntry[2] = fields[2].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->KillCredit[0] = fields[3].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->KillCredit[1] = fields[4].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->Modelid1 = fields[5].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->Modelid2 = fields[6].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->Modelid3 = fields[7].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->Modelid4 = fields[8].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->Name = fields[9].GetString();
+ const_cast<CreatureTemplate*>(cInfo)->SubName = fields[10].GetString();
+ const_cast<CreatureTemplate*>(cInfo)->IconName = fields[11].GetString();
+ const_cast<CreatureTemplate*>(cInfo)->GossipMenuId = fields[12].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->minlevel = fields[13].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->maxlevel = fields[14].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->expansion = fields[15].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->faction_A = fields[16].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->faction_H = fields[17].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->npcflag = fields[18].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->speed_walk = fields[19].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->speed_run = fields[20].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->scale = fields[21].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->rank = fields[22].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->mindmg = fields[23].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->maxdmg = fields[24].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->dmgschool = fields[25].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->attackpower = fields[26].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->dmg_multiplier = fields[27].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->baseattacktime = fields[28].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->rangeattacktime = fields[29].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->unit_class = fields[30].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->unit_flags = fields[31].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->dynamicflags = fields[32].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->family = fields[33].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->trainer_type = fields[34].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->trainer_spell = fields[35].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->trainer_class = fields[36].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->trainer_race = fields[37].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->minrangedmg = fields[38].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->maxrangedmg = fields[39].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->rangedattackpower = fields[40].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->type = fields[41].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->type_flags = fields[42].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->lootid = fields[43].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->pickpocketLootId = fields[44].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->SkinLootId = fields[45].GetUInt32();
+
+ for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
+ {
+ const_cast<CreatureTemplate*>(cInfo)->resistance[i] = fields[46 + i -1].GetUInt32();
+ }
+
+ const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString();
+ const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[67].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[68].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[69].GetFloat();
+ const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[70].GetBool();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[71].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[72].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[73].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[74].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[75].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[76].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->movementId = fields[77].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[78].GetBool();
+ const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[79].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[81].GetUInt32();
+ const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[82].GetCString());
+
+ sObjectMgr->CheckCreatureTemplate(cInfo);
}
- const_cast<CreatureTemplate*>(cInfo)->spells[0] = fields[52].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[1] = fields[53].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[2] = fields[54].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[3] = fields[55].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[4] = fields[56].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[5] = fields[57].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[6] = fields[58].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->spells[7] = fields[59].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->PetSpellDataId = fields[60].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->VehicleId = fields[61].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->mingold = fields[62].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->maxgold = fields[63].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->AIName = fields[64].GetString();
- const_cast<CreatureTemplate*>(cInfo)->MovementType = fields[65].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->InhabitType = fields[66].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->ModHealth = fields[67].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->ModMana = fields[68].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->ModArmor = fields[69].GetFloat();
- const_cast<CreatureTemplate*>(cInfo)->RacialLeader = fields[70].GetBool();
- const_cast<CreatureTemplate*>(cInfo)->questItems[0] = fields[71].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->questItems[1] = fields[72].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->questItems[2] = fields[73].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->questItems[3] = fields[74].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->questItems[4] = fields[75].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->questItems[5] = fields[76].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->movementId = fields[77].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->RegenHealth = fields[78].GetBool();
- const_cast<CreatureTemplate*>(cInfo)->equipmentId = fields[79].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->MechanicImmuneMask = fields[80].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->flags_extra = fields[81].GetUInt32();
- const_cast<CreatureTemplate*>(cInfo)->ScriptID = sObjectMgr->GetScriptId(fields[82].GetCString());
-
- sObjectMgr->CheckCreatureTemplate(cInfo);
-
handler->SendGlobalGMSysMessage("Creature template reloaded.");
return true;
}
@@ -989,7 +992,7 @@ public:
return true;
}
- static bool HandleReloadWpCommand(ChatHandler* handler, const char* args)
+ static bool HandleReloadWpCommand(ChatHandler* /*handler*/, const char* args)
{
if (*args != 'a')
sLog->outString("Re-Loading Waypoints data from 'waypoints_data'");
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp
index d3083146967..1292cdaee17 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp
+++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_balinda.cpp
@@ -27,8 +27,9 @@ enum Spells
enum Yells
{
- YELL_AGGRO = -1810023,
- YELL_EVADE = -1810024
+ YELL_AGGRO = 0,
+ YELL_EVADE = 1,
+ YELL_SALVATION = 2,
};
enum Creatures
@@ -122,7 +123,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(YELL_AGGRO, me);
+ Talk(YELL_AGGRO);
}
void JustRespawned()
@@ -185,7 +186,7 @@ public:
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
- DoScriptText(YELL_EVADE, me);
+ Talk(YELL_EVADE);
}
resetTimer = 5 * IN_MILLISECONDS;
} else resetTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp
index 959ed88be1c..8b2a95be977 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp
+++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_drekthar.cpp
@@ -31,14 +31,10 @@ enum Spells
enum Yells
{
- YELL_AGGRO = -1810000,
- YELL_EVADE = -1810001,
- YELL_RESPAWN = -1810002,
- YELL_RANDOM1 = -1810003,
- YELL_RANDOM2 = -1810004,
- YELL_RANDOM3 = -1810005,
- YELL_RANDOM4 = -1810006,
- YELL_RANDOM5 = -1810007
+ YELL_AGGRO = 0,
+ YELL_EVADE = 1,
+ YELL_RESPAWN = 2,
+ YELL_RANDOM = 3
};
class boss_drekthar : public CreatureScript
@@ -69,13 +65,13 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(YELL_AGGRO, me);
+ Talk(YELL_AGGRO);
}
void JustRespawned()
{
Reset();
- DoScriptText(YELL_RESPAWN, me);
+ Talk(YELL_RESPAWN);
}
void UpdateAI(const uint32 diff)
@@ -109,7 +105,7 @@ public:
if (YellTimer <= diff)
{
- DoScriptText(RAND(YELL_RANDOM1, YELL_RANDOM2, YELL_RANDOM3, YELL_RANDOM4, YELL_RANDOM5), me);
+ Talk(YELL_RANDOM);
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); //20 to 30 seconds
} else YellTimer -= diff;
@@ -119,7 +115,7 @@ public:
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
- DoScriptText(YELL_EVADE, me);
+ Talk(YELL_EVADE);
}
ResetTimer = 5 * IN_MILLISECONDS;
} else ResetTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp
index 95c16612aef..da53cffc99d 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp
+++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_galvangar.cpp
@@ -28,8 +28,8 @@ enum Spells
enum Yells
{
- YELL_AGGRO = -1810021,
- YELL_EVADE = -1810022
+ YELL_AGGRO = 0,
+ YELL_EVADE = 1
};
class boss_galvangar : public CreatureScript
@@ -60,7 +60,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(YELL_AGGRO, me);
+ Talk(YELL_AGGRO);
}
void JustRespawned()
@@ -109,7 +109,7 @@ public:
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
- DoScriptText(YELL_EVADE, me);
+ Talk(YELL_EVADE);
}
ResetTimer = 5 * IN_MILLISECONDS;
} else ResetTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp b/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp
index 94b5bc9a56c..54fcb9d99c2 100644
--- a/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp
+++ b/src/server/scripts/EasternKingdoms/AlteracValley/boss_vanndar.cpp
@@ -19,17 +19,12 @@
enum Yells
{
- YELL_AGGRO = -1810008,
- YELL_EVADE = -1810009,
- YELL_RESPAWN1 = -1810010,
- YELL_RESPAWN2 = -1810011,
- YELL_RANDOM1 = -1810012,
- YELL_RANDOM2 = -1810013,
- YELL_RANDOM3 = -1810014,
- YELL_RANDOM4 = -1810015,
- YELL_RANDOM5 = -1810016,
- YELL_RANDOM6 = -1810017,
- YELL_RANDOM7 = -1810018
+ YELL_AGGRO = 0,
+ YELL_EVADE = 1,
+ YELL_RESPAWN1 = -1810010, // no creature_text
+ YELL_RESPAWN2 = -1810011, // no creature_text
+ YELL_RANDOM = 2,
+ YELL_SPELL = 3,
};
enum Spells
@@ -65,7 +60,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(YELL_AGGRO, me);
+ Talk(YELL_AGGRO);
}
void JustRespawned()
@@ -99,7 +94,7 @@ public:
if (YellTimer <= diff)
{
- DoScriptText(RAND(YELL_RANDOM1, YELL_RANDOM2, YELL_RANDOM3, YELL_RANDOM4, YELL_RANDOM5, YELL_RANDOM6, YELL_RANDOM7), me);
+ Talk(YELL_RANDOM);
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); //20 to 30 seconds
} else YellTimer -= diff;
@@ -109,7 +104,7 @@ public:
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
- DoScriptText(YELL_EVADE, me);
+ Talk(YELL_EVADE);
}
ResetTimer = 5 * IN_MILLISECONDS;
} else ResetTimer -= diff;
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp
index a2e41f1af70..7a4ba5777d1 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_broodlord_lashlayer.cpp
@@ -24,14 +24,19 @@ SDCategory: Blackwing Lair
EndScriptData */
#include "ScriptPCH.h"
+enum Say
+{
+ SAY_AGGRO = -1469000,
+ SAY_LEASH = -1469001
+};
-#define SAY_AGGRO -1469000
-#define SAY_LEASH -1469001
-
-#define SPELL_CLEAVE 26350
-#define SPELL_BLASTWAVE 23331
-#define SPELL_MORTALSTRIKE 24573
-#define SPELL_KNOCKBACK 25778
+enum Spells
+{
+ SPELL_CLEAVE = 26350,
+ SPELL_BLASTWAVE = 23331,
+ SPELL_MORTALSTRIKE = 24573,
+ SPELL_KNOCKBACK = 25778
+};
class boss_broodlord : public CreatureScript
{
@@ -45,7 +50,7 @@ public:
struct boss_broodlordAI : public ScriptedAI
{
- boss_broodlordAI(Creature* c) : ScriptedAI(c) {}
+ boss_broodlordAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Cleave_Timer;
uint32 BlastWave_Timer;
@@ -54,10 +59,10 @@ public:
void Reset()
{
- Cleave_Timer = 8000; //These times are probably wrong
- BlastWave_Timer = 12000;
- MortalStrike_Timer = 20000;
- KnockBack_Timer = 30000;
+ Cleave_Timer = 8000; // These times are probably wrong
+ BlastWave_Timer = 12000;
+ MortalStrike_Timer = 20000;
+ KnockBack_Timer = 30000;
}
void EnterCombat(Unit* /*who*/)
@@ -108,7 +113,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_broodlord()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp
index 50bda73cfc6..818dcace078 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_chromaggus.cpp
@@ -71,7 +71,7 @@ public:
struct boss_chromaggusAI : public ScriptedAI
{
- boss_chromaggusAI(Creature* c) : ScriptedAI(c)
+ boss_chromaggusAI(Creature* creature) : ScriptedAI(creature)
{
//Select the 2 breaths that we are going to use until despawned
//5 possiblities for the first breath, 4 for the second, 20 total possiblites
@@ -197,9 +197,7 @@ public:
Enraged = false;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void UpdateAI(const uint32 diff)
{
@@ -297,7 +295,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_chromaggus()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp
index 09dd0138db8..c91e0fb3303 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_ebonroc.cpp
@@ -42,7 +42,7 @@ public:
struct boss_ebonrocAI : public ScriptedAI
{
- boss_ebonrocAI(Creature* c) : ScriptedAI(c) {}
+ boss_ebonrocAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ShadowFlame_Timer;
uint32 WingBuffet_Timer;
@@ -100,7 +100,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_ebonroc()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp
index 133d61422b2..c2a2350c0e8 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_firemaw.cpp
@@ -41,7 +41,7 @@ public:
struct boss_firemawAI : public ScriptedAI
{
- boss_firemawAI(Creature* c) : ScriptedAI(c) {}
+ boss_firemawAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ShadowFlame_Timer;
uint32 WingBuffet_Timer;
@@ -91,7 +91,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_firemaw()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp
index b71249dc3a3..41bcb6c5427 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_flamegor.cpp
@@ -25,11 +25,17 @@ EndScriptData */
#include "ScriptPCH.h"
-#define EMOTE_FRENZY -1469031
+enum Emotes
+{
+ EMOTE_FRENZY = -1469031
+};
-#define SPELL_SHADOWFLAME 22539
-#define SPELL_WINGBUFFET 23339
-#define SPELL_FRENZY 23342 //This spell periodically triggers fire nova
+enum Spells
+{
+ SPELL_SHADOWFLAME = 22539,
+ SPELL_WINGBUFFET = 23339,
+ SPELL_FRENZY = 23342 //This spell periodically triggers fire nova
+};
class boss_flamegor : public CreatureScript
{
@@ -43,7 +49,7 @@ public:
struct boss_flamegorAI : public ScriptedAI
{
- boss_flamegorAI(Creature* c) : ScriptedAI(c) {}
+ boss_flamegorAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ShadowFlame_Timer;
uint32 WingBuffet_Timer;
@@ -94,7 +100,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_flamegor()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp
index 506189697fe..c4e0d6ea715 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_nefarian.cpp
@@ -25,40 +25,46 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SAY_AGGRO -1469007
-#define SAY_XHEALTH -1469008
-#define SAY_SHADOWFLAME -1469009
-#define SAY_RAISE_SKELETONS -1469010
-#define SAY_SLAY -1469011
-#define SAY_DEATH -1469012
-
-#define SAY_MAGE -1469013
-#define SAY_WARRIOR -1469014
-#define SAY_DRUID -1469015
-#define SAY_PRIEST -1469016
-#define SAY_PALADIN -1469017
-#define SAY_SHAMAN -1469018
-#define SAY_WARLOCK -1469019
-#define SAY_HUNTER -1469020
-#define SAY_ROGUE -1469021
-
-#define SPELL_SHADOWFLAME_INITIAL 22972
-#define SPELL_SHADOWFLAME 22539
-#define SPELL_BELLOWINGROAR 22686
-#define SPELL_VEILOFSHADOW 7068
-#define SPELL_CLEAVE 20691
-#define SPELL_TAILLASH 23364
-#define SPELL_BONECONTRUST 23363 //23362, 23361
-
-#define SPELL_MAGE 23410 //wild magic
-#define SPELL_WARRIOR 23397 //beserk
-#define SPELL_DRUID 23398 // cat form
-#define SPELL_PRIEST 23401 // corrupted healing
-#define SPELL_PALADIN 23418 //syphon blessing
-#define SPELL_SHAMAN 23425 //totems
-#define SPELL_WARLOCK 23427 //infernals
-#define SPELL_HUNTER 23436 //bow broke
-#define SPELL_ROGUE 23414 //Paralise
+enum Say
+{
+ SAY_AGGRO = -1469007,
+ SAY_XHEALTH = -1469008,
+ SAY_SHADOWFLAME = -1469009,
+ SAY_RAISE_SKELETONS = -1469010,
+ SAY_SLAY = -1469011,
+ SAY_DEATH = -1469012,
+
+ SAY_MAGE = -1469013,
+ SAY_WARRIOR = -1469014,
+ SAY_DRUID = -1469015,
+ SAY_PRIEST = -1469016,
+ SAY_PALADIN = -1469017,
+ SAY_SHAMAN = -1469018,
+ SAY_WARLOCK = -1469019,
+ SAY_HUNTER = -1469020,
+ SAY_ROGUE = -1469021
+};
+
+enum Spells
+{
+ SPELL_SHADOWFLAME_INITIAL = 22972,
+ SPELL_SHADOWFLAME = 22539,
+ SPELL_BELLOWINGROAR = 22686,
+ SPELL_VEILOFSHADOW = 7068,
+ SPELL_CLEAVE = 20691,
+ SPELL_TAILLASH = 23364,
+ SPELL_BONECONTRUST = 23363, //23362, 23361
+
+ SPELL_MAGE = 23410, //wild magic
+ SPELL_WARRIOR = 23397, //beserk
+ SPELL_DRUID = 23398, // cat form
+ SPELL_PRIEST = 23401, // corrupted healing
+ SPELL_PALADIN = 23418, //syphon blessing
+ SPELL_SHAMAN = 23425, //totems
+ SPELL_WARLOCK = 23427, //infernals
+ SPELL_HUNTER = 23436, //bow broke
+ SPELL_ROGUE = 23414 //Paralise
+};
class boss_nefarian : public CreatureScript
{
@@ -72,7 +78,7 @@ public:
struct boss_nefarianAI : public ScriptedAI
{
- boss_nefarianAI(Creature* c) : ScriptedAI(c) {}
+ boss_nefarianAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ShadowFlame_Timer;
uint32 BellowingRoar_Timer;
@@ -86,15 +92,15 @@ public:
void Reset()
{
- ShadowFlame_Timer = 12000; //These times are probably wrong
- BellowingRoar_Timer = 30000;
- VeilOfShadow_Timer = 15000;
- Cleave_Timer = 7000;
- TailLash_Timer = 10000;
- ClassCall_Timer = 35000; //35-40 seconds
+ ShadowFlame_Timer = 12000; // These times are probably wrong
+ BellowingRoar_Timer = 30000;
+ VeilOfShadow_Timer = 15000;
+ Cleave_Timer = 7000;
+ TailLash_Timer = 10000;
+ ClassCall_Timer = 35000; // 35-40 seconds
Phase3 = false;
- DespawnTimer = 5000;
+ DespawnTimer = 5000;
}
void KilledUnit(Unit* Victim)
@@ -227,7 +233,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_nefarian()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp
index b643139a71e..a4fb4ad22a3 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_razorgore.cpp
@@ -27,15 +27,21 @@ EndScriptData */
//Razorgore Phase 2 Script
-#define SAY_EGGS_BROKEN1 -1469022
-#define SAY_EGGS_BROKEN2 -1469023
-#define SAY_EGGS_BROKEN3 -1469024
-#define SAY_DEATH -1469025
+enum Say
+{
+ SAY_EGGS_BROKEN1 = -1469022,
+ SAY_EGGS_BROKEN2 = -1469023,
+ SAY_EGGS_BROKEN3 = -1469024,
+ SAY_DEATH = -1469025
+};
-#define SPELL_CLEAVE 22540
-#define SPELL_WARSTOMP 24375
-#define SPELL_FIREBALLVOLLEY 22425
-#define SPELL_CONFLAGRATION 23023
+enum Spells
+{
+ SPELL_CLEAVE = 22540,
+ SPELL_WARSTOMP = 24375,
+ SPELL_FIREBALLVOLLEY = 22425,
+ SPELL_CONFLAGRATION = 23023
+};
class boss_razorgore : public CreatureScript
{
@@ -49,7 +55,7 @@ public:
struct boss_razorgoreAI : public ScriptedAI
{
- boss_razorgoreAI(Creature* c) : ScriptedAI(c) {}
+ boss_razorgoreAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Cleave_Timer;
uint32 WarStomp_Timer;
@@ -120,7 +126,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_razorgore()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp
index 4961d253a26..4a72bd0ca38 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_vaelastrasz.cpp
@@ -25,40 +25,46 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SAY_LINE1 -1469026
-#define SAY_LINE2 -1469027
-#define SAY_LINE3 -1469028
-#define SAY_HALFLIFE -1469029
-#define SAY_KILLTARGET -1469030
+enum Says
+{
+ SAY_LINE1 = -1469026,
+ SAY_LINE2 = -1469027,
+ SAY_LINE3 = -1469028,
+ SAY_HALFLIFE = -1469029,
+ SAY_KILLTARGET = -1469030
+};
#define GOSSIP_ITEM "Start Event <Needs Gossip Text>"
-#define SPELL_ESSENCEOFTHERED 23513
-#define SPELL_FLAMEBREATH 23461
-#define SPELL_FIRENOVA 23462
-#define SPELL_TAILSWIPE 15847
-#define SPELL_BURNINGADRENALINE 23620
-#define SPELL_CLEAVE 20684 //Chain cleave is most likely named something different and contains a dummy effect
+enum Spells
+{
+ SPELL_ESSENCEOFTHERED = 23513,
+ SPELL_FLAMEBREATH = 23461,
+ SPELL_FIRENOVA = 23462,
+ SPELL_TAILSWIPE = 15847,
+ SPELL_BURNINGADRENALINE = 23620,
+ SPELL_CLEAVE = 20684 //Chain cleave is most likely named something different and contains a dummy effect
+};
class boss_vaelastrasz : public CreatureScript
{
public:
boss_vaelastrasz() : CreatureScript("boss_vaelastrasz") { }
- void SendDefaultMenu(Player* player, Creature* creature, uint32 uiAction)
+ void SendDefaultMenu(Player* player, Creature* creature, uint32 Action)
{
- if (uiAction == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
+ if (Action == GOSSIP_ACTION_INFO_DEF + 1) //Fight time
{
player->CLOSE_GOSSIP_MENU();
CAST_AI(boss_vaelastrasz::boss_vaelAI, creature->AI())->BeginSpeech(player);
}
}
- bool OnGossipSelect(Player* player, Creature* creature, uint32 uiSender, uint32 uiAction)
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 Sender, uint32 Action)
{
player->PlayerTalkClass->ClearMenus();
- if (uiSender == GOSSIP_SENDER_MAIN)
- SendDefaultMenu(player, creature, uiAction);
+ if (Sender == GOSSIP_SENDER_MAIN)
+ SendDefaultMenu(player, creature, Action);
return true;
}
@@ -81,11 +87,11 @@ public:
struct boss_vaelAI : public ScriptedAI
{
- boss_vaelAI(Creature* c) : ScriptedAI(c)
+ boss_vaelAI(Creature* creature) : ScriptedAI(creature)
{
- c->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- c->setFaction(35);
- c->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ creature->setFaction(35);
+ creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
uint64 PlayerGUID;
@@ -102,17 +108,17 @@ public:
void Reset()
{
- PlayerGUID = 0;
- SpeechTimer = 0;
- SpeechNum = 0;
- Cleave_Timer = 8000; //These times are probably wrong
- FlameBreath_Timer = 11000;
- BurningAdrenalineCaster_Timer = 15000;
- BurningAdrenalineTank_Timer = 45000;
- FireNova_Timer = 5000;
- TailSwipe_Timer = 20000;
- HasYelled = false;
- DoingSpeech = false;
+ PlayerGUID = 0;
+ SpeechTimer = 0;
+ SpeechNum = 0;
+ Cleave_Timer = 8000; //These times are probably wrong
+ FlameBreath_Timer = 11000;
+ BurningAdrenalineCaster_Timer = 15000;
+ BurningAdrenalineTank_Timer = 45000;
+ FireNova_Timer = 5000;
+ TailSwipe_Timer = 20000;
+ HasYelled = false;
+ DoingSpeech = false;
}
void BeginSpeech(Unit* target)
@@ -213,7 +219,7 @@ public:
Unit* target = NULL;
uint8 i = 0;
- while (i < 3) // max 3 tries to get a random target with power_mana
+ while (i < 3) // max 3 tries to get a random target with power_mana
{
++i;
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); //not aggro leader
@@ -258,7 +264,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_vael()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp
index 89b34aada66..5222270df1a 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/boss_victor_nefarius.cpp
@@ -25,40 +25,49 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SAY_GAMESBEGIN_1 -1469004
-#define SAY_GAMESBEGIN_2 -1469005
-#define SAY_VAEL_INTRO -1469006 //when he corrupts Vaelastrasz
+enum Says
+{
+ SAY_GAMESBEGIN_1 = -1469004,
+ SAY_GAMESBEGIN_2 = -1469005,
+ SAY_VAEL_INTRO = -1469006 //when he corrupts Vaelastrasz
+};
#define GOSSIP_ITEM_1 "I've made no mistakes."
#define GOSSIP_ITEM_2 "You have lost your mind, Nefarius. You speak in riddles."
#define GOSSIP_ITEM_3 "Please do."
-#define CREATURE_BRONZE_DRAKANOID 14263
-#define CREATURE_BLUE_DRAKANOID 14261
-#define CREATURE_RED_DRAKANOID 14264
-#define CREATURE_GREEN_DRAKANOID 14262
-#define CREATURE_BLACK_DRAKANOID 14265
-
-#define CREATURE_CHROMATIC_DRAKANOID 14302
-#define CREATURE_NEFARIAN 11583
+enum Creatures
+{
+ CREATURE_BRONZE_DRAKANOID = 14263,
+ CREATURE_BLUE_DRAKANOID = 14261,
+ CREATURE_RED_DRAKANOID = 14264,
+ CREATURE_GREEN_DRAKANOID = 14262,
+ CREATURE_BLACK_DRAKANOID = 14265,
+
+ CREATURE_CHROMATIC_DRAKANOID = 14302,
+ CREATURE_NEFARIAN = 11583
+};
-#define ADD_X1 -7591.151855f
-#define ADD_X2 -7514.598633f
-#define ADD_Y1 -1204.051880f
-#define ADD_Y2 -1150.448853f
-#define ADD_Z1 476.800476f
-#define ADD_Z2 476.796570f
+#define ADD_X1 -7591.151855f
+#define ADD_X2 -7514.598633f
+#define ADD_Y1 -1204.051880f
+#define ADD_Y2 -1150.448853f
+#define ADD_Z1 476.800476f
+#define ADD_Z2 476.796570f
-#define NEF_X -7445
-#define NEF_Y -1332
-#define NEF_Z 536
+#define NEF_X -7445
+#define NEF_Y -1332
+#define NEF_Z 536
-#define HIDE_X -7592
-#define HIDE_Y -1264
-#define HIDE_Z 481
+#define HIDE_X -7592
+#define HIDE_Y -1264
+#define HIDE_Z 481
-#define SPELL_SHADOWBOLT 21077
-#define SPELL_FEAR 26070
+enum Spells
+{
+ SPELL_SHADOWBOLT = 21077,
+ SPELL_FEAR = 26070
+};
//This script is complicated
//Instead of morphing Victor Nefarius we will have him control phase 1
@@ -74,10 +83,10 @@ class boss_victor_nefarius : public CreatureScript
public:
boss_victor_nefarius() : CreatureScript("boss_victor_nefarius") { }
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*Sender*/, uint32 Action)
{
player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
+ switch (Action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
@@ -110,7 +119,7 @@ public:
struct boss_victor_nefariusAI : public ScriptedAI
{
- boss_victor_nefariusAI(Creature* c) : ScriptedAI(c)
+ boss_victor_nefariusAI(Creature* creature) : ScriptedAI(creature)
{
NefarianGUID = 0;
switch (urand(0, 19))
@@ -211,13 +220,13 @@ public:
void Reset()
{
- SpawnedAdds = 0;
- AddSpawnTimer = 10000;
- ShadowBoltTimer = 5000;
- FearTimer = 8000;
- ResetTimer = 900000; //On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier
- NefarianGUID = 0;
- NefCheckTime = 2000;
+ SpawnedAdds = 0;
+ AddSpawnTimer = 10000;
+ ShadowBoltTimer = 5000;
+ FearTimer = 8000;
+ ResetTimer = 900000; //On official it takes him 15 minutes(900 seconds) to reset. We are only doing 1 minute to make testing easier
+ NefarianGUID = 0;
+ NefCheckTime = 2000;
me->SetUInt32Value(UNIT_NPC_FLAGS, 1);
me->setFaction(35);
@@ -378,7 +387,6 @@ public:
}
}
};
-
};
void AddSC_boss_victor_nefarius()
diff --git a/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp
index 54c0855512f..8a9b930aa09 100644
--- a/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackwingLair/instance_blackwing_lair.cpp
@@ -24,4 +24,3 @@ SDCategory: Blackwing Lair
EndScriptData */
#include "ScriptPCH.h"
-
diff --git a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
index ecb909480c5..728446aa833 100644
--- a/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
+++ b/src/server/scripts/EasternKingdoms/Karazhan/boss_nightbane.cpp
@@ -186,7 +186,7 @@ public:
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
- return;
+ return;
if (Intro)
{
diff --git a/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.cpp b/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.cpp
index eafe55d3821..801a11fbfc8 100644
--- a/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.cpp
+++ b/src/server/scripts/EasternKingdoms/MoltenCore/molten_core.cpp
@@ -30,16 +30,19 @@ EndContentData */
#include "ScriptPCH.h"
#include "ScriptedSimpleAI.h"
-#define SPELL_CONE_OF_FIRE 19630
-#define SPELL_BITE 19771
+enum Spells
+{
+ SPELL_CONE_OF_FIRE = 19630,
+ SPELL_BITE = 19771,
-//Random Debuff (each hound has only one of these)
-#define SPELL_GROUND_STOMP 19364
-#define SPELL_ANCIENT_DREAD 19365
-#define SPELL_CAUTERIZING_FLAMES 19366
-#define SPELL_WITHERING_HEAT 19367
-#define SPELL_ANCIENT_DESPAIR 19369
-#define SPELL_ANCIENT_HYSTERIA 19372
+ //Random Debuff (each hound has only one of these)
+ SPELL_GROUND_STOMP = 19364,
+ SPELL_ANCIENT_DREAD = 19365,
+ SPELL_CAUTERIZING_FLAMES = 19366,
+ SPELL_WITHERING_HEAT = 19367,
+ SPELL_ANCIENT_DESPAIR = 19369,
+ SPELL_ANCIENT_HYSTERIA = 19372
+};
class mob_ancient_core_hound : public CreatureScript
{
@@ -75,7 +78,6 @@ public:
return ai;
}
-
};
void AddSC_molten_core()
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index 999f3fda2e4..a7d1c3ad8ba 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -1009,7 +1009,7 @@ public:
me->SetInFront(car);
me->SendMovementFlagUpdate();
car->Relocate(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1);
- car->SendMonsterStop();
+ car->StopMoving();
car->RemoveAura(SPELL_CART_DRAG);
}
me->MonsterSay(SAY_SCARLET_MINER2, LANG_UNIVERSAL, 0);
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp
index b3102f2dde7..e5886cc39d4 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_arcanist_doan.cpp
@@ -49,7 +49,7 @@ public:
struct boss_arcanist_doanAI : public ScriptedAI
{
- boss_arcanist_doanAI(Creature* c) : ScriptedAI(c) {}
+ boss_arcanist_doanAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Polymorph_Timer;
uint32 AoESilence_Timer;
@@ -105,26 +105,28 @@ public:
DoCast(target, SPELL_POLYMORPH);
Polymorph_Timer = 20000;
- } else Polymorph_Timer -= diff;
+ }
+ else Polymorph_Timer -= diff;
//AoESilence_Timer
if (AoESilence_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_AOESILENCE);
AoESilence_Timer = urand(15000, 20000);
- } else AoESilence_Timer -= diff;
+ }
+ else AoESilence_Timer -= diff;
//ArcaneExplosion_Timer
if (ArcaneExplosion_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_ARCANEEXPLOSION);
ArcaneExplosion_Timer = 8000;
- } else ArcaneExplosion_Timer -= diff;
+ }
+ else ArcaneExplosion_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_arcanist_doan()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp
index 36beecb2029..30105cc7315 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_azshir_the_sleepless.cpp
@@ -25,9 +25,12 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SPELL_CALLOFTHEGRAVE 17831
-#define SPELL_TERRIFY 7399
-#define SPELL_SOULSIPHON 7290
+enum Spells
+{
+ SPELL_CALLOFTHEGRAVE = 17831,
+ SPELL_TERRIFY = 7399,
+ SPELL_SOULSIPHON = 7290
+};
class boss_azshir_the_sleepless : public CreatureScript
{
@@ -41,7 +44,7 @@ public:
struct boss_azshir_the_sleeplessAI : public ScriptedAI
{
- boss_azshir_the_sleeplessAI(Creature* c) : ScriptedAI(c) {}
+ boss_azshir_the_sleeplessAI(Creature* creature) : ScriptedAI(creature) {}
uint32 SoulSiphon_Timer;
uint32 CallOftheGrave_Timer;
@@ -54,9 +57,7 @@ public:
Terrify_Timer = 20000;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void UpdateAI(const uint32 diff)
{
@@ -73,7 +74,8 @@ public:
return;
//SoulSiphon_Timer = 20000;
- } else SoulSiphon_Timer -= diff;
+ }
+ else SoulSiphon_Timer -= diff;
}
//CallOfTheGrave_Timer
@@ -81,19 +83,20 @@ public:
{
DoCast(me->getVictim(), SPELL_CALLOFTHEGRAVE);
CallOftheGrave_Timer = 30000;
- } else CallOftheGrave_Timer -= diff;
+ }
+ else CallOftheGrave_Timer -= diff;
//Terrify_Timer
if (Terrify_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_TERRIFY);
Terrify_Timer = 20000;
- } else Terrify_Timer -= diff;
+ }
+ else Terrify_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_azshir_the_sleepless()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp
index 794a686a550..466f940621d 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_bloodmage_thalnos.cpp
@@ -49,7 +49,7 @@ public:
struct boss_bloodmage_thalnosAI : public ScriptedAI
{
- boss_bloodmage_thalnosAI(Creature* c) : ScriptedAI(c) {}
+ boss_bloodmage_thalnosAI(Creature* creature) : ScriptedAI(creature) {}
bool HpYell;
uint32 FlameShock_Timer;
@@ -93,33 +93,36 @@ public:
{
DoCast(me->getVictim(), SPELL_FLAMESHOCK);
FlameShock_Timer = urand(10000, 15000);
- } else FlameShock_Timer -= diff;
+ }
+ else FlameShock_Timer -= diff;
//FlameSpike_Timer
if (FlameSpike_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_FLAMESPIKE);
FlameSpike_Timer = 30000;
- } else FlameSpike_Timer -= diff;
+ }
+ else FlameSpike_Timer -= diff;
//FireNova_Timer
if (FireNova_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_FIRENOVA);
FireNova_Timer = 40000;
- } else FireNova_Timer -= diff;
+ }
+ else FireNova_Timer -= diff;
//ShadowBolt_Timer
if (ShadowBolt_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_SHADOWBOLT);
ShadowBolt_Timer = 2000;
- } else ShadowBolt_Timer -= diff;
+ }
+ else ShadowBolt_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_bloodmage_thalnos()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
index 14b21504be5..77099f2e2d7 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_headless_horseman.cpp
@@ -28,59 +28,66 @@ EndScriptData */
#include "scarlet_monastery.h"
//this texts are already used by 3975 and 3976
-#define SAY_ENTRANCE -1189001
-#define SAY_REJOINED -1189002
-#define SAY_LOST_HEAD -1189003
-#define SAY_CONFLAGRATION -1189004
-#define SAY_SPROUTING_PUMPKINS -1189005
-#define SAY_PLAYER_DEATH -1189006
-#define SAY_DEATH -1189007
+enum Says
+{
+ SAY_ENTRANCE = -1189001,
+ SAY_REJOINED = -1189002,
+ SAY_LOST_HEAD = -1189003,
+ SAY_CONFLAGRATION = -1189004,
+ SAY_SPROUTING_PUMPKINS = -1189005,
+ SAY_PLAYER_DEATH = -1189006,
+ SAY_DEATH = -1189007
+};
uint32 RandomLaugh[] = {11965, 11975, 11976};
- // Entryes
-#define HH_MOUNTED 23682
-#define HH_UNHORSED 23800
-#define HEAD 23775
-#define PULSING_PUMPKIN 23694
-#define PUMPKIN_FIEND 23545
-#define HELPER 23686
-#define WISP_INVIS 24034
-
- //Spells
-#define SPELL_CLEAVE 42587
-#define SPELL_CONFLAGRATION 42380 //Phase 2, can't find real spell(Dim Fire?)
-//#define SPELL_CONFL_SPEED 22587 //8% increase speed, value 22587 from SPELL_CONFLAGRATION mains that spell?
-#define SPELL_SUMMON_PUMPKIN 42394
-
-#define SPELL_WHIRLWIND 43116
-#define SPELL_IMMUNE 42556
-#define SPELL_BODY_REGEN 42403
-#define SPELL_CONFUSE 43105
-
-#define SPELL_FLYING_HEAD 42399 //visual flying head
-#define SPELL_HEAD 42413 //visual buff, "head"
-#define SPELL_HEAD_IS_DEAD 42428 //at killing head, Phase 3
-
-#define SPELL_PUMPKIN_AURA 42280
-#define SPELL_PUMPKIN_AURA_GREEN 42294
-#define SPELL_SQUASH_SOUL 42514
-#define SPELL_SPROUTING 42281
-#define SPELL_SPROUT_BODY 42285
+enum Entry
+{
+ HH_MOUNTED = 23682,
+ HH_DISMOUNTED = 23800, // unhorsed?? wtf type of engrish was that?
+ HEAD = 23775,
+ PULSING_PUMPKIN = 23694,
+ PUMPKIN_FIEND = 23545,
+ HELPER = 23686,
+ WISP_INVIS = 24034
+};
+
+enum Spells
+{
+ SPELL_CLEAVE = 42587,
+ SPELL_CONFLAGRATION = 42380, //Phase 2, can't find real spell(Dim Fire?)
+ // SPELL_CONFL_SPEED = 22587, //8% increase speed, value 22587 from SPELL_CONFLAGRATION mains that spell?
+ SPELL_SUMMON_PUMPKIN = 42394,
+
+ SPELL_WHIRLWIND = 43116,
+ SPELL_IMMUNE = 42556,
+ SPELL_BODY_REGEN = 42403,
+ SPELL_CONFUSE = 43105,
+
+ SPELL_FLYING_HEAD = 42399, //visual flying head
+ SPELL_HEAD = 42413, //visual buff, "head"
+ SPELL_HEAD_IS_DEAD = 42428, //at killing head, Phase 3
+
+ SPELL_PUMPKIN_AURA = 42280,
+ SPELL_PUMPKIN_AURA_GREEN = 42294,
+ SPELL_SQUASH_SOUL = 42514,
+ SPELL_SPROUTING = 42281,
+ SPELL_SPROUT_BODY = 42285,
//Effects
-#define SPELL_RHYME_BIG 42909
-//#define SPELL_RHYME_SMALL 42910
-#define SPELL_HEAD_SPEAKS 43129
-#define SPELL_HEAD_LANDS 42400
-#define SPELL_BODY_FLAME 42074
-#define SPELL_HEAD_FLAME 42971
-//#define SPELL_ENRAGE_VISUAL 42438 // he uses this spell?
-#define SPELL_WISP_BLUE 42821
-#define SPELL_WISP_FLIGHT_PORT 42818
-//#define SPELL_WISP_INVIS 42823
-#define SPELL_SMOKE 42355
-#define SPELL_DEATH 42566 //not correct spell
+ SPELL_RHYME_BIG = 42909,
+ // SPELL_RHYME_SMALL = 42910,
+ SPELL_HEAD_SPEAKS = 43129,
+ SPELL_HEAD_LANDS = 42400,
+ SPELL_BODY_FLAME = 42074,
+ SPELL_HEAD_FLAME = 42971,
+ // SPELL_ENRAGE_VISUAL = 42438, // he uses this spell?
+ SPELL_WISP_BLUE = 42821,
+ SPELL_WISP_FLIGHT_PORT = 42818,
+ // SPELL_WISP_INVIS = 42823,
+ SPELL_SMOKE = 42355,
+ SPELL_DEATH = 42566 //not correct spell
+};
struct Locations
{
@@ -114,7 +121,7 @@ static Locations FlightPoint[]=
static Locations Spawn[]=
{
- {1776.27f, 1348.74f, 19.20f}, //spawn point for pumpkin shrine mob
+ {1776.27f, 1348.74f, 19.20f}, //spawn point for pumpkin shrine mob
{1765.28f, 1347.46f, 17.55f} //spawn point for smoke
};
@@ -126,7 +133,7 @@ static const char* Text[]=
"Now, know demise!"
};
-#define EMOTE_LAUGHS "Headless Horseman laughs"
+#define EMOTE_LAUGHS "Headless Horseman laughs" // needs assigned to db.
class mob_wisp_invis : public CreatureScript
{
@@ -140,7 +147,7 @@ public:
struct mob_wisp_invisAI : public ScriptedAI
{
- mob_wisp_invisAI(Creature* c) : ScriptedAI(c)
+ mob_wisp_invisAI(Creature* creature) : ScriptedAI(creature)
{
Creaturetype = delay = spell = spell2 = 0;
}
@@ -149,8 +156,8 @@ public:
uint32 delay;
uint32 spell;
uint32 spell2;
- void Reset(){}
- void EnterCombat(Unit* /*who*/){}
+ void Reset() {}
+ void EnterCombat(Unit* /*who*/) {}
void SetType(uint32 _type)
{
switch (Creaturetype = _type)
@@ -205,7 +212,6 @@ public:
}
}
};
-
};
class mob_head : public CreatureScript
@@ -220,7 +226,7 @@ public:
struct mob_headAI : public ScriptedAI
{
- mob_headAI(Creature* c) : ScriptedAI(c) {}
+ mob_headAI(Creature* creature) : ScriptedAI(creature) {}
uint64 bodyGUID;
@@ -316,7 +322,8 @@ public:
if (!me->getVictim()) return;
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveFleeing(me->getVictim());
- } else wait -= diff;
+ }
+ else wait -= diff;
if (laugh <= diff)
{
@@ -327,7 +334,8 @@ public:
if (speaker)
speaker->CastSpell(speaker, SPELL_HEAD_SPEAKS, false);
me->MonsterTextEmote(EMOTE_LAUGHS, 0);
- } else laugh -= diff;
+ }
+ else laugh -= diff;
}
else
{
@@ -339,12 +347,12 @@ public:
if (Unit* body = Unit::GetUnit((*me), bodyGUID))
body->Kill(body);
me->Kill(me);
- } else wait -= diff;
+ }
+ else wait -= diff;
}
}
}
};
-
};
class boss_headless_horseman : public CreatureScript
@@ -359,9 +367,9 @@ public:
struct boss_headless_horsemanAI : public ScriptedAI
{
- boss_headless_horsemanAI(Creature* c) : ScriptedAI(c)
+ boss_headless_horsemanAI(Creature* creature) : ScriptedAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
InstanceScript* instance;
@@ -636,7 +644,8 @@ public:
break;
}
++count;
- } else say_timer -= diff;
+ }
+ else say_timer -= diff;
}
else
{
@@ -657,7 +666,8 @@ public:
if (Creature* flame = me->SummonCreature(HELPER, Spawn[0].x, Spawn[0].y, Spawn[0].z, 0, TEMPSUMMON_TIMED_DESPAWN, 17000))
CAST_AI(mob_wisp_invis::mob_wisp_invisAI, flame->AI())->SetType(2);
burned = true;
- } else burn -= diff;
+ }
+ else burn -= diff;
break;
case 2:
if (conflagrate <= diff)
@@ -665,7 +675,8 @@ public:
if (Unit* player = SelectRandomPlayer(30.0f))
DoCast(player, SPELL_CONFLAGRATION, false);
conflagrate = urand(10000, 16000);
- } else conflagrate -= diff;
+ }
+ else conflagrate -= diff;
break;
case 3:
if (summonadds <= diff)
@@ -674,7 +685,8 @@ public:
DoCast(me, SPELL_SUMMON_PUMPKIN);
SaySound(SAY_SPROUTING_PUMPKINS);
summonadds = urand(25000, 35000);
- } else summonadds -= diff;
+ }
+ else summonadds -= diff;
break;
}
@@ -683,7 +695,8 @@ public:
laugh = urand(11000, 22000);
me->MonsterTextEmote(EMOTE_LAUGHS, 0);
DoPlaySoundToSet(me, RandomLaugh[rand()%3]);
- } else laugh -= diff;
+ }
+ else laugh -= diff;
if (UpdateVictim())
{
@@ -692,7 +705,8 @@ public:
{
DoCast(me->getVictim(), SPELL_CLEAVE);
cleave = urand(2000, 6000); //1 cleave per 2.0f-6.0fsec
- } else cleave -= diff;
+ }
+ else cleave -= diff;
}
}
else
@@ -725,13 +739,14 @@ public:
me->RemoveAurasDueToSpell(SPELL_CONFUSE);
DoCast(me, SPELL_WHIRLWIND, true);
DoCast(me, SPELL_CONFUSE);
- } else
+ }
+ else
me->RemoveAurasDueToSpell(SPELL_WHIRLWIND);
- } else whirlwind -= diff;
+ }
+ else whirlwind -= diff;
}
}
};
-
};
class mob_pulsing_pumpkin : public CreatureScript
@@ -746,7 +761,7 @@ public:
struct mob_pulsing_pumpkinAI : public ScriptedAI
{
- mob_pulsing_pumpkinAI(Creature* c) : ScriptedAI(c) {}
+ mob_pulsing_pumpkinAI(Creature* creature) : ScriptedAI(creature) {}
bool sprouted;
uint64 debuffGUID;
@@ -771,7 +786,7 @@ public:
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
}
- void EnterCombat(Unit* /*who*/){}
+ void EnterCombat(Unit* /*who*/) {}
void SpellHit(Unit* /*caster*/, const SpellInfo* spell)
{
@@ -813,7 +828,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
class go_loosely_turned_soil : public GameObjectScript
@@ -846,13 +860,13 @@ public:
//}
return true;
}
-
};
void mob_head::mob_headAI::Disappear()
{
if (withbody)
return;
+
if (bodyGUID)
{
Creature* body = Unit::GetCreature((*me), bodyGUID);
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp
index d99aabd60e8..16b90f89bb5 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_herod.cpp
@@ -26,19 +26,32 @@ EndScriptData */
#include "ScriptPCH.h"
#include "ScriptedEscortAI.h"
-#define SAY_AGGRO -1189000
-#define SAY_WHIRLWIND -1189001
-#define SAY_ENRAGE -1189002
-#define SAY_KILL -1189003
-#define EMOTE_ENRAGE -1189004
+enum Says
+{
+ SAY_AGGRO = -1189000,
+ SAY_WHIRLWIND = -1189001,
+ SAY_ENRAGE = -1189002,
+ SAY_KILL = -1189003
+};
-#define SPELL_RUSHINGCHARGE 8260
-#define SPELL_CLEAVE 15496
-#define SPELL_WHIRLWIND 8989
-#define SPELL_FRENZY 8269
+enum Emotes
+{
+ EMOTE_ENRAGE = -1189004
+};
-#define ENTRY_SCARLET_TRAINEE 6575
-#define ENTRY_SCARLET_MYRMIDON 4295
+enum Spells
+{
+ SPELL_RUSHINGCHARGE = 8260,
+ SPELL_CLEAVE = 15496,
+ SPELL_WHIRLWIND = 8989,
+ SPELL_FRENZY = 8269
+};
+
+enum Entry
+{
+ ENTRY_SCARLET_TRAINEE = 6575,
+ ENTRY_SCARLET_MYRMIDON = 4295
+};
class boss_herod : public CreatureScript
{
@@ -52,7 +65,7 @@ public:
struct boss_herodAI : public ScriptedAI
{
- boss_herodAI(Creature* c) : ScriptedAI(c) {}
+ boss_herodAI(Creature* creature) : ScriptedAI(creature) {}
bool Enrage;
@@ -102,7 +115,8 @@ public:
{
DoCast(me->getVictim(), SPELL_CLEAVE);
Cleave_Timer = 12000;
- } else Cleave_Timer -= diff;
+ }
+ else Cleave_Timer -= diff;
// Whirlwind_Timer
if (Whirlwind_Timer <= diff)
@@ -110,12 +124,12 @@ public:
DoScriptText(SAY_WHIRLWIND, me);
DoCast(me->getVictim(), SPELL_WHIRLWIND);
Whirlwind_Timer = 30000;
- } else Whirlwind_Timer -= diff;
+ }
+ else Whirlwind_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
class mob_scarlet_trainee : public CreatureScript
@@ -130,7 +144,7 @@ public:
struct mob_scarlet_traineeAI : public npc_escortAI
{
- mob_scarlet_traineeAI(Creature* c) : npc_escortAI(c)
+ mob_scarlet_traineeAI(Creature* creature) : npc_escortAI(creature)
{
Start_Timer = urand(1000, 6000);
}
@@ -138,7 +152,7 @@ public:
uint32 Start_Timer;
void Reset() {}
- void WaypointReached(uint32 /*uiPoint*/) {}
+ void WaypointReached(uint32 /*point*/) {}
void EnterCombat(Unit* /*who*/) {}
void UpdateAI(const uint32 diff)
@@ -155,7 +169,6 @@ public:
npc_escortAI::UpdateAI(diff);
}
};
-
};
void AddSC_boss_herod()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp
index 327c84327c5..a64636a4223 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_high_inquisitor_fairbanks.cpp
@@ -47,7 +47,7 @@ public:
struct boss_high_inquisitor_fairbanksAI : public ScriptedAI
{
- boss_high_inquisitor_fairbanksAI(Creature* c) : ScriptedAI(c) {}
+ boss_high_inquisitor_fairbanksAI(Creature* creature) : ScriptedAI(creature) {}
uint32 CurseOfBlood_Timer;
uint32 DispelMagic_Timer;
@@ -68,9 +68,7 @@ public:
PowerWordShield = false;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void UpdateAI(const uint32 diff)
{
@@ -82,7 +80,8 @@ public:
{
DoCast(me, SPELL_HEAL);
Heal_Timer = 30000;
- } else Heal_Timer -= diff;
+ }
+ else Heal_Timer -= diff;
//Fear_Timer
if (Fear_Timer <= diff)
@@ -91,7 +90,8 @@ public:
DoCast(target, SPELL_FEAR);
Fear_Timer = 40000;
- } else Fear_Timer -= diff;
+ }
+ else Fear_Timer -= diff;
//Sleep_Timer
if (Sleep_Timer <= diff)
@@ -100,7 +100,8 @@ public:
DoCast(target, SPELL_SLEEP);
Sleep_Timer = 30000;
- } else Sleep_Timer -= diff;
+ }
+ else Sleep_Timer -= diff;
//PowerWordShield_Timer
if (!PowerWordShield && !HealthAbovePct(25))
@@ -116,19 +117,20 @@ public:
DoCast(target, SPELL_DISPELMAGIC);
DispelMagic_Timer = 30000;
- } else DispelMagic_Timer -= diff;
+ }
+ else DispelMagic_Timer -= diff;
//CurseOfBlood_Timer
if (CurseOfBlood_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_CURSEOFBLOOD);
CurseOfBlood_Timer = 25000;
- } else CurseOfBlood_Timer -= diff;
+ }
+ else CurseOfBlood_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_high_inquisitor_fairbanks()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp
index b070a31d6ee..f311da401d4 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_houndmaster_loksey.cpp
@@ -44,7 +44,7 @@ public:
struct boss_houndmaster_lokseyAI : public ScriptedAI
{
- boss_houndmaster_lokseyAI(Creature* c) : ScriptedAI(c) {}
+ boss_houndmaster_lokseyAI(Creature* creature) : ScriptedAI(creature) {}
uint32 BloodLust_Timer;
@@ -67,12 +67,12 @@ public:
{
DoCast(me, SPELL_BLOODLUST);
BloodLust_Timer = 20000;
- } else BloodLust_Timer -= diff;
+ }
+ else BloodLust_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_houndmaster_loksey()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp
index 28c9b7ea434..058c688641f 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_interrogator_vishas.cpp
@@ -26,15 +26,18 @@ EndScriptData */
#include "ScriptPCH.h"
#include "scarlet_monastery.h"
-enum eEnums
+enum Says
{
SAY_AGGRO = -1189011,
SAY_HEALTH1 = -1189012,
SAY_HEALTH2 = -1189013,
SAY_KILL = -1189014,
- SAY_TRIGGER_VORREL = -1189015,
+ SAY_TRIGGER_VORREL = -1189015
+};
- SPELL_SHADOWWORDPAIN = 2767,
+enum Spells
+{
+ SPELL_SHADOWWORDPAIN = 2767
};
class boss_interrogator_vishas : public CreatureScript
@@ -49,7 +52,7 @@ public:
struct boss_interrogator_vishasAI : public ScriptedAI
{
- boss_interrogator_vishasAI(Creature* c) : ScriptedAI(c)
+ boss_interrogator_vishasAI(Creature* creature) : ScriptedAI(creature)
{
instance = me->GetInstanceScript();
}
@@ -108,12 +111,12 @@ public:
{
DoCast(me->getVictim(), SPELL_SHADOWWORDPAIN);
ShadowWordPain_Timer = urand(5000, 15000);
- } else ShadowWordPain_Timer -= diff;
+ }
+ else ShadowWordPain_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_interrogator_vishas()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
index 7e2d3cb6788..ec6ac34b0bb 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_mograine_and_whitemane.cpp
@@ -26,7 +26,7 @@ EndScriptData */
#include "ScriptPCH.h"
#include "scarlet_monastery.h"
-enum eEnums
+enum Says
{
//Mograine says
SAY_MO_AGGRO = -1189005,
@@ -37,7 +37,10 @@ enum eEnums
SAY_WH_INTRO = -1189008,
SAY_WH_KILL = -1189009,
SAY_WH_RESSURECT = -1189010,
+};
+enum Spells
+{
//Mograine Spells
SPELL_CRUSADERSTRIKE = 14518,
SPELL_HAMMEROFJUSTICE = 5589,
@@ -67,43 +70,43 @@ public:
{
boss_scarlet_commander_mograineAI(Creature* creature) : ScriptedAI(creature)
{
- m_instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- InstanceScript* m_instance;
+ InstanceScript* instance;
- uint32 m_uiCrusaderStrike_Timer;
- uint32 m_uiHammerOfJustice_Timer;
+ uint32 CrusaderStrike_Timer;
+ uint32 HammerOfJustice_Timer;
- bool m_bHasDied;
- bool m_bHeal;
- bool m_bFakeDeath;
+ bool _bHasDied;
+ bool _bHeal;
+ bool _bFakeDeath;
void Reset()
{
- m_uiCrusaderStrike_Timer = 10000;
- m_uiHammerOfJustice_Timer = 10000;
+ CrusaderStrike_Timer = 10000;
+ HammerOfJustice_Timer = 10000;
//Incase wipe during phase that mograine fake death
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetStandState(UNIT_STAND_STATE_STAND);
- if (m_instance)
+ if (instance)
if (me->isAlive())
- m_instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED);
+ instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED);
- m_bHasDied = false;
- m_bHeal = false;
- m_bFakeDeath = false;
+ _bHasDied = false;
+ _bHeal = false;
+ _bFakeDeath = false;
}
void JustReachedHome()
{
- if (m_instance)
+ if (instance)
{
- if (m_instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) != NOT_STARTED)
- m_instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, FAIL);
+ if (instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) != NOT_STARTED)
+ instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, FAIL);
}
}
@@ -120,18 +123,18 @@ public:
DoScriptText(SAY_MO_KILL, me);
}
- void DamageTaken(Unit* /*pDoneBy*/, uint32 &uiDamage)
+ void DamageTaken(Unit* /*doneBy*/, uint32 &damage)
{
- if (uiDamage < me->GetHealth() || m_bHasDied || m_bFakeDeath)
+ if (damage < me->GetHealth() || _bHasDied || _bFakeDeath)
return;
- if (!m_instance)
+ if (!instance)
return;
//On first death, fake death and open door, as well as initiate whitemane if exist
- if (Unit* Whitemane = Unit::GetUnit((*me), m_instance->GetData64(DATA_WHITEMANE)))
+ if (Unit* Whitemane = Unit::GetUnit((*me), instance->GetData64(DATA_WHITEMANE)))
{
- m_instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS);
+ instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, IN_PROGRESS);
Whitemane->GetMotionMaster()->MovePoint(1, 1163.113370f, 1398.856812f, 32.527786f);
@@ -150,72 +153,73 @@ public:
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetStandState(UNIT_STAND_STATE_DEAD);
- m_bHasDied = true;
- m_bFakeDeath = true;
+ _bHasDied = true;
+ _bFakeDeath = true;
- uiDamage = 0;
+ damage = 0;
}
}
- void SpellHit(Unit* /*who*/, const SpellInfo* pSpell)
+ void SpellHit(Unit* /*who*/, const SpellInfo* spell)
{
//When hit with ressurection say text
- if (pSpell->Id == SPELL_SCARLETRESURRECTION)
+ if (spell->Id == SPELL_SCARLETRESURRECTION)
{
DoScriptText(SAY_MO_RESSURECTED, me);
- m_bFakeDeath = false;
+ _bFakeDeath = false;
- if (m_instance)
- m_instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, SPECIAL);
+ if (instance)
+ instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, SPECIAL);
}
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
- if (m_bHasDied && !m_bHeal && m_instance && m_instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL)
+ if (_bHasDied && !_bHeal && instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == SPECIAL)
{
//On ressurection, stop fake death and heal whitemane and resume fight
- if (Unit* Whitemane = Unit::GetUnit((*me), m_instance->GetData64(DATA_WHITEMANE)))
+ if (Unit* Whitemane = Unit::GetUnit((*me), instance->GetData64(DATA_WHITEMANE)))
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetStandState(UNIT_STAND_STATE_STAND);
DoCast(Whitemane, SPELL_LAYONHANDS);
- m_uiCrusaderStrike_Timer = 10000;
- m_uiHammerOfJustice_Timer = 10000;
+ CrusaderStrike_Timer = 10000;
+ HammerOfJustice_Timer = 10000;
if (me->getVictim())
me->GetMotionMaster()->MoveChase(me->getVictim());
- m_bHeal = true;
+ _bHeal = true;
}
}
//This if-check to make sure mograine does not attack while fake death
- if (m_bFakeDeath)
+ if (_bFakeDeath)
return;
- //m_uiCrusaderStrike_Timer
- if (m_uiCrusaderStrike_Timer <= uiDiff)
+ //CrusaderStrike_Timer
+ if (CrusaderStrike_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_CRUSADERSTRIKE);
- m_uiCrusaderStrike_Timer = 10000;
- } else m_uiCrusaderStrike_Timer -= uiDiff;
+ CrusaderStrike_Timer = 10000;
+ }
+ else CrusaderStrike_Timer -= diff;
- //m_uiHammerOfJustice_Timer
- if (m_uiHammerOfJustice_Timer <= uiDiff)
+ //HammerOfJustice_Timer
+ if (HammerOfJustice_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_HAMMEROFJUSTICE);
- m_uiHammerOfJustice_Timer = 60000;
- } else m_uiHammerOfJustice_Timer -= uiDiff;
+ HammerOfJustice_Timer = 60000;
+ }
+ else HammerOfJustice_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
class boss_high_inquisitor_whitemane : public CreatureScript
@@ -232,37 +236,37 @@ public:
{
boss_high_inquisitor_whitemaneAI(Creature* creature) : ScriptedAI(creature)
{
- m_instance = creature->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- InstanceScript* m_instance;
+ InstanceScript* instance;
- uint32 m_uiHeal_Timer;
- uint32 m_uiPowerWordShield_Timer;
- uint32 m_uiHolySmite_Timer;
- uint32 m_uiWait_Timer;
+ uint32 Heal_Timer;
+ uint32 PowerWordShield_Timer;
+ uint32 HolySmite_Timer;
+ uint32 Wait_Timer;
- bool m_bCanResurrectCheck;
- bool m_bCanResurrect;
+ bool _bCanResurrectCheck;
+ bool _bCanResurrect;
void Reset()
{
- m_uiWait_Timer = 7000;
- m_uiHeal_Timer = 10000;
- m_uiPowerWordShield_Timer = 15000;
- m_uiHolySmite_Timer = 6000;
+ Wait_Timer = 7000;
+ Heal_Timer = 10000;
+ PowerWordShield_Timer = 15000;
+ HolySmite_Timer = 6000;
- m_bCanResurrectCheck = false;
- m_bCanResurrect = false;
+ _bCanResurrectCheck = false;
+ _bCanResurrect = false;
- if (m_instance)
+ if (instance)
if (me->isAlive())
- m_instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED);
+ instance->SetData(TYPE_MOGRAINE_AND_WHITE_EVENT, NOT_STARTED);
}
void AttackStart(Unit* who)
{
- if (m_instance && m_instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED)
+ if (instance && instance->GetData(TYPE_MOGRAINE_AND_WHITE_EVENT) == NOT_STARTED)
return;
ScriptedAI::AttackStart(who);
@@ -278,84 +282,86 @@ public:
DoScriptText(SAY_WH_KILL, me);
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
- if (m_bCanResurrect)
+ if (_bCanResurrect)
{
//When casting resuruction make sure to delay so on rez when reinstate battle deepsleep runs out
- if (m_instance && m_uiWait_Timer <= uiDiff)
+ if (instance && Wait_Timer <= diff)
{
- if (Unit* Mograine = Unit::GetUnit((*me), m_instance->GetData64(DATA_MOGRAINE)))
+ if (Unit* Mograine = Unit::GetUnit((*me), instance->GetData64(DATA_MOGRAINE)))
{
DoCast(Mograine, SPELL_SCARLETRESURRECTION);
DoScriptText(SAY_WH_RESSURECT, me);
- m_bCanResurrect = false;
+ _bCanResurrect = false;
}
}
- else m_uiWait_Timer -= uiDiff;
+ else Wait_Timer -= diff;
}
//Cast Deep sleep when health is less than 50%
- if (!m_bCanResurrectCheck && !HealthAbovePct(50))
+ if (!_bCanResurrectCheck && !HealthAbovePct(50))
{
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
DoCast(me->getVictim(), SPELL_DEEPSLEEP);
- m_bCanResurrectCheck = true;
- m_bCanResurrect = true;
+ _bCanResurrectCheck = true;
+ _bCanResurrect = true;
return;
}
//while in "resurrect-mode", don't do anything
- if (m_bCanResurrect)
+ if (_bCanResurrect)
return;
//If we are <75% hp cast healing spells at self or Mograine
- if (m_uiHeal_Timer <= uiDiff)
+ if (Heal_Timer <= diff)
{
Creature* target = NULL;
if (!HealthAbovePct(75))
target = me;
- if (m_instance)
+ if (instance)
{
- if (Creature* pMograine = Unit::GetCreature((*me), m_instance->GetData64(DATA_MOGRAINE)))
+ if (Creature* mograine = Unit::GetCreature((*me), instance->GetData64(DATA_MOGRAINE)))
{
- // checking m_bCanResurrectCheck prevents her healing Mograine while he is "faking death"
- if (m_bCanResurrectCheck && pMograine->isAlive() && !pMograine->HealthAbovePct(75))
- target = pMograine;
+ // checking _bCanResurrectCheck prevents her healing Mograine while he is "faking death"
+ if (_bCanResurrectCheck && mograine->isAlive() && !mograine->HealthAbovePct(75))
+ target = mograine;
}
}
if (target)
DoCast(target, SPELL_HEAL);
- m_uiHeal_Timer = 13000;
- } else m_uiHeal_Timer -= uiDiff;
+ Heal_Timer = 13000;
+ }
+ else Heal_Timer -= diff;
- //m_uiPowerWordShield_Timer
- if (m_uiPowerWordShield_Timer <= uiDiff)
+ //PowerWordShield_Timer
+ if (PowerWordShield_Timer <= diff)
{
DoCast(me, SPELL_POWERWORDSHIELD);
- m_uiPowerWordShield_Timer = 15000;
- } else m_uiPowerWordShield_Timer -= uiDiff;
+ PowerWordShield_Timer = 15000;
+ }
+ else PowerWordShield_Timer -= diff;
- //m_uiHolySmite_Timer
- if (m_uiHolySmite_Timer <= uiDiff)
+ //HolySmite_Timer
+ if (HolySmite_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_HOLYSMITE);
- m_uiHolySmite_Timer = 6000;
- } else m_uiHolySmite_Timer -= uiDiff;
+ HolySmite_Timer = 6000;
+ }
+ else HolySmite_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_mograine_and_whitemane()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp
index dc10cb4d60f..8035adfc33f 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/boss_scorn.cpp
@@ -25,10 +25,13 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SPELL_LICHSLAP 28873
-#define SPELL_FROSTBOLTVOLLEY 8398
-#define SPELL_MINDFLAY 17313
-#define SPELL_FROSTNOVA 15531
+enum Spells
+{
+ SPELL_LICHSLAP = 28873,
+ SPELL_FROSTBOLTVOLLEY = 8398,
+ SPELL_MINDFLAY = 17313,
+ SPELL_FROSTNOVA = 15531
+};
class boss_scorn : public CreatureScript
{
@@ -42,7 +45,7 @@ public:
struct boss_scornAI : public ScriptedAI
{
- boss_scornAI(Creature* c) : ScriptedAI(c) {}
+ boss_scornAI(Creature* creature) : ScriptedAI(creature) {}
uint32 LichSlap_Timer;
uint32 FrostboltVolley_Timer;
@@ -57,9 +60,7 @@ public:
FrostNova_Timer = 30000;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void UpdateAI(const uint32 diff)
{
@@ -71,33 +72,36 @@ public:
{
DoCast(me->getVictim(), SPELL_LICHSLAP);
LichSlap_Timer = 45000;
- } else LichSlap_Timer -= diff;
+ }
+ else LichSlap_Timer -= diff;
//FrostboltVolley_Timer
if (FrostboltVolley_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_FROSTBOLTVOLLEY);
FrostboltVolley_Timer = 20000;
- } else FrostboltVolley_Timer -= diff;
+ }
+ else FrostboltVolley_Timer -= diff;
//MindFlay_Timer
if (MindFlay_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_MINDFLAY);
MindFlay_Timer = 20000;
- } else MindFlay_Timer -= diff;
+ }
+ else MindFlay_Timer -= diff;
//FrostNova_Timer
if (FrostNova_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_FROSTNOVA);
FrostNova_Timer = 15000;
- } else FrostNova_Timer -= diff;
+ }
+ else FrostNova_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_scorn()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
index f1cddb08a69..ba0b854754e 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp
@@ -26,10 +26,13 @@ EndScriptData */
#include "ScriptPCH.h"
#include "scarlet_monastery.h"
-#define ENTRY_PUMPKIN_SHRINE 186267
-#define ENTRY_HORSEMAN 23682
-#define ENTRY_HEAD 23775
-#define ENTRY_PUMPKIN 23694
+enum Entry
+{
+ ENTRY_PUMPKIN_SHRINE = 186267,
+ ENTRY_HORSEMAN = 23682,
+ ENTRY_HEAD = 23775,
+ ENTRY_PUMPKIN = 23694
+};
#define MAX_ENCOUNTER 2
@@ -57,11 +60,11 @@ public:
uint64 VorrelGUID;
uint64 DoorHighInquisitorGUID;
- uint32 m_auiEncounter[MAX_ENCOUNTER];
+ uint32 encounter[MAX_ENCOUNTER];
void Initialize()
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ memset(&encounter, 0, sizeof(encounter));
PumpkinShrineGUID = 0;
HorsemanGUID = 0;
@@ -106,13 +109,13 @@ public:
if (data == FAIL)
DoUseDoorOrButton(DoorHighInquisitorGUID);
- m_auiEncounter[0] = data;
+ encounter[0] = data;
break;
case GAMEOBJECT_PUMPKIN_SHRINE:
HandleGameObject(PumpkinShrineGUID, false);
break;
case DATA_HORSEMAN_EVENT:
- m_auiEncounter[1] = data;
+ encounter[1] = data;
if (data == DONE)
{
for (std::set<uint64>::const_iterator itr = HorsemanAdds.begin(); itr != HorsemanAdds.end(); ++itr)
@@ -146,13 +149,12 @@ public:
uint32 GetData(uint32 type)
{
if (type == TYPE_MOGRAINE_AND_WHITE_EVENT)
- return m_auiEncounter[0];
+ return encounter[0];
if (type == DATA_HORSEMAN_EVENT)
- return m_auiEncounter[1];
+ return encounter[1];
return 0;
}
};
-
};
void AddSC_instance_scarlet_monastery()
diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h
index ca6bd1d185a..70b18919704 100644
--- a/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h
+++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/scarlet_monastery.h
@@ -19,14 +19,17 @@
#ifndef DEF_SCARLET_M
#define DEF_SCARLET_M
-#define TYPE_MOGRAINE_AND_WHITE_EVENT 1
-#define DATA_MOGRAINE 2
-#define DATA_WHITEMANE 3
-#define DATA_DOOR_WHITEMANE 4
+enum eEnums
+{
+ TYPE_MOGRAINE_AND_WHITE_EVENT = 1,
-#define DATA_HORSEMAN_EVENT 5
-#define GAMEOBJECT_PUMPKIN_SHRINE 6
+ DATA_MOGRAINE = 2,
+ DATA_WHITEMANE = 3,
+ DATA_DOOR_WHITEMANE = 4,
-#define DATA_VORREL 7
-#endif
+ DATA_HORSEMAN_EVENT = 5,
+ GAMEOBJECT_PUMPKIN_SHRINE = 6,
+ DATA_VORREL = 7
+};
+#endif
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
index d04d7af5c80..eee6b08d834 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp
@@ -325,7 +325,7 @@ class boss_akilzon : public CreatureScript
if (target)
{
target->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
- target->SendMonsterMove(x, y, me->GetPositionZ()+15, 0);
+ target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0);
}
Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000);
if (Cloud)
diff --git a/src/server/scripts/EasternKingdoms/arathi_highlands.cpp b/src/server/scripts/EasternKingdoms/arathi_highlands.cpp
index 8b6cbf26de2..e2a9717882b 100644
--- a/src/server/scripts/EasternKingdoms/arathi_highlands.cpp
+++ b/src/server/scripts/EasternKingdoms/arathi_highlands.cpp
@@ -36,16 +36,16 @@ EndContentData */
enum eEnums
{
- SAY_PROGRESS_1 = -1000264,
- SAY_PROGRESS_2 = -1000265,
- SAY_PROGRESS_3 = -1000266,
- EMOTE_PROGRESS_4 = -1000267,
- SAY_AGGRO = -1000268,
- SAY_PROGRESS_5 = -1000269,
- SAY_PROGRESS_6 = -1000270,
- SAY_PROGRESS_7 = -1000271,
- EMOTE_PROGRESS_8 = -1000272,
- SAY_PROGRESS_9 = -1000273,
+ SAY_PROGRESS_1 = 0,
+ SAY_PROGRESS_2 = 1,
+ SAY_PROGRESS_3 = 2,
+ EMOTE_PROGRESS_4 = 3,
+ SAY_AGGRO = 4,
+ SAY_PROGRESS_5 = 5,
+ SAY_PROGRESS_6 = 6,
+ SAY_PROGRESS_7 = 7,
+ EMOTE_PROGRESS_8 = 8,
+ SAY_PROGRESS_9 = 9,
QUEST_SUNKEN_TREASURE = 665,
MOB_VENGEFUL_SURGE = 2776
@@ -73,24 +73,24 @@ class npc_professor_phizzlethorpe : public CreatureScript
switch (uiPointId)
{
- case 4:DoScriptText(SAY_PROGRESS_2, me, player);break;
- case 5:DoScriptText(SAY_PROGRESS_3, me, player);break;
- case 8:DoScriptText(EMOTE_PROGRESS_4, me);break;
+ case 4:Talk(SAY_PROGRESS_2, player->GetGUID());break;
+ case 5:Talk(SAY_PROGRESS_3, player->GetGUID());break;
+ case 8:Talk(EMOTE_PROGRESS_4);break;
case 9:
{
me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
me->SummonCreature(MOB_VENGEFUL_SURGE, -2052.96f, -2142.49f, 20.15f, 1.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
break;
}
- case 10:DoScriptText(SAY_PROGRESS_5, me, player);break;
+ case 10:Talk(SAY_PROGRESS_5, player->GetGUID());break;
case 11:
- DoScriptText(SAY_PROGRESS_6, me, player);
+ Talk(SAY_PROGRESS_6, player->GetGUID());
SetRun();
break;
- case 19:DoScriptText(SAY_PROGRESS_7, me, player); break;
+ case 19:Talk(SAY_PROGRESS_7, player->GetGUID()); break;
case 20:
- DoScriptText(EMOTE_PROGRESS_8, me);
- DoScriptText(SAY_PROGRESS_9, me, player);
+ Talk(EMOTE_PROGRESS_8);
+ Talk(SAY_PROGRESS_9, player->GetGUID());
if (player)
CAST_PLR(player)->GroupEventHappens(QUEST_SUNKEN_TREASURE, me);
break;
@@ -104,7 +104,7 @@ class npc_professor_phizzlethorpe : public CreatureScript
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
}
void UpdateAI(const uint32 diff)
@@ -122,7 +122,7 @@ class npc_professor_phizzlethorpe : public CreatureScript
{
if (quest->GetQuestId() == QUEST_SUNKEN_TREASURE)
{
- DoScriptText(SAY_PROGRESS_1, creature, player);
+ creature->AI()->Talk(SAY_PROGRESS_1, player->GetGUID());
if (npc_escortAI* pEscortAI = CAST_AI(npc_professor_phizzlethorpeAI, (creature->AI())))
pEscortAI->Start(false, false, player->GetGUID(), quest);
diff --git a/src/server/scripts/EasternKingdoms/duskwood.cpp b/src/server/scripts/EasternKingdoms/duskwood.cpp
index 872137ee937..5d04489bbca 100644
--- a/src/server/scripts/EasternKingdoms/duskwood.cpp
+++ b/src/server/scripts/EasternKingdoms/duskwood.cpp
@@ -25,6 +25,14 @@ EndScriptData */
#include "ScriptPCH.h"
+enum Yells
+{
+ YELL_TWILIGHTCORRUPTOR_RESPAWN = 0,
+ YELL_TWILIGHTCORRUPTOR_AGGRO = 1,
+ YELL_TWILIGHTCORRUPTOR_KILL = 2,
+};
+
+
/*######
# at_twilight_grove
######*/
@@ -43,11 +51,11 @@ public:
TCorrupter->setFaction(14);
TCorrupter->SetMaxHealth(832750);
}
- if (Unit* CorrupterSpeaker = player->SummonCreature(1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()-1, 0, TEMPSUMMON_TIMED_DESPAWN, 15000))
+ if (Creature* CorrupterSpeaker = player->SummonCreature(1, player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()-1, 0, TEMPSUMMON_TIMED_DESPAWN, 15000))
{
CorrupterSpeaker->SetName("Twilight Corrupter");
CorrupterSpeaker->SetVisible(true);
- CorrupterSpeaker->MonsterYell("Come, $N. See what the Nightmare brings...", 0, player->GetGUID());
+ CorrupterSpeaker->AI()->Talk(YELL_TWILIGHTCORRUPTOR_RESPAWN, player->GetGUID());
}
}
return false;
@@ -89,7 +97,7 @@ public:
}
void EnterCombat(Unit* /*who*/)
{
- me->MonsterYell("The Nightmare cannot be stopped!", 0, me->GetGUID());
+ Talk(YELL_TWILIGHTCORRUPTOR_AGGRO);
}
void KilledUnit(Unit* victim)
@@ -97,7 +105,7 @@ public:
if (victim->GetTypeId() == TYPEID_PLAYER)
{
++KillCount;
- me->MonsterTextEmote("Twilight Corrupter squeezes the last bit of life out of $N and swallows their soul.", victim->GetGUID(), true);
+ Talk(YELL_TWILIGHTCORRUPTOR_KILL, victim->GetGUID());
if (KillCount == 3)
{
diff --git a/src/server/scripts/EasternKingdoms/eversong_woods.cpp b/src/server/scripts/EasternKingdoms/eversong_woods.cpp
index 7c09a740d26..4797774ef49 100644
--- a/src/server/scripts/EasternKingdoms/eversong_woods.cpp
+++ b/src/server/scripts/EasternKingdoms/eversong_woods.cpp
@@ -69,10 +69,10 @@ enum eFaction
enum eSays
{
- TEXT_SECOND_TRIAL_1 = -1000637,
- TEXT_SECOND_TRIAL_2 = -1000638,
- TEXT_SECOND_TRIAL_3 = -1000639,
- TEXT_SECOND_TRIAL_4 = -1000640,
+ TEXT_SECOND_TRIAL_1 = 0,
+ TEXT_SECOND_TRIAL_2 = 1,
+ TEXT_SECOND_TRIAL_3 = 2,
+ TEXT_SECOND_TRIAL_4 = 3,
};
struct Locations
@@ -335,16 +335,16 @@ public:
switch (paladinPhase)
{
case 0:
- DoScriptText(TEXT_SECOND_TRIAL_1, me);
+ Talk(TEXT_SECOND_TRIAL_1);
break;
case 1:
- DoScriptText(TEXT_SECOND_TRIAL_2, me);
+ Talk(TEXT_SECOND_TRIAL_2);
break;
case 2:
- DoScriptText(TEXT_SECOND_TRIAL_3, me);
+ Talk(TEXT_SECOND_TRIAL_3);
break;
case 3:
- DoScriptText(TEXT_SECOND_TRIAL_4, me);
+ Talk(TEXT_SECOND_TRIAL_4);
break;
}
}
diff --git a/src/server/scripts/EasternKingdoms/ghostlands.cpp b/src/server/scripts/EasternKingdoms/ghostlands.cpp
index a5a8bd45cfd..412613572f1 100644
--- a/src/server/scripts/EasternKingdoms/ghostlands.cpp
+++ b/src/server/scripts/EasternKingdoms/ghostlands.cpp
@@ -34,45 +34,6 @@ EndContentData */
#include "ScriptedEscortAI.h"
/*######
-## npc_blood_knight_dawnstar
-######*/
-
-#define GOSSIP_H_BKD "Take Blood Knight Insignia"
-
-class npc_blood_knight_dawnstar : public CreatureScript
-{
-public:
- npc_blood_knight_dawnstar() : CreatureScript("npc_blood_knight_dawnstar") { }
-
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- if (uiAction == GOSSIP_ACTION_INFO_DEF+1)
- {
- ItemPosCountVec dest;
- uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, 24226, 1, NULL);
- if (msg == EQUIP_ERR_OK)
- {
- player->StoreNewItem(dest, 24226, 1, true);
- player->PlayerTalkClass->ClearMenus();
- }
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (player->GetQuestStatus(9692) == QUEST_STATUS_INCOMPLETE && !player->HasItemCount(24226, 1, true))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_H_BKD, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_budd_nedreck
######*/
@@ -255,7 +216,6 @@ public:
void AddSC_ghostlands()
{
- new npc_blood_knight_dawnstar();
new npc_budd_nedreck();
new npc_rathis_tomber();
new npc_ranger_lilatha();
diff --git a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/silverpine_forest.cpp
index e166013a4b2..4d897c4f3b8 100644
--- a/src/server/scripts/EasternKingdoms/silverpine_forest.cpp
+++ b/src/server/scripts/EasternKingdoms/silverpine_forest.cpp
@@ -19,12 +19,11 @@
/* ScriptData
SDName: Silverpine_Forest
SD%Complete: 100
-SDComment: Quest support: 1886, 435, 452
+SDComment: Quest support: 435, 452
SDCategory: Silverpine Forest
EndScriptData */
/* ContentData
-npc_astor_hadren
npc_deathstalker_erland
pyrewood_ambush
EndContentData */
@@ -33,73 +32,6 @@ EndContentData */
#include "ScriptedEscortAI.h"
/*######
-## npc_astor_hadren
-######*/
-
-#define GOSSIP_HAH "You're Astor Hadren, right?"
-#define GOSSIP_SAH "You've got something I need, Astor. And I'll be taking it now."
-
-class npc_astor_hadren : public CreatureScript
-{
-public:
- npc_astor_hadren() : CreatureScript("npc_astor_hadren") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_astor_hadrenAI(creature);
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF + 1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SAH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(624, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF + 2:
- player->CLOSE_GOSSIP_MENU();
- creature->setFaction(21);
- if (player)
- CAST_AI(npc_astor_hadren::npc_astor_hadrenAI, creature->AI())->AttackStart(player);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (player->GetQuestStatus(1886) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HAH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
-
- player->SEND_GOSSIP_MENU(623, creature->GetGUID());
-
- return true;
- }
-
- struct npc_astor_hadrenAI : public ScriptedAI
- {
- npc_astor_hadrenAI(Creature* c) : ScriptedAI(c) {}
-
- void Reset()
- {
- me->setFaction(68);
- }
-
- void EnterCombat(Unit* /*who*/)
- {
- }
-
- void JustDied(Unit* /*who*/)
- {
- me->setFaction(68);
- }
- };
-
-};
-
-/*######
## npc_deathstalker_erland
######*/
@@ -386,7 +318,6 @@ public:
void AddSC_silverpine_forest()
{
- new npc_astor_hadren();
new npc_deathstalker_erland();
new pyrewood_ambush();
}
diff --git a/src/server/scripts/EasternKingdoms/stormwind_city.cpp b/src/server/scripts/EasternKingdoms/stormwind_city.cpp
index 4d43e4adefe..a4eca1950f8 100644
--- a/src/server/scripts/EasternKingdoms/stormwind_city.cpp
+++ b/src/server/scripts/EasternKingdoms/stormwind_city.cpp
@@ -26,7 +26,6 @@ EndScriptData */
/* ContentData
npc_archmage_malin
npc_bartleby
-npc_dashel_stonefist
npc_lady_katrana_prestor
npc_tyrion
npc_tyrion_spybot
@@ -148,78 +147,6 @@ public:
};
/*######
-## npc_dashel_stonefist
-######*/
-
-enum eDashel
-{
- QUEST_MISSING_DIPLO_PT8 = 1447,
- FACTION_HOSTILE = 168
-};
-
-class npc_dashel_stonefist : public CreatureScript
-{
-public:
- npc_dashel_stonefist() : CreatureScript("npc_dashel_stonefist") { }
-
- bool OnQuestAccept(Player* player, Creature* creature, Quest const* quest)
- {
- if (quest->GetQuestId() == QUEST_MISSING_DIPLO_PT8)
- {
- creature->setFaction(FACTION_HOSTILE);
- CAST_AI(npc_dashel_stonefist::npc_dashel_stonefistAI, creature->AI())->AttackStart(player);
- }
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_dashel_stonefistAI(creature);
- }
-
- struct npc_dashel_stonefistAI : public ScriptedAI
- {
- npc_dashel_stonefistAI(Creature* c) : ScriptedAI(c)
- {
- m_uiNormalFaction = c->getFaction();
- }
-
- uint32 m_uiNormalFaction;
-
- void Reset()
- {
- if (me->getFaction() != m_uiNormalFaction)
- me->setFaction(m_uiNormalFaction);
- }
-
- void AttackedBy(Unit* pAttacker)
- {
- if (me->getVictim())
- return;
-
- if (me->IsFriendlyTo(pAttacker))
- return;
-
- AttackStart(pAttacker);
- }
-
- void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
- {
- if (uiDamage > me->GetHealth() || me->HealthBelowPctDamaged(15, uiDamage))
- {
- uiDamage = 0;
-
- if (pDoneBy->GetTypeId() == TYPEID_PLAYER)
- CAST_PLR(pDoneBy)->AreaExploredOrEventHappens(QUEST_MISSING_DIPLO_PT8);
-
- EnterEvadeMode();
- }
- }
- };
-
-};
-
-/*######
## npc_lady_katrana_prestor
######*/
@@ -716,7 +643,6 @@ void AddSC_stormwind_city()
{
new npc_archmage_malin();
new npc_bartleby();
- new npc_dashel_stonefist();
new npc_lady_katrana_prestor();
new npc_tyrion();
new npc_tyrion_spybot();
diff --git a/src/server/scripts/EasternKingdoms/undercity.cpp b/src/server/scripts/EasternKingdoms/undercity.cpp
index f1c0fba2e29..fe9c40e6dbd 100644
--- a/src/server/scripts/EasternKingdoms/undercity.cpp
+++ b/src/server/scripts/EasternKingdoms/undercity.cpp
@@ -109,7 +109,7 @@ public:
{
if (Creature* target = Unit::GetCreature(*summoned, targetGUID))
{
- target->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0);
+ target->MonsterMoveWithSpeed(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0);
target->SetPosition(target->GetPositionX(), target->GetPositionY(), me->GetPositionZ()+15.0f, 0.0f);
summoned->CastSpell(target, SPELL_RIBBON_OF_SOULS, false);
}
@@ -186,7 +186,7 @@ public:
if (EventMove_Timer <= diff)
{
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
- me->SendMonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, 5000);
+ me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetDistance(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW) / (5000 * 0.001f));
me->SetPosition(me->GetPositionX(), me->GetPositionY(), HIGHBORNE_LOC_Y_NEW, me->GetOrientation());
EventMove = false;
} else EventMove_Timer -= diff;
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
index 29029803369..878116ad476 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
@@ -43,7 +43,6 @@ public:
player->AddAura(SPELL_BLESSING_OF_BLACKFATHOM, player);
return true;
}
-
};
class go_blackfathom_fire : public GameObjectScript
@@ -64,7 +63,6 @@ public:
}
return false;
}
-
};
class npc_blackfathom_deeps_event : public CreatureScript
@@ -92,9 +90,9 @@ public:
InstanceScript* instance;
- uint32 uiRavageTimer;
- uint32 uiFrostNovaTimer;
- uint32 uiFrostBoltVolleyTimer;
+ uint32 ravageTimer;
+ uint32 frostNovaTimer;
+ uint32 frostBoltVolleyTimer;
bool bFlee;
@@ -102,9 +100,9 @@ public:
{
bFlee = false;
- uiRavageTimer = urand(5000, 8000);
- uiFrostNovaTimer = urand(9000, 12000);
- uiFrostBoltVolleyTimer = urand(2000, 4000);
+ ravageTimer = urand(5000, 8000);
+ frostNovaTimer = urand(9000, 12000);
+ frostBoltVolleyTimer = urand(2000, 4000);
}
void AttackPlayer()
@@ -131,7 +129,7 @@ public:
}
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
@@ -140,11 +138,11 @@ public:
{
case NPC_AKU_MAI_SNAPJAW:
{
- if (uiRavageTimer <= uiDiff)
+ if (ravageTimer <= diff)
{
DoCast(me->getVictim(), SPELL_RAVAGE);
- uiRavageTimer = urand(9000, 14000);
- } else uiRavageTimer -= uiDiff;
+ ravageTimer = urand(9000, 14000);
+ } else ravageTimer -= diff;
break;
}
case NPC_MURKSHALLOW_SOFTSHELL:
@@ -159,20 +157,23 @@ public:
}
case NPC_AKU_MAI_SERVANT:
{
- if (uiFrostBoltVolleyTimer <= uiDiff)
+ if (frostBoltVolleyTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
if (target)
DoCast(target, SPELL_FROST_BOLT_VOLLEY);
}
- uiFrostBoltVolleyTimer = urand(5000, 8000);
- } else uiFrostBoltVolleyTimer -= uiDiff;
- if (uiFrostNovaTimer <= uiDiff)
+ frostBoltVolleyTimer = urand(5000, 8000);
+ }
+ else frostBoltVolleyTimer -= diff;
+
+ if (frostNovaTimer <= diff)
{
DoCastAOE(SPELL_FROST_NOVA, false);
- uiFrostNovaTimer = urand(25000, 30000);
- } else uiFrostNovaTimer -= uiDiff;
+ frostNovaTimer = urand(25000, 30000);
+ }
+ else frostNovaTimer -= diff;
break;
}
}
@@ -187,7 +188,6 @@ public:
instance->SetData(DATA_EVENT, instance->GetData(DATA_EVENT) + 1);
}
};
-
};
enum eMorridune
@@ -201,12 +201,12 @@ class npc_morridune : public CreatureScript
public:
npc_morridune() : CreatureScript("npc_morridune") { }
- bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*uiSender*/, uint32 uiAction)
+ bool OnGossipSelect(Player* player, Creature* /*creature*/, uint32 /*Sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
+ switch (action)
{
- case GOSSIP_ACTION_INFO_DEF+1:
+ case GOSSIP_ACTION_INFO_DEF + 1:
player->TeleportTo(1, 9952.239f, 2284.277f, 1341.394f, 1.595f);
player->CLOSE_GOSSIP_MENU();
break;
@@ -216,7 +216,7 @@ public:
bool OnGossipHello(Player* player, Creature* creature)
{
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MORRIDUNE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_MORRIDUNE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
return true;
@@ -250,7 +250,6 @@ public:
}
}
};
-
};
void AddSC_blackfathom_deeps()
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
index 87e8478532d..32a6bcbde77 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
@@ -36,19 +36,19 @@ public:
struct boss_aku_maiAI : public ScriptedAI
{
- boss_aku_maiAI(Creature* c) : ScriptedAI(c)
+ boss_aku_maiAI(Creature* creature) : ScriptedAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- uint32 uiPoisonCloudTimer;
+ uint32 poisonCloudTimer;
bool bIsEnraged;
InstanceScript* instance;
void Reset()
{
- uiPoisonCloudTimer = urand(5000, 9000);
+ poisonCloudTimer = urand(5000, 9000);
bIsEnraged = false;
if (instance)
instance->SetData(TYPE_AKU_MAI, NOT_STARTED);
@@ -71,11 +71,11 @@ public:
if (!UpdateVictim())
return;
- if (uiPoisonCloudTimer < diff)
+ if (poisonCloudTimer < diff)
{
DoCastVictim(SPELL_POISON_CLOUD);
- uiPoisonCloudTimer = urand(25000, 50000);
- } else uiPoisonCloudTimer -= diff;
+ poisonCloudTimer = urand(25000, 50000);
+ } else poisonCloudTimer -= diff;
if (!bIsEnraged && HealthBelowPct(30))
{
@@ -86,7 +86,6 @@ public:
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_aku_mai()
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
index e7822a6edb3..5a60a849b75 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
@@ -35,18 +35,18 @@ public:
struct boss_gelihastAI : public ScriptedAI
{
- boss_gelihastAI(Creature* c) : ScriptedAI(c)
+ boss_gelihastAI(Creature* creature) : ScriptedAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- uint32 uiNetTimer;
+ uint32 netTimer;
InstanceScript* instance;
void Reset()
{
- uiNetTimer = urand(2000, 4000);
+ netTimer = urand(2000, 4000);
if (instance)
instance->SetData(TYPE_GELIHAST, NOT_STARTED);
}
@@ -68,16 +68,15 @@ public:
if (!UpdateVictim())
return;
- if (uiNetTimer < diff)
+ if (netTimer < diff)
{
DoCastVictim(SPELL_NET);
- uiNetTimer = urand(4000, 7000);
- } else uiNetTimer -= diff;
+ netTimer = urand(4000, 7000);
+ } else netTimer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_gelihast()
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
index 5823ed15ed5..7ee17172102 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
@@ -44,20 +44,20 @@ public:
struct boss_kelrisAI : public ScriptedAI
{
- boss_kelrisAI(Creature* c) : ScriptedAI(c)
+ boss_kelrisAI(Creature* creature) : ScriptedAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
- uint32 uiMindBlastTimer;
- uint32 uiSleepTimer;
+ uint32 mindBlastTimer;
+ uint32 sleepTimer;
InstanceScript* instance;
void Reset()
{
- uiMindBlastTimer = urand(2000, 5000);
- uiSleepTimer = urand(9000, 12000);
+ mindBlastTimer = urand(2000, 5000);
+ sleepTimer = urand(9000, 12000);
if (instance)
instance->SetData(TYPE_KELRIS, NOT_STARTED);
}
@@ -81,26 +81,25 @@ public:
if (!UpdateVictim())
return;
- if (uiMindBlastTimer < diff)
+ if (mindBlastTimer < diff)
{
DoCastVictim(SPELL_MIND_BLAST);
- uiMindBlastTimer = urand(7000, 9000);
- } else uiMindBlastTimer -= diff;
+ mindBlastTimer = urand(7000, 9000);
+ } else mindBlastTimer -= diff;
- if (uiSleepTimer < diff)
+ if (sleepTimer < diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
DoScriptText(SAY_SLEEP, me);
DoCast(target, SPELL_SLEEP);
}
- uiSleepTimer = urand(15000, 20000);
- } else uiSleepTimer -= diff;
+ sleepTimer = urand(15000, 20000);
+ } else sleepTimer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_kelris()
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
index 8dd4e60f281..ea33499a960 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
@@ -65,33 +65,33 @@ public:
{
instance_blackfathom_deeps_InstanceMapScript(Map* map) : InstanceScript(map) {}
- uint64 m_uiTwilightLordKelrisGUID;
- uint64 m_uiShrine1GUID;
- uint64 m_uiShrine2GUID;
- uint64 m_uiShrine3GUID;
- uint64 m_uiShrine4GUID;
- uint64 m_uiShrineOfGelihastGUID;
- uint64 m_uiAltarOfTheDeepsGUID;
- uint64 m_uiMainDoorGUID;
+ uint64 twilightLordKelrisGUID;
+ uint64 shrine1GUID;
+ uint64 shrine2GUID;
+ uint64 shrine3GUID;
+ uint64 shrine4GUID;
+ uint64 shrineOfGelihastGUID;
+ uint64 altarOfTheDeepsGUID;
+ uint64 mainDoorGUID;
- uint8 m_auiEncounter[MAX_ENCOUNTER];
- uint8 m_uiCountFires;
- uint8 uiDeathTimes;
+ uint8 encounter[MAX_ENCOUNTER];
+ uint8 countFires;
+ uint8 deathTimes;
void Initialize()
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ memset(&encounter, 0, sizeof(encounter));
- m_uiTwilightLordKelrisGUID = 0;
- m_uiShrine1GUID = 0;
- m_uiShrine2GUID = 0;
- m_uiShrine3GUID = 0;
- m_uiShrine4GUID = 0;
- m_uiShrineOfGelihastGUID = 0;
- m_uiAltarOfTheDeepsGUID = 0;
- m_uiMainDoorGUID = 0;
- m_uiCountFires = 0;
- uiDeathTimes = 0;
+ twilightLordKelrisGUID = 0;
+ shrine1GUID = 0;
+ shrine2GUID = 0;
+ shrine3GUID = 0;
+ shrine4GUID = 0;
+ shrineOfGelihastGUID = 0;
+ altarOfTheDeepsGUID = 0;
+ mainDoorGUID = 0;
+ countFires = 0;
+ deathTimes = 0;
}
void OnCreatureCreate(Creature* creature)
@@ -99,7 +99,7 @@ public:
switch (creature->GetEntry())
{
case NPC_TWILIGHT_LORD_KELRIS:
- m_uiTwilightLordKelrisGUID = creature->GetGUID();
+ twilightLordKelrisGUID = creature->GetGUID();
break;
case NPC_LORGUS_JETT:
creature->SetHomePosition(LorgusPosition[urand(0, 3)]);
@@ -112,150 +112,149 @@ public:
switch (go->GetEntry())
{
case GO_FIRE_OF_AKU_MAI_1:
- m_uiShrine1GUID = go->GetGUID();
+ shrine1GUID = go->GetGUID();
break;
case GO_FIRE_OF_AKU_MAI_2:
- m_uiShrine2GUID = go->GetGUID();
+ shrine2GUID = go->GetGUID();
break;
case GO_FIRE_OF_AKU_MAI_3:
- m_uiShrine3GUID = go->GetGUID();
+ shrine3GUID = go->GetGUID();
break;
case GO_FIRE_OF_AKU_MAI_4:
- m_uiShrine4GUID = go->GetGUID();
+ shrine4GUID = go->GetGUID();
break;
case GO_SHRINE_OF_GELIHAST:
- m_uiShrineOfGelihastGUID = go->GetGUID();
- if (m_auiEncounter[0] != DONE)
+ shrineOfGelihastGUID = go->GetGUID();
+ if (encounter[0] != DONE)
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case GO_ALTAR_OF_THE_DEEPS:
- m_uiAltarOfTheDeepsGUID = go->GetGUID();
- if (m_auiEncounter[3] != DONE)
+ altarOfTheDeepsGUID = go->GetGUID();
+ if (encounter[3] != DONE)
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case GO_AKU_MAI_DOOR:
- if (m_auiEncounter[2] == DONE)
+ if (encounter[2] == DONE)
HandleGameObject(0, true, go);
- m_uiMainDoorGUID = go->GetGUID();
+ mainDoorGUID = go->GetGUID();
break;
}
}
- void SetData(uint32 uiType, uint32 uiData)
+ void SetData(uint32 type, uint32 data)
{
- switch (uiType)
+ switch (type)
{
case TYPE_GELIHAST:
- m_auiEncounter[0] = uiData;
- if (uiData == DONE)
- if (GameObject* go = instance->GetGameObject(m_uiShrineOfGelihastGUID))
+ encounter[0] = data;
+ if (data == DONE)
+ if (GameObject* go = instance->GetGameObject(shrineOfGelihastGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
break;
case TYPE_AKU_MAI:
- m_auiEncounter[3] = uiData;
- if (uiData == DONE)
- if (GameObject* go = instance->GetGameObject(m_uiAltarOfTheDeepsGUID))
+ encounter[3] = data;
+ if (data == DONE)
+ if (GameObject* go = instance->GetGameObject(altarOfTheDeepsGUID))
{
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
go->SummonCreature(NPC_MORRIDUNE, SpawnsLocation[4], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
}
break;
case DATA_FIRE:
- m_uiCountFires = uiData;
- switch (m_uiCountFires)
+ countFires = data;
+ switch (countFires)
{
case 1:
- if (GameObject* pGO = instance->GetGameObject(m_uiShrine1GUID))
+ if (GameObject* go = instance->GetGameObject(shrine1GUID))
{
- pGO->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SNAPJAW, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
}
break;
case 2:
- if (GameObject* pGO = instance->GetGameObject(m_uiShrine1GUID))
+ if (GameObject* go = instance->GetGameObject(shrine1GUID))
{
for (uint8 i = 0; i < 2; ++i)
{
- pGO->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_MURKSHALLOW_SOFTSHELL, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
}
}
break;
case 3:
- if (GameObject* pGO = instance->GetGameObject(m_uiShrine1GUID))
+ if (GameObject* go = instance->GetGameObject(shrine1GUID))
{
- pGO->SummonCreature(NPC_AKU_MAI_SERVANT, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_AKU_MAI_SERVANT, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SERVANT, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_AKU_MAI_SERVANT, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
}
break;
case 4:
- if (GameObject* pGO = instance->GetGameObject(m_uiShrine1GUID))
+ if (GameObject* go = instance->GetGameObject(shrine1GUID))
{
- pGO->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
- pGO->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
+ go->SummonCreature(NPC_BARBED_CRUSTACEAN, SpawnsLocation[3], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300000);
}
break;
}
break;
case DATA_EVENT:
- uiDeathTimes = uiData;
- if (uiDeathTimes == 18)
- HandleGameObject(m_uiMainDoorGUID, true);
+ deathTimes = data;
+ if (deathTimes == 18)
+ HandleGameObject(mainDoorGUID, true);
break;
}
}
- uint32 GetData(uint32 uiType)
+ uint32 GetData(uint32 type)
{
- switch (uiType)
+ switch (type)
{
case TYPE_GELIHAST:
- return m_auiEncounter[0];
+ return encounter[0];
case TYPE_KELRIS:
- return m_auiEncounter[1];
+ return encounter[1];
case TYPE_SHRINE:
- return m_auiEncounter[2];
+ return encounter[2];
case TYPE_AKU_MAI:
- return m_auiEncounter[3];
+ return encounter[3];
case DATA_FIRE:
- return m_uiCountFires;
+ return countFires;
case DATA_EVENT:
- return uiDeathTimes;
+ return deathTimes;
}
return 0;
}
- uint64 GetData64(uint32 uiData)
+ uint64 GetData64(uint32 data)
{
- switch (uiData)
+ switch (data)
{
case DATA_TWILIGHT_LORD_KELRIS:
- return m_uiTwilightLordKelrisGUID;
+ return twilightLordKelrisGUID;
case DATA_SHRINE1:
- return m_uiShrine1GUID;
+ return shrine1GUID;
case DATA_SHRINE2:
- return m_uiShrine2GUID;
+ return shrine2GUID;
case DATA_SHRINE3:
- return m_uiShrine3GUID;
+ return shrine3GUID;
case DATA_SHRINE4:
- return m_uiShrine4GUID;
+ return shrine4GUID;
case DATA_SHRINE_OF_GELIHAST:
- return m_uiShrineOfGelihastGUID;
+ return shrineOfGelihastGUID;
case DATA_MAINDOOR:
- return m_uiMainDoorGUID;
+ return mainDoorGUID;
}
return 0;
}
};
-
};
void AddSC_instance_blackfathom_deeps()
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
index ad0a36da84e..6cdb794bf5e 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.cpp
@@ -234,53 +234,53 @@ public:
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
- npc_arthasAI* pAI = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
+ npc_arthasAI* ai = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
- if (!pAI)
+ if (!ai)
return false;
switch (action)
{
case GOSSIP_ACTION_INFO_DEF:
- pAI->Start(true, true, player->GetGUID(), 0, false, false);
- pAI->SetDespawnAtEnd(false);
- pAI->bStepping = false;
- pAI->uiStep = 1;
+ ai->Start(true, true, player->GetGUID(), 0, false, false);
+ ai->SetDespawnAtEnd(false);
+ ai->bStepping = false;
+ ai->uiStep = 1;
break;
case GOSSIP_ACTION_INFO_DEF+1:
- pAI->bStepping = true;
- pAI->uiStep = 24;
+ ai->bStepping = true;
+ ai->uiStep = 24;
break;
case GOSSIP_ACTION_INFO_DEF+2:
- pAI->SetHoldState(false);
- pAI->bStepping = false;
- pAI->uiStep = 61;
+ ai->SetHoldState(false);
+ ai->bStepping = false;
+ ai->uiStep = 61;
break;
case GOSSIP_ACTION_INFO_DEF+3:
- pAI->SetHoldState(false);
+ ai->SetHoldState(false);
break;
case GOSSIP_ACTION_INFO_DEF+4:
- pAI->bStepping = true;
- pAI->uiStep = 84;
+ ai->bStepping = true;
+ ai->uiStep = 84;
break;
case GOSSIP_ACTION_INFO_DEF+5:
- pAI->bStepping = true;
- pAI->uiStep = 85;
+ ai->bStepping = true;
+ ai->uiStep = 85;
break;
}
player->CLOSE_GOSSIP_MENU();
- pAI->SetDespawnAtFar(true);
+ ai->SetDespawnAtFar(true);
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
return true;
}
bool OnGossipHello(Player* player, Creature* creature)
{
- npc_arthasAI* pAI = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
+ npc_arthasAI* ai = CAST_AI(npc_arthas::npc_arthasAI, creature->AI());
- if (pAI && pAI->bStepping == false)
+ if (ai && ai->bStepping == false)
{
- switch (pAI->uiGossipStep)
+ switch (ai->uiGossipStep)
{
case 0: //This one is a workaround since the very beggining of the script is wrong.
{
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
index 0010db68673..74e7a919263 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
@@ -25,9 +25,12 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SPELL_WRATH 21807
-#define SPELL_ENTANGLINGROOTS 12747
-#define SPELL_CORRUPT_FORCES 21968
+enum Spells
+{
+ SPELL_WRATH = 21807,
+ SPELL_ENTANGLINGROOTS = 12747,
+ SPELL_CORRUPT_FORCES = 21968
+};
class celebras_the_cursed : public CreatureScript
{
@@ -41,7 +44,7 @@ public:
struct celebras_the_cursedAI : public ScriptedAI
{
- celebras_the_cursedAI(Creature* c) : ScriptedAI(c) {}
+ celebras_the_cursedAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Wrath_Timer;
uint32 EntanglingRoots_Timer;
@@ -74,14 +77,16 @@ public:
if (target)
DoCast(target, SPELL_WRATH);
Wrath_Timer = 8000;
- } else Wrath_Timer -= diff;
+ }
+ else Wrath_Timer -= diff;
//EntanglingRoots
if (EntanglingRoots_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_ENTANGLINGROOTS);
EntanglingRoots_Timer = 20000;
- } else EntanglingRoots_Timer -= diff;
+ }
+ else EntanglingRoots_Timer -= diff;
//CorruptForces
if (CorruptForces_Timer <= diff)
@@ -89,12 +94,12 @@ public:
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_CORRUPT_FORCES);
CorruptForces_Timer = 20000;
- } else CorruptForces_Timer -= diff;
+ }
+ else CorruptForces_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_celebras_the_cursed()
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
index fdb5207acd5..418bf3a09ce 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
@@ -25,9 +25,12 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SPELL_KNOCKAWAY 18670
-#define SPELL_TRAMPLE 5568
-#define SPELL_LANDSLIDE 21808
+enum Spells
+{
+ SPELL_KNOCKAWAY = 18670,
+ SPELL_TRAMPLE = 5568,
+ SPELL_LANDSLIDE = 21808
+};
class boss_landslide : public CreatureScript
{
@@ -41,7 +44,7 @@ public:
struct boss_landslideAI : public ScriptedAI
{
- boss_landslideAI(Creature* c) : ScriptedAI(c) {}
+ boss_landslideAI(Creature* creature) : ScriptedAI(creature) {}
uint32 KnockAway_Timer;
uint32 Trample_Timer;
@@ -68,14 +71,16 @@ public:
{
DoCast(me->getVictim(), SPELL_KNOCKAWAY);
KnockAway_Timer = 15000;
- } else KnockAway_Timer -= diff;
+ }
+ else KnockAway_Timer -= diff;
//Trample_Timer
if (Trample_Timer <= diff)
{
DoCast(me, SPELL_TRAMPLE);
Trample_Timer = 8000;
- } else Trample_Timer -= diff;
+ }
+ else Trample_Timer -= diff;
//Landslide
if (HealthBelowPct(50))
@@ -85,13 +90,13 @@ public:
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_LANDSLIDE);
Landslide_Timer = 60000;
- } else Landslide_Timer -= diff;
+ }
+ else Landslide_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_landslide()
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
index 2d4c817ffe2..0e3ee5dc52b 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
@@ -24,9 +24,11 @@ SDCategory: Maraudon
EndScriptData */
#include "ScriptPCH.h"
-
-#define SPELL_TOXICVOLLEY 21687
-#define SPELL_UPPERCUT 22916
+enum Spells
+{
+ SPELL_TOXICVOLLEY = 21687,
+ SPELL_UPPERCUT = 22916
+};
class boss_noxxion : public CreatureScript
{
@@ -40,7 +42,7 @@ public:
struct boss_noxxionAI : public ScriptedAI
{
- boss_noxxionAI(Creature* c) : ScriptedAI(c) {}
+ boss_noxxionAI(Creature* creature) : ScriptedAI(creature) {}
uint32 ToxicVolley_Timer;
uint32 Uppercut_Timer;
@@ -78,7 +80,8 @@ public:
me->SetDisplayId(11172);
Invisible = false;
//me->m_canMove = true;
- } else if (Invisible)
+ }
+ else if (Invisible)
{
Invisible_Timer -= diff;
//Do nothing while invisible
@@ -94,14 +97,16 @@ public:
{
DoCast(me->getVictim(), SPELL_TOXICVOLLEY);
ToxicVolley_Timer = 9000;
- } else ToxicVolley_Timer -= diff;
+ }
+ else ToxicVolley_Timer -= diff;
//Uppercut_Timer
if (Uppercut_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_UPPERCUT);
Uppercut_Timer = 12000;
- } else Uppercut_Timer -= diff;
+ }
+ else Uppercut_Timer -= diff;
//Adds_Timer
if (!Invisible && Adds_Timer <= diff)
@@ -122,12 +127,12 @@ public:
Invisible_Timer = 15000;
Adds_Timer = 40000;
- } else Adds_Timer -= diff;
+ }
+ else Adds_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_noxxion()
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
index cb2c7b320e0..bade5655f36 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
@@ -25,10 +25,13 @@ EndScriptData */
#include "ScriptPCH.h"
-#define SPELL_DUSTFIELD 21909
-#define SPELL_BOULDER 21832
-#define SPELL_THRASH 3391
-#define SPELL_REPULSIVEGAZE 21869
+enum Spells
+{
+ SPELL_DUSTFIELD = 21909,
+ SPELL_BOULDER = 21832,
+ SPELL_THRASH = 3391,
+ SPELL_REPULSIVEGAZE = 21869
+};
class boss_princess_theradras : public CreatureScript
{
@@ -42,7 +45,7 @@ public:
struct boss_ptheradrasAI : public ScriptedAI
{
- boss_ptheradrasAI(Creature* c) : ScriptedAI(c) {}
+ boss_ptheradrasAI(Creature* creature) : ScriptedAI(creature) {}
uint32 Dustfield_Timer;
uint32 Boulder_Timer;
@@ -57,9 +60,7 @@ public:
RepulsiveGaze_Timer = 23000;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void JustDied(Unit* /*killer*/)
{
@@ -76,7 +77,8 @@ public:
{
DoCast(me, SPELL_DUSTFIELD);
Dustfield_Timer = 14000;
- } else Dustfield_Timer -= diff;
+ }
+ else Dustfield_Timer -= diff;
//Boulder_Timer
if (Boulder_Timer <= diff)
@@ -86,26 +88,28 @@ public:
if (target)
DoCast(target, SPELL_BOULDER);
Boulder_Timer = 10000;
- } else Boulder_Timer -= diff;
+ }
+ else Boulder_Timer -= diff;
//RepulsiveGaze_Timer
if (RepulsiveGaze_Timer <= diff)
{
DoCast(me->getVictim(), SPELL_REPULSIVEGAZE);
RepulsiveGaze_Timer = 20000;
- } else RepulsiveGaze_Timer -= diff;
+ }
+ else RepulsiveGaze_Timer -= diff;
//Thrash_Timer
if (Thrash_Timer <= diff)
{
DoCast(me, SPELL_THRASH);
Thrash_Timer = 18000;
- } else Thrash_Timer -= diff;
+ }
+ else Thrash_Timer -= diff;
DoMeleeAttackIfReady();
}
};
-
};
void AddSC_boss_ptheradras()
diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp
index e27d7287179..5d26653a1a8 100644
--- a/src/server/scripts/Kalimdor/ashenvale.cpp
+++ b/src/server/scripts/Kalimdor/ashenvale.cpp
@@ -35,34 +35,42 @@ EndContentData */
# npc_torek
####*/
-#define SAY_READY -1000106
-#define SAY_MOVE -1000107
-#define SAY_PREPARE -1000108
-#define SAY_WIN -1000109
-#define SAY_END -1000110
+enum TorekSays
+{
+ SAY_READY = 0,
+ SAY_MOVE = 1,
+ SAY_PREPARE = 2,
+ SAY_WIN = 3,
+ SAY_END = 4,
+};
-#define SPELL_REND 11977
-#define SPELL_THUNDERCLAP 8078
+enum TorekSpells
+{
+ SPELL_REND = 11977,
+ SPELL_THUNDERCLAP = 8078,
+};
-#define QUEST_TOREK_ASSULT 6544
+enum TorekMisc
+{
+ QUEST_TOREK_ASSULT = 6544,
-#define ENTRY_SPLINTERTREE_RAIDER 12859
-#define ENTRY_DURIEL 12860
-#define ENTRY_SILVERWING_SENTINEL 12896
-#define ENTRY_SILVERWING_WARRIOR 12897
+ ENTRY_SPLINTERTREE_RAIDER = 12859,
+ ENTRY_DURIEL = 12860,
+ ENTRY_SILVERWING_SENTINEL = 12896,
+ ENTRY_SILVERWING_WARRIOR = 12897,
+};
class npc_torek : public CreatureScript
{
public:
- npc_torek()
- : CreatureScript("npc_torek")
+ npc_torek() : CreatureScript("npc_torek")
{
}
struct npc_torekAI : public npc_escortAI
{
- npc_torekAI(Creature* c) : npc_escortAI(c) {}
+ npc_torekAI(Creature* creature) : npc_escortAI(creature) {}
uint32 Rend_Timer;
uint32 Thunderclap_Timer;
@@ -78,10 +86,10 @@ class npc_torek : public CreatureScript
switch (i)
{
case 1:
- DoScriptText(SAY_MOVE, me, player);
+ Talk(SAY_MOVE, player->GetGUID());
break;
case 8:
- DoScriptText(SAY_PREPARE, me, player);
+ Talk(SAY_PREPARE, player->GetGUID());
break;
case 19:
//TODO: verify location and creatures amount.
@@ -96,7 +104,7 @@ class npc_torek : public CreatureScript
player->GroupEventHappens(QUEST_TOREK_ASSULT, me);
break;
case 21:
- DoScriptText(SAY_END, me, player);
+ Talk(SAY_END, player->GetGUID());
break;
}
}
@@ -148,7 +156,7 @@ class npc_torek : public CreatureScript
if (quest->GetQuestId() == QUEST_TOREK_ASSULT)
{
//TODO: find companions, make them follow Torek, at any time (possibly done by core/database in future?)
- DoScriptText(SAY_READY, creature, player);
+ creature->AI()->Talk(SAY_READY, player->GetGUID());
creature->setFaction(113);
if (npc_escortAI* pEscortAI = CAST_AI(npc_torekAI, creature->AI()))
diff --git a/src/server/scripts/Kalimdor/moonglade.cpp b/src/server/scripts/Kalimdor/moonglade.cpp
index 595a72ec2bf..f9e4bce34d0 100644
--- a/src/server/scripts/Kalimdor/moonglade.cpp
+++ b/src/server/scripts/Kalimdor/moonglade.cpp
@@ -573,9 +573,151 @@ public:
};
/*####
-#
+# npc_omen
####*/
+enum Omen
+{
+ NPC_OMEN = 15467,
+
+ SPELL_OMEN_CLEAVE = 15284,
+ SPELL_OMEN_STARFALL = 26540,
+ SPELL_OMEN_SUMMON_SPOTLIGHT = 26392,
+ SPELL_ELUNE_CANDLE = 26374,
+
+ GO_ELUNE_TRAP_1 = 180876,
+ GO_ELUNE_TRAP_2 = 180877,
+
+ EVENT_CAST_CLEAVE = 1,
+ EVENT_CAST_STARFALL = 2,
+ EVENT_DESPAWN = 3,
+};
+
+class npc_omen : public CreatureScript
+{
+public:
+ npc_omen() : CreatureScript("npc_omen") { }
+
+ struct npc_omenAI : public ScriptedAI
+ {
+ npc_omenAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ me->GetMotionMaster()->MovePoint(1, 7549.977f, -2855.137f, 456.9678f);
+ }
+
+ EventMap events;
+
+ void MovementInform(uint32 type, uint32 pointId)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (pointId == 1)
+ {
+ me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
+ if (Player* player = me->SelectNearestPlayer(40.0f))
+ AttackStart(player);
+ }
+ }
+
+ void EnterCombat(Unit* /*attacker*/)
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(3000, 5000));
+ events.ScheduleEvent(EVENT_CAST_STARFALL, urand(8000, 10000));
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ DoCast(SPELL_OMEN_SUMMON_SPOTLIGHT);
+ }
+
+ void SpellHit(Unit* /*caster*/, const SpellInfo* spell)
+ {
+ if (spell->Id == SPELL_ELUNE_CANDLE)
+ {
+ if (me->HasAura(SPELL_OMEN_STARFALL))
+ me->RemoveAurasDueToSpell(SPELL_OMEN_STARFALL);
+
+ events.RescheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000));
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_CAST_CLEAVE:
+ DoCastVictim(SPELL_OMEN_CLEAVE);
+ events.ScheduleEvent(EVENT_CAST_CLEAVE, urand(8000, 10000));
+ break;
+ case EVENT_CAST_STARFALL:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_OMEN_STARFALL);
+ events.ScheduleEvent(EVENT_CAST_STARFALL, urand(14000, 16000));
+ break;
+ }
+
+ DoMeleeAttackIfReady();
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_omenAI(creature);
+ }
+};
+
+class npc_giant_spotlight : public CreatureScript
+{
+public:
+ npc_giant_spotlight() : CreatureScript("npc_giant_spotlight") { }
+
+ struct npc_giant_spotlightAI : public ScriptedAI
+ {
+ npc_giant_spotlightAI(Creature* creature) : ScriptedAI(creature) {}
+
+ EventMap events;
+
+ void Reset()
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_DESPAWN, 5*MINUTE*IN_MILLISECONDS);
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ events.Update(diff);
+
+ if (events.ExecuteEvent() == EVENT_DESPAWN)
+ {
+ if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_1, 5.0f))
+ trap->RemoveFromWorld();
+
+ if (GameObject* trap = me->FindNearestGameObject(GO_ELUNE_TRAP_2, 5.0f))
+ trap->RemoveFromWorld();
+
+ if (Creature* omen = me->FindNearestCreature(NPC_OMEN, 5.0f, false))
+ omen->DespawnOrUnsummon();
+
+ me->DespawnOrUnsummon();
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_giant_spotlightAI(creature);
+ }
+};
+
void AddSC_moonglade()
{
new npc_bunthen_plainswind();
@@ -583,4 +725,6 @@ void AddSC_moonglade()
new npc_silva_filnaveth();
new npc_clintar_dreamwalker();
new npc_clintar_spirit();
+ new npc_omen();
+ new npc_giant_spotlight();
}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
index e6678be3a2b..d3d92375d39 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_anubarak_trial.cpp
@@ -122,6 +122,11 @@ const Position SphereSpawn[6] =
{ 706.6383f, 161.5266f, 155.6701f, 0 },
};
+enum MovementPoints
+{
+ POINT_FALL_GROUND = 1
+};
+
class boss_anubarak_trial : public CreatureScript
{
public:
@@ -553,82 +558,68 @@ public:
class mob_frost_sphere : public CreatureScript
{
-public:
- mob_frost_sphere() : CreatureScript("mob_frost_sphere") { }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new mob_frost_sphereAI(creature);
- };
+ public:
+ mob_frost_sphere() : CreatureScript("mob_frost_sphere") { }
- struct mob_frost_sphereAI : public ScriptedAI
- {
- mob_frost_sphereAI(Creature* creature) : ScriptedAI(creature)
+ struct mob_frost_sphereAI : public ScriptedAI
{
- }
-
- bool m_bFall;
- uint32 m_uiPermafrostTimer;
+ mob_frost_sphereAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
- void Reset()
- {
- m_bFall = false;
- m_uiPermafrostTimer = 0;
- me->SetReactState(REACT_PASSIVE);
- me->SetFlying(true);
- me->SetDisplayId(25144);
- me->SetSpeed(MOVE_RUN, 0.5f, false);
- me->GetMotionMaster()->MoveRandom(20.0f);
- DoCast(SPELL_FROST_SPHERE);
- }
+ void Reset()
+ {
+ _isFalling = false;
+ me->SetReactState(REACT_PASSIVE);
+ me->SetFlying(true);
+ me->SetDisplayId(me->GetCreatureInfo()->Modelid2);
+ me->SetSpeed(MOVE_RUN, 0.5f, false);
+ me->GetMotionMaster()->MoveRandom(20.0f);
+ DoCast(SPELL_FROST_SPHERE);
+ }
- void DamageTaken(Unit* /*who*/, uint32& uiDamage)
- {
- if (me->GetHealth() < uiDamage)
+ void DamageTaken(Unit* /*who*/, uint32& damage)
{
- uiDamage = 0;
- if (!m_bFall)
+ if (me->GetHealth() <= damage)
{
- m_bFall = true;
- me->SetFlying(false);
- me->GetMotionMaster()->MoveIdle();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- //At hit the ground
- me->GetMotionMaster()->MoveFall(142.2f, 0);
- //me->FallGround(); //need correct vmap use (i believe it isn't working properly right now)
+ damage = 0;
+ if (!_isFalling)
+ {
+ _isFalling = true;
+ me->GetMotionMaster()->MoveIdle();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ //At hit the ground
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
+ me->GetMotionMaster()->MoveFall(POINT_FALL_GROUND);
+ }
}
}
- }
- void MovementInform(uint32 uiType, uint32 uiId)
- {
- if (uiType != POINT_MOTION_TYPE) return;
-
- switch (uiId)
+ void MovementInform(uint32 type, uint32 pointId)
{
- case 0:
- m_uiPermafrostTimer = IN_MILLISECONDS;
- break;
- }
- }
+ if (type != EFFECT_MOTION_TYPE)
+ return;
- void UpdateAI(const uint32 uiDiff)
- {
- if (m_uiPermafrostTimer)
- {
- if (m_uiPermafrostTimer <= uiDiff)
+ switch (pointId)
{
- m_uiPermafrostTimer = 0;
- me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE);
- me->SetDisplayId(11686);
- me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
- DoCast(SPELL_PERMAFROST_VISUAL);
- DoCast(SPELL_PERMAFROST);
- } else m_uiPermafrostTimer -= uiDiff;
+ case POINT_FALL_GROUND:
+ me->RemoveAurasDueToSpell(SPELL_FROST_SPHERE);
+ me->SetDisplayId(me->GetCreatureInfo()->Modelid1);
+ DoCast(SPELL_PERMAFROST_VISUAL);
+ DoCast(SPELL_PERMAFROST);
+ me->SetFloatValue(OBJECT_FIELD_SCALE_X, 2.0f);
+ break;
+ }
}
- }
- };
+ private:
+ bool _isFalling;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_frost_sphereAI(creature);
+ };
};
class mob_anubarak_spike : public CreatureScript
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index bc06a92ef07..a0d6f04f44c 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -67,6 +67,7 @@ class boss_bronjahm : public CreatureScript
{
boss_bronjahmAI(Creature* creature) : BossAI(creature, DATA_BRONJAHM)
{
+ DoCast(me, SPELL_SOULSTORM_CHANNEL, true);
}
void InitializeAI()
@@ -82,14 +83,17 @@ class boss_bronjahm : public CreatureScript
events.Reset();
events.SetPhase(PHASE_1);
events.ScheduleEvent(EVENT_SHADOW_BOLT, 2000);
- events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000));
+ events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000));
events.ScheduleEvent(EVENT_CORRUPT_SOUL, urand(25000, 35000), 0, PHASE_1);
- me->CastSpell(me, SPELL_SOULSTORM_CHANNEL, true);
-
instance->SetBossState(DATA_BRONJAHM, NOT_STARTED);
}
+ void JustReachedHome()
+ {
+ DoCast(me, SPELL_SOULSTORM_CHANNEL, true);
+ }
+
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_AGGRO, me);
@@ -118,7 +122,7 @@ class boss_bronjahm : public CreatureScript
events.SetPhase(PHASE_2);
DoCast(me, SPELL_TELEPORT);
events.ScheduleEvent(EVENT_FEAR, urand(12000, 16000), 0, PHASE_2);
- events.ScheduleEvent(EVENT_SOULSTORM, 700, 0, PHASE_2);
+ events.ScheduleEvent(EVENT_SOULSTORM, 100, 0, PHASE_2);
}
}
@@ -147,7 +151,7 @@ class boss_bronjahm : public CreatureScript
{
case EVENT_MAGIC_BANE:
DoCastVictim(SPELL_MAGIC_S_BANE);
- events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 15000));
+ events.ScheduleEvent(EVENT_MAGIC_BANE, urand(8000, 20000));
break;
case EVENT_SHADOW_BOLT:
if (!me->IsWithinMeleeRange(me->getVictim()))
@@ -201,7 +205,7 @@ class mob_corrupted_soul_fragment : public CreatureScript
void MovementInform(uint32 type, uint32 id)
{
- if (type != TARGETED_MOTION_TYPE)
+ if (type != CHASE_MOTION_TYPE)
return;
if (instance)
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
index 8180a686e0e..fb39019fb84 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_devourer_of_souls.cpp
@@ -306,6 +306,7 @@ class boss_devourer_of_souls : public CreatureScript
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
me->SetOrientation(me->GetAngle(target));
+ me->SendMovementFlagUpdate();
DoCast(me, SPELL_WAILING_SOULS_BEAM);
}
@@ -332,6 +333,7 @@ class boss_devourer_of_souls : public CreatureScript
case EVENT_WAILING_SOULS_TICK:
beamAngle += beamAngleDiff;
me->SetOrientation(beamAngle);
+ me->SendMovementFlagUpdate();
me->StopMoving();
DoCast(me, SPELL_WAILING_SOULS);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
index 3b15bba5c5d..94a3da2672b 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_prince_council.cpp
@@ -1159,7 +1159,7 @@ class npc_ball_of_flame : public CreatureScript
void MovementInform(uint32 type, uint32 id)
{
- if (type == TARGETED_MOTION_TYPE && id == GUID_LOPART(_chaseGUID) && _chaseGUID)
+ if (type == CHASE_MOTION_TYPE && id == GUID_LOPART(_chaseGUID) && _chaseGUID)
{
me->RemoveAurasDueToSpell(SPELL_BALL_OF_FLAMES_PERIODIC);
DoCast(me, SPELL_FLAMES);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 8396b6e6c85..31b3786a360 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -608,7 +608,7 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
- me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
+ me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
break;
@@ -815,7 +815,7 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->SendMovementFlagUpdate();
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
- me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
+ me->MonsterMoveWithSpeed(me->GetPositionX(), me->GetPositionY(), 539.2917f, 0.0f);
for (std::list<Creature*>::iterator itr = _guardList.begin(); itr != _guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
break;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index 0d3640504c1..cf22338995b 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -75,6 +75,7 @@ enum Spells
SPELL_PLAGUE_SICKNESS = 70953,
SPELL_UNBOUND_PLAGUE_PROTECTION = 70955,
SPELL_MUTATED_PLAGUE = 72451,
+ SPELL_MUTATED_PLAGUE_CLEAR = 72618,
// Slime Puddle
SPELL_GROW_STACKER = 70345,
@@ -244,6 +245,7 @@ class boss_professor_putricide : public CreatureScript
{
_JustDied();
Talk(SAY_DEATH);
+ DoCast(SPELL_MUTATED_PLAGUE_CLEAR);
}
void JustSummoned(Creature* summon)
@@ -1427,6 +1429,34 @@ class spell_putricide_regurgitated_ooze : public SpellScriptLoader
}
};
+class spell_putricide_clear_mutated_plague : public SpellScriptLoader
+{
+ public:
+ spell_putricide_clear_mutated_plague() : SpellScriptLoader("spell_putricide_clear_mutated_plague") { }
+
+ class spell_putricide_clear_mutated_plague_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_putricide_clear_mutated_plague_SpellScript);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+ uint32 auraId = sSpellMgr->GetSpellIdForDifficulty(uint32(GetEffectValue()), GetCaster());
+ GetHitUnit()->RemoveAurasDueToSpell(auraId);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_putricide_clear_mutated_plague_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_putricide_clear_mutated_plague_SpellScript();
+ }
+};
+
// Stinky and Precious spell, it's here because its used for both (Festergut and Rotface "pets")
class spell_stinky_precious_decimate : public SpellScriptLoader
{
@@ -1478,5 +1508,6 @@ void AddSC_boss_professor_putricide()
new spell_putricide_mutated_transformation();
new spell_putricide_mutated_transformation_dmg();
new spell_putricide_regurgitated_ooze();
+ new spell_putricide_clear_mutated_plague();
new spell_stinky_precious_decimate();
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 25610341a2f..3d3eaa1cc87 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -268,7 +268,7 @@ class boss_sindragosa : public CreatureScript
void MovementInform(uint32 type, uint32 point)
{
- if (type != POINT_MOTION_TYPE)
+ if (type != POINT_MOTION_TYPE && type != EFFECT_MOTION_TYPE)
return;
switch (point)
@@ -638,7 +638,7 @@ class npc_spinestalker : public CreatureScript
float moveTime = me->GetExactDist(&SpinestalkerFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f);
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, SpinestalkerLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
me->SetDefaultMovementType(IDLE_MOTION_TYPE);
- me->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
+ me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->GetMotionMaster()->MovePoint(POINT_FROSTWYRM_FLY_IN, SpinestalkerFlyPos);
}
@@ -646,7 +646,7 @@ class npc_spinestalker : public CreatureScript
void MovementInform(uint32 type, uint32 point)
{
- if (type != POINT_MOTION_TYPE || point != POINT_FROSTWYRM_LAND)
+ if (type != EFFECT_MOTION_TYPE || point != POINT_FROSTWYRM_LAND)
return;
me->setActive(false);
@@ -753,7 +753,7 @@ class npc_rimefang : public CreatureScript
float moveTime = me->GetExactDist(&RimefangFlyPos) / (me->GetSpeed(MOVE_FLIGHT) * 0.001f);
me->m_Events.AddEvent(new FrostwyrmLandEvent(*me, RimefangLandPos), me->m_Events.CalculateTime(uint64(moveTime) + 250));
me->SetDefaultMovementType(IDLE_MOTION_TYPE);
- me->GetMotionMaster()->MoveIdle(MOTION_SLOT_IDLE);
+ me->GetMotionMaster()->MoveIdle();
me->StopMoving();
me->GetMotionMaster()->MovePoint(POINT_FROSTWYRM_FLY_IN, RimefangFlyPos);
}
@@ -761,7 +761,7 @@ class npc_rimefang : public CreatureScript
void MovementInform(uint32 type, uint32 point)
{
- if (type != POINT_MOTION_TYPE || point != POINT_FROSTWYRM_LAND)
+ if (type != EFFECT_MOTION_TYPE || point != POINT_FROSTWYRM_LAND)
return;
me->setActive(false);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index 1fbdb7f4677..5029dbcceee 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -508,7 +508,7 @@ class boss_the_lich_king : public CreatureScript
if (fabs(ground_Z - z) < 0.1f)
return;
- me->GetMotionMaster()->MoveFall(ground_Z);
+ me->GetMotionMaster()->MoveFall();
}
void EnterCombat(Unit* target)
@@ -801,7 +801,7 @@ class boss_the_lich_king : public CreatureScript
events.ScheduleEvent(EVENT_INTRO_TALK_1, 9000, 0, PHASE_INTRO);
break;
case POINT_CENTER_1:
- me->SetFacing(0.0f);
+ me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
me->SetReactState(REACT_PASSIVE);
@@ -818,7 +818,7 @@ class boss_the_lich_king : public CreatureScript
events.ScheduleEvent(EVENT_SOUL_REAPER, 94000, 0, PHASE_TWO);
break;
case POINT_CENTER_2:
- me->SetFacing(0.0f);
+ me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
me->SetReactState(REACT_PASSIVE);
@@ -1047,14 +1047,14 @@ class boss_the_lich_king : public CreatureScript
break;
case EVENT_OUTRO_TALK_3:
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
- me->SetFacing(0.0f, tirion);
+ me->SetFacingToObject(tirion);
Talk(SAY_LK_OUTRO_3);
break;
case EVENT_OUTRO_MOVE_CENTER:
me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_1, CenterPosition);
break;
case EVENT_OUTRO_TALK_4:
- me->SetFacing(0.01745329f);
+ me->SetFacingTo(0.01745329f);
Talk(SAY_LK_OUTRO_4);
break;
case EVENT_OUTRO_RAISE_DEAD:
@@ -1070,7 +1070,7 @@ class boss_the_lich_king : public CreatureScript
case EVENT_OUTRO_TALK_6:
Talk(SAY_LK_OUTRO_6);
if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING)))
- tirion->SetFacing(0.0f, me);
+ tirion->SetFacingToObject(me);
me->ClearUnitState(UNIT_STAT_CASTING);
DoCastAOE(SPELL_SUMMON_BROKEN_FROSTMOURNE_3);
SetEquipmentSlots(false, EQUIP_UNEQUIP);
@@ -1222,7 +1222,7 @@ class npc_tirion_fordring_tft : public CreatureScript
void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
{
if (spell->Id == SPELL_ICE_LOCK)
- me->SetFacing(3.085098f);
+ me->SetFacingTo(3.085098f);
else if (spell->Id == SPELL_BROKEN_FROSTMOURNE_KNOCK)
SetEquipmentSlots(true); // remove glow on ashbringer
}
@@ -1285,7 +1285,7 @@ class npc_tirion_fordring_tft : public CreatureScript
SetEquipmentSlots(false, EQUIP_ASHBRINGER_GLOWING);
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
{
- me->SetFacing(0.0f, lichKing);
+ me->SetFacingToObject(lichKing);
lichKing->AI()->DoAction(ACTION_PLAY_MUSIC);
}
break;
@@ -1621,7 +1621,7 @@ class npc_strangulate_vehicle : public CreatureScript
void IsSummonedBy(Unit* summoner)
{
- me->SetFacing(0.0f, summoner);
+ me->SetFacingToObject(summoner);
DoCast(summoner, SPELL_HARVEST_SOUL_VEHICLE);
_events.Reset();
_events.ScheduleEvent(EVENT_MOVE_TO_LICH_KING, 2000);
@@ -1656,7 +1656,8 @@ class npc_strangulate_vehicle : public CreatureScript
switch (eventId)
{
case EVENT_TELEPORT:
- me->GetMotionMaster()->MoveIdle(MOTION_SLOT_ACTIVE);
+ me->GetMotionMaster()->Clear(false);
+ me->GetMotionMaster()->MoveIdle();
if (TempSummon* summ = me->ToTempSummon())
{
if (Unit* summoner = summ->GetSummoner())
@@ -1788,7 +1789,7 @@ class npc_terenas_menethil : public CreatureScript
_events.Reset();
_events.SetPhase(PHASE_OUTRO);
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
- me->SetFacing(0.0f, lichKing);
+ me->SetFacingToObject(lichKing);
_events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_1, 2000, 0, PHASE_OUTRO);
_events.ScheduleEvent(EVENT_OUTRO_TERENAS_TALK_2, 14000, 0, PHASE_OUTRO);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index ab3046806db..6bd8f3cba7d 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1264,7 +1264,7 @@ struct npc_argent_captainAI : public ScriptedAI
void EnterEvadeMode()
{
// not yet following
- if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != TARGETED_MOTION_TYPE || IsUndead)
+ if (me->GetMotionMaster()->GetMotionSlotType(MOTION_SLOT_IDLE) != CHASE_MOTION_TYPE || IsUndead)
{
ScriptedAI::EnterEvadeMode();
return;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
index 4c2348d30c9..58d3a4240b2 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
@@ -20,79 +20,185 @@
enum Spells
{
- SPELL_NECROTIC_AURA = 55593,
- SPELL_SUMMON_SPORE = 29234,
- SPELL_DEATHBLOOM = 29865,
- H_SPELL_DEATHBLOOM = 55053,
- SPELL_INEVITABLE_DOOM = 29204,
- H_SPELL_INEVITABLE_DOOM = 55052
+ SPELL_NECROTIC_AURA = 55593,
+ SPELL_WARN_NECROTIC_AURA = 59481,
+ SPELL_SUMMON_SPORE = 29234,
+ SPELL_DEATHBLOOM = 29865,
+ H_SPELL_DEATHBLOOM = 55053,
+ SPELL_INEVITABLE_DOOM = 29204,
+ H_SPELL_INEVITABLE_DOOM = 55052
+};
+
+enum Texts
+{
+ SAY_NECROTIC_AURA_APPLIED = 0,
+ SAY_NECROTIC_AURA_REMOVED = 1,
+ SAY_NECROTIC_AURA_FADING = 2,
};
enum Events
{
- EVENT_NONE,
- EVENT_AURA,
- EVENT_BLOOM,
- EVENT_DOOM,
+ EVENT_NECROTIC_AURA = 1,
+ EVENT_DEATHBLOOM = 2,
+ EVENT_INEVITABLE_DOOM = 3,
+ EVENT_SPORE = 4,
+ EVENT_NECROTIC_AURA_FADING = 5,
+};
+
+enum Achievement
+{
+ DATA_ACHIEVEMENT_SPORE_LOSER = 21822183,
};
class boss_loatheb : public CreatureScript
{
-public:
- boss_loatheb() : CreatureScript("boss_loatheb") { }
+ public:
+ boss_loatheb() : CreatureScript("boss_loatheb") { }
- CreatureAI* GetAI(Creature* creature) const
- {
- return new boss_loathebAI (creature);
- }
+ struct boss_loathebAI : public BossAI
+ {
+ boss_loathebAI(Creature* creature) : BossAI(creature, BOSS_LOATHEB)
+ {
+ }
- struct boss_loathebAI : public BossAI
- {
- boss_loathebAI(Creature* c) : BossAI(c, BOSS_LOATHEB) {}
+ void Reset()
+ {
+ _Reset();
+ _doomCounter = 0;
+ _sporeLoserData = true;
+ }
- void EnterCombat(Unit* /*who*/)
- {
- _EnterCombat();
- events.ScheduleEvent(EVENT_AURA, 10000);
- events.ScheduleEvent(EVENT_BLOOM, 5000);
- events.ScheduleEvent(EVENT_DOOM, 120000);
- }
+ void EnterCombat(Unit* /*who*/)
+ {
+ _EnterCombat();
+ events.ScheduleEvent(EVENT_NECROTIC_AURA, 17000);
+ events.ScheduleEvent(EVENT_DEATHBLOOM, 5000);
+ events.ScheduleEvent(EVENT_SPORE, IsHeroic() ? 18000 : 36000);
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 120000);
+ }
- void UpdateAI(const uint32 diff)
- {
- if (!UpdateVictim())
- return;
+ void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/)
+ {
+ _sporeLoserData = false;
+ }
- events.Update(diff);
+ uint32 GetData(uint32 id)
+ {
+ if (id != DATA_ACHIEVEMENT_SPORE_LOSER)
+ return 0;
- while (uint32 eventId = events.ExecuteEvent())
+ return uint32(_sporeLoserData);
+ }
+
+ void UpdateAI(uint32 const diff)
{
- switch (eventId)
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- case EVENT_AURA:
- DoCastAOE(SPELL_NECROTIC_AURA);
- events.ScheduleEvent(EVENT_AURA, 20000);
- break;
- case EVENT_BLOOM:
- // TODO : Add missing text
- DoCastAOE(SPELL_SUMMON_SPORE, true);
- DoCastAOE(RAID_MODE(SPELL_DEATHBLOOM, H_SPELL_DEATHBLOOM));
- events.ScheduleEvent(EVENT_BLOOM, 30000);
- break;
- case EVENT_DOOM:
- DoCastAOE(RAID_MODE(SPELL_INEVITABLE_DOOM, H_SPELL_INEVITABLE_DOOM));
- events.ScheduleEvent(EVENT_DOOM, events.GetTimer() < 5*60000 ? 30000 : 15000);
- break;
+ switch (eventId)
+ {
+ case EVENT_NECROTIC_AURA:
+ DoCastAOE(SPELL_NECROTIC_AURA);
+ DoCast(me, SPELL_WARN_NECROTIC_AURA);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA, 20000);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14000);
+ break;
+ case EVENT_DEATHBLOOM:
+ DoCastAOE(RAID_MODE(SPELL_DEATHBLOOM, H_SPELL_DEATHBLOOM));
+ events.ScheduleEvent(EVENT_DEATHBLOOM, 30000);
+ break;
+ case EVENT_INEVITABLE_DOOM:
+ _doomCounter++;
+ DoCastAOE(RAID_MODE(SPELL_INEVITABLE_DOOM, H_SPELL_INEVITABLE_DOOM));
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, std::max(120000 - _doomCounter * 15000, 15000)); // needs to be confirmed
+ break;
+ case EVENT_SPORE:
+ DoCast(me, SPELL_SUMMON_SPORE, false);
+ events.ScheduleEvent(EVENT_SPORE, IsHeroic() ? 18000 : 36000);
+ break;
+ case EVENT_NECROTIC_AURA_FADING:
+ Talk(SAY_NECROTIC_AURA_FADING);
+ break;
+ default:
+ break;
+ }
}
+
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
+ private:
+ bool _sporeLoserData;
+ uint8 _doomCounter;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new boss_loathebAI(creature);
+ }
+};
+
+class achievement_spore_loser : public AchievementCriteriaScript
+{
+ public:
+ achievement_spore_loser() : AchievementCriteriaScript("achievement_spore_loser") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_ACHIEVEMENT_SPORE_LOSER);
}
- };
+};
+
+typedef boss_loatheb::boss_loathebAI LoathebAI;
+
+class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader
+{
+ public:
+ spell_loatheb_necrotic_aura_warning() : SpellScriptLoader("spell_loatheb_necrotic_aura_warning") { }
+
+ class spell_loatheb_necrotic_aura_warning_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_loatheb_necrotic_aura_warning_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellStore.LookupEntry(SPELL_WARN_NECROTIC_AURA))
+ return false;
+ return true;
+ }
+ void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTarget()->IsAIEnabled)
+ CAST_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_APPLIED);
+ }
+
+ void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTarget()->IsAIEnabled)
+ CAST_AI(LoathebAI, GetTarget()->GetAI())->Talk(SAY_NECROTIC_AURA_REMOVED);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_necrotic_aura_warning_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_loatheb_necrotic_aura_warning_AuraScript();
+ }
};
void AddSC_boss_loatheb()
{
new boss_loatheb();
+ new achievement_spore_loser();
+ new spell_loatheb_necrotic_aura_warning();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
index b0138fb1a5e..be9168c6fd4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
@@ -83,7 +83,11 @@ enum ThaddiusSpells
SPELL_BALL_LIGHTNING = 28299,
SPELL_CHAIN_LIGHTNING = 28167,
H_SPELL_CHAIN_LIGHTNING = 54531,
- SPELL_BERSERK = 27680
+ SPELL_BERSERK = 27680,
+ SPELL_POSITIVE_CHARGE = 28062,
+ SPELL_POSITIVE_CHARGE_STACK = 29659,
+ SPELL_NEGATIVE_CHARGE = 28085,
+ SPELL_NEGATIVE_CHARGE_STACK = 29660
};
enum Events
@@ -94,6 +98,11 @@ enum Events
EVENT_BERSERK,
};
+enum Achievement
+{
+ DATA_POLARITY_SWITCH = 76047605,
+};
+
class boss_thaddius : public CreatureScript
{
public:
@@ -135,6 +144,7 @@ public:
bool checkStalaggAlive;
bool checkFeugenAlive;
+ bool polaritySwitch;
uint32 uiAddsTimer;
void KilledUnit(Unit* /*victim*/)
@@ -194,6 +204,20 @@ public:
me->SetReactState(REACT_AGGRESSIVE);
}
+ void SetData(uint32 id, uint32 data)
+ {
+ if (id == DATA_POLARITY_SWITCH)
+ polaritySwitch = data ? true : false;
+ }
+
+ uint32 GetData(uint32 id)
+ {
+ if (id != DATA_POLARITY_SWITCH)
+ return 0;
+
+ return uint32(polaritySwitch);
+ }
+
void UpdateAI(const uint32 diff)
{
if (checkFeugenAlive && checkStalaggAlive)
@@ -400,9 +424,101 @@ public:
};
+class spell_thaddius_pos_neg_charge : public SpellScriptLoader
+{
+ public:
+ spell_thaddius_pos_neg_charge() : SpellScriptLoader("spell_thaddius_pos_neg_charge") { }
+
+ class spell_thaddius_pos_neg_charge_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_thaddius_pos_neg_charge_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_STACK))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_STACK))
+ return false;
+ return true;
+ }
+
+ bool Load()
+ {
+ return GetCaster()->GetTypeId() == TYPEID_UNIT;
+ }
+
+ void HandleTargets(std::list<Unit*>& targetList)
+ {
+ uint8 count = 0;
+ for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
+ if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
+ if (Player* target = (*ihit)->ToPlayer())
+ if (target->HasAura(GetTriggeringSpell()->Id))
+ ++count;
+
+ if (count)
+ {
+ uint32 spellId = 0;
+
+ if (GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE)
+ spellId = SPELL_POSITIVE_CHARGE_STACK;
+ else // if (GetSpellInfo()->Id == SPELL_NEGATIVE_CHARGE)
+ spellId = SPELL_NEGATIVE_CHARGE_STACK;
+
+ GetCaster()->SetAuraStack(spellId, GetCaster(), count);
+ }
+ }
+
+ void HandleDamage(SpellEffIndex /*effIndex*/)
+ {
+ if (!GetTriggeringSpell())
+ return;
+
+ Unit* target = GetHitUnit();
+ Unit* caster = GetCaster();
+
+ if (target->HasAura(GetTriggeringSpell()->Id))
+ SetHitDamage(0);
+ else
+ {
+ if (target->GetTypeId() == TYPEID_PLAYER && caster->IsAIEnabled)
+ caster->ToCreature()->AI()->SetData(DATA_POLARITY_SWITCH, 1);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_thaddius_pos_neg_charge_SpellScript();
+ }
+};
+
+class achievement_polarity_switch : public AchievementCriteriaScript
+{
+ public:
+ achievement_polarity_switch() : AchievementCriteriaScript("achievement_polarity_switch") { }
+
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->GetAI()->GetData(DATA_POLARITY_SWITCH);
+ }
+};
+
void AddSC_boss_thaddius()
{
new boss_thaddius();
new mob_stalagg();
new mob_feugen();
+ new spell_thaddius_pos_neg_charge();
+ new achievement_polarity_switch();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 32cb279ce5f..c05d9a21850 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -166,8 +166,8 @@ public:
kelthuzadGUID = 0;
kelthuzadTriggerGUID = 0;
- playerDied = 0;
- gothikDoorState = GO_STATE_ACTIVE;
+ playerDied = 0;
+ gothikDoorState = GO_STATE_ACTIVE;
memset(portalsGUID, 0, sizeof(portalsGUID));
}
diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
index 8e995a9b260..052fa3ba4a5 100644
--- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
+++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp
@@ -838,7 +838,7 @@ public:
return;
}
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
me->GetMotionMaster()->MoveFollow(malygos, 0.0f, 0.0f);
}
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
index e96801f3ecb..c6f72890d1f 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_bjarngrim.cpp
@@ -61,7 +61,7 @@ enum eEnums
//OTHER SPELLS
//SPELL_CHARGE_UP = 52098, // only used when starting walk from one platform to the other
- //SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
+ SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
NPC_STORMFORGED_LIEUTENANT = 29240,
SPELL_ARC_WELD = 59085,
@@ -98,11 +98,13 @@ public:
m_instance = creature->GetInstanceScript();
m_uiStance = STANCE_DEFENSIVE;
memset(&m_auiStormforgedLieutenantGUID, 0, sizeof(m_auiStormforgedLieutenantGUID));
+ canBuff = true;
}
InstanceScript* m_instance;
bool m_bIsChangingStance;
+ bool canBuff;
uint8 m_uiChargingStatus;
uint8 m_uiStance;
@@ -126,6 +128,10 @@ public:
void Reset()
{
+ if (canBuff)
+ if (!me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE))
+ me->AddAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE, me);
+
m_bIsChangingStance = false;
m_uiChargingStatus = 0;
@@ -167,6 +173,16 @@ public:
m_instance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
}
+ void EnterEvadeMode()
+ {
+ if (me->HasAura(SPELL_TEMPORARY_ELECTRICAL_CHARGE))
+ canBuff = true;
+ else
+ canBuff = false;
+
+ ScriptedAI::EnterEvadeMode();
+ }
+
void EnterCombat(Unit* /*who*/)
{
DoScriptText(SAY_AGGRO, me);
@@ -211,7 +227,7 @@ public:
void UpdateAI(const uint32 uiDiff)
{
//Return since we have no target
- if (!UpdateVictim())
+ if (!UpdateVictim())
return;
// Change stance
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
index 194c2a36862..1fc724c8b6c 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_volkhan.cpp
@@ -243,7 +243,7 @@ public:
{
if (m_uiPause_Timer <= uiDiff)
{
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
if (me->getVictim())
me->GetMotionMaster()->MoveChase(me->getVictim());
@@ -421,7 +421,7 @@ public:
// me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); //Set in DB
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
m_bIsFrozen = true;
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
index 4ee71367b55..d1aba800094 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
@@ -174,7 +174,7 @@ public:
bIsSlam = false;
//and correct movement, if not already
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
{
if (me->getVictim())
me->GetMotionMaster()->MoveChase(me->getVictim());
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
index 68435fffb1b..2c7532fcf70 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_assembly_of_iron.cpp
@@ -634,7 +634,7 @@ class boss_stormcaller_brundir : public CreatureScript
// Prevent to have Brundir somewhere in the air when he die in Air phase
if (me->GetPositionZ() > FLOOR_Z)
- me->GetMotionMaster()->MoveFall(FLOOR_Z);
+ me->GetMotionMaster()->MoveFall();
}
void KilledUnit(Unit* /*who*/)
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
index ea84502c16d..0c59097a9ec 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_ingvar_the_plunderer.cpp
@@ -18,7 +18,7 @@
/* ScriptData
SDName: Boss_Ingvar_The_Plunderer
SD%Complete: 95
-SDComment: Some Problems with Annhylde Movement, Blizzlike Timers
+SDComment: Some Problems with Annhylde Movement, Blizzlike Timers (just shadow axe summon needs a new timer)
SDCategory: Udgarde Keep
EndScriptData */
@@ -45,16 +45,32 @@ enum Creatures
MOB_INGVAR_UNDEAD = 23980,
};
+enum Events
+{
+ EVENT_CLEAVE = 1,
+ EVENT_SMASH,
+ EVENT_STAGGERING_ROAR,
+ EVENT_ENRAGE,
+
+ EVENT_DARK_SMASH,
+ EVENT_DREADFUL_ROAR,
+ EVENT_WOE_STRIKE,
+ EVENT_SHADOW_AXE
+};
+
+enum Phases
+{
+ PHASE_HUMAN = 1,
+ PHASE_UNDEAD,
+};
+
enum Spells
{
//Ingvar Spells human form
SPELL_CLEAVE = 42724,
SPELL_SMASH = 42669,
- H_SPELL_SMASH = 59706,
SPELL_STAGGERING_ROAR = 42708,
- H_SPELL_STAGGERING_ROAR = 59708,
SPELL_ENRAGE = 42705,
- H_SPELL_ENRAGE = 59707,
SPELL_INGVAR_FEIGN_DEATH = 42795,
SPELL_SUMMON_BANSHEE = 42912,
@@ -63,9 +79,7 @@ enum Spells
//Ingvar Spells undead form
SPELL_DARK_SMASH = 42723,
SPELL_DREADFUL_ROAR = 42729,
- H_SPELL_DREADFUL_ROAR = 59734,
SPELL_WOE_STRIKE = 42730,
- H_SPELL_WOE_STRIKE = 59735,
ENTRY_THROW_TARGET = 23996,
SPELL_SHADOW_AXE_SUMMON = 42749
@@ -83,9 +97,9 @@ public:
struct boss_ingvar_the_plundererAI : public ScriptedAI
{
- boss_ingvar_the_plundererAI(Creature* c) : ScriptedAI(c)
+ boss_ingvar_the_plundererAI(Creature* creature) : ScriptedAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
InstanceScript* instance;
@@ -93,10 +107,6 @@ public:
bool bIsUndead;
bool bEventInProgress;
- uint32 uiCleaveTimer;
- uint32 uiSmashTimer;
- uint32 uiEnrageTimer;
- uint32 uiRoarTimer;
uint32 uiSpawnResTimer;
void Reset()
@@ -110,10 +120,18 @@ public:
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
me->SetStandState(UNIT_STAND_STATE_STAND);
- uiCleaveTimer = 2000;
- uiSmashTimer = 5000;
- uiEnrageTimer = 10000;
- uiRoarTimer = 15000;
+ events.Reset();
+ events.SetPhase(PHASE_HUMAN);
+
+ events.ScheduleEvent(EVENT_CLEAVE, urand(6,12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+
+ events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
uiSpawnResTimer = 3000;
@@ -138,6 +156,7 @@ public:
bEventInProgress = true;
bIsUndead = true;
+ events.SetPhase(PHASE_UNDEAD);
DoScriptText(YELL_DEAD_1, me);
}
@@ -208,70 +227,60 @@ public:
return;
}
- if (uiCleaveTimer <= diff)
- {
- if (!me->HasUnitState(UNIT_STAT_CASTING))
- {
- if (bIsUndead)
- DoCast(me->getVictim(), SPELL_WOE_STRIKE);
- else
- DoCast(me->getVictim(), SPELL_CLEAVE);
- uiCleaveTimer = rand()%5000 + 2000;
- }
- } else uiCleaveTimer -= diff;
+ events.Update(diff);
- if (uiSmashTimer <= diff)
- {
- if (!me->HasUnitState(UNIT_STAT_CASTING))
- {
- if (bIsUndead)
- DoCast(me->getVictim(), SPELL_DARK_SMASH);
- else
- DoCast(me->getVictim(), SPELL_SMASH);
- uiSmashTimer = 10000;
- }
- } else uiSmashTimer -= diff;
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
- if (!bIsUndead)
- {
- if (uiEnrageTimer <= diff)
- {
- DoCast(me, SPELL_ENRAGE);
- uiEnrageTimer = 10000;
- } else uiEnrageTimer -= diff;
- } else // In Undead form used to summon weapon
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (uiEnrageTimer <= diff)
+ switch (eventId)
{
- if (!me->HasUnitState(UNIT_STAT_CASTING))
- {
- // Spawn target for Axe
- Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1);
- if (target)
+ // PHASE ONE
+ case EVENT_CLEAVE:
+ DoCastVictim(SPELL_CLEAVE);
+ events.ScheduleEvent(EVENT_CLEAVE, urand(6,12)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ break;
+ case EVENT_STAGGERING_ROAR:
+ DoCast(me, SPELL_STAGGERING_ROAR);
+ events.ScheduleEvent(EVENT_STAGGERING_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ break;
+ case EVENT_ENRAGE:
+ DoCast(me, SPELL_ENRAGE);
+ events.ScheduleEvent(EVENT_ENRAGE, urand(7,14)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ break;
+ case EVENT_SMASH:
+ DoCastVictim(SPELL_SMASH);
+ events.ScheduleEvent(EVENT_SMASH, urand(12,17)*IN_MILLISECONDS, 0, PHASE_HUMAN);
+ break;
+ // PHASE TWO
+ case EVENT_DARK_SMASH:
+ DoCastVictim(SPELL_DARK_SMASH);
+ events.ScheduleEvent(EVENT_DARK_SMASH, urand(14,22)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ break;
+ case EVENT_DREADFUL_ROAR:
+ DoCast(me, SPELL_DREADFUL_ROAR);
+ events.ScheduleEvent(EVENT_DREADFUL_ROAR, urand(18,21)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ break;
+ case EVENT_WOE_STRIKE:
+ DoCastVictim(SPELL_WOE_STRIKE);
+ events.ScheduleEvent(EVENT_WOE_STRIKE, urand(10,14)*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ break;
+ case EVENT_SHADOW_AXE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1))
{
me->SummonCreature(ENTRY_THROW_TARGET, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
-
DoCast(me, SPELL_SHADOW_AXE_SUMMON);
}
- uiEnrageTimer = 30000;
- }
- } else uiEnrageTimer -= diff;
- }
-
- if (uiRoarTimer <= diff)
- {
- if (!me->HasUnitState(UNIT_STAT_CASTING))
- {
- if (bIsUndead)
- DoCast(me, SPELL_DREADFUL_ROAR);
- else
- DoCast(me, SPELL_STAGGERING_ROAR);
- uiRoarTimer = 10000;
+ events.ScheduleEvent(EVENT_SHADOW_AXE, 30*IN_MILLISECONDS, 0, PHASE_UNDEAD);
+ break;
}
- } else uiRoarTimer -= diff;
+ }
DoMeleeAttackIfReady();
}
+ private:
+ EventMap events;
};
};
@@ -381,8 +390,9 @@ public:
{
ingvar->RemoveAurasDueToSpell(SPELL_SCOURG_RESURRECTION_DUMMY);
- if (boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI* pAI = CAST_AI(boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI, ingvar->AI()))
- pAI->StartZombiePhase();
+ if (ingvar->getVictim())
+ if (boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI* ai = CAST_AI(boss_ingvar_the_plunderer::boss_ingvar_the_plundererAI, ingvar->AI()))
+ ai->StartZombiePhase();
me->GetMotionMaster()->MovePoint(2, x+1, y, z+30);
++uiResurectPhase;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
index dc93917f2e5..94a133c78a6 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardeKeep/boss_keleseth.cpp
@@ -17,354 +17,323 @@
/* ScriptData
SDName: Boss_Prince_Keleseth
-SD%Complete: 90
-SDComment: Needs Prince Movements, Needs adjustments to blizzlike timers, Needs Shadowbolt castbar, Needs right Ressurect Visual, Needs Some Heroic Spells
+SD%Complete: 100
+SDComment:
SDCategory: Utgarde Keep
EndScriptData */
#include "ScriptPCH.h"
#include "utgarde_keep.h"
-enum eEnums
+enum KelsethEncounter
{
- ACHIEVEMENT_ON_THE_ROCKS = 1919,
-
SPELL_SHADOWBOLT = 43667,
- SPELL_SHADOWBOLT_HEROIC = 59389,
SPELL_FROST_TOMB = 48400,
+ SPELL_FROST_TOMB_STUN = 42672,
SPELL_FROST_TOMB_SUMMON = 42714,
+
+ SPELL_SHADOW_FISSURE = 50657,
+ SPELL_FULL_HEAL = 17683,
SPELL_DECREPIFY = 42702,
- SPELL_SCOURGE_RESSURRECTION = 42704,
- CREATURE_FROSTTOMB = 23965,
- CREATURE_SKELETON = 23970,
-
- SAY_AGGRO = -1574000,
- SAY_FROST_TOMB = -1574001,
- SAY_SKELETONS = -1574002,
- SAY_KILL = -1574003,
- SAY_DEATH = -1574004
+ SPELL_BONE_ARMOR = 59386,
+
+ NPC_FROSTTOMB = 23965,
+ NPC_SKELETON = 23970,
+
+ SAY_START_COMBAT = 1,
+ SAY_SUMMON_SKELETONS,
+ SAY_FROST_TOMB,
+ SAY_FROST_TOMB_EMOTE,
+ SAY_DEATH,
+
+ EVENT_SHADOWBOLT = 1,
+ EVENT_FROST_TOMB,
+ EVENT_SUMMON_SKELETONS,
+
+ EVENT_DECREPIFY,
+ EVENT_FULL_HEAL,
+ EVENT_SHADOW_FISSURE,
+ EVENT_RESURRECT,
+
+ DATA_ON_THE_ROCKS
};
#define SKELETONSPAWN_Z 42.8668f
-float SkeletonSpawnPoint[5][5]=
+float const SkeletonSpawnPoint[1][2] =
{
{156.2559f, 259.2093f},
- {156.2559f, 259.2093f},
- {156.2559f, 259.2093f},
- {156.2559f, 259.2093f},
- {156.2559f, 259.2093f},
};
-float AttackLoc[3]={197.636f, 194.046f, 40.8164f};
+float AttackLoc[3]= {197.636f, 194.046f, 40.8164f};
-bool ShatterFrostTomb; // needed for achievement: On The Rocks(1919)
-
-class mob_frost_tomb : public CreatureScript
+class npc_frost_tomb : public CreatureScript
{
public:
- mob_frost_tomb() : CreatureScript("mob_frost_tomb") { }
+ npc_frost_tomb() : CreatureScript("npc_frost_tomb") {}
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_frost_tombAI(creature);
+ return new npc_frost_tombAI(creature);
}
- struct mob_frost_tombAI : public ScriptedAI
+ struct npc_frost_tombAI : public ScriptedAI
{
- mob_frost_tombAI(Creature* c) : ScriptedAI(c)
+ npc_frost_tombAI(Creature* creature) : ScriptedAI(creature)
{
- FrostTombGUID = 0;
- }
-
- uint64 FrostTombGUID;
+ if (me->isSummon())
+ if (Unit* summon = me->ToTempSummon()->GetSummoner())
+ DoCast(summon, SPELL_FROST_TOMB, true);
- void SetPrisoner(Unit* uPrisoner)
- {
- FrostTombGUID = uPrisoner->GetGUID();
+ instance = creature->GetInstanceScript();
}
- void Reset(){ FrostTombGUID = 0; }
- void EnterCombat(Unit* /*who*/) {}
- void AttackStart(Unit* /*who*/) {}
- void MoveInLineOfSight(Unit* /*who*/) {}
+ void UpdateAI(const uint32 /*diff*/) {}
- void JustDied(Unit* killer)
+ void JustDied(Unit* /*killer*/)
{
- if (killer->GetGUID() != me->GetGUID())
- ShatterFrostTomb = true;
-
- if (FrostTombGUID)
- {
- Unit* FrostTomb = Unit::GetUnit((*me), FrostTombGUID);
- if (FrostTomb)
- FrostTomb->RemoveAurasDueToSpell(SPELL_FROST_TOMB);
- }
+ if (instance)
+ if (Unit* boss = me->GetUnit(*me, instance->GetData64(DATA_PRINCEKELESETH)))
+ if (boss->ToCreature() && boss->ToCreature()->AI())
+ boss->ToCreature()->AI()->SetData(DATA_ON_THE_ROCKS, false);
}
- void UpdateAI(const uint32 /*diff*/)
- {
- Unit* temp = Unit::GetUnit((*me), FrostTombGUID);
- if ((temp && temp->isAlive() && !temp->HasAura(SPELL_FROST_TOMB)) || !temp)
- me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- }
+ private:
+ InstanceScript* instance;
};
-
};
class boss_keleseth : public CreatureScript
{
public:
- boss_keleseth() : CreatureScript("boss_keleseth") { }
+ boss_keleseth() : CreatureScript("boss_keleseth") {}
CreatureAI* GetAI(Creature* creature) const
{
return new boss_kelesethAI (creature);
}
- struct boss_kelesethAI : public ScriptedAI
+ struct boss_kelesethAI : public BossAI
{
- boss_kelesethAI(Creature* c) : ScriptedAI(c)
+ boss_kelesethAI(Creature* creature) : BossAI(creature, DATA_PRINCEKELESETH_EVENT)
{
- instance = c->GetInstanceScript();
+ creature->SetReactState(REACT_DEFENSIVE);
}
- InstanceScript* instance;
-
- uint32 FrostTombTimer;
- uint32 SummonSkeletonsTimer;
- uint32 RespawnSkeletonsTimer;
- uint32 ShadowboltTimer;
- uint64 SkeletonGUID[5];
- bool Skeletons;
- bool RespawnSkeletons;
-
void Reset()
{
- ShadowboltTimer = 0;
- Skeletons = false;
+ instance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED);
- ShatterFrostTomb = false;
+ events.Reset();
+ events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2,3)*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_FROST_TOMB, urand(14,19)*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SUMMON_SKELETONS, 6*IN_MILLISECONDS);
- ResetTimer();
+ summons.DespawnAll();
- if (instance)
- instance->SetData(DATA_PRINCEKELESETH_EVENT, NOT_STARTED);
+ onTheRocks = true;
}
- void KilledUnit(Unit* victim)
+ void EnterCombat(Unit* /*who*/)
{
- if (victim == me)
- return;
-
- DoScriptText(SAY_KILL, me);
+ me->SetInCombatWithZone();
+ instance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS);
+ Talk(SAY_START_COMBAT);
}
void JustDied(Unit* /*killer*/)
{
- DoScriptText(SAY_DEATH, me);
-
- if (IsHeroic() && !ShatterFrostTomb)
- {
- AchievementEntry const* AchievOnTheRocks = GetAchievementStore()->LookupEntry(ACHIEVEMENT_ON_THE_ROCKS);
- if (AchievOnTheRocks)
- {
- Map* map = me->GetMap();
- if (map && map->IsDungeon())
- {
- Map::PlayerList const &players = map->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- itr->getSource()->CompletedAchievement(AchievOnTheRocks);
- }
- }
- }
-
- if (instance)
- instance->SetData(DATA_PRINCEKELESETH_EVENT, DONE);
+ instance->SetData(DATA_PRINCEKELESETH_EVENT, DONE);
+ summons.DespawnAll();
+ Talk(SAY_DEATH);
}
- void EnterCombat(Unit* /*who*/)
+ void SetData(uint32 data, uint32 value)
{
- DoScriptText(SAY_AGGRO, me);
- DoZoneInCombat();
-
- if (instance)
- instance->SetData(DATA_PRINCEKELESETH_EVENT, IN_PROGRESS);
+ if (data == DATA_ON_THE_ROCKS)
+ onTheRocks = value;
}
- void ResetTimer(uint32 inc = 0)
+ uint32 GetData(uint32 data)
{
- SummonSkeletonsTimer = 5000 + inc;
- FrostTombTimer = 28000 + inc;
+ if (data == DATA_ON_THE_ROCKS)
+ return onTheRocks;
+
+ return 0;
}
- void UpdateAI(const uint32 diff)
+ void ExecuteEvent(uint32 const eventId)
{
- if (!UpdateVictim())
- return;
-
- if (ShadowboltTimer <= diff)
+ switch (eventId)
{
- Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 0);
- if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
- me->CastSpell(target, DUNGEON_MODE(SPELL_SHADOWBOLT, SPELL_SHADOWBOLT_HEROIC), true);
- ShadowboltTimer = 10000;
- } else ShadowboltTimer -= diff;
-
- if (!Skeletons)
- {
- if ((SummonSkeletonsTimer <= diff))
- {
- Creature* Skeleton;
- DoScriptText(SAY_SKELETONS, me);
- for (uint8 i = 0; i < 5; ++i)
+ case EVENT_SUMMON_SKELETONS:
+ Talk(SAY_SUMMON_SKELETONS);
+ SummonSkeletons();
+ break;
+ case EVENT_SHADOWBOLT:
+ DoCastVictim(SPELL_SHADOWBOLT);
+ events.ScheduleEvent(EVENT_SHADOWBOLT, urand(2,3)*IN_MILLISECONDS);
+ break;
+ case EVENT_FROST_TOMB:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true, -SPELL_FROST_TOMB))
{
- Skeleton = me->SummonCreature(CREATURE_SKELETON, SkeletonSpawnPoint[i][0], SkeletonSpawnPoint[i][1], SKELETONSPAWN_Z, 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
- if (Skeleton)
- {
- Skeleton->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
- Skeleton->GetMotionMaster()->MovePoint(0, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ());
- Skeleton->AddThreat(me->getVictim(), 0.0f);
- DoZoneInCombat(Skeleton);
- }
- }
- Skeletons = true;
- } else SummonSkeletonsTimer -= diff;
- }
+ Talk(SAY_FROST_TOMB);
+ Talk(SAY_FROST_TOMB_EMOTE, target->GetGUID());
- if (FrostTombTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- if (target->isAlive())
- {
- //DoCast(target, SPELL_FROST_TOMB_SUMMON, true);
- if (Creature* pChains = me->SummonCreature(CREATURE_FROSTTOMB, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 20000))
- {
- CAST_AI(mob_frost_tomb::mob_frost_tombAI, pChains->AI())->SetPrisoner(target);
- pChains->CastSpell(target, SPELL_FROST_TOMB, true);
-
- DoScriptText(SAY_FROST_TOMB, me);
- }
+ DoCast(target, SPELL_FROST_TOMB_STUN, true);
+ // checked from sniffs - the player casts the spell
+ target->CastSpell(target, SPELL_FROST_TOMB_SUMMON, true);
}
- FrostTombTimer = 15000;
- } else FrostTombTimer -= diff;
+ events.ScheduleEvent(EVENT_FROST_TOMB, urand(14,19)*IN_MILLISECONDS);
+ break;
+ }
+ }
- DoMeleeAttackIfReady();
+ void SummonSkeletons()
+ {
+ // I could not found any spell casted for this
+ for (uint8 i = 0; i < 4; ++i)
+ me->SummonCreature(NPC_SKELETON, SkeletonSpawnPoint[0][0], SkeletonSpawnPoint[0][1], SKELETONSPAWN_Z, 0);
}
+ private:
+ bool onTheRocks;
};
-
};
-class mob_vrykul_skeleton : public CreatureScript
+class npc_vrykul_skeleton : public CreatureScript
{
public:
- mob_vrykul_skeleton() : CreatureScript("mob_vrykul_skeleton") { }
+ npc_vrykul_skeleton() : CreatureScript("npc_vrykul_skeleton") {}
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_vrykul_skeletonAI (creature);
+ return new npc_vrykul_skeletonAI (creature);
}
- struct mob_vrykul_skeletonAI : public ScriptedAI
+ struct npc_vrykul_skeletonAI : public ScriptedAI
{
- mob_vrykul_skeletonAI(Creature* c) : ScriptedAI(c)
- {
- instance = c->GetInstanceScript();
- }
-
- InstanceScript* instance;
- uint32 Respawn_Time;
- uint64 Target_Guid;
- uint32 Decrepify_Timer;
-
- bool isDead;
+ npc_vrykul_skeletonAI(Creature* creature) : ScriptedAI(creature) {}
void Reset()
{
- Respawn_Time = 12000;
- Decrepify_Timer = urand(10000, 20000);
- isDead = false;
+ events.Reset();
+ events.ScheduleEvent(EVENT_DECREPIFY, urand(4,6)*IN_MILLISECONDS);
+
+ DoCast(SPELL_BONE_ARMOR);
}
- void EnterCombat(Unit* /*who*/){}
- void DamageTaken(Unit* done_by, uint32 &damage)
+ void DamageTaken(Unit* /*done_by*/, uint32 &damage)
{
- if (done_by->GetGUID() == me->GetGUID())
- return;
-
if (damage >= me->GetHealth())
{
- PretendToDie();
damage = 0;
- }
- }
- void PretendToDie()
- {
- isDead = true;
- me->InterruptNonMeleeSpells(true);
- me->RemoveAllAuras();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->GetMotionMaster()->MovementExpired(false);
- me->GetMotionMaster()->MoveIdle();
- me->SetStandState(UNIT_STAND_STATE_DEAD);
- };
+ // There are some issues with pets
+ // they will still attack. I would say it is a PetAI bug
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ {
+ // from sniffs
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
- void Resurrect()
- {
- isDead = false;
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- me->SetStandState(UNIT_STAND_STATE_STAND);
- DoCast(me, SPELL_SCOURGE_RESSURRECTION, true);
+ events.Reset();
+ events.ScheduleEvent(EVENT_RESURRECT, urand(18,22)*IN_MILLISECONDS);
- if (me->getVictim())
- {
- me->GetMotionMaster()->MoveChase(me->getVictim());
- me->AI()->AttackStart(me->getVictim());
+ me->GetMotionMaster()->MovementExpired(false);
+ me->GetMotionMaster()->MoveIdle();
+ }
}
- else
- me->GetMotionMaster()->Initialize();
- };
+ }
void UpdateAI(const uint32 diff)
{
- if (instance && instance->GetData(DATA_PRINCEKELESETH_EVENT) == IN_PROGRESS)
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ while (uint32 eventId = events.ExecuteEvent())
{
- if (isDead)
+ switch (eventId)
{
- if (Respawn_Time <= diff)
- {
- Resurrect();
- Respawn_Time = 12000;
- } else Respawn_Time -= diff;
+ case EVENT_DECREPIFY:
+ DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true, -SPELL_DECREPIFY), SPELL_DECREPIFY);
+ events.ScheduleEvent(EVENT_DECREPIFY, urand(1,5)*IN_MILLISECONDS);
+ break;
+ case EVENT_RESURRECT:
+ events.ScheduleEvent(EVENT_FULL_HEAL, 1*IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SHADOW_FISSURE, 1*IN_MILLISECONDS);
+ break;
+ case EVENT_FULL_HEAL:
+ DoCast(me, SPELL_FULL_HEAL, true);
+ break;
+ case EVENT_SHADOW_FISSURE:
+ DoCast(me, SPELL_SHADOW_FISSURE, true);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->RemoveFlag(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD);
+ me->GetMotionMaster()->MoveChase(me->getVictim());
+ events.ScheduleEvent(EVENT_DECREPIFY, urand(4,6)*IN_MILLISECONDS);
+ break;
}
- else
- {
- if (!UpdateVictim())
- return;
+ }
- if (Decrepify_Timer <= diff)
- {
- DoCast(me->getVictim(), SPELL_DECREPIFY);
- Decrepify_Timer = 30000;
- } else Decrepify_Timer -= diff;
+ if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
+ DoMeleeAttackIfReady();
+ }
- DoMeleeAttackIfReady();
- }
- }else
+ private:
+ EventMap events;
+ };
+};
+
+class spell_frost_tomb : public SpellScriptLoader
+{
+ public:
+ spell_frost_tomb() : SpellScriptLoader("spell_frost_tomb") {}
+
+ class spell_frost_tomb_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_frost_tomb_AuraScript);
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (me->isAlive())
- me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
+ if (Unit* caster = GetCaster())
+ if (caster->ToCreature() && caster->isAlive())
+ caster->ToCreature()->DespawnOrUnsummon(1000);
}
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_frost_tomb_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_frost_tomb_AuraScript();
}
- };
+};
+
+
+class achievement_on_the_rocks : public AchievementCriteriaScript
+{
+ public:
+ achievement_on_the_rocks() : AchievementCriteriaScript("achievement_on_the_rocks") {}
+ bool OnCheck(Player* /*source*/, Unit* target)
+ {
+ return target && target->IsAIEnabled && target->GetAI()->GetData(DATA_ON_THE_ROCKS);
+ }
};
void AddSC_boss_keleseth()
{
new boss_keleseth();
- new mob_frost_tomb();
- new mob_vrykul_skeleton();
+ new npc_frost_tomb();
+ new npc_vrykul_skeleton();
+ new spell_frost_tomb();
+ new achievement_on_the_rocks();
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
index 1bedd7e19e9..d5cd79b25f1 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_skadi.cpp
@@ -288,7 +288,7 @@ public:
me->Dismount();
if (Creature* pGrauf = me->SummonCreature(CREATURE_GRAUF, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 3*IN_MILLISECONDS))
{
- pGrauf->GetMotionMaster()->MoveFall(0);
+ pGrauf->GetMotionMaster()->MoveFall();
pGrauf->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
}
me->GetMotionMaster()->MoveJump(Location[4].GetPositionX(), Location[4].GetPositionY(), Location[4].GetPositionZ(), 5.0f, 10.0f);
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
index 01cd36266d0..5c1ec15030c 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
@@ -20,69 +20,94 @@
enum Spells
{
- SPELL_CALL_FLAMES = 48258,
- SPELL_RITUAL_OF_THE_SWORD = 48276, //Effect #1 Teleport, Effect #2 Dummy
+ SPELL_SVALA_TRANSFORMING1 = 54140,
+ SPELL_SVALA_TRANSFORMING2 = 54205,
+ SPELL_TRANSFORMING_CHANNEL = 54142,
+
+ SPELL_CALL_FLAMES = 48258, // caster effect only, triggers event 17841
SPELL_SINSTER_STRIKE = 15667,
H_SPELL_SINSTER_STRIKE = 59409,
- SPELL_SVALA_TRANSFORMING1 = 54140,
- SPELL_SVALA_TRANSFORMING2 = 54205
+
+ SPELL_RITUAL_PREPARATION = 48267,
+ SPELL_RITUAL_OF_THE_SWORD = 48276,
+ SPELL_RITUAL_STRIKE_TRIGGER = 48331, // triggers 48277 & 59930, needs NPC_RITUAL_TARGET as spell_script_target
+ SPELL_RITUAL_DISARM = 54159,
+ SPELL_RITUAL_STRIKE_EFF_1 = 48277,
+ SPELL_RITUAL_STRIKE_EFF_2 = 59930,
+
+ SPELL_SUMMONED_VIS = 64446,
+ SPELL_RITUAL_CHANNELER_1 = 48271,
+ SPELL_RITUAL_CHANNELER_2 = 48274,
+ SPELL_RITUAL_CHANNELER_3 = 48275,
+
+ // Ritual Channeler spells
+ SPELL_PARALYZE = 48278,
+ SPELL_SHADOWS_IN_THE_DARK = 59407,
+
+ // Scourge Hulk spells
+ SPELL_MIGHTY_BLOW = 48697,
+ SPELL_VOLATILE_INFECTION = 56785,
+ H_SPELL_VOLATILE_INFECTION = 59228
};
-//not in db
+
enum Yells
{
- SAY_DIALOG_WITH_ARTHAS_1 = -1575015,
- SAY_DIALOG_WITH_ARTHAS_2 = -1575016,
- SAY_DIALOG_WITH_ARTHAS_3 = -1575017,
- SAY_AGGRO = -1575018,
- SAY_SLAY_1 = -1575019,
- SAY_SLAY_2 = -1575020,
- SAY_SLAY_3 = -1575021,
- SAY_DEATH = -1575022,
- SAY_SACRIFICE_PLAYER_1 = -1575023,
- SAY_SACRIFICE_PLAYER_2 = -1575024,
- SAY_SACRIFICE_PLAYER_3 = -1575025,
- SAY_SACRIFICE_PLAYER_4 = -1575026,
- SAY_SACRIFICE_PLAYER_5 = -1575027,
- SAY_DIALOG_OF_ARTHAS_1 = -1575028,
- SAY_DIALOG_OF_ARTHAS_2 = -1575029
+ // Svala
+ SAY_SVALA_INTRO_0 = 0,
+
+ // Svala Sorrowgrave
+ SAY_SVALA_INTRO_1 = 0,
+ SAY_SVALA_INTRO_2 = 1,
+ SAY_AGGRO = 2,
+ SAY_SLAY = 3,
+ SAY_DEATH = 4,
+ SAY_SACRIFICE_PLAYER = 5,
+
+ // Image of Arthas
+ SAY_DIALOG_OF_ARTHAS_1 = 0,
+ SAY_DIALOG_OF_ARTHAS_2 = 1
};
+
enum Creatures
{
CREATURE_ARTHAS = 29280, // Image of Arthas
CREATURE_SVALA_SORROWGRAVE = 26668, // Svala after transformation
CREATURE_SVALA = 29281, // Svala before transformation
- CREATURE_RITUAL_CHANNELER = 27281
+ CREATURE_RITUAL_CHANNELER = 27281,
+ CREATURE_SPECTATOR = 26667,
+ CREATURE_RITUAL_TARGET = 27327,
+ CREATURE_FLAME_BRAZIER = 27273,
+ CREATURE_SCOURGE_HULK = 26555
};
-enum ChannelerSpells
-{
- //ritual channeler's spells
- SPELL_PARALYZE = 48278,
- SPELL_SHADOWS_IN_THE_DARK = 59407
-};
-enum Misc
+
+enum Objects
{
- DATA_SVALA_DISPLAY_ID = 25944
+ OBJECT_UTGARDE_MIRROR = 191745
};
-enum IntroPhase
+
+enum SvalaPhase
{
IDLE,
INTRO,
- FINISHED
+ NORMAL,
+ SACRIFICING,
+ SVALADEAD
};
-enum CombatPhase
+
+enum SvalaPoint
{
- NORMAL,
- SACRIFICING
+ POINT_FALL_GROUND = 1,
};
-static Position RitualChannelerPos[]=
+#define DATA_INCREDIBLE_HULK 2043
+
+static const float spectatorWP[2][3] =
{
- {296.42f, -355.01f, 90.94f, 0.0f},
- {302.36f, -352.01f, 90.54f, 0.0f},
- {291.39f, -350.89f, 90.54f, 0.0f}
+ {296.95f,-312.76f,86.36f},
+ {297.69f,-275.81f,86.36f}
};
+
static Position ArthasPos = { 295.81f, -366.16f, 92.57f, 1.58f };
-static Position SvalaPos = { 296.632f, -346.075f, 90.6307f, 1.58f };
class boss_svala : public CreatureScript
{
@@ -96,31 +121,96 @@ public:
struct boss_svalaAI : public ScriptedAI
{
- boss_svalaAI(Creature* c) : ScriptedAI(c)
+ boss_svalaAI(Creature* creature) : ScriptedAI(creature), summons(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
+ Phase = IDLE;
+
+ me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_1, true);
+ me->ApplySpellImmune(0, IMMUNITY_ID, SPELL_RITUAL_STRIKE_EFF_2, true);
}
- uint32 uiIntroTimer;
+ InstanceScript* instance;
+ SummonList summons;
+ SvalaPhase Phase;
+
+ Position pos;
+ float x, y, z;
- uint8 uiIntroPhase;
+ uint32 introTimer;
+ uint8 introPhase;
+ uint8 sacrePhase;
- IntroPhase Phase;
+ TempSummon* arthas;
+ uint64 arthasGUID;
- TempSummon* pArthas;
- uint64 uiArthasGUID;
+ uint32 sinsterStrikeTimer;
+ uint32 callFlamesTimer;
+ uint32 sacrificeTimer;
- InstanceScript* instance;
+ bool sacrificed;
void Reset()
{
- Phase = IDLE;
- uiIntroTimer = 1 * IN_MILLISECONDS;
- uiIntroPhase = 0;
- uiArthasGUID = 0;
+ sacrificed = false;
+ SetCombatMovement(true);
+
+ summons.DespawnAll();
+ me->RemoveAllAuras();
+
+ if (Phase > INTRO)
+ {
+ me->SetFlying(true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ }
+
+ if (Phase > NORMAL)
+ Phase = NORMAL;
+
+ introTimer = 1 * IN_MILLISECONDS;
+ introPhase = 0;
+ arthasGUID = 0;
if (instance)
+ {
instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
+ instance->SetData64(DATA_SACRIFICED_PLAYER, 0);
+ }
+ }
+
+ void JustReachedHome()
+ {
+ if (Phase > INTRO)
+ {
+ me->SetFlying(false);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SetOrientation(1.58f);
+ me->SendMovementFlagUpdate();
+ }
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ Talk(SAY_AGGRO);
+
+ sinsterStrikeTimer = 7 * IN_MILLISECONDS;
+ callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
+
+ if (instance)
+ instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
+ }
+
+ void JustSummoned(Creature* summon)
+ {
+ if (summon->GetEntry() == CREATURE_RITUAL_CHANNELER)
+ summon->CastSpell(summon, SPELL_SUMMONED_VIS, true);
+
+ summons.Summon(summon);
+ }
+
+ void SummonedCreatureDespawn(Creature* summon)
+ {
+ summons.Despawn(summon);
}
void MoveInLineOfSight(Unit* who)
@@ -132,287 +222,492 @@ public:
{
Phase = INTRO;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+
+ if (GameObject* mirror = GetClosestGameObjectWithEntry(me, OBJECT_UTGARDE_MIRROR, 100.0f))
+ mirror->SetGoState(GO_STATE_READY);
- if (Creature* pArthas = me->SummonCreature(CREATURE_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
+ if (Creature* arthas = me->SummonCreature(CREATURE_ARTHAS, ArthasPos, TEMPSUMMON_MANUAL_DESPAWN))
{
- pArthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- uiArthasGUID = pArthas->GetGUID();
+ arthas->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ arthasGUID = arthas->GetGUID();
}
}
}
+
+ void KilledUnit(Unit* victim)
+ {
+ if (victim != me)
+ Talk(SAY_SLAY);
+ }
+
+ void DamageTaken(Unit* attacker, uint32 &damage)
+ {
+ if (Phase == SVALADEAD)
+ {
+ if (attacker != me)
+ damage = 0;
+ return;
+ }
- void AttackStart(Unit* /*who*/) {}
+ if (damage >= me->GetHealth())
+ {
+ if (Phase == SACRIFICING)
+ SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
+
+ damage = 0;
+ Phase = SVALADEAD;
+ me->InterruptNonMeleeSpells(true);
+ me->RemoveAllAuras();
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ me->SetHealth(1);
+
+ SetCombatMovement(false);
+ me->HandleEmoteCommand(EMOTE_ONESHOT_FLYDEATH);
+ me->GetMotionMaster()->MoveFall(POINT_FALL_GROUND);
+ }
+ }
+
+ void MovementInform(uint32 motionType, uint32 pointId)
+ {
+ if (motionType != EFFECT_MOTION_TYPE)
+ return;
+
+ if (pointId == POINT_FALL_GROUND)
+ me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ }
+
+ void JustDied(Unit* /*killer*/)
+ {
+ summons.DespawnAll();
+
+ if (instance)
+ instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
+
+ Talk(SAY_DEATH);
+ }
+
+ void SpellHitTarget(Unit* /*target*/, const SpellInfo* spell)
+ {
+ if (spell->Id == SPELL_RITUAL_STRIKE_EFF_1 && Phase != NORMAL && Phase != SVALADEAD)
+ {
+ Phase = NORMAL;
+ SetCombatMovement(true);
+
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 300.0f, true))
+ me->GetMotionMaster()->MoveChase(target);
+ }
+ }
void UpdateAI(const uint32 diff)
{
- if (Phase != INTRO)
+ if (Phase == IDLE)
return;
- if (uiIntroTimer <= diff)
+ if (Phase == INTRO)
{
- Creature* pArthas = Unit::GetCreature(*me, uiArthasGUID);
- if (!pArthas)
+ if (introTimer <= diff)
+ {
+ Creature* arthas = Unit::GetCreature(*me, arthasGUID);
+ if (!arthas)
+ return;
+
+ switch (introPhase)
+ {
+ case 0:
+ Talk(SAY_SVALA_INTRO_0);
+ ++introPhase;
+ introTimer = 8100;
+ break;
+ case 1:
+ arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_1);
+ ++introPhase;
+ introTimer = 10000;
+ break;
+ case 2:
+ arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
+ me->SetFlying(true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ pos.Relocate(me);
+ pos.m_positionZ += 8.0f;
+ me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
+ // spectators flee event
+ if (instance)
+ {
+ std::list<Creature*> lspectatorList;
+ GetCreatureListWithEntryInGrid(lspectatorList, me, CREATURE_SPECTATOR, 100.0f);
+ for (std::list<Creature*>::iterator itr = lspectatorList.begin(); itr != lspectatorList.end(); ++itr)
+ {
+ if ((*itr)->isAlive())
+ {
+ (*itr)->SetStandState(UNIT_STAND_STATE_STAND);
+ (*itr)->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
+ (*itr)->GetMotionMaster()->MovePoint(1, spectatorWP[0][0], spectatorWP[0][1], spectatorWP[0][2]);
+ }
+ }
+ }
+ ++introPhase;
+ introTimer = 4200;
+ break;
+ case 3:
+ me->CastSpell(me, SPELL_SVALA_TRANSFORMING1, false);
+ ++introPhase;
+ introTimer = 6200;
+ break;
+ case 4:
+ me->CastSpell(me, SPELL_SVALA_TRANSFORMING2, false);
+ arthas->InterruptNonMeleeSpells(true);
+ me->RemoveAllAuras();
+ me->UpdateEntry(CREATURE_SVALA_SORROWGRAVE);
+ me->SetFacingToObject(arthas);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ ++introPhase;
+ introTimer = 3200;
+ break;
+ case 5:
+ Talk(SAY_SVALA_INTRO_1);
+ ++introPhase;
+ introTimer = 10000;
+ break;
+ case 6:
+ arthas->AI()->Talk(SAY_DIALOG_OF_ARTHAS_2);
+ ++introPhase;
+ introTimer = 7200;
+ break;
+ case 7:
+ Talk(SAY_SVALA_INTRO_2);
+ me->SetOrientation(1.58f);
+ me->SendMovementFlagUpdate();
+ arthas->SetVisible(false);
+ ++introPhase;
+ introTimer = 13800;
+ break;
+ case 8:
+ me->SetFlying(false);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SendMovementFlagUpdate();
+ pos.Relocate(me);
+ pos.m_positionX = me->GetHomePosition().GetPositionX();
+ pos.m_positionY = me->GetHomePosition().GetPositionY();
+ pos.m_positionZ = 90.6065f;
+ me->GetMotionMaster()->MoveLand(0, pos, 6.247422f);
+ ++introPhase;
+ introTimer = 3000;
+ break;
+ case 9:
+ if (GameObject* mirror = GetClosestGameObjectWithEntry(me, OBJECT_UTGARDE_MIRROR, 100.0f))
+ mirror->SetGoState(GO_STATE_ACTIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ arthas->DespawnOrUnsummon();
+ arthasGUID = 0;
+ Phase = NORMAL;
+ break;
+ }
+ }
+ else introTimer -= diff;
+
+ return;
+ }
+
+ if (Phase == NORMAL)
+ {
+ //Return since we have no target
+ if (!UpdateVictim())
return;
- switch (uiIntroPhase)
+ if (me->IsWithinMeleeRange(me->getVictim()) && me->HasUnitMovementFlag(MOVEMENTFLAG_LEVITATING))
+ {
+ me->SetFlying(false);
+ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+ me->SendMovementFlagUpdate();
+ }
+
+ if (sinsterStrikeTimer <= diff)
+ {
+ DoCast(me->getVictim(), SPELL_SINSTER_STRIKE);
+ sinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
+ } else sinsterStrikeTimer -= diff;
+
+ if (callFlamesTimer <= diff)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
+ {
+ DoCast(target, SPELL_CALL_FLAMES);
+ callFlamesTimer = urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
+ }
+ } else callFlamesTimer -= diff;
+
+ if (!sacrificed)
{
- case 0:
- DoScriptText(SAY_DIALOG_WITH_ARTHAS_1, me);
- ++uiIntroPhase;
- uiIntroTimer = 3500;
- break;
- case 1:
- DoScriptText(SAY_DIALOG_OF_ARTHAS_1, pArthas);
- ++uiIntroPhase;
- uiIntroTimer = 3500;
- break;
- case 2:
- DoScriptText(SAY_DIALOG_WITH_ARTHAS_2, me);
- ++uiIntroPhase;
- uiIntroTimer = 3500;
- break;
- case 3:
- DoScriptText(SAY_DIALOG_OF_ARTHAS_2, pArthas);
- ++uiIntroPhase;
- uiIntroTimer = 3500;
- break;
- case 4:
- DoScriptText(SAY_DIALOG_WITH_ARTHAS_3, me);
- DoCast(me, SPELL_SVALA_TRANSFORMING1);
- ++uiIntroPhase;
- uiIntroTimer = 2800;
- break;
- case 5:
- DoCast(me, SPELL_SVALA_TRANSFORMING2);
- ++uiIntroPhase;
- uiIntroTimer = 200;
- break;
- case 6:
- if (me->SummonCreature(CREATURE_SVALA_SORROWGRAVE, SvalaPos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 60*IN_MILLISECONDS))
+ if (HealthBelowPct(50))
+ {
+ if (Unit* sacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 80, true))
{
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetDisplayId(DATA_SVALA_DISPLAY_ID);
- pArthas->DespawnOrUnsummon();
- uiArthasGUID = 0;
- Phase = FINISHED;
+ if (instance)
+ instance->SetData64(DATA_SACRIFICED_PLAYER, sacrificeTarget->GetGUID());
+
+ Talk(SAY_SACRIFICE_PLAYER);
+
+ DoCast(sacrificeTarget, SPELL_RITUAL_PREPARATION);
+
+ SetCombatMovement(false);
+ me->SetFlying(true);
+ me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
+
+ Phase = SACRIFICING;
+ sacrePhase = 0;
+ sacrificeTimer = 1 * IN_MILLISECONDS;
+
+ DoCast(me, SPELL_RITUAL_OF_THE_SWORD);
+ sacrificed = true;
}
- else
- Reset();
- break;
+ }
}
- } else uiIntroTimer -= diff;
+
+ DoMeleeAttackIfReady();
+ }
+ else //SACRIFICING
+ {
+ if (sacrificeTimer <= diff)
+ {
+ switch (sacrePhase)
+ {
+ case 0:
+ // spawn ritual channelers
+ if (instance)
+ {
+ DoCast(me, SPELL_RITUAL_CHANNELER_1, true);
+ DoCast(me, SPELL_RITUAL_CHANNELER_2, true);
+ DoCast(me, SPELL_RITUAL_CHANNELER_3, true);
+ }
+ ++sacrePhase;
+ sacrificeTimer = 2 * IN_MILLISECONDS;
+ break;
+ case 1:
+ me->StopMoving();
+ me->GetMotionMaster()->MoveIdle();
+ me->InterruptNonMeleeSpells(true);
+ DoCast(me, SPELL_RITUAL_STRIKE_TRIGGER, true);
+ ++sacrePhase;
+ sacrificeTimer = 200;
+ break;
+ case 2:
+ DoCast(me, SPELL_RITUAL_DISARM);
+ ++sacrePhase;
+ break;
+ case 3:
+ break;
+ }
+ }
+ else sacrificeTimer -= diff;
+ }
}
};
};
-class mob_ritual_channeler : public CreatureScript
+class npc_ritual_channeler : public CreatureScript
{
public:
- mob_ritual_channeler() : CreatureScript("mob_ritual_channeler") { }
+ npc_ritual_channeler() : CreatureScript("npc_ritual_channeler") { }
CreatureAI* GetAI(Creature* creature) const
{
- return new mob_ritual_channelerAI(creature);
+ return new npc_ritual_channelerAI(creature);
}
- struct mob_ritual_channelerAI : public Scripted_NoMovementAI
+ struct npc_ritual_channelerAI : public Scripted_NoMovementAI
{
- mob_ritual_channelerAI(Creature* c) :Scripted_NoMovementAI(c)
+ npc_ritual_channelerAI(Creature* creature) :Scripted_NoMovementAI(creature)
{
- instance = c->GetInstanceScript();
+ instance = creature->GetInstanceScript();
}
InstanceScript* instance;
+ uint32 paralyzeTimer;
void Reset()
{
- DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
- }
-
- // called by svala sorrowgrave to set guid of victim
- void DoAction(const int32 /*action*/)
- {
+ paralyzeTimer = 1600;
if (instance)
- if (Unit* victim = me->GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
- DoCast(victim, SPELL_PARALYZE);
+ if (IsHeroic())
+ DoCast(me, SPELL_SHADOWS_IN_THE_DARK);
}
-
- void EnterCombat(Unit* /*who*/)
+
+ void UpdateAI(const uint32 diff)
{
+ if (me->HasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if (paralyzeTimer <= diff)
+ {
+ if (instance)
+ if (Unit* victim = me->GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)))
+ DoCast(victim, SPELL_PARALYZE, false);
+
+ paralyzeTimer = 200;
+ }
+ else
+ paralyzeTimer -= diff;
}
};
-
};
-class boss_svala_sorrowgrave : public CreatureScript
+class npc_spectator : public CreatureScript
{
public:
- boss_svala_sorrowgrave() : CreatureScript("boss_svala_sorrowgrave") { }
+ npc_spectator() : CreatureScript("npc_spectator") { }
CreatureAI* GetAI(Creature* creature) const
{
- return new boss_svala_sorrowgraveAI(creature);
+ return new npc_spectatorAI(creature);
}
- struct boss_svala_sorrowgraveAI : public ScriptedAI
+ struct npc_spectatorAI : public ScriptedAI
{
- boss_svala_sorrowgraveAI(Creature* c) : ScriptedAI(c), summons(c)
+ npc_spectatorAI(Creature* creature) : ScriptedAI(creature) { }
+
+ void Reset() { }
+
+ void MovementInform(uint32 motionType, uint32 pointId)
{
- instance = c->GetInstanceScript();
+ if (motionType == POINT_MOTION_TYPE)
+ {
+ if (pointId == 1)
+ me->GetMotionMaster()->MovePoint(2,spectatorWP[1][0],spectatorWP[1][1],spectatorWP[1][2]);
+ else if (pointId == 2)
+ me->DespawnOrUnsummon(1000);
+ }
}
+ };
+};
- uint32 uiSinsterStrikeTimer;
- uint32 uiCallFlamesTimer;
- uint32 uiRitualOfSwordTimer;
- uint32 uiSacrificeTimer;
+class checkRitualTarget
+{
+ public:
+ explicit checkRitualTarget(Unit* _caster) : caster(_caster) { }
- CombatPhase Phase;
+ bool operator() (Unit* unit)
+ {
+ if (InstanceScript* instance = caster->GetInstanceScript())
+ if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID())
+ return false;
- SummonList summons;
+ return true;
+ }
- bool bSacrificed;
+ private:
+ Unit* caster;
+};
- InstanceScript* instance;
+class spell_paralyze_pinnacle : public SpellScriptLoader
+{
+ public:
+ spell_paralyze_pinnacle() : SpellScriptLoader("spell_paralyze_pinnacle") { }
- void Reset()
+ class spell_paralyze_pinnacle_SpellScript : public SpellScript
{
- uiSinsterStrikeTimer = 7 * IN_MILLISECONDS;
- uiCallFlamesTimer = 10 * IN_MILLISECONDS;
- uiRitualOfSwordTimer = 20 * IN_MILLISECONDS;
- uiSacrificeTimer = 8 * IN_MILLISECONDS;
-
- bSacrificed = false;
-
- Phase = NORMAL;
-
- DoTeleportTo(296.632f, -346.075f, 90.6307f);
- me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
+ PrepareSpellScript(spell_paralyze_pinnacle_SpellScript);
- summons.DespawnAll();
+ void FilterTargets(std::list<Unit*>& unitList)
+ {
+ unitList.remove_if(checkRitualTarget(GetCaster()));
+ }
- if (instance)
+ void Register()
{
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, NOT_STARTED);
- instance->SetData64(DATA_SACRIFICED_PLAYER, 0);
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
- }
+ };
- void EnterCombat(Unit* /*who*/)
+ SpellScript* GetSpellScript() const
{
- DoScriptText(SAY_AGGRO, me);
-
- if (instance)
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, IN_PROGRESS);
+ return new spell_paralyze_pinnacle_SpellScript();
}
+};
- void JustSummoned(Creature* summon)
- {
- summons.Summon(summon);
- }
+class npc_scourge_hulk : public CreatureScript
+{
+ public:
+ npc_scourge_hulk() : CreatureScript("npc_scourge_hulk") { }
- void SummonedCreatureDespawn(Creature* summon)
+ struct npc_scourge_hulkAI : public ScriptedAI
{
- summons.Despawn(summon);
- }
+ npc_scourge_hulkAI(Creature* creature) : ScriptedAI(creature) { }
- void UpdateAI(const uint32 diff)
- {
- if (Phase == NORMAL)
+ uint32 mightyBlow;
+ uint32 volatileInfection;
+
+ void Reset()
+ {
+ mightyBlow = urand(4000, 9000);
+ volatileInfection = urand(10000, 14000);
+ killedByRitualStrike = false;
+ }
+
+ uint32 GetData(uint32 type)
+ {
+ return type == DATA_INCREDIBLE_HULK ? killedByRitualStrike : 0;
+ }
+
+ void DamageTaken(Unit* attacker, uint32 &damage)
+ {
+ if (damage >= me->GetHealth() && attacker->GetEntry() == CREATURE_SVALA_SORROWGRAVE)
+ killedByRitualStrike = true;
+ }
+
+ void UpdateAI(uint32 const diff)
{
- //Return since we have no target
if (!UpdateVictim())
return;
- if (uiSinsterStrikeTimer <= diff)
- {
- DoCast(me->getVictim(), SPELL_SINSTER_STRIKE);
- uiSinsterStrikeTimer = urand(5 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
- } else uiSinsterStrikeTimer -= diff;
-
- if (uiCallFlamesTimer <= diff)
+ if (mightyBlow <= diff)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- {
- DoCast(target, SPELL_CALL_FLAMES);
- uiCallFlamesTimer = urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS);
- }
- } else uiCallFlamesTimer -= diff;
+ if (Unit* victim = me->getVictim())
+ if (!victim->HasUnitState(UNIT_STAT_STUNNED)) // Prevent knocking back a ritual player
+ DoCast(victim, SPELL_MIGHTY_BLOW);
+ mightyBlow = urand(12000, 17000);
+ }
+ else
+ mightyBlow -= diff;
- if (!bSacrificed)
+ if (volatileInfection <= diff)
{
- if (uiRitualOfSwordTimer <= diff)
- {
- if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- {
- DoScriptText(RAND(SAY_SACRIFICE_PLAYER_1, SAY_SACRIFICE_PLAYER_2, SAY_SACRIFICE_PLAYER_3, SAY_SACRIFICE_PLAYER_4, SAY_SACRIFICE_PLAYER_5), me);
- DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD);
- //Spell doesn't teleport
- DoTeleportPlayer(pSacrificeTarget, 296.632f, -346.075f, 90.63f, 4.6f);
- me->SetUnitMovementFlags(MOVEMENTFLAG_CAN_FLY);
- DoTeleportTo(296.632f, -346.075f, 120.85f);
- Phase = SACRIFICING;
- if (instance)
- {
- instance->SetData64(DATA_SACRIFICED_PLAYER, pSacrificeTarget->GetGUID());
-
- for (uint8 i = 0; i < 3; ++i)
- if (Creature* summon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
- summon->AI()->DoAction(0);
- }
-
- bSacrificed = true;
- }
- } else uiRitualOfSwordTimer -= diff;
+ DoCastVictim(SPELL_VOLATILE_INFECTION);
+ volatileInfection = urand(13000, 17000);
}
+ else
+ volatileInfection -= diff;
DoMeleeAttackIfReady();
}
- else //SACRIFICING
- {
- if (uiSacrificeTimer <= diff)
- {
- Unit* pSacrificeTarget = instance ? Unit::GetUnit(*me, instance->GetData64(DATA_SACRIFICED_PLAYER)) : NULL;
- if (instance && !summons.empty() && pSacrificeTarget && pSacrificeTarget->isAlive())
- me->Kill(pSacrificeTarget, false); // durability damage?
-
- //go down
- Phase = NORMAL;
- pSacrificeTarget = NULL;
- me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- me->GetMotionMaster()->MoveChase(target);
- uiSacrificeTimer = 8 * IN_MILLISECONDS;
- }
- else uiSacrificeTimer -= diff;
- }
- }
+ private:
+ bool killedByRitualStrike;
+ };
- void KilledUnit(Unit* /*victim*/)
+ CreatureAI* GetAI(Creature* creature) const
{
- DoScriptText(RAND(SAY_SLAY_1, SAY_SLAY_2, SAY_SLAY_3), me);
+ return new npc_scourge_hulkAI(creature);
}
+};
- void JustDied(Unit* killer)
- {
- if (instance)
- {
- Creature* pSvala = Unit::GetCreature((*me), instance->GetData64(DATA_SVALA));
- if (pSvala && pSvala->isAlive())
- killer->Kill(pSvala);
+class achievement_incredible_hulk : public AchievementCriteriaScript
+{
+ public:
+ achievement_incredible_hulk() : AchievementCriteriaScript("achievement_incredible_hulk") { }
- instance->SetData(DATA_SVALA_SORROWGRAVE_EVENT, DONE);
- }
- DoScriptText(SAY_DEATH, me);
+ bool OnCheck(Player* /*player*/, Unit* target)
+ {
+ return target && target->IsAIEnabled && target->GetAI()->GetData(DATA_INCREDIBLE_HULK);
}
- };
-
};
void AddSC_boss_svala()
{
new boss_svala();
- new mob_ritual_channeler();
- new boss_svala_sorrowgrave();
+ new npc_ritual_channeler();
+ new npc_spectator();
+ new spell_paralyze_pinnacle();
+ new npc_scourge_hulk();
+ new achievement_incredible_hulk();
}
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp
index c5bc235da1f..cb596f284c5 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/instance_pinnacle.cpp
@@ -170,8 +170,12 @@ public:
void SetData64(uint32 type, uint64 data)
{
- if (type == DATA_SACRIFICED_PLAYER)
- uiSacrificedPlayer = data;
+ switch (type)
+ {
+ case DATA_SACRIFICED_PLAYER:
+ uiSacrificedPlayer = data;
+ break;
+ }
}
uint32 GetData(uint32 type)
@@ -201,6 +205,7 @@ public:
case DATA_MOB_ORB: return uiPalehoofOrb;
case DATA_SVALA: return uiSvala;
case DATA_GORTOK_PALEHOOF_SPHERE: return uiGortokPalehoofSphere;
+ case DATA_SACRIFICED_PLAYER: return uiSacrificedPlayer;
}
return 0;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
index 7d10483ca1d..872314ee25e 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/utgarde_pinnacle.h
@@ -53,7 +53,7 @@ enum eCreatures
MOB_MASSIVE_JORMUNGAR = 26685,
MOB_FEROCIOUS_RHINO = 26686,
MOB_SVALA = 29281,
- MOB_PALEHOOF_ORB = 26688,
+ MOB_PALEHOOF_ORB = 26688
};
#endif
diff --git a/src/server/scripts/Northrend/dalaran.cpp b/src/server/scripts/Northrend/dalaran.cpp
index 57007a93fa7..cd3cbf29d0d 100644
--- a/src/server/scripts/Northrend/dalaran.cpp
+++ b/src/server/scripts/Northrend/dalaran.cpp
@@ -32,7 +32,12 @@ Script Data End */
enum Spells
{
SPELL_TRESPASSER_A = 54028,
- SPELL_TRESPASSER_H = 54029
+ SPELL_TRESPASSER_H = 54029,
+
+ SPELL_SUNREAVER_DISGUISE_FEMALE = 70973,
+ SPELL_SUNREAVER_DISGUISE_MALE = 70974,
+ SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971,
+ SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972,
};
enum NPCs // All outdoor guards are within 35.0f of these NPCs
@@ -71,8 +76,10 @@ public:
Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself();
- // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
- if (!player || player->isGameMaster() || player->IsBeingTeleported() || player->HasAura(70973) || player->HasAura(70971))
+ if (!player || player->isGameMaster() || player->IsBeingTeleported() ||
+ // If player has Disguise aura for quest A Meeting With The Magister or An Audience With The Arcanist, do not teleport it away but let it pass
+ player->HasAura(SPELL_SUNREAVER_DISGUISE_FEMALE) || player->HasAura(SPELL_SUNREAVER_DISGUISE_MALE) ||
+ player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_FEMALE) || player->HasAura(SPELL_SILVER_COVENANT_DISGUISE_MALE))
return;
switch (me->GetEntry())
diff --git a/src/server/scripts/Northrend/grizzly_hills.cpp b/src/server/scripts/Northrend/grizzly_hills.cpp
index de0c6a909ad..9eb73463795 100644
--- a/src/server/scripts/Northrend/grizzly_hills.cpp
+++ b/src/server/scripts/Northrend/grizzly_hills.cpp
@@ -16,115 +16,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Grizzly_Hills
-SD%Complete: 80
-SDComment: Quest support: 12231, 12247
-SDCategory: Grizzly Hills
-EndScriptData */
-
-/* ContentData
-npc_orsonn_and_kodian
-EndContentData */
-
#include "ScriptPCH.h"
#include "ScriptedEscortAI.h"
-#define GOSSIP_ITEM1 "You're free to go Orsonn, but first tell me what's wrong with the furbolg."
-#define GOSSIP_ITEM2 "What happened then?"
-#define GOSSIP_ITEM3 "Thank you, Son of Ursoc. I'll see what can be done."
-#define GOSSIP_ITEM4 "Who was this stranger?"
-#define GOSSIP_ITEM5 "Thank you, Kodian. I'll do what I can."
-
-enum eEnums
-{
- GOSSIP_TEXTID_ORSONN1 = 12793,
- GOSSIP_TEXTID_ORSONN2 = 12794,
- GOSSIP_TEXTID_ORSONN3 = 12796,
-
- GOSSIP_TEXTID_KODIAN1 = 12797,
- GOSSIP_TEXTID_KODIAN2 = 12798,
-
- NPC_ORSONN = 27274,
- NPC_KODIAN = 27275,
-
- //trigger creatures
- NPC_ORSONN_CREDIT = 27322,
- NPC_KODIAN_CREDIT = 27321,
-
- QUEST_CHILDREN_OF_URSOC = 12247,
- QUEST_THE_BEAR_GODS_OFFSPRING = 12231
-};
-
-class npc_orsonn_and_kodian : public CreatureScript
-{
-public:
- npc_orsonn_and_kodian() : CreatureScript("npc_orsonn_and_kodian") { }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(QUEST_CHILDREN_OF_URSOC) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_THE_BEAR_GODS_OFFSPRING) == QUEST_STATUS_INCOMPLETE)
- {
- switch (creature->GetEntry())
- {
- case NPC_ORSONN:
- if (!player->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_ORSONN_CREDIT) || !player->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_ORSONN_CREDIT))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN1, creature->GetGUID());
- return true;
- }
- break;
- case NPC_KODIAN:
- if (!player->GetReqKillOrCastCurrentCount(QUEST_CHILDREN_OF_URSOC, NPC_KODIAN_CREDIT) || !player->GetReqKillOrCastCurrentCount(QUEST_THE_BEAR_GODS_OFFSPRING, NPC_KODIAN_CREDIT))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN1, creature->GetGUID());
- return true;
- }
- break;
- }
- }
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (uiAction)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN2, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_ORSONN3, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->CLOSE_GOSSIP_MENU();
- player->TalkedToCreature(NPC_ORSONN_CREDIT, creature->GetGUID());
- break;
-
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(GOSSIP_TEXTID_KODIAN2, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->CLOSE_GOSSIP_MENU();
- player->TalkedToCreature(NPC_KODIAN_CREDIT, creature->GetGUID());
- break;
- }
-
- return true;
- }
-};
-
/*######
## Quest 12027: Mr. Floppy's Perilous Adventure
######*/
@@ -801,7 +695,6 @@ public:
void AddSC_grizzly_hills()
{
- new npc_orsonn_and_kodian;
new npc_emily;
new npc_mrfloppy;
new npc_outhouse_bunny;
diff --git a/src/server/scripts/Northrend/icecrown.cpp b/src/server/scripts/Northrend/icecrown.cpp
index 28384455616..91522503d65 100644
--- a/src/server/scripts/Northrend/icecrown.cpp
+++ b/src/server/scripts/Northrend/icecrown.cpp
@@ -115,38 +115,6 @@ public:
};
/*######
-## npc_dame_evniki_kapsalis
-######*/
-
-enum eDameEnvikiKapsalis
-{
- TITLE_CRUSADER = 123
-};
-
-class npc_dame_evniki_kapsalis : public CreatureScript
-{
-public:
- npc_dame_evniki_kapsalis() : CreatureScript("npc_dame_evniki_kapsalis") { }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (player->HasTitle(TITLE_CRUSADER))
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*uiSender*/, uint32 uiAction)
- {
- player->PlayerTalkClass->ClearMenus();
- if (uiAction == GOSSIP_ACTION_TRADE)
- player->GetSession()->SendListInventory(creature->GetGUID());
- return true;
- }
-};
-
-/*######
## npc_squire_david
######*/
@@ -276,65 +244,6 @@ public:
};
/*######
-## npc_alorah_and_grimmin
-######*/
-
-enum ealorah_and_grimmin
-{
- SPELL_CHAIN = 68341,
- NPC_FJOLA_LIGHTBANE = 36065,
- NPC_EYDIS_DARKBANE = 36066,
- NPC_PRIESTESS_ALORAH = 36101,
- NPC_PRIEST_GRIMMIN = 36102
-};
-
-class npc_alorah_and_grimmin : public CreatureScript
-{
-public:
- npc_alorah_and_grimmin() : CreatureScript("npc_alorah_and_grimmin") { }
-
- struct npc_alorah_and_grimminAI : public ScriptedAI
- {
- npc_alorah_and_grimminAI(Creature* creature) : ScriptedAI(creature) {}
-
- bool uiCast;
-
- void Reset()
- {
- uiCast = false;
- }
-
- void UpdateAI(const uint32 /*uiDiff*/)
- {
- if (uiCast)
- return;
- uiCast = true;
- Creature* target = NULL;
-
- switch (me->GetEntry())
- {
- case NPC_PRIESTESS_ALORAH:
- target = me->FindNearestCreature(NPC_EYDIS_DARKBANE, 10.0f);
- break;
- case NPC_PRIEST_GRIMMIN:
- target = me->FindNearestCreature(NPC_FJOLA_LIGHTBANE, 10.0f);
- break;
- }
- if (target)
- DoCast(target, SPELL_CHAIN);
-
- if (!UpdateVictim())
- return;
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_alorah_and_grimminAI(creature);
- }
-};
-
-/*######
## npc_guardian_pavilion
######*/
@@ -429,10 +338,8 @@ public:
void AddSC_icecrown()
{
new npc_arete;
- new npc_dame_evniki_kapsalis;
new npc_squire_david;
new npc_argent_valiant;
- new npc_alorah_and_grimmin;
new npc_guardian_pavilion;
new npc_vereth_the_cunning;
}
diff --git a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp
index 81211b6e3d9..aa63f1adf18 100644
--- a/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ManaTombs/boss_nexusprince_shaffar.cpp
@@ -187,7 +187,7 @@ public:
//expire movement, will prevent from running right back to victim after cast
//(but should MoveChase be used again at a certain time or should he not move?)
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == CHASE_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired();
DoCast(me, SPELL_BLINK);
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index b23b7bcd1ac..c17b6d5baf3 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -1982,7 +1982,7 @@ void boss_illidan_stormrage::boss_illidan_stormrageAI::HandleTalkSequence()
Akama->GetMotionMaster()->Clear(false);
// Akama->GetMotionMaster()->MoveIdle();
Akama->SetPosition(x, y, z, 0.0f);
- Akama->SendMonsterMove(x, y, z, 0, MOVEMENTFLAG_NONE, 0); // Illidan must not die until Akama arrives.
+ Akama->MonsterMoveWithSpeed(x, y, z, 0); // Illidan must not die until Akama arrives.
Akama->GetMotionMaster()->MoveChase(me);
}
diff --git a/src/server/scripts/Outland/CMakeLists.txt b/src/server/scripts/Outland/CMakeLists.txt
index ffd9332c8aa..229f7de72ec 100644
--- a/src/server/scripts/Outland/CMakeLists.txt
+++ b/src/server/scripts/Outland/CMakeLists.txt
@@ -45,6 +45,7 @@ set(scripts_STAT_SRCS
Outland/CoilfangReservoir/underbog/boss_hungarfen.cpp
Outland/CoilfangReservoir/underbog/boss_the_black_stalker.cpp
Outland/shattrath_city.cpp
+ Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
Outland/TempestKeep/Mechanar/boss_pathaleon_the_calculator.cpp
Outland/TempestKeep/Mechanar/boss_nethermancer_sepethrea.cpp
Outland/TempestKeep/Mechanar/mechanar.h
diff --git a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
index 33196b1213a..b7604c41794 100644
--- a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
+++ b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
@@ -151,7 +151,7 @@ public:
m_bPerformingGroundSlam = false;
//and correct movement, if not already
- if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
{
if (me->getVictim())
me->GetMotionMaster()->MoveChase(me->getVictim());
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
index 8cd516f44df..982b8372b7c 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_kaelthas.cpp
@@ -820,7 +820,7 @@ class boss_kaelthas : public CreatureScript
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
me->SetPosition(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
- me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, 0, 0);
+ me->MonsterMoveWithSpeed(afGravityPos[0], afGravityPos[1], afGravityPos[2], 1);
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_FULLPOWER);
@@ -887,7 +887,7 @@ class boss_kaelthas : public CreatureScript
me->GetMotionMaster()->Clear();
me->GetMotionMaster()->MoveIdle();
me->SetPosition(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
- me->SendMonsterMove(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0, MOVEMENTFLAG_NONE, 0);
+ me->MonsterMoveWithSpeed(afGravityPos[0], afGravityPos[1], afGravityPos[2], 0);
// 1) Kael'thas will portal the whole raid right into his body
for (i = me->getThreatManager().getThreatList().begin(); i!= me->getThreatManager().getThreatList().end(); ++i)
diff --git a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
new file mode 100644
index 00000000000..ed818fb13be
--- /dev/null
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+//! TODO - Boss not scripted, just ported required spellscript from core
+
+#include "ScriptMgr.h"
+#include "SpellScript.h"
+
+enum Spells
+{
+ SPELL_POSITIVE_CHARGE = 39090,
+ SPELL_POSITIVE_CHARGE_STACK = 39089,
+ SPELL_NEGATIVE_CHARGE = 39093,
+ SPELL_NEGATIVE_CHARGE_STACK = 39092
+};
+
+class spell_capacitus_polarity_shift : public SpellScriptLoader
+{
+ public:
+ spell_capacitus_polarity_shift() : SpellScriptLoader("spell_capacitus_polarity_shift") { }
+
+ class spell_capacitus_polarity_shift_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_capacitus_polarity_shift_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_POSITIVE_CHARGE_STACK))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_NEGATIVE_CHARGE_STACK))
+ return false;
+ return true;
+ }
+
+ void HandleTargets(std::list<Unit*>& targetList)
+ {
+ uint8 count = 0;
+ for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
+ if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
+ if (Player* target = (*ihit)->ToPlayer())
+ if (target->HasAura(GetTriggeringSpell()->Id))
+ ++count;
+
+ if (count)
+ {
+ uint32 spellId = 0;
+
+ if (GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE)
+ spellId = SPELL_POSITIVE_CHARGE_STACK;
+ else // if (GetSpellInfo()->Id == SPELL_NEGATIVE_CHARGE)
+ spellId = SPELL_NEGATIVE_CHARGE_STACK;
+
+ GetCaster()->SetAuraStack(spellId, GetCaster(), count);
+ }
+ }
+
+ void HandleDamage(SpellEffIndex /*effIndex*/)
+ {
+ if (!GetTriggeringSpell())
+ return;
+
+ Unit* target = GetHitUnit();
+
+ if (target->HasAura(GetTriggeringSpell()->Id))
+ SetHitDamage(0);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_shift_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ OnUnitTargetSelect += SpellUnitTargetFn(spell_capacitus_polarity_shift_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_capacitus_polarity_shift_SpellScript();
+ }
+};
+
+void AddSC_boss_mechano_lord_capacitus()
+{
+ new spell_capacitus_polarity_shift();
+}
diff --git a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
index 78acd88c894..db95f60f556 100644
--- a/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
+++ b/src/server/scripts/Outland/TempestKeep/arcatraz/arcatraz.cpp
@@ -38,19 +38,18 @@ EndContentData */
enum eMillhouseSays
{
- SAY_INTRO_1 = -1552010,
- SAY_INTRO_2 = -1552011,
- SAY_WATER = -1552012,
- SAY_BUFFS = -1552013,
- SAY_DRINK = -1552014,
- SAY_READY = -1552015,
- SAY_KILL_1 = -1552016,
- SAY_KILL_2 = -1552017,
- SAY_PYRO = -1552018,
- SAY_ICEBLOCK = -1552019,
- SAY_LOWHP = -1552020,
- SAY_DEATH = -1552021,
- SAY_COMPLETE = -1552022,
+ SAY_INTRO_1 = 0,
+ SAY_INTRO_2 = 1,
+ SAY_WATER = 2,
+ SAY_BUFFS = 3,
+ SAY_DRINK = 4,
+ SAY_READY = 5,
+ SAY_KILL = 6,
+ SAY_PYRO = 7,
+ SAY_ICEBLOCK = 8,
+ SAY_LOWHP = 9,
+ SAY_DEATH = 10,
+ SAY_COMPLETE = 11,
};
enum eMillhouseSpells
@@ -107,7 +106,7 @@ class npc_millhouse_manastorm : public CreatureScript
Init = true;
if (instance->GetData(TYPE_HARBINGERSKYRISS) == DONE)
- DoScriptText(SAY_COMPLETE, me);
+ Talk(SAY_COMPLETE);
}
}
@@ -126,12 +125,12 @@ class npc_millhouse_manastorm : public CreatureScript
void KilledUnit(Unit* /*victim*/)
{
- DoScriptText(RAND(SAY_KILL_1, SAY_KILL_2), me);
+ Talk(SAY_KILL);
}
void JustDied(Unit* /*victim*/)
{
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
/*for questId 10886 (heroic mode only)
if (instance && instance->GetData(TYPE_HARBINGERSKYRISS) != DONE)
@@ -149,30 +148,30 @@ class npc_millhouse_manastorm : public CreatureScript
switch (Phase)
{
case 1:
- DoScriptText(SAY_INTRO_1, me);
+ Talk(SAY_INTRO_1);
EventProgress_Timer = 18000;
break;
case 2:
- DoScriptText(SAY_INTRO_2, me);
+ Talk(SAY_INTRO_2);
EventProgress_Timer = 18000;
break;
case 3:
- DoScriptText(SAY_WATER, me);
+ Talk(SAY_WATER);
DoCast(me, SPELL_CONJURE_WATER);
EventProgress_Timer = 7000;
break;
case 4:
- DoScriptText(SAY_BUFFS, me);
+ Talk(SAY_BUFFS);
DoCast(me, SPELL_ICE_ARMOR);
EventProgress_Timer = 7000;
break;
case 5:
- DoScriptText(SAY_DRINK, me);
+ Talk(SAY_DRINK);
DoCast(me, SPELL_ARCANE_INTELLECT);
EventProgress_Timer = 7000;
break;
case 6:
- DoScriptText(SAY_READY, me);
+ Talk(SAY_READY);
EventProgress_Timer = 6000;
break;
case 7:
@@ -192,7 +191,7 @@ class npc_millhouse_manastorm : public CreatureScript
return;
if (!LowHp && HealthBelowPct(20))
{
- DoScriptText(SAY_LOWHP, me);
+ Talk(SAY_LOWHP);
LowHp = true;
}
@@ -201,7 +200,7 @@ class npc_millhouse_manastorm : public CreatureScript
if (me->IsNonMeleeSpellCasted(false))
return;
- DoScriptText(SAY_PYRO, me);
+ Talk(SAY_PYRO);
DoCast(me->getVictim(), SPELL_PYROBLAST);
Pyroblast_Timer = 40000;
@@ -232,14 +231,14 @@ class npc_millhouse_manastorm : public CreatureScript
enum eWardenSays
{
- YELL_INTRO1 = -1552023,
- YELL_INTRO2 = -1552024,
- YELL_RELEASE1 = -1552025,
- YELL_RELEASE2A = -1552026,
- YELL_RELEASE2B = -1552027,
- YELL_RELEASE3 = -1552028,
- YELL_RELEASE4 = -1552029,
- YELL_WELCOME = -1552030,
+ YELL_INTRO1 = 0,
+ YELL_INTRO2 = 1,
+ YELL_RELEASE1 = 2,
+ YELL_RELEASE2A = 3,
+ YELL_RELEASE2B = 4,
+ YELL_RELEASE3 = 5,
+ YELL_RELEASE4 = 6,
+ YELL_WELCOME = 7,
};
enum eWardenUnits
@@ -274,10 +273,10 @@ class npc_warden_mellichar : public CreatureScript
{
public:
- npc_warden_mellichar()
- : CreatureScript("npc_warden_mellichar")
+ npc_warden_mellichar() : CreatureScript("npc_warden_mellichar")
{
}
+
struct npc_warden_mellicharAI : public ScriptedAI
{
npc_warden_mellicharAI(Creature* creature) : ScriptedAI(creature)
@@ -330,7 +329,7 @@ class npc_warden_mellichar : public CreatureScript
void EnterCombat(Unit* /*who*/)
{
- DoScriptText(YELL_INTRO1, me);
+ Talk(YELL_INTRO1);
DoCast(me, SPELL_BUBBLE_VISUAL);
if (instance)
@@ -437,7 +436,7 @@ class npc_warden_mellichar : public CreatureScript
me->SummonCreature(ENTRY_MILLHOUSE, 413.292f, -148.378f, 42.56f, 6.27f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000);
break;
case 4:
- DoScriptText(YELL_RELEASE2B, me);
+ Talk(YELL_RELEASE2B);
break;
case 5:
switch (urand(0, 1))
@@ -463,7 +462,7 @@ class npc_warden_mellichar : public CreatureScript
break;
case 7:
me->SummonCreature(ENTRY_SKYRISS, 445.763f, -191.639f, 44.64f, 1.60f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 600000);
- DoScriptText(YELL_WELCOME, me);
+ Talk(YELL_WELCOME);
break;
}
CanSpawn = false;
@@ -474,17 +473,17 @@ class npc_warden_mellichar : public CreatureScript
switch (Phase)
{
case 1:
- DoScriptText(YELL_INTRO2, me);
+ Talk(YELL_INTRO2);
EventProgress_Timer = 10000;
++Phase;
break;
case 2:
- DoScriptText(YELL_RELEASE1, me);
+ Talk(YELL_RELEASE1);
DoPrepareForPhase();
EventProgress_Timer = 7000;
break;
case 3:
- DoScriptText(YELL_RELEASE2A, me);
+ Talk(YELL_RELEASE2A);
DoPrepareForPhase();
EventProgress_Timer = 10000;
break;
@@ -493,12 +492,12 @@ class npc_warden_mellichar : public CreatureScript
EventProgress_Timer = 15000;
break;
case 5:
- DoScriptText(YELL_RELEASE3, me);
+ Talk(YELL_RELEASE3);
DoPrepareForPhase();
EventProgress_Timer = 15000;
break;
case 6:
- DoScriptText(YELL_RELEASE4, me);
+ Talk(YELL_RELEASE4);
DoPrepareForPhase();
EventProgress_Timer = 15000;
break;
@@ -524,14 +523,16 @@ class npc_warden_mellichar : public CreatureScript
# mob_zerekethvoidzone (this script probably not needed in future -> `creature_template_addon`.`auras`='36120 0')
#####*/
-#define SPELL_VOID_ZONE_DAMAGE 36120
+enum ZerekethSpell
+{
+ SPELL_VOID_ZONE_DAMAGE = 36120,
+};
class mob_zerekethvoidzone : public CreatureScript
{
public:
- mob_zerekethvoidzone()
- : CreatureScript("mob_zerekethvoidzone")
+ mob_zerekethvoidzone() : CreatureScript("mob_zerekethvoidzone")
{
}
struct mob_zerekethvoidzoneAI : public ScriptedAI
@@ -555,10 +556,10 @@ class mob_zerekethvoidzone : public CreatureScript
return new mob_zerekethvoidzoneAI(creature);
}
};
+
void AddSC_arcatraz()
{
new npc_millhouse_manastorm();
new npc_warden_mellichar();
new mob_zerekethvoidzone();
}
-
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 38e5771ccca..96d259817c0 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -412,6 +412,75 @@ class spell_gen_leeching_swarm : public SpellScriptLoader
}
};
+enum EluneCandle
+{
+ NPC_OMEN = 15467,
+
+ SPELL_ELUNE_CANDLE_OMEN_HEAD = 26622,
+ SPELL_ELUNE_CANDLE_OMEN_CHEST = 26624,
+ SPELL_ELUNE_CANDLE_OMEN_HAND_R = 26625,
+ SPELL_ELUNE_CANDLE_OMEN_HAND_L = 26649,
+ SPELL_ELUNE_CANDLE_NORMAL = 26636,
+};
+
+class spell_gen_elune_candle : public SpellScriptLoader
+{
+ public:
+ spell_gen_elune_candle() : SpellScriptLoader("spell_gen_elune_candle") {}
+
+ class spell_gen_elune_candle_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_elune_candle_SpellScript);
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HEAD))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_CHEST))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HAND_R))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_OMEN_HAND_L))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_ELUNE_CANDLE_NORMAL))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ uint32 spellId = 0;
+
+ if (target->GetEntry() == NPC_OMEN)
+ {
+ switch (urand(0, 3))
+ {
+ case 0: spellId = SPELL_ELUNE_CANDLE_OMEN_HEAD; break;
+ case 1: spellId = SPELL_ELUNE_CANDLE_OMEN_CHEST; break;
+ case 2: spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_R; break;
+ case 3: spellId = SPELL_ELUNE_CANDLE_OMEN_HAND_L; break;
+ }
+ }
+ else
+ spellId = SPELL_ELUNE_CANDLE_NORMAL;
+
+ GetCaster()->CastSpell(target, spellId, true, NULL);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_elune_candle_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_elune_candle_SpellScript();
+ }
+};
+
// 24750 Trick
enum eTrickSpells
{
@@ -1445,7 +1514,17 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader
if (GetUnitOwner()->GetTypeId() != TYPEID_PLAYER)
return;
- LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*(sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID()).begin()));
+ const LfgDungeonSet dungeons = sLFGMgr->GetSelectedDungeons(GetUnitOwner()->GetGUID());
+ LfgDungeonSet::const_iterator itr = dungeons.begin();
+
+ if (itr == dungeons.end())
+ {
+ Remove(AURA_REMOVE_BY_DEFAULT);
+ return;
+ }
+
+
+ LFGDungeonEntry const* randomDungeon = sLFGDungeonStore.LookupEntry(*itr);
Group* group = GetUnitOwner()->ToPlayer()->GetGroup();
Map const* map = GetUnitOwner()->GetMap();
if (group && group->isLFGGroup())
@@ -1471,6 +1550,824 @@ class spell_gen_luck_of_the_draw : public SpellScriptLoader
}
};
+enum DalaranDisguiseSpells
+{
+ SPELL_SUNREAVER_DISGUISE_TRIGGER = 69672,
+ SPELL_SUNREAVER_DISGUISE_FEMALE = 70973,
+ SPELL_SUNREAVER_DISGUISE_MALE = 70974,
+
+ SPELL_SILVER_COVENANT_DISGUISE_TRIGGER = 69673,
+ SPELL_SILVER_COVENANT_DISGUISE_FEMALE = 70971,
+ SPELL_SILVER_COVENANT_DISGUISE_MALE = 70972,
+};
+
+class spell_gen_dalaran_disguise : public SpellScriptLoader
+{
+ public:
+ spell_gen_dalaran_disguise(const char* name) : SpellScriptLoader(name) {}
+
+ class spell_gen_dalaran_disguise_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_dalaran_disguise_SpellScript);
+ bool Validate(SpellInfo const* spellEntry)
+ {
+ switch (spellEntry->Id)
+ {
+ case SPELL_SUNREAVER_DISGUISE_TRIGGER:
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_FEMALE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUNREAVER_DISGUISE_MALE))
+ return false;
+ break;
+ case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
+ if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_FEMALE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_SILVER_COVENANT_DISGUISE_MALE))
+ return false;
+ break;
+ }
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+
+ if (Player* player = GetHitPlayer())
+ {
+ uint8 gender = player->getGender();
+
+ uint32 spellId = GetSpellInfo()->Id;
+
+ switch (spellId)
+ {
+ case SPELL_SUNREAVER_DISGUISE_TRIGGER:
+ spellId = gender ? SPELL_SUNREAVER_DISGUISE_FEMALE : SPELL_SUNREAVER_DISGUISE_MALE;
+ break;
+ case SPELL_SILVER_COVENANT_DISGUISE_TRIGGER:
+ spellId = gender ? SPELL_SILVER_COVENANT_DISGUISE_FEMALE : SPELL_SILVER_COVENANT_DISGUISE_MALE;
+ break;
+ default:
+ break;
+ }
+
+ GetCaster()->CastSpell(player, spellId, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_dalaran_disguise_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_dalaran_disguise_SpellScript();
+ }
+};
+
+/* DOCUMENTATION: Break-Shield spells
+ Break-Shield spells can be classified in three groups:
+
+ - Spells on vehicle bar used by players:
+ + EFFECT_0: SCRIPT_EFFECT
+ + EFFECT_1: NONE
+ + EFFECT_2: NONE
+ - Spells casted by players triggered by script:
+ + EFFECT_0: SCHOOL_DAMAGE
+ + EFFECT_1: SCRIPT_EFFECT
+ + EFFECT_2: FORCE_CAST
+ - Spells casted by NPCs on players:
+ + EFFECT_0: SCHOOL_DAMAGE
+ + EFFECT_1: SCRIPT_EFFECT
+ + EFFECT_2: NONE
+
+ In the following script we handle the SCRIPT_EFFECT for effIndex EFFECT_0 and EFFECT_1.
+ - When handling EFFECT_0 we're in the "Spells on vehicle bar used by players" case
+ and we'll trigger "Spells casted by players triggered by script"
+ - When handling EFFECT_1 we're in the "Spells casted by players triggered by script"
+ or "Spells casted by NPCs on players" so we'll search for the first defend layer and drop it.
+*/
+
+enum BreakShieldSpells
+{
+ SPELL_BREAK_SHIELD_DAMAGE_2K = 62626,
+ SPELL_BREAK_SHIELD_DAMAGE_10K = 64590,
+
+ SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS = 62575, // Also on ToC5 mounts
+ SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE = 64595,
+ SPELL_BREAK_SHIELD_TRIGGER_UNK = 66480,
+};
+
+class spell_gen_break_shield: public SpellScriptLoader
+{
+public:
+ spell_gen_break_shield() : SpellScriptLoader("spell_gen_break_shield") { }
+
+ class spell_gen_break_shield_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_break_shield_SpellScript)
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTargetUnit();
+
+ if (!caster || !target)
+ return;
+
+ switch (effIndex)
+ {
+ case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual)
+ uint32 spellId;
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_BREAK_SHIELD_TRIGGER_UNK:
+ case SPELL_BREAK_SHIELD_TRIGGER_CAMPAING_WARHORSE:
+ spellId = SPELL_BREAK_SHIELD_DAMAGE_10K;
+ break;
+ case SPELL_BREAK_SHIELD_TRIGGER_FACTION_MOUNTS:
+ spellId = SPELL_BREAK_SHIELD_DAMAGE_2K;
+ break;
+ default:
+ return;
+ }
+
+ if (Unit* rider = caster->GetCharmer())
+ rider->CastSpell(target, spellId, false);
+ else
+ caster->CastSpell(target, spellId, false);
+ break;
+ case EFFECT_1: // On damaging spells, for removing the a defend layer
+ Unit::AuraApplicationMap const& auras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ Aura* aura = itr->second->GetBase();
+ SpellInfo const* auraInfo = aura->GetSpellInfo();
+ if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN))
+ aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
+ }
+ break;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_gen_break_shield_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_break_shield_SpellScript();
+ }
+};
+
+/* DOCUMENTATION: Charge spells
+ Charge spells can be classified in four groups:
+
+ - Spells on vehicle bar used by players:
+ + EFFECT_0: SCRIPT_EFFECT
+ + EFFECT_1: TRIGGER_SPELL
+ + EFFECT_2: NONE
+ - Spells casted by player's mounts triggered by script:
+ + EFFECT_0: CHARGE
+ + EFFECT_1: TRIGGER_SPELL
+ + EFFECT_2: APPLY_AURA
+ - Spells casted by players on the target triggered by script:
+ + EFFECT_0: SCHOOL_DAMAGE
+ + EFFECT_1: SCRIPT_EFFECT
+ + EFFECT_2: NONE
+ - Spells casted by NPCs on players:
+ + EFFECT_0: SCHOOL_DAMAGE
+ + EFFECT_1: CHARGE
+ + EFFECT_2: SCRIPT_EFFECT
+
+ In the following script we handle the SCRIPT_EFFECT and CHARGE
+ - When handling SCRIPT_EFFECT:
+ + EFFECT_0: Corresponds to "Spells on vehicle bar used by players" and we make player's mount cast
+ the charge effect on the current target ("Spells casted by player's mounts triggered by script").
+ + EFFECT_1 and EFFECT_2: Triggered when "Spells casted by player's mounts triggered by script" hits target,
+ corresponding to "Spells casted by players on the target triggered by script" and "Spells casted by
+ NPCs on players" and we check Defend layers and drop a charge of the first found.
+ - When handling CHARGE:
+ + Only launched for "Spells casted by player's mounts triggered by script", makes the player cast the
+ damaging spell on target with a small chance of failing it.
+*/
+
+enum ChargeSpells
+{
+ SPELL_CHARGE_DAMAGE_8K5 = 62874,
+ SPELL_CHARGE_DAMAGE_20K = 68498,
+ SPELL_CHARGE_DAMAGE_45K = 64591,
+
+ SPELL_CHARGE_CHARGING_EFFECT_8K5 = 63661,
+ SPELL_CHARGE_CHARGING_EFFECT_20K_1 = 68284,
+ SPELL_CHARGE_CHARGING_EFFECT_20K_2 = 68501,
+ SPELL_CHARGE_CHARGING_EFFECT_45K_1 = 62563,
+ SPELL_CHARGE_CHARGING_EFFECT_45K_2 = 66481,
+
+ SPELL_CHARGE_TRIGGER_FACTION_MOUNTS = 62960,
+ SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION = 68282,
+
+ SPELL_CHARGE_MISS_EFFECT = 62977,
+};
+
+class spell_gen_mounted_charge: public SpellScriptLoader
+{
+public:
+ spell_gen_mounted_charge() : SpellScriptLoader("spell_gen_mounted_charge") { }
+
+ class spell_gen_mounted_charge_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_mounted_charge_SpellScript)
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTargetUnit();
+
+ if (!caster || !target)
+ return;
+
+ switch (effIndex)
+ {
+ case EFFECT_0: // On spells wich trigger the damaging spell (and also the visual)
+ uint32 spellId;
+
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_CHARGE_TRIGGER_TRIAL_CHAMPION:
+ spellId = SPELL_CHARGE_CHARGING_EFFECT_20K_1;
+ case SPELL_CHARGE_TRIGGER_FACTION_MOUNTS:
+ spellId = SPELL_CHARGE_CHARGING_EFFECT_8K5;
+ break;
+ default:
+ return;
+ }
+
+ if (Unit* vehicle = caster->GetVehicleBase())
+ vehicle->CastSpell(target, spellId, false);
+ else
+ caster->CastSpell(target, spellId, false);
+ break;
+ case EFFECT_1: // On damaging spells, for removing the a defend layer
+ case EFFECT_2:
+ Unit::AuraApplicationMap const& auras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ Aura* aura = itr->second->GetBase();
+ SpellInfo const* auraInfo = aura->GetSpellInfo();
+ if (aura && auraInfo->SpellIconID == 2007 && aura->HasEffectType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN))
+ aura->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL);
+ }
+ break;
+ }
+ }
+
+ void HandleChargeEffect(SpellEffIndex effIndex)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTargetUnit();
+
+ if (!caster || !target)
+ return;
+
+ uint32 spellId;
+
+ switch (GetSpellInfo()->Id)
+ {
+ case SPELL_CHARGE_CHARGING_EFFECT_8K5:
+ spellId = SPELL_CHARGE_DAMAGE_8K5;
+ break;
+ case SPELL_CHARGE_CHARGING_EFFECT_20K_1:
+ case SPELL_CHARGE_CHARGING_EFFECT_20K_2:
+ spellId = SPELL_CHARGE_DAMAGE_20K;
+ break;
+ case SPELL_CHARGE_CHARGING_EFFECT_45K_1:
+ case SPELL_CHARGE_CHARGING_EFFECT_45K_2:
+ spellId = SPELL_CHARGE_DAMAGE_45K;
+ break;
+ default:
+ return;
+ }
+
+ // If target isn't a training dummy there's a chance of failing the charge
+ if (!target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE) && urand(0,7) == 0)
+ spellId = SPELL_CHARGE_MISS_EFFECT;
+
+ if (Unit* rider = caster->GetCharmer())
+ rider->CastSpell(target, spellId, false);
+ else
+ caster->CastSpell(target, spellId, false);
+ }
+
+ void Register()
+ {
+ SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId);
+
+ if (spell->HasEffect(SPELL_EFFECT_SCRIPT_EFFECT))
+ OnEffectHit += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleScriptEffect, EFFECT_FIRST_FOUND, SPELL_EFFECT_SCRIPT_EFFECT);
+
+ if (spell->Effects[EFFECT_0].Effect == SPELL_EFFECT_CHARGE)
+ OnEffectHit += SpellEffectFn(spell_gen_mounted_charge_SpellScript::HandleChargeEffect, EFFECT_0, SPELL_EFFECT_CHARGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_mounted_charge_SpellScript();
+ }
+};
+
+enum DefendVisuals
+{
+ SPELL_VISUAL_SHIELD_1 = 63130,
+ SPELL_VISUAL_SHIELD_2 = 63131,
+ SPELL_VISUAL_SHIELD_3 = 63132,
+};
+
+class spell_gen_defend : public SpellScriptLoader
+{
+ public:
+ spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
+
+ class spell_gen_defendAuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_defendAuraScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_1))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_2))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_VISUAL_SHIELD_3))
+ return false;
+ return true;
+ }
+
+ void RefreshVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTarget();
+
+ if(!target)
+ return;
+
+ if (!caster)
+ {
+ target->RemoveAurasDueToSpell(GetId());
+ return;
+ }
+
+ for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
+ target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
+
+ target->CastSpell(target, SPELL_VISUAL_SHIELD_1 + GetAura()->GetStackAmount() - 1);
+ }
+
+ void RemoveVisualShields(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+
+ if(!target)
+ return;
+
+ for (uint8 i = 0; i < GetSpellInfo()->StackAmount; ++i)
+ target->RemoveAurasDueToSpell(SPELL_VISUAL_SHIELD_1 + i);
+ }
+
+ void RemoveDummyFromDriver(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+
+ if (caster && caster->ToTempSummon())
+ if (Unit* rider = caster->ToTempSummon()->GetSummoner())
+ rider->RemoveAurasDueToSpell(GetId());
+ }
+
+ void Register()
+ {
+ SpellInfo const* spell = sSpellMgr->GetSpellInfo(m_scriptSpellId);
+
+ // Defend spells casted by NPCs (add visuals)
+ if (spell->Effects[EFFECT_0].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ // Remove Defend spell from player when he dismounts
+ if (spell->Effects[EFFECT_2].ApplyAuraName == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveDummyFromDriver, EFFECT_2, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
+
+ // Defend spells casted by players (add/remove visuals)
+ if (spell->Effects[EFFECT_1].ApplyAuraName == SPELL_AURA_DUMMY)
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defendAuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defendAuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_defendAuraScript();
+ }
+};
+
+enum MountedDuelSpells
+{
+ SPELL_ON_TOURNAMENT_MOUNT = 63034,
+ SPELL_MOUNTED_DUEL = 62875,
+};
+
+class spell_gen_tournament_duel : public SpellScriptLoader
+{
+ public:
+ spell_gen_tournament_duel() : SpellScriptLoader("spell_gen_tournament_duel") { }
+
+ class spell_gen_tournament_duel_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_tournament_duel_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_ON_TOURNAMENT_MOUNT))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_MOUNTED_DUEL))
+ return false;
+ return true;
+ }
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetTargetUnit();
+ Unit* player = GetCaster()->GetCharmer();
+
+ if (!caster || !target || !player)
+ return;
+
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+
+ if (!target->HasAura(SPELL_ON_TOURNAMENT_MOUNT) || !target->GetVehicleBase())
+ return;
+
+ player->CastSpell(target, SPELL_MOUNTED_DUEL, true);
+ }
+ else if (target->GetTypeId() == TYPEID_UNIT)
+ {
+ if (!target->GetCharmer() || target->GetCharmer()->GetTypeId() != TYPEID_PLAYER || !target->GetCharmer()->HasAura(SPELL_ON_TOURNAMENT_MOUNT))
+ return;
+
+ player->CastSpell(target->GetCharmer(), SPELL_MOUNTED_DUEL, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHit += SpellEffectFn(spell_gen_tournament_duel_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_tournament_duel_SpellScript();
+ }
+};
+
+enum TournamentMountsSpells
+{
+ SPELL_LANCE_EQUIPPED = 62853,
+};
+
+class spell_gen_summon_tournament_mount : public SpellScriptLoader
+{
+ public:
+ spell_gen_summon_tournament_mount() : SpellScriptLoader("spell_gen_summon_tournament_mount") { }
+
+ class spell_gen_summon_tournament_mount_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_summon_tournament_mount_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellEntry*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_LANCE_EQUIPPED))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckIfLanceEquiped()
+ {
+ Unit* caster = GetCaster();
+
+ if (!caster->HasAura(SPELL_LANCE_EQUIPPED))
+ {
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_HAVE_LANCE_EQUIPPED);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_gen_summon_tournament_mount_SpellScript::CheckIfLanceEquiped);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_summon_tournament_mount_SpellScript();
+ }
+};
+
+enum TournamentPennantSpells
+{
+ SPELL_PENNANT_STORMWIND_ASPIRANT = 62595,
+ SPELL_PENNANT_STORMWIND_VALIANT = 62596,
+ SPELL_PENNANT_STORMWIND_CHAMPION = 62594,
+ SPELL_PENNANT_GNOMEREGAN_ASPIRANT = 63394,
+ SPELL_PENNANT_GNOMEREGAN_VALIANT = 63395,
+ SPELL_PENNANT_GNOMEREGAN_CHAMPION = 63396,
+ SPELL_PENNANT_SEN_JIN_ASPIRANT = 63397,
+ SPELL_PENNANT_SEN_JIN_VALIANT = 63398,
+ SPELL_PENNANT_SEN_JIN_CHAMPION = 63399,
+ SPELL_PENNANT_SILVERMOON_ASPIRANT = 63401,
+ SPELL_PENNANT_SILVERMOON_VALIANT = 63402,
+ SPELL_PENNANT_SILVERMOON_CHAMPION = 63403,
+ SPELL_PENNANT_DARNASSUS_ASPIRANT = 63404,
+ SPELL_PENNANT_DARNASSUS_VALIANT = 63405,
+ SPELL_PENNANT_DARNASSUS_CHAMPION = 63406,
+ SPELL_PENNANT_EXODAR_ASPIRANT = 63421,
+ SPELL_PENNANT_EXODAR_VALIANT = 63422,
+ SPELL_PENNANT_EXODAR_CHAMPION = 63423,
+ SPELL_PENNANT_IRONFORGE_ASPIRANT = 63425,
+ SPELL_PENNANT_IRONFORGE_VALIANT = 63426,
+ SPELL_PENNANT_IRONFORGE_CHAMPION = 63427,
+ SPELL_PENNANT_UNDERCITY_ASPIRANT = 63428,
+ SPELL_PENNANT_UNDERCITY_VALIANT = 63429,
+ SPELL_PENNANT_UNDERCITY_CHAMPION = 63430,
+ SPELL_PENNANT_ORGRIMMAR_ASPIRANT = 63431,
+ SPELL_PENNANT_ORGRIMMAR_VALIANT = 63432,
+ SPELL_PENNANT_ORGRIMMAR_CHAMPION = 63433,
+ SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT = 63434,
+ SPELL_PENNANT_THUNDER_BLUFF_VALIANT = 63435,
+ SPELL_PENNANT_THUNDER_BLUFF_CHAMPION = 63436,
+ SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT = 63606,
+ SPELL_PENNANT_ARGENT_CRUSADE_VALIANT = 63500,
+ SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION = 63501,
+ SPELL_PENNANT_EBON_BLADE_ASPIRANT = 63607,
+ SPELL_PENNANT_EBON_BLADE_VALIANT = 63608,
+ SPELL_PENNANT_EBON_BLADE_CHAMPION = 63609,
+};
+
+enum TournamentMounts
+{
+ NPC_STORMWIND_STEED = 33217,
+ NPC_IRONFORGE_RAM = 33316,
+ NPC_GNOMEREGAN_MECHANOSTRIDER = 33317,
+ NPC_EXODAR_ELEKK = 33318,
+ NPC_DARNASSIAN_NIGHTSABER = 33319,
+ NPC_ORGRIMMAR_WOLF = 33320,
+ NPC_DARK_SPEAR_RAPTOR = 33321,
+ NPC_THUNDER_BLUFF_KODO = 33322,
+ NPC_SILVERMOON_HAWKSTRIDER = 33323,
+ NPC_FORSAKEN_WARHORSE = 33324,
+ NPC_ARGENT_WARHORSE = 33782,
+ NPC_ARGENT_STEED_ASPIRANT = 33845,
+ NPC_ARGENT_HAWKSTRIDER_ASPIRANT = 33844,
+};
+
+enum TournamentQuestsAchievements
+{
+ ACHIEVEMENT_CHAMPION_STORMWIND = 2781,
+ ACHIEVEMENT_CHAMPION_DARNASSUS = 2777,
+ ACHIEVEMENT_CHAMPION_IRONFORGE = 2780,
+ ACHIEVEMENT_CHAMPION_GNOMEREGAN = 2779,
+ ACHIEVEMENT_CHAMPION_THE_EXODAR = 2778,
+ ACHIEVEMENT_CHAMPION_ORGRIMMAR = 2783,
+ ACHIEVEMENT_CHAMPION_SEN_JIN = 2784,
+ ACHIEVEMENT_CHAMPION_THUNDER_BLUFF = 2786,
+ ACHIEVEMENT_CHAMPION_UNDERCITY = 2787,
+ ACHIEVEMENT_CHAMPION_SILVERMOON = 2785,
+ ACHIEVEMENT_ARGENT_VALOR = 2758,
+ ACHIEVEMENT_CHAMPION_ALLIANCE = 2782,
+ ACHIEVEMENT_CHAMPION_HORDE = 2788,
+
+ QUEST_VALIANT_OF_STORMWIND = 13593,
+ QUEST_A_VALIANT_OF_STORMWIND = 13684,
+ QUEST_VALIANT_OF_DARNASSUS = 13706,
+ QUEST_A_VALIANT_OF_DARNASSUS = 13689,
+ QUEST_VALIANT_OF_IRONFORGE = 13703,
+ QUEST_A_VALIANT_OF_IRONFORGE = 13685,
+ QUEST_VALIANT_OF_GNOMEREGAN = 13704,
+ QUEST_A_VALIANT_OF_GNOMEREGAN = 13688,
+ QUEST_VALIANT_OF_THE_EXODAR = 13705,
+ QUEST_A_VALIANT_OF_THE_EXODAR = 13690,
+ QUEST_VALIANT_OF_ORGRIMMAR = 13707,
+ QUEST_A_VALIANT_OF_ORGRIMMAR = 13691,
+ QUEST_VALIANT_OF_SEN_JIN = 13708,
+ QUEST_A_VALIANT_OF_SEN_JIN = 13693,
+ QUEST_VALIANT_OF_THUNDER_BLUFF = 13709,
+ QUEST_A_VALIANT_OF_THUNDER_BLUFF = 13694,
+ QUEST_VALIANT_OF_UNDERCITY = 13710,
+ QUEST_A_VALIANT_OF_UNDERCITY = 13695,
+ QUEST_VALIANT_OF_SILVERMOON = 13711,
+ QUEST_A_VALIANT_OF_SILVERMOON = 13696,
+};
+
+class spell_gen_on_tournament_mount : public SpellScriptLoader
+{
+ public:
+ spell_gen_on_tournament_mount() : SpellScriptLoader("spell_gen_on_tournament_mount") { }
+
+ class spell_gen_on_tournament_mountAuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_on_tournament_mountAuraScript);
+
+ uint32 _pennantSpellId;
+
+ bool Load()
+ {
+ _pennantSpellId = 0;
+ return (GetCaster()->GetTypeId() == TYPEID_PLAYER);
+ }
+
+ void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+
+ if (caster && caster->GetVehicleBase())
+ {
+ _pennantSpellId = GetPennatSpellId(caster->ToPlayer(), caster->GetVehicleBase());
+ caster->CastSpell(caster, _pennantSpellId,true);
+ }
+ }
+
+ void HandleRemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+
+ if (caster)
+ caster->RemoveAurasDueToSpell(_pennantSpellId);
+ }
+
+ uint32 GetPennatSpellId(Player* player, Unit* mount)
+ {
+ switch (mount->GetEntry())
+ {
+ case NPC_ARGENT_STEED_ASPIRANT:
+ case NPC_STORMWIND_STEED:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_STORMWIND))
+ return SPELL_PENNANT_STORMWIND_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_STORMWIND) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_STORMWIND))
+ return SPELL_PENNANT_STORMWIND_VALIANT;
+ else
+ return SPELL_PENNANT_STORMWIND_ASPIRANT;
+ }
+ case NPC_GNOMEREGAN_MECHANOSTRIDER:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_GNOMEREGAN))
+ return SPELL_PENNANT_GNOMEREGAN_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_GNOMEREGAN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_GNOMEREGAN))
+ return SPELL_PENNANT_GNOMEREGAN_VALIANT;
+ else
+ return SPELL_PENNANT_GNOMEREGAN_ASPIRANT;
+ }
+ case NPC_DARK_SPEAR_RAPTOR:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SEN_JIN))
+ return SPELL_PENNANT_SEN_JIN_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SEN_JIN) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SEN_JIN))
+ return SPELL_PENNANT_SEN_JIN_VALIANT;
+ else
+ return SPELL_PENNANT_SEN_JIN_ASPIRANT;
+ }
+ case NPC_ARGENT_HAWKSTRIDER_ASPIRANT:
+ case NPC_SILVERMOON_HAWKSTRIDER:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_SILVERMOON))
+ return SPELL_PENNANT_SILVERMOON_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_SILVERMOON) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_SILVERMOON))
+ return SPELL_PENNANT_SILVERMOON_VALIANT;
+ else
+ return SPELL_PENNANT_SILVERMOON_ASPIRANT;
+ }
+ case NPC_DARNASSIAN_NIGHTSABER:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_DARNASSUS))
+ return SPELL_PENNANT_DARNASSUS_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_DARNASSUS) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_DARNASSUS))
+ return SPELL_PENNANT_DARNASSUS_VALIANT;
+ else
+ return SPELL_PENNANT_DARNASSUS_ASPIRANT;
+ }
+ case NPC_EXODAR_ELEKK:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THE_EXODAR))
+ return SPELL_PENNANT_EXODAR_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THE_EXODAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THE_EXODAR))
+ return SPELL_PENNANT_EXODAR_VALIANT;
+ else
+ return SPELL_PENNANT_EXODAR_ASPIRANT;
+ }
+ case NPC_IRONFORGE_RAM:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_IRONFORGE))
+ return SPELL_PENNANT_IRONFORGE_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_IRONFORGE) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_IRONFORGE))
+ return SPELL_PENNANT_IRONFORGE_VALIANT;
+ else
+ return SPELL_PENNANT_IRONFORGE_ASPIRANT;
+ }
+ case NPC_FORSAKEN_WARHORSE:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_UNDERCITY))
+ return SPELL_PENNANT_UNDERCITY_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_UNDERCITY) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_UNDERCITY))
+ return SPELL_PENNANT_UNDERCITY_VALIANT;
+ else
+ return SPELL_PENNANT_UNDERCITY_ASPIRANT;
+ }
+ case NPC_ORGRIMMAR_WOLF:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ORGRIMMAR))
+ return SPELL_PENNANT_ORGRIMMAR_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_ORGRIMMAR) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_ORGRIMMAR))
+ return SPELL_PENNANT_ORGRIMMAR_VALIANT;
+ else
+ return SPELL_PENNANT_ORGRIMMAR_ASPIRANT;
+ }
+ case NPC_THUNDER_BLUFF_KODO:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_THUNDER_BLUFF))
+ return SPELL_PENNANT_THUNDER_BLUFF_CHAMPION;
+ else if (player->GetQuestRewardStatus(QUEST_VALIANT_OF_THUNDER_BLUFF) || player->GetQuestRewardStatus(QUEST_A_VALIANT_OF_THUNDER_BLUFF))
+ return SPELL_PENNANT_THUNDER_BLUFF_VALIANT;
+ else
+ return SPELL_PENNANT_THUNDER_BLUFF_ASPIRANT;
+ }
+ case NPC_ARGENT_WARHORSE:
+ {
+ if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_ALLIANCE) || player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_CHAMPION_HORDE))
+ return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_CHAMPION : SPELL_PENNANT_ARGENT_CRUSADE_CHAMPION;
+ else if (player->GetAchievementMgr().HasAchieved(ACHIEVEMENT_ARGENT_VALOR))
+ return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_VALIANT : SPELL_PENNANT_ARGENT_CRUSADE_VALIANT;
+ else
+ return player->getClass() == CLASS_DEATH_KNIGHT ? SPELL_PENNANT_EBON_BLADE_ASPIRANT : SPELL_PENNANT_ARGENT_CRUSADE_ASPIRANT;
+ }
+ default:
+ return 0;
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mountAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mountAuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_on_tournament_mountAuraScript();
+ }
+};
+
+class spell_gen_tournament_pennant : public SpellScriptLoader
+{
+ public:
+ spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { }
+
+ class spell_gen_tournament_pennantAuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_tournament_pennantAuraScript);
+
+ void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+
+ if (caster && caster->GetTypeId() == TYPEID_PLAYER && !caster->GetVehicleBase())
+ caster->RemoveAurasDueToSpell(GetId());
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_tournament_pennantAuraScript();
+ }
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -1504,4 +2401,14 @@ void AddSC_generic_spell_scripts()
new spell_gen_oracle_wolvar_reputation();
new spell_gen_damage_reduction_aura();
new spell_gen_luck_of_the_draw();
+ new spell_gen_dalaran_disguise("spell_gen_sunreaver_disguise");
+ new spell_gen_dalaran_disguise("spell_gen_silver_covenant_disguise");
+ new spell_gen_elune_candle();
+ new spell_gen_break_shield();
+ new spell_gen_mounted_charge();
+ new spell_gen_defend();
+ new spell_gen_tournament_duel();
+ new spell_gen_summon_tournament_mount();
+ new spell_gen_on_tournament_mount();
+ new spell_gen_tournament_pennant();
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 5a0ffbd2c90..b40879d500e 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -1128,6 +1128,51 @@ class spell_magic_eater_food : public SpellScriptLoader
}
};
+enum Refocus
+{
+ SPELL_AIMED_SHOT = 19434,
+ SPELL_MULTISHOT = 2643,
+ SPELL_VOLLEY = 42243,
+};
+
+class spell_item_refocus : public SpellScriptLoader
+{
+ public:
+ spell_item_refocus() : SpellScriptLoader("spell_item_refocus") { }
+
+ class spell_item_refocus_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_refocus_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+
+ if (!caster || caster->getClass() != CLASS_HUNTER)
+ return;
+
+ if (caster->HasSpellCooldown(SPELL_AIMED_SHOT))
+ caster->RemoveSpellCooldown(SPELL_AIMED_SHOT, true);
+
+ if (caster->HasSpellCooldown(SPELL_MULTISHOT))
+ caster->RemoveSpellCooldown(SPELL_MULTISHOT, true);
+
+ if (caster->HasSpellCooldown(SPELL_VOLLEY))
+ caster->RemoveSpellCooldown(SPELL_VOLLEY, true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_item_refocus_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_item_refocus_SpellScript();
+ }
+};
+
void AddSC_item_spell_scripts()
{
// 23074 Arcanite Dragonling
@@ -1160,4 +1205,5 @@ void AddSC_item_spell_scripts()
new spell_item_ashbringer();
new spell_magic_eater_food();
+ new spell_item_refocus();
}
diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp
index 8ce06685893..135f22e0a01 100755
--- a/src/server/scripts/World/achievement_scripts.cpp
+++ b/src/server/scripts/World/achievement_scripts.cpp
@@ -285,6 +285,17 @@ class achievement_bg_sa_defense_of_ancients : public AchievementCriteriaScript
}
};
+class achievement_tilted : public AchievementCriteriaScript
+{
+ public:
+ achievement_tilted() : AchievementCriteriaScript("achievement_tilted") {}
+
+ bool OnCheck(Player* player, Unit* /*target*/)
+ {
+ return player && player->duel && player->duel->isMounted;
+ }
+};
+
void AddSC_achievement_scripts()
{
new achievement_resilient_victory();
@@ -302,4 +313,5 @@ void AddSC_achievement_scripts()
new achievement_arena_kills("achievement_arena_3v3_kills", ARENA_TYPE_3v3);
new achievement_arena_kills("achievement_arena_5v5_kills", ARENA_TYPE_5v5);
new achievement_bg_sa_defense_of_ancients();
+ new achievement_tilted();
}
diff --git a/src/server/scripts/World/guards.cpp b/src/server/scripts/World/guards.cpp
index d562542a7d7..9bc511931b9 100644
--- a/src/server/scripts/World/guards.cpp
+++ b/src/server/scripts/World/guards.cpp
@@ -179,7 +179,7 @@ public:
globalCooldown = GENERIC_CREATURE_COOLDOWN;
} //If no spells available and we arn't moving run to target
- else if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
+ else if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != CHASE_MOTION_TYPE)
{
//Cancel our current spell and then mutate new movement generator
me->InterruptNonMeleeSpells(false);
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index 21e4fe6a3a0..9227c0c1138 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -40,6 +40,7 @@ npc_sayge 100% Darkmoon event fortune teller, buff player based
npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap
npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage
npc_locksmith 75% list of keys needs to be confirmed
+npc_firework 100% NPC's summoned by rockets and rocket clusters, for making them cast visual
EndContentData */
#include "ScriptPCH.h"
@@ -2764,6 +2765,285 @@ public:
}
};
+enum Fireworks
+{
+ NPC_OMEN = 15467,
+ NPC_MINION_OF_OMEN = 15466,
+ NPC_FIREWORK_BLUE = 15879,
+ NPC_FIREWORK_GREEN = 15880,
+ NPC_FIREWORK_PURPLE = 15881,
+ NPC_FIREWORK_RED = 15882,
+ NPC_FIREWORK_YELLOW = 15883,
+ NPC_FIREWORK_WHITE = 15884,
+ NPC_FIREWORK_BIG_BLUE = 15885,
+ NPC_FIREWORK_BIG_GREEN = 15886,
+ NPC_FIREWORK_BIG_PURPLE = 15887,
+ NPC_FIREWORK_BIG_RED = 15888,
+ NPC_FIREWORK_BIG_YELLOW = 15889,
+ NPC_FIREWORK_BIG_WHITE = 15890,
+
+ NPC_CLUSTER_BLUE = 15872,
+ NPC_CLUSTER_RED = 15873,
+ NPC_CLUSTER_GREEN = 15874,
+ NPC_CLUSTER_PURPLE = 15875,
+ NPC_CLUSTER_WHITE = 15876,
+ NPC_CLUSTER_YELLOW = 15877,
+ NPC_CLUSTER_BIG_BLUE = 15911,
+ NPC_CLUSTER_BIG_GREEN = 15912,
+ NPC_CLUSTER_BIG_PURPLE = 15913,
+ NPC_CLUSTER_BIG_RED = 15914,
+ NPC_CLUSTER_BIG_WHITE = 15915,
+ NPC_CLUSTER_BIG_YELLOW = 15916,
+ NPC_CLUSTER_ELUNE = 15918,
+
+ GO_FIREWORK_LAUNCHER_1 = 180771,
+ GO_FIREWORK_LAUNCHER_2 = 180868,
+ GO_FIREWORK_LAUNCHER_3 = 180850,
+ GO_CLUSTER_LAUNCHER_1 = 180772,
+ GO_CLUSTER_LAUNCHER_2 = 180859,
+ GO_CLUSTER_LAUNCHER_3 = 180869,
+ GO_CLUSTER_LAUNCHER_4 = 180874,
+
+ SPELL_ROCKET_BLUE = 26344,
+ SPELL_ROCKET_GREEN = 26345,
+ SPELL_ROCKET_PURPLE = 26346,
+ SPELL_ROCKET_RED = 26347,
+ SPELL_ROCKET_WHITE = 26348,
+ SPELL_ROCKET_YELLOW = 26349,
+ SPELL_ROCKET_BIG_BLUE = 26351,
+ SPELL_ROCKET_BIG_GREEN = 26352,
+ SPELL_ROCKET_BIG_PURPLE = 26353,
+ SPELL_ROCKET_BIG_RED = 26354,
+ SPELL_ROCKET_BIG_WHITE = 26355,
+ SPELL_ROCKET_BIG_YELLOW = 26356,
+ SPELL_LUNAR_FORTUNE = 26522,
+
+ ANIM_GO_LAUNCH_FIREWORK = 3,
+ ZONE_MOONGLADE = 493,
+};
+
+Position omenSummonPos = {7558.993f, -2839.999f, 450.0214f, 4.46f};
+
+class npc_firework : public CreatureScript
+{
+public:
+ npc_firework() : CreatureScript("npc_firework") { }
+
+ struct npc_fireworkAI : public ScriptedAI
+ {
+ npc_fireworkAI(Creature* creature) : ScriptedAI(creature) {}
+
+ bool isCluster()
+ {
+ switch (me->GetEntry())
+ {
+ case NPC_FIREWORK_BLUE:
+ case NPC_FIREWORK_GREEN:
+ case NPC_FIREWORK_PURPLE:
+ case NPC_FIREWORK_RED:
+ case NPC_FIREWORK_YELLOW:
+ case NPC_FIREWORK_WHITE:
+ case NPC_FIREWORK_BIG_BLUE:
+ case NPC_FIREWORK_BIG_GREEN:
+ case NPC_FIREWORK_BIG_PURPLE:
+ case NPC_FIREWORK_BIG_RED:
+ case NPC_FIREWORK_BIG_YELLOW:
+ case NPC_FIREWORK_BIG_WHITE:
+ return false;
+ case NPC_CLUSTER_BLUE:
+ case NPC_CLUSTER_GREEN:
+ case NPC_CLUSTER_PURPLE:
+ case NPC_CLUSTER_RED:
+ case NPC_CLUSTER_YELLOW:
+ case NPC_CLUSTER_WHITE:
+ case NPC_CLUSTER_BIG_BLUE:
+ case NPC_CLUSTER_BIG_GREEN:
+ case NPC_CLUSTER_BIG_PURPLE:
+ case NPC_CLUSTER_BIG_RED:
+ case NPC_CLUSTER_BIG_YELLOW:
+ case NPC_CLUSTER_BIG_WHITE:
+ case NPC_CLUSTER_ELUNE:
+ default:
+ return true;
+ }
+ }
+
+ GameObject* FindNearestLauncher()
+ {
+ GameObject* launcher = NULL;
+
+ if (isCluster())
+ {
+ GameObject* launcher1 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_1, 0.5f);
+ GameObject* launcher2 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_2, 0.5f);
+ GameObject* launcher3 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_3, 0.5f);
+ GameObject* launcher4 = GetClosestGameObjectWithEntry(me, GO_CLUSTER_LAUNCHER_4, 0.5f);
+
+ if (launcher1)
+ launcher = launcher1;
+ else if (launcher2)
+ launcher = launcher2;
+ else if (launcher3)
+ launcher = launcher3;
+ else if (launcher4)
+ launcher = launcher4;
+ }
+ else
+ {
+ GameObject* launcher1 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_1, 0.5f);
+ GameObject* launcher2 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_2, 0.5f);
+ GameObject* launcher3 = GetClosestGameObjectWithEntry(me, GO_FIREWORK_LAUNCHER_3, 0.5f);
+
+ if (launcher1)
+ launcher = launcher1;
+ else if (launcher2)
+ launcher = launcher2;
+ else if (launcher3)
+ launcher = launcher3;
+ }
+
+ return launcher;
+ }
+
+ uint32 GetFireworkSpell(uint32 entry)
+ {
+ switch (entry)
+ {
+ case NPC_FIREWORK_BLUE:
+ return SPELL_ROCKET_BLUE;
+ case NPC_FIREWORK_GREEN:
+ return SPELL_ROCKET_GREEN;
+ case NPC_FIREWORK_PURPLE:
+ return SPELL_ROCKET_PURPLE;
+ case NPC_FIREWORK_RED:
+ return SPELL_ROCKET_RED;
+ case NPC_FIREWORK_YELLOW:
+ return SPELL_ROCKET_YELLOW;
+ case NPC_FIREWORK_WHITE:
+ return SPELL_ROCKET_WHITE;
+ case NPC_FIREWORK_BIG_BLUE:
+ return SPELL_ROCKET_BIG_BLUE;
+ case NPC_FIREWORK_BIG_GREEN:
+ return SPELL_ROCKET_BIG_GREEN;
+ case NPC_FIREWORK_BIG_PURPLE:
+ return SPELL_ROCKET_BIG_PURPLE;
+ case NPC_FIREWORK_BIG_RED:
+ return SPELL_ROCKET_BIG_RED;
+ case NPC_FIREWORK_BIG_YELLOW:
+ return SPELL_ROCKET_BIG_YELLOW;
+ case NPC_FIREWORK_BIG_WHITE:
+ return SPELL_ROCKET_BIG_WHITE;
+ default:
+ return 0;
+ }
+ }
+
+ uint32 GetFireworkGameObjectId()
+ {
+ uint32 spellId = 0;
+
+ switch (me->GetEntry())
+ {
+ case NPC_CLUSTER_BLUE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BLUE);
+ break;
+ case NPC_CLUSTER_GREEN:
+ spellId = GetFireworkSpell(NPC_FIREWORK_GREEN);
+ break;
+ case NPC_CLUSTER_PURPLE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_PURPLE);
+ break;
+ case NPC_CLUSTER_RED:
+ spellId = GetFireworkSpell(NPC_FIREWORK_RED);
+ break;
+ case NPC_CLUSTER_YELLOW:
+ spellId = GetFireworkSpell(NPC_FIREWORK_YELLOW);
+ break;
+ case NPC_CLUSTER_WHITE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_WHITE);
+ break;
+ case NPC_CLUSTER_BIG_BLUE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_BLUE);
+ break;
+ case NPC_CLUSTER_BIG_GREEN:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_GREEN);
+ break;
+ case NPC_CLUSTER_BIG_PURPLE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_PURPLE);
+ break;
+ case NPC_CLUSTER_BIG_RED:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_RED);
+ break;
+ case NPC_CLUSTER_BIG_YELLOW:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_YELLOW);
+ break;
+ case NPC_CLUSTER_BIG_WHITE:
+ spellId = GetFireworkSpell(NPC_FIREWORK_BIG_WHITE);
+ break;
+ case NPC_CLUSTER_ELUNE:
+ spellId = GetFireworkSpell(urand(NPC_FIREWORK_BLUE, NPC_FIREWORK_WHITE));
+ break;
+ }
+
+ const SpellInfo* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+
+ if (spellInfo && spellInfo->Effects[0].Effect == SPELL_EFFECT_SUMMON_OBJECT_WILD)
+ return spellInfo->Effects[0].MiscValue;
+
+ return 0;
+ }
+
+ void Reset()
+ {
+ if (GameObject* launcher = FindNearestLauncher())
+ {
+ launcher->SendCustomAnim(ANIM_GO_LAUNCH_FIREWORK);
+ me->SetOrientation(launcher->GetOrientation() + M_PI/2);
+ }
+ else
+ return;
+
+ if (isCluster())
+ {
+ // Check if we are near Elune'ara lake south, if so try to summon Omen or a minion
+ if (me->GetZoneId() == ZONE_MOONGLADE)
+ {
+ if (!me->FindNearestCreature(NPC_OMEN, 100.0f, false) && me->GetDistance2d(omenSummonPos.GetPositionX(), omenSummonPos.GetPositionY()) <= 100.0f)
+ {
+ switch (urand(0,9))
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ if (Creature* minion = me->SummonCreature(NPC_MINION_OF_OMEN, me->GetPositionX()+frand(-5.0f, 5.0f), me->GetPositionY()+frand(-5.0f, 5.0f), me->GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000))
+ minion->AI()->AttackStart(me->SelectNearestPlayer(20.0f));
+ break;
+ case 9:
+ me->SummonCreature(NPC_OMEN, omenSummonPos);
+ break;
+ }
+ }
+ }
+ if (me->GetEntry() == NPC_CLUSTER_ELUNE)
+ DoCast(SPELL_LUNAR_FORTUNE);
+
+ float displacement = 0.7f;
+ for (uint8 i = 0; i < 4; i++)
+ me->SummonGameObject(GetFireworkGameObjectId(), me->GetPositionX() + (i%2 == 0 ? displacement : -displacement), me->GetPositionY() + (i > 1 ? displacement : -displacement), me->GetPositionZ() + 4.0f, me->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 1);
+ }
+ else
+ //me->CastSpell(me, GetFireworkSpell(me->GetEntry()), true);
+ me->CastSpell(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), GetFireworkSpell(me->GetEntry()), true);
+ }
+ };
+
+ CreatureAI *GetAI(Creature* creature) const
+ {
+ return new npc_fireworkAI(creature);
+ }
+};
+
void AddSC_npcs_special()
{
new npc_air_force_bots;
@@ -2796,5 +3076,6 @@ void AddSC_npcs_special()
new npc_experience;
new npc_fire_elemental;
new npc_earth_elemental;
+ new npc_firework;
}
diff --git a/src/server/shared/Cryptography/HMACSHA1.cpp b/src/server/shared/Cryptography/HMACSHA1.cpp
index 3f21aa4582d..447d0b58efc 100755
--- a/src/server/shared/Cryptography/HMACSHA1.cpp
+++ b/src/server/shared/Cryptography/HMACSHA1.cpp
@@ -18,6 +18,7 @@
#include "HMACSHA1.h"
#include "BigNumber.h"
+#include "Common.h"
HmacHash::HmacHash(uint32 len, uint8 *seed)
{
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index b0054aca5a5..72f509706e8 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -305,7 +305,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_GUID, "DELETE FROM creature_respawn WHERE guid = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE instanceId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_SEL_MAX_CREATURE_RESPAWNS, "SELECT MAX(respawnTime), instanceId FROM creature_respawn WHERE instanceId > 0 GROUP BY instanceId", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_CREATURE_RESPAWNS, "DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT instanceId FROM instance)", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_CREATURE_RESPAWNS, "DELETE FROM creature_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)", CONNECTION_SYNCH)
// Gameobject respawn
PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM gameobject_respawn", CONNECTION_SYNCH)
@@ -313,7 +313,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE instanceId = ?", CONNECTION_ASYNC)
PREPARE_STATEMENT(CHAR_DEL_EXPIRED_GO_RESPAWNS, "DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_GO_RESPAWNS, "DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT instanceId FROM instance)", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_DEL_NONEXISTENT_INSTANCE_GO_RESPAWNS, "DELETE FROM gameobject_respawn WHERE instanceId > 0 AND instanceId NOT IN (SELECT id FROM instance)", CONNECTION_SYNCH)
// GM Tickets
PREPARE_STATEMENT(CHAR_SEL_GM_TICKETS, "SELECT ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed FROM gm_tickets", CONNECTION_SYNCH)
@@ -329,6 +329,10 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// For loading and deleting expired auctions at startup
PREPARE_STATEMENT(CHAR_SEL_EXPIRED_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid WHERE ah.time <= ?", CONNECTION_SYNCH)
+ // LFG Data
+ PREPARE_STATEMENT(CHAR_INS_LFG_DATA, "INSERT INTO lfg_data (guid, dungeon, state) VALUES (?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC)
+
// Player saving
PREPARE_STATEMENT(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, "
"map, instance_id, instance_mode_mask, position_x, position_y, position_z, orientation, "
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 0ea1549eff2..c510f6d03a6 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -353,6 +353,9 @@ enum CharacterDatabaseStatements
CHAR_DEL_CHARACTER_SOCIAL,
CHAR_UPD_CHARACTER_SOCIAL_NOTE,
CHAR_UPD_CHARACTER_POSITION,
+
+ CHAR_INS_LFG_DATA,
+ CHAR_DEL_LFG_DATA,
MAX_CHARACTERDATABASE_STATEMENTS,
};
diff --git a/src/server/shared/Utilities/Timer.h b/src/server/shared/Utilities/Timer.h
index 4dae8ac30d2..4d3f02f6688 100755
--- a/src/server/shared/Utilities/Timer.h
+++ b/src/server/shared/Utilities/Timer.h
@@ -133,7 +133,7 @@ struct TimeTrackerSmall
{
public:
- TimeTrackerSmall(uint32 expiry)
+ TimeTrackerSmall(uint32 expiry = 0)
: i_expiryTime(expiry)
{
}
diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt
index 60adce41326..191bbbf35b4 100644
--- a/src/server/worldserver/CMakeLists.txt
+++ b/src/server/worldserver/CMakeLists.txt
@@ -57,12 +57,10 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/shared/Database
${CMAKE_SOURCE_DIR}/src/server/shared/DataStores
${CMAKE_SOURCE_DIR}/src/server/shared/Debugging
- ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/CountedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference
${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic
${CMAKE_SOURCE_DIR}/src/server/shared/Logging
${CMAKE_SOURCE_DIR}/src/server/shared/Packets
- ${CMAKE_SOURCE_DIR}/src/server/shared/Policies
${CMAKE_SOURCE_DIR}/src/server/shared/Threading
${CMAKE_SOURCE_DIR}/src/server/shared/Utilities
${CMAKE_SOURCE_DIR}/src/server/game
@@ -108,6 +106,7 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Grids
${CMAKE_SOURCE_DIR}/src/server/game/Groups
${CMAKE_SOURCE_DIR}/src/server/game/Guilds
+ ${CMAKE_SOURCE_DIR}/src/server/game/Handlers
${CMAKE_SOURCE_DIR}/src/server/game/Instances
${CMAKE_SOURCE_DIR}/src/server/game/Loot
${CMAKE_SOURCE_DIR}/src/server/game/Mails
@@ -123,7 +122,6 @@ include_directories(
${CMAKE_SOURCE_DIR}/src/server/game/Reputation
${CMAKE_SOURCE_DIR}/src/server/game/Scripting
${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol
- ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol/Handlers
${CMAKE_SOURCE_DIR}/src/server/game/Server
${CMAKE_SOURCE_DIR}/src/server/game/Skills
${CMAKE_SOURCE_DIR}/src/server/game/Spells
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 64a7dcb7276..82f71aed030 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index 641bf00c678..afeb8af99ba 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
diff --git a/src/tools/vmap3_assembler/CMakeLists.txt b/src/tools/vmap3_assembler/CMakeLists.txt
index d596fb3e818..ba5d1649d38 100644
--- a/src/tools/vmap3_assembler/CMakeLists.txt
+++ b/src/tools/vmap3_assembler/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
diff --git a/src/tools/vmap3_extractor/CMakeLists.txt b/src/tools/vmap3_extractor/CMakeLists.txt
index 905e9318985..2ff2fd0cf6b 100644
--- a/src/tools/vmap3_extractor/CMakeLists.txt
+++ b/src/tools/vmap3_extractor/CMakeLists.txt
@@ -1,5 +1,5 @@
# Copyright (C) 2005-2009 MaNGOS project <http://getmangos.com/>
-# Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+# Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without