aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/server/collision/BoundingIntervalHierarchy.h5
-rw-r--r--src/server/collision/Maps/TileAssembler.cpp2
-rw-r--r--src/server/collision/Models/GameObjectModel.cpp2
-rw-r--r--src/server/collision/Models/WorldModel.cpp2
-rw-r--r--src/server/collision/RegularGrid.h2
-rw-r--r--src/server/game/AI/CoreAI/GameObjectAI.h3
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.cpp16
-rwxr-xr-xsrc/server/game/AI/CoreAI/PetAI.h1
-rwxr-xr-xsrc/server/game/AI/CreatureAI.h4
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAIMgr.cpp21
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h14
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp1
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp33
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.h53
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp66
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.h2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.cpp79
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h200
-rwxr-xr-xsrc/server/game/Achievements/AchievementMgr.cpp6
-rw-r--r--src/server/game/Battlegrounds/ArenaTeamMgr.cpp6
-rwxr-xr-xsrc/server/game/Battlegrounds/Battleground.cpp22
-rwxr-xr-xsrc/server/game/Battlegrounds/BattlegroundMgr.cpp13
-rwxr-xr-xsrc/server/game/Battlegrounds/BattlegroundMgr.h2
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundSA.cpp12
-rwxr-xr-xsrc/server/game/Battlegrounds/Zones/BattlegroundSA.h9
-rwxr-xr-xsrc/server/game/Chat/Chat.cpp124
-rwxr-xr-xsrc/server/game/Chat/Chat.h84
-rwxr-xr-xsrc/server/game/Chat/Commands/Level0.cpp30
-rwxr-xr-xsrc/server/game/Chat/Commands/Level2.cpp231
-rwxr-xr-xsrc/server/game/Chat/Commands/Level3.cpp1350
-rwxr-xr-xsrc/server/game/Combat/ThreatManager.cpp4
-rwxr-xr-xsrc/server/game/Conditions/ConditionMgr.cpp2
-rwxr-xr-xsrc/server/game/DataStores/DBCEnums.h14
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.cpp10
-rwxr-xr-xsrc/server/game/DataStores/DBCStores.h9
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.cpp55
-rwxr-xr-xsrc/server/game/DungeonFinding/LFGMgr.h1
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp7
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp22
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h6
-rwxr-xr-xsrc/server/game/Entities/Creature/TemporarySummon.h1
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp20
-rwxr-xr-xsrc/server/game/Entities/Item/Item.cpp4
-rwxr-xr-xsrc/server/game/Entities/Item/Item.h1
-rwxr-xr-xsrc/server/game/Entities/Item/ItemPrototype.h11
-rwxr-xr-xsrc/server/game/Entities/Object/Object.h12
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h1
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp211
-rwxr-xr-xsrc/server/game/Entities/Player/Player.h3
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.cpp33
-rwxr-xr-xsrc/server/game/Entities/Transport/Transport.h2
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp343
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h27
-rwxr-xr-xsrc/server/game/Entities/Vehicle/Vehicle.cpp13
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.cpp206
-rwxr-xr-xsrc/server/game/Globals/ObjectMgr.h49
-rwxr-xr-xsrc/server/game/Grids/Notifiers/GridNotifiers.h7
-rwxr-xr-xsrc/server/game/Groups/Group.cpp76
-rwxr-xr-xsrc/server/game/Groups/Group.h14
-rwxr-xr-xsrc/server/game/Groups/GroupRefManager.h3
-rwxr-xr-xsrc/server/game/Groups/GroupReference.h1
-rwxr-xr-xsrc/server/game/Guilds/Guild.cpp2
-rwxr-xr-xsrc/server/game/Handlers/AuctionHouseHandler.cpp2
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp12
-rwxr-xr-xsrc/server/game/Handlers/GroupHandler.cpp22
-rwxr-xr-xsrc/server/game/Handlers/ItemHandler.cpp1
-rwxr-xr-xsrc/server/game/Handlers/LFGHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/LootHandler.cpp8
-rwxr-xr-xsrc/server/game/Handlers/MailHandler.cpp2
-rwxr-xr-xsrc/server/game/Handlers/MiscHandler.cpp36
-rwxr-xr-xsrc/server/game/Handlers/MovementHandler.cpp45
-rwxr-xr-xsrc/server/game/Handlers/PetHandler.cpp6
-rwxr-xr-xsrc/server/game/Handlers/QueryHandler.cpp10
-rwxr-xr-xsrc/server/game/Handlers/QuestHandler.cpp9
-rwxr-xr-xsrc/server/game/Handlers/SpellHandler.cpp23
-rwxr-xr-xsrc/server/game/Instances/InstanceSaveMgr.cpp5
-rwxr-xr-xsrc/server/game/Loot/LootMgr.cpp38
-rwxr-xr-xsrc/server/game/Maps/Map.cpp139
-rwxr-xr-xsrc/server/game/Maps/Map.h44
-rwxr-xr-xsrc/server/game/Maps/MapInstanced.cpp2
-rwxr-xr-xsrc/server/game/Maps/MapManager.cpp1
-rwxr-xr-xsrc/server/game/Maps/MapManager.h4
-rwxr-xr-xsrc/server/game/Miscellaneous/SharedDefines.h2
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.cpp6
-rwxr-xr-xsrc/server/game/Movement/MotionMaster.h4
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp17
-rwxr-xr-xsrc/server/game/Movement/MovementGenerators/PointMovementGenerator.h3
-rw-r--r--src/server/game/Movement/Spline/MoveSpline.cpp2
-rw-r--r--src/server/game/Movement/Spline/MoveSplineFlag.h76
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp74
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.h50
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInitArgs.h5
-rw-r--r--src/server/game/Movement/Spline/MovementPacketBuilder.cpp16
-rwxr-xr-xsrc/server/game/OutdoorPvP/OutdoorPvP.cpp4
-rwxr-xr-xsrc/server/game/Quests/QuestDef.cpp8
-rwxr-xr-xsrc/server/game/Scripting/ScriptLoader.cpp12
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp49
-rwxr-xr-xsrc/server/game/Server/Protocol/Opcodes.h74
-rw-r--r--src/server/game/Server/Protocol/PacketLog.cpp62
-rw-r--r--[-rwxr-xr-x]src/server/game/Server/Protocol/PacketLog.h (renamed from src/server/game/Server/Protocol/WorldLog.h)45
-rwxr-xr-xsrc/server/game/Server/Protocol/WorldLog.cpp114
-rwxr-xr-xsrc/server/game/Server/WorldSession.cpp4
-rwxr-xr-xsrc/server/game/Server/WorldSession.h6
-rwxr-xr-xsrc/server/game/Server/WorldSocket.cpp66
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuraEffects.cpp516
-rwxr-xr-xsrc/server/game/Spells/Auras/SpellAuras.cpp13
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp324
-rwxr-xr-xsrc/server/game/Spells/Spell.h3
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp405
-rw-r--r--src/server/game/Spells/SpellInfo.cpp2
-rwxr-xr-xsrc/server/game/Spells/SpellMgr.cpp37
-rwxr-xr-xsrc/server/game/Spells/SpellScript.cpp82
-rwxr-xr-xsrc/server/game/Spells/SpellScript.h56
-rw-r--r--src/server/game/Warden/Warden.cpp9
-rw-r--r--src/server/game/Warden/WardenCheckMgr.cpp2
-rw-r--r--src/server/game/Warden/WardenMac.cpp10
-rw-r--r--src/server/game/Warden/WardenWin.cpp4
-rwxr-xr-xsrc/server/game/World/World.cpp7
-rwxr-xr-xsrc/server/game/World/World.h1
-rw-r--r--src/server/scripts/Commands/CMakeLists.txt12
-rw-r--r--src/server/scripts/Commands/cs_cast.cpp310
-rw-r--r--src/server/scripts/Commands/cs_character.cpp679
-rw-r--r--src/server/scripts/Commands/cs_instance.cpp193
-rw-r--r--src/server/scripts/Commands/cs_list.cpp469
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp9
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp89
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp310
-rw-r--r--src/server/scripts/Commands/cs_server.cpp445
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp9
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp46
-rw-r--r--src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp140
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp23
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp11
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp3
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp3
-rw-r--r--src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp3
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp113
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp123
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp69
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp157
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp85
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp4
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h2
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp23
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h80
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp55
-rw-r--r--src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp9
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp39
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp39
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp58
-rw-r--r--src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp57
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp279
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp107
-rw-r--r--src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h12
-rw-r--r--src/server/scripts/Kalimdor/ashenvale.cpp6
-rw-r--r--src/server/scripts/Kalimdor/dustwallow_marsh.cpp102
-rw-r--r--src/server/scripts/Kalimdor/winterspring.cpp113
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp12
-rw-r--r--src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp13
-rwxr-xr-xsrc/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp62
-rw-r--r--src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp18
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp32
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp39
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp4
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp46
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp30
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp136
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp200
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp15
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp134
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h5
-rwxr-xr-xsrc/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp184
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp66
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp39
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp42
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp6
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp16
-rw-r--r--src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp36
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp86
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp80
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp18
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp18
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp34
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp42
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp24
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp70
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h6
-rw-r--r--src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp18
-rw-r--r--src/server/scripts/Northrend/dragonblight.cpp99
-rw-r--r--src/server/scripts/Northrend/sholazar_basin.cpp125
-rw-r--r--src/server/scripts/Outland/GruulsLair/boss_gruul.cpp89
-rw-r--r--src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp4
-rw-r--r--src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp6
-rw-r--r--src/server/scripts/Outland/blades_edge_mountains.cpp2
-rw-r--r--src/server/scripts/Outland/boss_doomlord_kazzak.cpp54
-rw-r--r--src/server/scripts/Outland/netherstorm.cpp8
-rw-r--r--src/server/scripts/Spells/CMakeLists.txt1
-rw-r--r--src/server/scripts/Spells/spell_dk.cpp73
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp290
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp465
-rw-r--r--src/server/scripts/Spells/spell_hunter.cpp82
-rw-r--r--src/server/scripts/Spells/spell_item.cpp55
-rw-r--r--src/server/scripts/Spells/spell_mage.cpp47
-rw-r--r--src/server/scripts/Spells/spell_paladin.cpp114
-rw-r--r--src/server/scripts/Spells/spell_pet.cpp1726
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp93
-rw-r--r--src/server/scripts/Spells/spell_quest.cpp82
-rw-r--r--src/server/scripts/Spells/spell_shaman.cpp129
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp112
-rw-r--r--src/server/scripts/Spells/spell_warrior.cpp59
-rwxr-xr-xsrc/server/scripts/World/achievement_scripts.cpp22
-rw-r--r--src/server/scripts/World/boss_emerald_dragons.cpp24
-rw-r--r--src/server/scripts/World/go_scripts.cpp54
-rw-r--r--src/server/scripts/World/npcs_special.cpp37
-rw-r--r--src/server/shared/Cryptography/WardenKeyGeneration.h42
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.cpp17
-rwxr-xr-xsrc/server/shared/Database/Implementation/CharacterDatabase.h1
-rwxr-xr-xsrc/server/shared/Database/PreparedStatement.cpp2
-rwxr-xr-xsrc/server/shared/Packets/ByteBuffer.h3
-rwxr-xr-xsrc/server/worldserver/CommandLine/CliRunnable.cpp452
-rw-r--r--src/server/worldserver/worldserver.conf.dist30
-rw-r--r--src/tools/map_extractor/CMakeLists.txt1
-rw-r--r--src/tools/map_extractor/System.cpp34
-rw-r--r--src/tools/vmap4_extractor/CMakeLists.txt9
-rw-r--r--src/tools/vmap4_extractor/adtfile.cpp4
-rw-r--r--src/tools/vmap4_extractor/adtfile.h2
-rw-r--r--src/tools/vmap4_extractor/dbcfile.cpp14
-rw-r--r--src/tools/vmap4_extractor/dbcfile.h4
-rw-r--r--src/tools/vmap4_extractor/gameobject_extract.cpp4
-rw-r--r--src/tools/vmap4_extractor/model.cpp6
-rw-r--r--src/tools/vmap4_extractor/modelheaders.h7
-rw-r--r--src/tools/vmap4_extractor/mpq_libmpq.cpp111
-rw-r--r--src/tools/vmap4_extractor/mpq_libmpq04.h90
-rw-r--r--src/tools/vmap4_extractor/mpqfile.cpp86
-rw-r--r--src/tools/vmap4_extractor/mpqfile.h80
-rw-r--r--src/tools/vmap4_extractor/vmapexport.cpp324
-rw-r--r--src/tools/vmap4_extractor/wdtfile.cpp6
-rw-r--r--src/tools/vmap4_extractor/wdtfile.h2
-rw-r--r--src/tools/vmap4_extractor/wmo.cpp8
-rw-r--r--src/tools/vmap4_extractor/wmo.h1
241 files changed, 10419 insertions, 6738 deletions
diff --git a/src/server/collision/BoundingIntervalHierarchy.h b/src/server/collision/BoundingIntervalHierarchy.h
index ea70fc3e322..a4bbe21006a 100755
--- a/src/server/collision/BoundingIntervalHierarchy.h
+++ b/src/server/collision/BoundingIntervalHierarchy.h
@@ -128,7 +128,7 @@ class BIH
delete[] dat.primBound;
delete[] dat.indices;
}
- uint32 primCount() { return objects.size(); }
+ uint32 primCount() const { return objects.size(); }
template<typename RayCallback>
void intersectRay(const Ray &r, RayCallback& intersectCallback, float &maxDist, bool stopAtFirst=false) const
@@ -400,7 +400,8 @@ class BIH
void buildHierarchy(std::vector<uint32> &tempTree, buildData &dat, BuildStats &stats);
- void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) {
+ void createNode(std::vector<uint32> &tempTree, int nodeIndex, uint32 left, uint32 right) const
+ {
// write leaf node
tempTree[nodeIndex + 0] = (3 << 30) | left;
tempTree[nodeIndex + 1] = right - left + 1;
diff --git a/src/server/collision/Maps/TileAssembler.cpp b/src/server/collision/Maps/TileAssembler.cpp
index e7693a70de4..3bfed7d322d 100644
--- a/src/server/collision/Maps/TileAssembler.cpp
+++ b/src/server/collision/Maps/TileAssembler.cpp
@@ -312,7 +312,7 @@ namespace VMAP
// write WorldModel
WorldModel model;
model.setRootWmoID(raw_model.RootWMOID);
- if (raw_model.groupsArray.size())
+ if (!raw_model.groupsArray.empty())
{
std::vector<GroupModel> groupsArray;
diff --git a/src/server/collision/Models/GameObjectModel.cpp b/src/server/collision/Models/GameObjectModel.cpp
index 84c736c22e8..8b63620e783 100644
--- a/src/server/collision/Models/GameObjectModel.cpp
+++ b/src/server/collision/Models/GameObjectModel.cpp
@@ -176,7 +176,7 @@ bool GameObjectModel::intersectRay(const G3D::Ray& ray, float& MaxDist, bool Sto
Ray modRay(p, iInvRot * ray.direction());
float distance = MaxDist * iInvScale;
bool hit = iModel->IntersectRay(modRay, distance, StopAtFirstHit);
- if(hit)
+ if (hit)
{
distance *= iScale;
MaxDist = distance;
diff --git a/src/server/collision/Models/WorldModel.cpp b/src/server/collision/Models/WorldModel.cpp
index b818232fb32..b4f3f73fc98 100644
--- a/src/server/collision/Models/WorldModel.cpp
+++ b/src/server/collision/Models/WorldModel.cpp
@@ -42,7 +42,7 @@ namespace VMAP
const Vector3 p(ray.direction().cross(e2));
const float a = e1.dot(p);
- if (abs(a) < EPS) {
+ if (fabs(a) < EPS) {
// Determinant is ill-conditioned; abort early
return false;
}
diff --git a/src/server/collision/RegularGrid.h b/src/server/collision/RegularGrid.h
index 2867b29cfc1..00d7b0cd209 100644
--- a/src/server/collision/RegularGrid.h
+++ b/src/server/collision/RegularGrid.h
@@ -176,7 +176,7 @@ public:
}
if (cell == last_cell)
break;
- if(tMaxX < tMaxY)
+ if (tMaxX < tMaxY)
{
tMaxX += tDeltaX;
cell.x += stepX;
diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h
index f4555649210..fbc8675cc47 100644
--- a/src/server/game/AI/CoreAI/GameObjectAI.h
+++ b/src/server/game/AI/CoreAI/GameObjectAI.h
@@ -53,7 +53,8 @@ class GameObjectAI
virtual uint64 GetData64(uint32 /*id*/) { return 0; }
virtual void SetData(uint32 /*id*/, uint32 /*value*/) {}
virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) {}
- virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) { }
+ virtual void OnStateChanged(uint32 /*state*/, Unit* /*unit*/) {}
+ virtual void EventInform(uint32 /*eventId*/) {}
};
class NullGameObjectAI : public GameObjectAI
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp
index 160b406a6ea..97ae0581a18 100755
--- a/src/server/game/AI/CoreAI/PetAI.cpp
+++ b/src/server/game/AI/CoreAI/PetAI.cpp
@@ -532,3 +532,19 @@ bool PetAI::CanAttack(Unit* target)
// default, though we shouldn't ever get here
return false;
}
+
+void PetAI::ReceiveEmote(Player* player, uint32 emote)
+{
+ if (me->GetOwnerGUID() && me->GetOwnerGUID() == player->GetGUID())
+ switch (emote)
+ {
+ case TEXT_EMOTE_COWER:
+ if (me->isPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+ break;
+ case TEXT_EMOTE_ANGRY:
+ if (me->isPet() && me->ToPet()->IsPetGhoul())
+ me->HandleEmoteCommand(EMOTE_ONESHOT_COWER);
+ break;
+ }
+}
diff --git a/src/server/game/AI/CoreAI/PetAI.h b/src/server/game/AI/CoreAI/PetAI.h
index ed3e2305556..8e5311fa000 100755
--- a/src/server/game/AI/CoreAI/PetAI.h
+++ b/src/server/game/AI/CoreAI/PetAI.h
@@ -42,6 +42,7 @@ class PetAI : public CreatureAI
void MovementInform(uint32 moveType, uint32 data);
void OwnerDamagedBy(Unit* attacker);
void OwnerAttacked(Unit* target);
+ void ReceiveEmote(Player* player, uint32 textEmote);
private:
bool _isVisible(Unit*) const;
diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h
index 94ac452b9f3..68752b82e7f 100755
--- a/src/server/game/AI/CreatureAI.h
+++ b/src/server/game/AI/CreatureAI.h
@@ -128,8 +128,6 @@ class CreatureAI : public UnitAI
void OnCharmed(bool apply);
- //virtual void SpellClick(Player* player) {}
-
// Called at reaching home after evade
virtual void JustReachedHome() {}
@@ -171,6 +169,8 @@ class CreatureAI : public UnitAI
virtual void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool /*apply*/) {}
+ virtual void OnSpellClick(Unit* /*clicker*/) { }
+
virtual bool CanSeeAlways(WorldObject const* /*obj*/) { return false; }
protected:
virtual void MoveInLineOfSight(Unit* /*who*/);
diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
index 517e55af457..a863f2f89cf 100755
--- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp
@@ -204,12 +204,17 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
temp.raw.param3 = fields[8].GetInt32();
temp.raw.param4 = fields[9].GetInt32();
+ CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creature_id);
//Creature does not exist in database
- if (!sObjectMgr->GetCreatureTemplate(temp.creature_id))
+ if (!cInfo)
{
- sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, temp.creature_id);
+ sLog->outErrorDb("CreatureEventAI: Event %u has script for non-existing creature entry (%u), skipping.", i, creature_id);
continue;
}
+
+ // Only on the first script
+ if (cInfo->AIName != "EventAI" && m_CreatureEventAI_Event_Map[creature_id].empty())
+ sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI' - possible AI-mismatch?", temp.creature_id);
//No chance of this event occuring
if (temp.event_chance == 0)
@@ -735,18 +740,6 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts()
}
while (result->NextRow());
- for (CreatureEventAI_Event_Map::const_iterator itr = m_CreatureEventAI_Event_Map.begin(); itr != m_CreatureEventAI_Event_Map.end(); ++itr)
- {
- if (CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(itr->first))
- {
- if (cInfo->AIName != "EventAI")
- {
- sLog->outErrorDb("Creature entry %u has EventAI scripts, but its AIName is not 'EventAI', changing to EventAI", itr->first);
- const_cast<CreatureTemplate*>(cInfo)->AIName = "EventAI";
- }
- }
- }
-
sLog->outString(">> Loaded %u CreatureEventAI scripts in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 4fac8b3cba5..ba0a94d2590 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -191,7 +191,7 @@ struct ScriptedAI : public CreatureAI
//Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
void SetCombatMovement(bool allowMovement);
- bool IsCombatMovementAllowed() { return _isCombatMovementAllowed; }
+ bool IsCombatMovementAllowed() const { return _isCombatMovementAllowed; }
bool EnterEvadeIfOutOfCombatArea(uint32 const diff);
@@ -200,16 +200,16 @@ struct ScriptedAI : public CreatureAI
// - for raid in mode 10-Heroic
// - for raid in mode 25-heroic
// DO NOT USE to check raid in mode 25-normal.
- bool IsHeroic() { return _isHeroic; }
+ bool IsHeroic() const { return _isHeroic; }
// return the dungeon or raid difficulty
- Difficulty GetDifficulty() { return _difficulty; }
+ Difficulty GetDifficulty() const { return _difficulty; }
// return true for 25 man or 25 man heroic mode
- bool Is25ManRaid() { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; }
+ bool Is25ManRaid() const { return _difficulty & RAID_DIFFICULTY_MASK_25MAN; }
template<class T> inline
- const T& DUNGEON_MODE(const T& normal5, const T& heroic10)
+ const T& DUNGEON_MODE(const T& normal5, const T& heroic10) const
{
switch (_difficulty)
{
@@ -225,7 +225,7 @@ struct ScriptedAI : public CreatureAI
}
template<class T> inline
- const T& RAID_MODE(const T& normal10, const T& normal25)
+ const T& RAID_MODE(const T& normal10, const T& normal25) const
{
switch (_difficulty)
{
@@ -241,7 +241,7 @@ struct ScriptedAI : public CreatureAI
}
template<class T> inline
- const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25)
+ const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) const
{
switch (_difficulty)
{
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 13bbbe2c338..987af82e496 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -327,7 +327,6 @@ Player* FollowerAI::GetLeaderForFollower()
sLog->outDebug(LOG_FILTER_TSCR, "TSCR: FollowerAI GetLeader changed and returned new leader.");
m_uiLeaderGUID = member->GetGUID();
return member;
- break;
}
}
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index 08f1b18ffad..96fc43e0572 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -696,8 +696,9 @@ void SmartAI::OnCharmed(bool apply)
GetScript()->ProcessEventsFor(SMART_EVENT_CHARMED, NULL, 0, 0, apply);
}
-void SmartAI::DoAction(const int32 /*param*/)
+void SmartAI::DoAction(const int32 param)
{
+ GetScript()->ProcessEventsFor(SMART_EVENT_ACTION_DONE, NULL, param);
}
uint32 SmartAI::GetData(uint32 /*id*/)
@@ -825,27 +826,10 @@ void SmartAI::sOnGameEvent(bool start, uint16 eventId)
GetScript()->ProcessEventsFor(start ? SMART_EVENT_GAME_EVENT_START : SMART_EVENT_GAME_EVENT_END, NULL, eventId);
}
-/*
-SMART_EVENT_UPDATE_OOC
-SMART_EVENT_SPELLHIT
-SMART_EVENT_RANGE
-SMART_EVENT_RESPAWN
-SMART_EVENT_SUMMONED_UNIT
-SMART_EVENT_ACCEPTED_QUEST
-SMART_EVENT_REWARD_QUEST
-SMART_EVENT_TARGET_BUFFED
-SMART_EVENT_SUMMON_DESPAWNED
-SMART_EVENT_AI_INIT
-SMART_EVENT_DATA_SET
-SMART_EVENT_TEXT_OVER
-SMART_EVENT_TIMED_EVENT_TRIGGERED
-SMART_EVENT_UPDATE
-SMART_EVENT_LINK
-SMART_EVENT_GOSSIP_SELECT
-SMART_EVENT_JUST_CREATED
-SMART_EVENT_GOSSIP_HELLO
-SMART_EVENT_DEATH
-*/
+void SmartAI::OnSpellClick(Unit* clicker)
+{
+ GetScript()->ProcessEventsFor(SMART_EVENT_ON_SPELLCLICK, clicker);
+}
int SmartGameObjectAI::Permissible(const GameObject* g)
{
@@ -937,6 +921,11 @@ void SmartGameObjectAI::OnStateChanged(uint32 state, Unit* unit)
GetScript()->ProcessEventsFor(SMART_EVENT_GO_STATE_CHANGED, unit, state);
}
+void SmartGameObjectAI::EventInform(uint32 eventId)
+{
+ GetScript()->ProcessEventsFor(SMART_EVENT_GO_EVENT_INFORM, NULL, eventId);
+}
+
class SmartTrigger : public AreaTriggerScript
{
public:
diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h
index 435aa176d4d..79cef0c3b37 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.h
+++ b/src/server/game/AI/SmartScripts/SmartAI.h
@@ -198,6 +198,8 @@ class SmartAI : public CreatureAI
void RemoveAuras();
+ void OnSpellClick(Unit* clicker);
+
private:
uint32 mFollowCreditType;
uint32 mFollowArrivedTimer;
@@ -235,30 +237,31 @@ class SmartAI : public CreatureAI
class SmartGameObjectAI : public GameObjectAI
{
-public:
- SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {}
- ~SmartGameObjectAI() {}
-
- void UpdateAI(uint32 diff);
- void InitializeAI();
- void Reset();
- SmartScript* GetScript() { return &mScript; }
- static int Permissible(const GameObject* g);
-
- bool GossipHello(Player* player);
- bool GossipSelect(Player* player, uint32 sender, uint32 action);
- bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/);
- bool QuestAccept(Player* player, Quest const* quest);
- bool QuestReward(Player* player, Quest const* quest, uint32 opt);
- uint32 GetDialogStatus(Player* /*player*/);
- void Destroyed(Player* player, uint32 eventId);
- 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;
- SmartScript mScript;
+ public:
+ SmartGameObjectAI(GameObject* g) : GameObjectAI(g), go(g) {}
+ ~SmartGameObjectAI() {}
+
+ void UpdateAI(uint32 diff);
+ void InitializeAI();
+ void Reset();
+ SmartScript* GetScript() { return &mScript; }
+ static int Permissible(const GameObject* g);
+
+ bool GossipHello(Player* player);
+ bool GossipSelect(Player* player, uint32 sender, uint32 action);
+ bool GossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/);
+ bool QuestAccept(Player* player, Quest const* quest);
+ bool QuestReward(Player* player, Quest const* quest, uint32 opt);
+ uint32 GetDialogStatus(Player* /*player*/);
+ void Destroyed(Player* player, uint32 eventId);
+ 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);
+ void EventInform(uint32 eventId);
+
+ protected:
+ GameObject* const go;
+ SmartScript mScript;
};
#endif
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index 01a9b777358..103cde80f43 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -160,9 +160,6 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
case SMART_ACTION_TALK:
{
- if (!me)
- break;
-
ObjectList* targets = GetTargets(e, unit);
Creature* talker = me;
Player* targetPlayer = NULL;
@@ -185,6 +182,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
delete targets;
}
+ if (!talker)
+ break;
+
mTalkerEntry = talker->GetEntry();
mLastTextID = e.action.talk.textGroupID;
mTextTimer = e.action.talk.duration;
@@ -789,7 +789,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsUnit((*itr)))
continue;
- (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+ if (e.action.removeAura.spell == 0)
+ (*itr)->ToUnit()->RemoveAllAuras();
+ else
+ (*itr)->ToUnit()->RemoveAurasDueToSpell(e.action.removeAura.spell);
+
sLog->outDebug(LOG_FILTER_DATABASE_AI, "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u",
(*itr)->GetGUIDLow(), e.action.removeAura.spell);
}
@@ -1539,8 +1543,8 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (!IsSmart())
break;
- float attackDistance = (float)e.action.setRangedMovement.distance;
- float attackAngle = e.action.setRangedMovement.angle / 180.0f * M_PI;
+ float attackDistance = float(e.action.setRangedMovement.distance);
+ float attackAngle = float(e.action.setRangedMovement.angle) / 180.0f * M_PI;
ObjectList* targets = GetTargets(e, unit);
if (targets)
@@ -2016,16 +2020,16 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e)
if (!go)
return;
//store hostage as id1
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 1, 0, 0, 0, 0, 0, SMART_TARGET_CLOSEST_CREATURE, e.action.installTtemplate.param1, 10, 0, 0);
//store invoker as id2
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_STORE_TARGET_LIST, 2, 0, 0, 0, 0, 0, SMART_TARGET_NONE, 0, 0, 0, 0);
//signal hostage
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_SET_DATA, 0, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 1, 0, 0, 0);
//when hostage raeched end point, give credit to invoker
if (e.action.installTtemplate.param2)
AddEvent(SMART_EVENT_DATA_SET, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
else
- AddEvent(SMART_EVENT_GOSSIP_HELLO, 0, 0, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
+ AddEvent(SMART_EVENT_GO_STATE_CHANGED, 0, 2, 0, 0, 0, SMART_ACTION_CALL_KILLEDMONSTER, e.action.installTtemplate.param1, 0, 0, 0, 0, 0, SMART_TARGET_STORED, 2, 0, 0, 0);
break;
}
case SMARTAI_TEMPLATE_BASIC:
@@ -2119,12 +2123,20 @@ ObjectList* SmartScript::GetTargets(SmartScriptHolder const& e, Unit* invoker /*
case SMART_TARGET_INVOKER_PARTY:
if (trigger)
{
- l->push_back(trigger);
if (Player* player = trigger->ToPlayer())
+ {
if (Group* group = player->GetGroup())
+ {
for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next())
if (Player* member = groupRef->getSource())
l->push_back(member);
+ }
+ // We still add the player to the list if there is no group. If we do
+ // this even if there is a group (thus the else-check), it will add the
+ // same player to the list twice. We don't want that to happen.
+ else
+ l->push_back(trigger);
+ }
}
break;
case SMART_TARGET_CREATURE_RANGE:
@@ -2522,6 +2534,7 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
case SMART_EVENT_JUST_CREATED:
case SMART_EVENT_GOSSIP_HELLO:
case SMART_EVENT_FOLLOW_COMPLETED:
+ case SMART_EVENT_ON_SPELLCLICK:
ProcessAction(e, unit, var0, var1, bvar, spell, gob);
break;
case SMART_EVENT_IS_BEHIND_TARGET:
@@ -2759,6 +2772,20 @@ void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, ui
ProcessAction(e, unit, var0, var1);
break;
}
+ case SMART_EVENT_GO_EVENT_INFORM:
+ {
+ if (e.event.eventInform.eventId != var0)
+ return;
+ ProcessAction(e, NULL, var0);
+ break;
+ }
+ case SMART_EVENT_ACTION_DONE:
+ {
+ if (e.event.doAction.eventId != var0)
+ return;
+ ProcessAction(e, unit, var0);
+ break;
+ }
default:
sLog->outErrorDb("SmartScript::ProcessEvent: Unhandled Event type %u", e.GetEventType());
break;
@@ -2875,23 +2902,6 @@ void SmartScript::InstallEvents()
}
}
-bool SmartScript::ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3)
-{
- if (c == 0)
- return true;
-
- if (!u || !u->ToPlayer())
- return false;
-
- Condition cond;
- cond.ConditionType = ConditionTypes(uint32(c));
- cond.ConditionValue1 = uint32(v1);
- cond.ConditionValue1 = uint32(v2);
- cond.ConditionValue1 = uint32(v3);
- ConditionSourceInfo srcInfo = ConditionSourceInfo(u->ToPlayer());
- return cond.Meets(srcInfo);
-}
-
void SmartScript::OnUpdate(uint32 const diff)
{
if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject())
diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h
index 5fb691c87f2..03d533e69e5 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.h
+++ b/src/server/game/AI/SmartScripts/SmartScript.h
@@ -83,8 +83,6 @@ class SmartScript
return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT;
}
- bool ConditionValid(Unit* u, int32 c, int32 v1, int32 v2, int32 v3);
-
void OnUpdate(const uint32 diff);
void OnMoveInLineOfSight(Unit* who);
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
index a7149f37480..de766d2a7e1 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp
@@ -475,64 +475,78 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
break;
}
case SMART_EVENT_TRANSPORT_ADDCREATURE:
- {
- if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature))
- return false;
- break;
- }
+ {
+ if (e.event.transportAddCreature.creature && !IsCreatureValid(e, e.event.transportAddCreature.creature))
+ return false;
+ break;
+ }
case SMART_EVENT_MOVEMENTINFORM:
+ {
+ if (e.event.movementInform.type > NULL_MOTION_TYPE)
{
- if (e.event.movementInform.type > NULL_MOTION_TYPE)
- {
- sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type);
- return false;
- }
- break;
+ sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Motion type %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.movementInform.type);
+ return false;
}
+ break;
+ }
case SMART_EVENT_DATA_SET:
- {
- if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax))
- return false;
- break;
- }
+ {
+ if (!IsMinMaxValid(e, e.event.dataSet.cooldownMin, e.event.dataSet.cooldownMax))
+ return false;
+ break;
+ }
case SMART_EVENT_AREATRIGGER_ONTRIGGER:
- {
- if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id))
- return false;
- break;
- }
+ {
+ if (e.event.areatrigger.id && !IsAreaTriggerValid(e, e.event.areatrigger.id))
+ return false;
+ break;
+ }
case SMART_EVENT_TEXT_OVER:
//if (e.event.textOver.textGroupID && !IsTextValid(e, e.event.textOver.textGroupID)) return false;// 0 is a valid text group!
break;
case SMART_EVENT_LINK:
+ {
+ if (e.link && e.link == e.event_id)
{
- if (e.link && e.link == e.event_id)
- {
- sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
- return false;
- }
- break;
+ sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u, Event %u, Link Event is linking self (infinite loop), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id);
+ return false;
}
+ break;
+ }
case SMART_EVENT_DUMMY_EFFECT:
+ {
if (!IsSpellValid(e, e.event.dummy.spell))
return false;
if (e.event.dummy.effIndex > EFFECT_2)
return false;
break;
+ }
case SMART_EVENT_IS_BEHIND_TARGET:
+ {
if (!IsMinMaxValid(e, e.event.behindTarget.cooldownMin, e.event.behindTarget.cooldownMax))
return false;
break;
+ }
case SMART_EVENT_GAME_EVENT_START:
case SMART_EVENT_GAME_EVENT_END:
+ {
+ GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
+ if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid())
+ return false;
+ break;
+ }
+ case SMART_EVENT_ACTION_DONE:
+ {
+ if (e.event.doAction.eventId > EVENT_CHARGE)
{
- GameEventMgr::GameEventDataMap const& events = sGameEventMgr->GetEventMap();
- if (e.event.gameEvent.gameEventId >= events.size() || !events[e.event.gameEvent.gameEventId].isValid())
- return false;
- break;
+ sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid event id %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), e.event.doAction.eventId);
+ return false;
}
+ break;
+ }
case SMART_EVENT_GO_STATE_CHANGED:
+ case SMART_EVENT_GO_EVENT_INFORM:
case SMART_EVENT_TIMED_EVENT_TRIGGERED:
case SMART_EVENT_INSTANCE_PLAYER_ENTER:
case SMART_EVENT_TRANSPORT_RELOCATE:
@@ -563,6 +577,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
case SMART_EVENT_GOSSIP_HELLO:
case SMART_EVENT_JUST_CREATED:
case SMART_EVENT_FOLLOW_COMPLETED:
+ case SMART_EVENT_ON_SPELLCLICK:
break;
default:
sLog->outErrorDb("SmartAIMgr: Not handled event_type(%u), Entry %d SourceType %u Event %u Action %u, skipped.", e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
@@ -709,7 +724,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e)
return false;
break;
case SMART_ACTION_REMOVEAURASFROMSPELL:
- if (!IsSpellValid(e, e.action.removeAura.spell))
+ if (e.action.removeAura.spell != 0 && !IsSpellValid(e, e.action.removeAura.spell))
return false;
break;
case SMART_ACTION_RANDOM_PHASE:
diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
index e6c5eb727d7..155f27d0fe7 100644
--- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h
+++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h
@@ -22,7 +22,6 @@
#include "Creature.h"
#include "CreatureAI.h"
#include "Unit.h"
-#include "ConditionMgr.h"
#include "Spell.h"
#include "DB2Stores.h"
@@ -83,80 +82,82 @@ const uint32 SmartPhaseMask[SMART_EVENT_PHASE_COUNT][2] =
enum SMART_EVENT
{
- SMART_EVENT_UPDATE_IC = 0, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax
- SMART_EVENT_UPDATE_OOC = 1, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax
- SMART_EVENT_HEALT_PCT = 2, //1 // HPMin%, HPMax%, RepeatMin, RepeatMax
- SMART_EVENT_MANA_PCT = 3, //1 // ManaMin%, ManaMax%, RepeatMin, RepeatMax
- SMART_EVENT_AGGRO = 4, //1 // NONE
- SMART_EVENT_KILL = 5, //1 // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3
- SMART_EVENT_DEATH = 6, //1 // NONE
- SMART_EVENT_EVADE = 7, //1 // NONE
- SMART_EVENT_SPELLHIT = 8, //1 // SpellID, School, CooldownMin, CooldownMax
- SMART_EVENT_RANGE = 9, //1 // MinDist, MaxDist, RepeatMin, RepeatMax
- SMART_EVENT_OOC_LOS = 10, //1 // NoHostile, MaxRnage, CooldownMin, CooldownMax
- SMART_EVENT_RESPAWN = 11, //1 // type, MapId, ZoneId
- SMART_EVENT_TARGET_HEALTH_PCT = 12, //1 // HPMin%, HPMax%, RepeatMin, RepeatMax
- SMART_EVENT_TARGET_CASTING = 13, //1 // RepeatMin, RepeatMax
- SMART_EVENT_FRIENDLY_HEALTH = 14, //1 // HPDeficit, Radius, RepeatMin, RepeatMax
- SMART_EVENT_FRIENDLY_IS_CC = 15, //1 // Radius, RepeatMin, RepeatMax
- SMART_EVENT_FRIENDLY_MISSING_BUFF = 16, //1 // SpellId, Radius, RepeatMin, RepeatMax
- SMART_EVENT_SUMMONED_UNIT = 17, //1 // CreatureId(0 all), CooldownMin, CooldownMax
- SMART_EVENT_TARGET_MANA_PCT = 18, //1 // ManaMin%, ManaMax%, RepeatMin, RepeatMax
- SMART_EVENT_ACCEPTED_QUEST = 19, //1 // QuestID(0any)
- SMART_EVENT_REWARD_QUEST = 20, //1 // QuestID(0any)
- SMART_EVENT_REACHED_HOME = 21, //1 // NONE
- SMART_EVENT_RECEIVE_EMOTE = 22, //1 // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3
- SMART_EVENT_HAS_AURA = 23, //1 // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
- SMART_EVENT_TARGET_BUFFED = 24, //1 // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
- SMART_EVENT_RESET = 25, //1 // Called after combat, when the creature respawn and spawn.
-
- SMART_EVENT_IC_LOS = 26, //1 // NoHostile, MaxRnage, CooldownMin, CooldownMax
- SMART_EVENT_PASSENGER_BOARDED = 27, //1 // CooldownMin, CooldownMax
- SMART_EVENT_PASSENGER_REMOVED = 28, //1 // CooldownMin, CooldownMax
- SMART_EVENT_CHARMED = 29, //1 // NONE
- SMART_EVENT_CHARMED_TARGET = 30, //1 // NONE
- SMART_EVENT_SPELLHIT_TARGET = 31, //1 // SpellID, School, CooldownMin, CooldownMax
- SMART_EVENT_DAMAGED = 32, //1 // MinDmg, MaxDmg, CooldownMin, CooldownMax
- SMART_EVENT_DAMAGED_TARGET = 33, //1 // MinDmg, MaxDmg, CooldownMin, CooldownMax
- SMART_EVENT_MOVEMENTINFORM = 34, //1 // MovementType(any), PointID
- SMART_EVENT_SUMMON_DESPAWNED = 35, //1 // Entry, CooldownMin, CooldownMax
- SMART_EVENT_CORPSE_REMOVED = 36, //1 // NONE
- SMART_EVENT_AI_INIT = 37, //1 // NONE
- SMART_EVENT_DATA_SET = 38, //1 // Id, Value, CooldownMin, CooldownMax
- SMART_EVENT_WAYPOINT_START = 39, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_WAYPOINT_REACHED = 40, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_TRANSPORT_ADDPLAYER = 41, //1 // NONE
- SMART_EVENT_TRANSPORT_ADDCREATURE = 42, //1 // Entry (0 any)
- SMART_EVENT_TRANSPORT_REMOVE_PLAYER = 43, //1 // NONE
- SMART_EVENT_TRANSPORT_RELOCATE = 44, //1 // PointId
- SMART_EVENT_INSTANCE_PLAYER_ENTER = 45, //1 // Team (0 any), CooldownMin, CooldownMax
- SMART_EVENT_AREATRIGGER_ONTRIGGER = 46, //1 // TriggerId(0 any)
- SMART_EVENT_QUEST_ACCEPTED = 47, //1 // none
- SMART_EVENT_QUEST_OBJ_COPLETETION = 48, //1 // none
- SMART_EVENT_QUEST_COMPLETION = 49, //1 // none
- SMART_EVENT_QUEST_REWARDED = 50, //1 // none
- SMART_EVENT_QUEST_FAIL = 51, //1 // none
- SMART_EVENT_TEXT_OVER = 52, //1 // GroupId from creature_text, creature entry who talks (0 any)
- SMART_EVENT_RECEIVE_HEAL = 53, //1 // MinHeal, MaxHeal, CooldownMin, CooldownMax
- SMART_EVENT_JUST_SUMMONED = 54, //1 // none
- SMART_EVENT_WAYPOINT_PAUSED = 55, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_WAYPOINT_RESUMED = 56, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_WAYPOINT_STOPPED = 57, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_WAYPOINT_ENDED = 58, //1 // PointId(0any), pathID(0any)
- SMART_EVENT_TIMED_EVENT_TRIGGERED = 59, //1 // id
- SMART_EVENT_UPDATE = 60, //1 // InitialMin, InitialMax, RepeatMin, RepeatMax
- SMART_EVENT_LINK = 61, //1 // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly
- SMART_EVENT_GOSSIP_SELECT = 62, //1 // menuID, actionID
- SMART_EVENT_JUST_CREATED = 63, //1 // none
- SMART_EVENT_GOSSIP_HELLO = 64, //1 // none
- SMART_EVENT_FOLLOW_COMPLETED = 65, //1 // none
- SMART_EVENT_DUMMY_EFFECT = 66, //1 // spellId, effectIndex
- 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 = 71,
+ SMART_EVENT_UPDATE_IC = 0, // InitialMin, InitialMax, RepeatMin, RepeatMax
+ SMART_EVENT_UPDATE_OOC = 1, // InitialMin, InitialMax, RepeatMin, RepeatMax
+ SMART_EVENT_HEALT_PCT = 2, // HPMin%, HPMax%, RepeatMin, RepeatMax
+ SMART_EVENT_MANA_PCT = 3, // ManaMin%, ManaMax%, RepeatMin, RepeatMax
+ SMART_EVENT_AGGRO = 4, // NONE
+ SMART_EVENT_KILL = 5, // CooldownMin0, CooldownMax1, playerOnly2, else creature entry3
+ SMART_EVENT_DEATH = 6, // NONE
+ SMART_EVENT_EVADE = 7, // NONE
+ SMART_EVENT_SPELLHIT = 8, // SpellID, School, CooldownMin, CooldownMax
+ SMART_EVENT_RANGE = 9, // MinDist, MaxDist, RepeatMin, RepeatMax
+ SMART_EVENT_OOC_LOS = 10, // NoHostile, MaxRnage, CooldownMin, CooldownMax
+ SMART_EVENT_RESPAWN = 11, // type, MapId, ZoneId
+ SMART_EVENT_TARGET_HEALTH_PCT = 12, // HPMin%, HPMax%, RepeatMin, RepeatMax
+ SMART_EVENT_TARGET_CASTING = 13, // RepeatMin, RepeatMax
+ SMART_EVENT_FRIENDLY_HEALTH = 14, // HPDeficit, Radius, RepeatMin, RepeatMax
+ SMART_EVENT_FRIENDLY_IS_CC = 15, // Radius, RepeatMin, RepeatMax
+ SMART_EVENT_FRIENDLY_MISSING_BUFF = 16, // SpellId, Radius, RepeatMin, RepeatMax
+ SMART_EVENT_SUMMONED_UNIT = 17, // CreatureId(0 all), CooldownMin, CooldownMax
+ SMART_EVENT_TARGET_MANA_PCT = 18, // ManaMin%, ManaMax%, RepeatMin, RepeatMax
+ SMART_EVENT_ACCEPTED_QUEST = 19, // QuestID(0any)
+ SMART_EVENT_REWARD_QUEST = 20, // QuestID(0any)
+ SMART_EVENT_REACHED_HOME = 21, // NONE
+ SMART_EVENT_RECEIVE_EMOTE = 22, // EmoteId, CooldownMin, CooldownMax, condition, val1, val2, val3
+ SMART_EVENT_HAS_AURA = 23, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
+ SMART_EVENT_TARGET_BUFFED = 24, // Param1 = SpellID, Param2 = Number of Time STacked, Param3/4 RepeatMin, RepeatMax
+ SMART_EVENT_RESET = 25, // Called after combat, when the creature respawn and spawn.
+ SMART_EVENT_IC_LOS = 26, // NoHostile, MaxRnage, CooldownMin, CooldownMax
+ SMART_EVENT_PASSENGER_BOARDED = 27, // CooldownMin, CooldownMax
+ SMART_EVENT_PASSENGER_REMOVED = 28, // CooldownMin, CooldownMax
+ SMART_EVENT_CHARMED = 29, // NONE
+ SMART_EVENT_CHARMED_TARGET = 30, // NONE
+ SMART_EVENT_SPELLHIT_TARGET = 31, // SpellID, School, CooldownMin, CooldownMax
+ SMART_EVENT_DAMAGED = 32, // MinDmg, MaxDmg, CooldownMin, CooldownMax
+ SMART_EVENT_DAMAGED_TARGET = 33, // MinDmg, MaxDmg, CooldownMin, CooldownMax
+ SMART_EVENT_MOVEMENTINFORM = 34, // MovementType(any), PointID
+ SMART_EVENT_SUMMON_DESPAWNED = 35, // Entry, CooldownMin, CooldownMax
+ SMART_EVENT_CORPSE_REMOVED = 36, // NONE
+ SMART_EVENT_AI_INIT = 37, // NONE
+ SMART_EVENT_DATA_SET = 38, // Id, Value, CooldownMin, CooldownMax
+ SMART_EVENT_WAYPOINT_START = 39, // PointId(0any), pathID(0any)
+ SMART_EVENT_WAYPOINT_REACHED = 40, // PointId(0any), pathID(0any)
+ SMART_EVENT_TRANSPORT_ADDPLAYER = 41, // NONE
+ SMART_EVENT_TRANSPORT_ADDCREATURE = 42, // Entry (0 any)
+ SMART_EVENT_TRANSPORT_REMOVE_PLAYER = 43, // NONE
+ SMART_EVENT_TRANSPORT_RELOCATE = 44, // PointId
+ SMART_EVENT_INSTANCE_PLAYER_ENTER = 45, // Team (0 any), CooldownMin, CooldownMax
+ SMART_EVENT_AREATRIGGER_ONTRIGGER = 46, // TriggerId(0 any)
+ SMART_EVENT_QUEST_ACCEPTED = 47, // none
+ SMART_EVENT_QUEST_OBJ_COPLETETION = 48, // none
+ SMART_EVENT_QUEST_COMPLETION = 49, // none
+ SMART_EVENT_QUEST_REWARDED = 50, // none
+ SMART_EVENT_QUEST_FAIL = 51, // none
+ SMART_EVENT_TEXT_OVER = 52, // GroupId from creature_text, creature entry who talks (0 any)
+ SMART_EVENT_RECEIVE_HEAL = 53, // MinHeal, MaxHeal, CooldownMin, CooldownMax
+ SMART_EVENT_JUST_SUMMONED = 54, // none
+ SMART_EVENT_WAYPOINT_PAUSED = 55, // PointId(0any), pathID(0any)
+ SMART_EVENT_WAYPOINT_RESUMED = 56, // PointId(0any), pathID(0any)
+ SMART_EVENT_WAYPOINT_STOPPED = 57, // PointId(0any), pathID(0any)
+ SMART_EVENT_WAYPOINT_ENDED = 58, // PointId(0any), pathID(0any)
+ SMART_EVENT_TIMED_EVENT_TRIGGERED = 59, // id
+ SMART_EVENT_UPDATE = 60, // InitialMin, InitialMax, RepeatMin, RepeatMax
+ SMART_EVENT_LINK = 61, // INTERNAL USAGE, no params, used to link together multiple events, does not use any extra resources to iterate event lists needlessly
+ SMART_EVENT_GOSSIP_SELECT = 62, // menuID, actionID
+ SMART_EVENT_JUST_CREATED = 63, // none
+ SMART_EVENT_GOSSIP_HELLO = 64, // none
+ SMART_EVENT_FOLLOW_COMPLETED = 65, // none
+ SMART_EVENT_DUMMY_EFFECT = 66, // spellId, effectIndex
+ SMART_EVENT_IS_BEHIND_TARGET = 67, // cooldownMin, CooldownMax
+ SMART_EVENT_GAME_EVENT_START = 68, // game_event.Entry
+ SMART_EVENT_GAME_EVENT_END = 69, // game_event.Entry
+ SMART_EVENT_GO_STATE_CHANGED = 70, // go state
+ SMART_EVENT_GO_EVENT_INFORM = 71, // eventId
+ SMART_EVENT_ACTION_DONE = 72, // eventId (SharedDefines.EventId)
+ SMART_EVENT_ON_SPELLCLICK = 73, // clicker (unit)
+
+ SMART_EVENT_END = 74,
};
struct SmartEvent
@@ -353,6 +354,16 @@ struct SmartEvent
struct
{
+ uint32 eventId;
+ } eventInform;
+
+ struct
+ {
+ uint32 eventId;
+ } doAction;
+
+ struct
+ {
uint32 param1;
uint32 param2;
uint32 param3;
@@ -399,7 +410,7 @@ enum SMART_ACTION
SMART_ACTION_FLEE_FOR_ASSIST = 25, // With Emote
SMART_ACTION_CALL_GROUPEVENTHAPPENS = 26, // QuestID
SMART_ACTION_CALL_CASTEDCREATUREORGO = 27, // CreatureId, SpellId
- SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid
+ SMART_ACTION_REMOVEAURASFROMSPELL = 28, // Spellid, 0 removes all auras
SMART_ACTION_FOLLOW = 29, // Distance (0 = default), Angle (0 = default), EndCreatureEntry, credit, creditType (0monsterkill, 1event)
SMART_ACTION_RANDOM_PHASE = 30, // PhaseId1, PhaseId2, PhaseId3...
SMART_ACTION_RANDOM_PHASE_RANGE = 31, // PhaseMin, PhaseMax
@@ -847,9 +858,9 @@ struct SmartAction
struct
{
- bool withDelayed;
+ uint32 withDelayed;
uint32 spell_id;
- bool withInstant;
+ uint32 withInstant;
} interruptSpellCasting;
struct
@@ -875,7 +886,7 @@ struct SmartAction
struct
{
- uint8 pointId;
+ uint32 pointId;
} MoveToPos;
struct
@@ -896,10 +907,13 @@ struct SmartAction
struct
{
- float distance;
- float angle;
+ uint32 distance;
+ uint32 angle;
} setRangedMovement;
+ //! Note for any new future actions
+ //! All parameters must have type uint32
+
struct
{
uint32 param1;
@@ -1167,7 +1181,9 @@ const uint32 SmartAIEventMask[SMART_EVENT_END][2] =
{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 },
-
+ {SMART_EVENT_GO_EVENT_INFORM, SMART_SCRIPT_TYPE_MASK_GAMEOBJECT },
+ {SMART_EVENT_ACTION_DONE, SMART_SCRIPT_TYPE_MASK_CREATURE },
+ {SMART_EVENT_ON_SPELLCLICK, SMART_SCRIPT_TYPE_MASK_CREATURE },
};
enum SmartEventFlags
@@ -1380,26 +1396,6 @@ class SmartAIMgr
}
return true;
}
- /*inline bool IsConditionValid(SmartScriptHolder e, int32 t, int32 v1, int32 v2, int32 v3)
- {
- bool error = false;
- if (t > 0 && v1 >= 0 && v2 >= 0 && v3 >= 0)
- {
- Condition cond;
- cond.mConditionType = ConditionType(t);
- cond.mConditionValue1 = uint32(v1);
- cond.mConditionValue2 = uint32(v2);
- cond.mConditionValue3 = uint32(v3);
- if (!sConditionMgr->isConditionTypeValid(&cond))
- error = true;
- }
- if (error)
- {
- sLog->outErrorDb("SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses invalid Condition, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType());
- return false;
- }
- return true;
- }*/
bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry)
{
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 21a2a75b470..252e120f0c9 100755
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -2207,7 +2207,6 @@ void AchievementGlobalMgr::LoadAchievementCriteriaList()
for (uint32 entryId = 0; entryId < sAchievementCriteriaStore.GetNumRows(); ++entryId)
{
-
AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId);
if (!criteria)
continue;
@@ -2238,7 +2237,6 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()
for (uint32 entryId = 0; entryId < sAchievementStore.GetNumRows(); ++entryId)
{
-
AchievementEntry const* achievement = sAchievementStore.LookupEntry(entryId);
if (!achievement || !achievement->refAchievement)
continue;
@@ -2247,6 +2245,10 @@ void AchievementGlobalMgr::LoadAchievementReferenceList()
++count;
}
+ // Once Bitten, Twice Shy (10 player) - Icecrown Citadel
+ if (AchievementEntry const* achievement = sAchievementStore.LookupEntry(4539))
+ const_cast<AchievementEntry*>(achievement)->mapID = 631; // Correct map requirement (currently has Ulduar)
+
sLog->outString(">> Loaded %u achievement references in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
sLog->outString();
}
diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
index c964f47f495..1b666859749 100644
--- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
+++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp
@@ -151,11 +151,11 @@ void ArenaTeamMgr::DistributeArenaPoints()
if (ArenaTeam* at = teamItr->second)
at->UpdateArenaPointsHelper(PlayerPoints);
+ /*
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Cycle that gives points to all players
- /*
- PreparedStatement* stmt;
+ PreparedStatement* stmt;
for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr)
{
@@ -170,9 +170,9 @@ void ArenaTeamMgr::DistributeArenaPoints()
trans->Append(stmt);
}
}
- */
CharacterDatabase.CommitTransaction(trans);
+ */
PlayerPoints.clear();
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 54c84f2e6d4..ebcf5495a55 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -850,12 +850,8 @@ void Battleground::EndBattleground(uint32 winner)
if (team == winner)
{
// update achievement BEFORE personal rating update
- if (ArenaTeamMember* member = winner_arena_team->GetMember(player->GetGUID()))
- {
- uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
- player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA,
- rating ? rating : 1);
- }
+ uint32 rating = player->GetArenaPersonalRating(winner_arena_team->GetSlot());
+ player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA, rating ? rating : 1);
winner_arena_team->MemberWon(player, loser_matchmaker_rating, winner_matchmaker_change);
}
@@ -1776,15 +1772,19 @@ void Battleground::HandleTriggerBuff(uint64 go_guid)
SpawnBGObject(index, BUFF_RESPAWN_TIME);
}
-void Battleground::HandleKillPlayer(Player* player, Player* killer)
+void Battleground::HandleKillPlayer(Player* victim, Player* killer)
{
// Keep in mind that for arena this will have to be changed a bit
// Add +1 deaths
- UpdatePlayerScore(player, SCORE_DEATHS, 1);
+ UpdatePlayerScore(victim, SCORE_DEATHS, 1);
// Add +1 kills to group and +1 killing_blows to killer
if (killer)
{
+ // Don't reward credit for killing ourselves, like fall damage of hellfire (warlock)
+ if (killer == victim)
+ return;
+
UpdatePlayerScore(killer, SCORE_HONORABLE_KILLS, 1);
UpdatePlayerScore(killer, SCORE_KILLING_BLOWS, 1);
@@ -1794,7 +1794,7 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer)
if (!creditedPlayer || creditedPlayer == killer)
continue;
- if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(player))
+ if (creditedPlayer->GetTeam() == killer->GetTeam() && creditedPlayer->IsAtGroupRewardDistance(victim))
UpdatePlayerScore(creditedPlayer, SCORE_HONORABLE_KILLS, 1);
}
}
@@ -1802,8 +1802,8 @@ void Battleground::HandleKillPlayer(Player* player, Player* killer)
if (!isArena())
{
// To be able to remove insignia -- ONLY IN Battlegrounds
- player->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
- RewardXPAtKill(killer, player);
+ victim->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
+ RewardXPAtKill(killer, victim);
}
}
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index b7079fb00e0..0d4fc458faa 100755
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -55,7 +55,7 @@ BattlegroundMgr::BattlegroundMgr() : m_AutoDistributionTimeChecker(0), m_ArenaTe
{
for (uint32 i = BATTLEGROUND_TYPE_NONE; i < MAX_BATTLEGROUND_TYPE_ID; i++)
m_Battlegrounds[i].clear();
- m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+ m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER);
m_Testing=false;
}
@@ -143,10 +143,10 @@ void BattlegroundMgr::Update(uint32 diff)
}
// if rating difference counts, maybe force-update queues
- if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER))
+ if (sWorld->getIntConfig(CONFIG_ARENA_MAX_RATING_DIFFERENCE) && sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER))
{
// it's time to force update
- if (m_NextRatingDiscardUpdate < diff)
+ if (m_NextRatedArenaUpdate < diff)
{
// forced update for rated arenas (scan all, but skipped non rated)
sLog->outDebug(LOG_FILTER_BATTLEGROUND, "BattlegroundMgr: UPDATING ARENA QUEUES");
@@ -156,10 +156,10 @@ void BattlegroundMgr::Update(uint32 diff)
BATTLEGROUND_AA, BattlegroundBracketId(bracket),
BattlegroundMgr::BGArenaType(BattlegroundQueueTypeId(qtype)), true, 0);
- m_NextRatingDiscardUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATING_DISCARD_TIMER);
+ m_NextRatedArenaUpdate = sWorld->getIntConfig(CONFIG_ARENA_RATED_UPDATE_TIMER);
}
else
- m_NextRatingDiscardUpdate -= diff;
+ m_NextRatedArenaUpdate -= diff;
}
if (sWorld->getBoolConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS))
{
@@ -771,8 +771,9 @@ void BattlegroundMgr::CreateInitialBattlegrounds()
continue;
}
- selectionWeight = fields[10].GetUInt8();
data.StartMaxDist = fields[9].GetFloat();
+
+ selectionWeight = fields[10].GetUInt8();
data.scriptId = sObjectMgr->GetScriptId(fields[11].GetCString());
//data.BattlegroundName = bl->name[sWorld->GetDefaultDbcLocale()];
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h
index dd502409178..4edad4da742 100755
--- a/src/server/game/Battlegrounds/BattlegroundMgr.h
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.h
@@ -141,7 +141,7 @@ class BattlegroundMgr
BattlegroundSelectionWeightMap m_BGSelectionWeights;
std::vector<uint64> m_QueueUpdateScheduler;
std::set<uint32> m_ClientBattlegroundIds[MAX_BATTLEGROUND_TYPE_ID][MAX_BATTLEGROUND_BRACKETS]; //the instanceids just visible for the client
- uint32 m_NextRatingDiscardUpdate;
+ uint32 m_NextRatedArenaUpdate;
time_t m_NextAutoDistributionTime;
uint32 m_AutoDistributionTimeChecker;
bool m_ArenaTesting;
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
index 39c6e00946a..bda1bdfa8d3 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp
@@ -56,6 +56,8 @@ void BattlegroundSA::Reset()
GateStatus[i] = BG_SA_GATE_OK;
ShipsStarted = false;
gateDestroyed = false;
+ _notEvenAScratch[BG_TEAM_ALLIANCE] = true;
+ _notEvenAScratch[BG_TEAM_HORDE] = true;
Status = BG_SA_WARMUP;
}
@@ -553,13 +555,13 @@ void BattlegroundSA::EventPlayerDamagedGO(Player* /*player*/, GameObject* go, ui
SendWarningToAll(LANG_BG_SA_IS_UNDER_ATTACK, go->GetGOInfo()->name.c_str());
}
-void BattlegroundSA::HandleKillUnit(Creature* unit, Player* killer)
+void BattlegroundSA::HandleKillUnit(Creature* creature, Player* killer)
{
- if (!unit)
- return;
-
- if (unit->GetEntry() == NPC_DEMOLISHER_SA)
+ if (creature->GetEntry() == NPC_DEMOLISHER_SA)
+ {
UpdatePlayerScore(killer, SCORE_DESTROYED_DEMOLISHER, 1);
+ _notEvenAScratch[Attackers] = false;
+ }
}
/*
diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
index c18806490f2..fd11cb2c5ea 100755
--- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
+++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h
@@ -456,7 +456,7 @@ class BattlegroundSA : public Battleground
/// Called when a player deal damage to building (door)
virtual void EventPlayerDamagedGO(Player* player, GameObject* go, uint32 eventType);
/// Called when a player kill a unit in bg
- virtual void HandleKillUnit(Creature* unit, Player* killer);
+ virtual void HandleKillUnit(Creature* creature, Player* killer);
/// Return the nearest graveyard where player can respawn
virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player);
/// Called when a player click on flag (graveyard flag)
@@ -531,9 +531,12 @@ class BattlegroundSA : public Battleground
/// Update score board
void UpdatePlayerScore(Player* Source, uint32 type, uint32 value, bool doAddHonor = true);
- // Achievement Defense of the Ancients
+ // Achievement: Defense of the Ancients
bool gateDestroyed;
+ // Achievement: Not Even a Scratch
+ bool notEvenAScratch(uint32 team) const { return _notEvenAScratch[GetTeamIndexByTeamId(team)]; }
+
/// Id of attacker team
TeamId Attackers;
@@ -615,5 +618,7 @@ class BattlegroundSA : public Battleground
bool InitSecondRound;
std::map<uint32/*id*/, uint32/*timer*/> DemoliserRespawnList;
+ // Achievement: Not Even a Scratch
+ bool _notEvenAScratch[BG_TEAMS_COUNT];
};
#endif
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index cc64a8e22dd..7a146e89505 100755
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -92,40 +92,6 @@ ChatCommand* ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand castCommandTable[] =
- {
- { "back", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastBackCommand>, "", NULL },
- { "dist", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastDistCommand>, "", NULL },
- { "self", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastSelfCommand>, "", NULL },
- { "target", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastTargetCommand>, "", NULL },
- { "dest", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastDestCommand>, "", NULL },
- { "", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleCastCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand characterDeletedCommandTable[] =
- {
- { "delete", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterDeletedDeleteCommand>, "", NULL },
- { "list", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterDeletedListCommand>, "", NULL },
- { "restore", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterDeletedRestoreCommand>, "", NULL },
- { "old", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterDeletedOldCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand characterCommandTable[] =
- {
- { "customize", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterCustomizeCommand>, "", NULL },
- { "changefaction", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterChangeFactionCommand>, "", NULL },
- { "changerace", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterChangeRaceCommand>, "", NULL },
- { "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable},
- { "erase", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleCharacterEraseCommand>, "", NULL },
- { "level", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleCharacterLevelCommand>, "", NULL },
- { "rename", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterRenameCommand>, "", NULL },
- { "reputation", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterReputationCommand>, "", NULL },
- { "titles", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleCharacterTitlesCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
static ChatCommand channelSetCommandTable[] =
{
{ "ownership", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleChannelSetOwnership>, "", NULL },
@@ -156,24 +122,6 @@ ChatCommand* ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand instanceCommandTable[] =
- {
- { "listbinds", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceListBindsCommand>, "", NULL },
- { "unbind", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceUnbindCommand>, "", NULL },
- { "stats", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleInstanceStatsCommand>, "", NULL },
- { "savedata", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleInstanceSaveDataCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand listCommandTable[] =
- {
- { "creature", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListCreatureCommand>, "", NULL },
- { "item", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListItemCommand>, "", NULL },
- { "object", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleListObjectCommand>, "", NULL },
- { "auras", SEC_ADMINISTRATOR, false, OldHandler<&ChatHandler::HandleListAurasCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
static ChatCommand lookupPlayerCommandTable[] =
{
{ "ip", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleLookupPlayerIpCommand>, "", NULL },
@@ -217,18 +165,6 @@ ChatCommand* ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand resetCommandTable[] =
- {
- { "achievements", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetAchievementsCommand>, "", NULL },
- { "honor", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetHonorCommand>, "", NULL },
- { "level", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetLevelCommand>, "", NULL },
- { "spells", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetSpellsCommand>, "", NULL },
- { "stats", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetStatsCommand>, "", NULL },
- { "talents", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetTalentsCommand>, "", NULL },
- { "all", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleResetAllCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
static ChatCommand sendCommandTable[] =
{
{ "items", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleSendItemsCommand>, "", NULL },
@@ -238,60 +174,6 @@ ChatCommand* ChatHandler::getCommandTable()
{ NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand serverIdleRestartCommandTable[] =
- {
- { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL },
- { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerIdleRestartCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand serverIdleShutdownCommandTable[] =
- {
- { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL },
- { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerIdleShutDownCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand serverRestartCommandTable[] =
- {
- { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL },
- { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerRestartCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand serverShutdownCommandTable[] =
- {
- { "cancel", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCancelCommand>, "", NULL },
- { "" , SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerShutDownCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand serverSetCommandTable[] =
- {
- { "difftime", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetDiffTimeCommand>, "", NULL },
- { "loglevel", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetLogLevelCommand>, "", NULL },
- { "logfilelevel", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerSetLogFileLevelCommand>, "", NULL },
- { "motd", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerSetMotdCommand>, "", NULL },
- { "closed", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerSetClosedCommand>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
- static ChatCommand serverCommandTable[] =
- {
- { "corpses", SEC_GAMEMASTER, true, OldHandler<&ChatHandler::HandleServerCorpsesCommand>, "", NULL },
- { "exit", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerExitCommand>, "", NULL },
- { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
- { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverIdleShutdownCommandTable },
- { "info", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleServerInfoCommand>, "", NULL },
- { "motd", SEC_PLAYER, true, OldHandler<&ChatHandler::HandleServerMotdCommand>, "", NULL },
- { "plimit", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleServerPLimitCommand>, "", NULL },
- { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
- { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
- { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
- { "togglequerylog", SEC_CONSOLE, true, OldHandler<&ChatHandler::HandleServerToggleQueryLogging>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
- };
-
static ChatCommand unbanCommandTable[] =
{
{ "account", SEC_ADMINISTRATOR, true, OldHandler<&ChatHandler::HandleUnBanAccountCommand>, "", NULL },
@@ -331,16 +213,10 @@ ChatCommand* ChatHandler::getCommandTable()
static ChatCommand commandTable[] =
{
- { "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable},
- { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
{ "lookup", SEC_ADMINISTRATOR, true, NULL, "", lookupCommandTable },
{ "pdump", SEC_ADMINISTRATOR, true, NULL, "", pdumpCommandTable },
{ "guild", SEC_ADMINISTRATOR, true, NULL, "", guildCommandTable },
{ "group", SEC_ADMINISTRATOR, false, NULL, "", groupCommandTable },
- { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
- { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
- { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
- { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
{ "channel", SEC_ADMINISTRATOR, true, NULL, "", channelCommandTable },
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index e88914a2daf..bbe138b923d 100755
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -119,10 +119,13 @@ class ChatHandler
GameObject* GetNearbyGameObject();
GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid, uint32 entry);
- bool HasSentErrorMessage() const { return sentErrorMessage;}
- void SetSentErrorMessage(bool val){ sentErrorMessage = val;};
- static bool LoadCommandTable() { return load_command_table;}
- static void SetLoadCommandTable(bool val){ load_command_table = val;};
+ bool HasSentErrorMessage() const { return sentErrorMessage; }
+ void SetSentErrorMessage(bool val){ sentErrorMessage = val; }
+ static bool LoadCommandTable() { return load_command_table; }
+ static void SetLoadCommandTable(bool val) { load_command_table = val; }
+
+ // cs_character
+ void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);
protected:
explicit ChatHandler() : m_session(NULL) {} // for CLI subclass
@@ -147,26 +150,6 @@ class ChatHandler
bool HandleBanListCharacterCommand(const char* args);
bool HandleBanListIPCommand(const char* args);
- bool HandleCastCommand(const char *args);
- bool HandleCastBackCommand(const char *args);
- bool HandleCastDistCommand(const char *args);
- bool HandleCastSelfCommand(const char *args);
- bool HandleCastTargetCommand(const char *args);
- bool HandleCastDestCommand(const char *args);
-
- bool HandleCharacterCustomizeCommand(const char* args);
- bool HandleCharacterChangeFactionCommand(const char* args);
- bool HandleCharacterChangeRaceCommand(const char * args);
- bool HandleCharacterDeletedDeleteCommand(const char* args);
- bool HandleCharacterDeletedListCommand(const char* args);
- bool HandleCharacterDeletedRestoreCommand(const char* args);
- bool HandleCharacterDeletedOldCommand(const char* args);
- bool HandleCharacterEraseCommand(const char* args);
- bool HandleCharacterLevelCommand(const char* args);
- bool HandleCharacterRenameCommand(const char* args);
- bool HandleCharacterReputationCommand(const char* args);
- bool HandleCharacterTitlesCommand(const char* args);
-
bool HandleChannelSetOwnership(const char *args);
bool HandlePossessCommand(const char* args);
@@ -180,16 +163,6 @@ class ChatHandler
bool HandleGuildRankCommand(const char* args);
bool HandleGuildDeleteCommand(const char* args);
- bool HandleInstanceListBindsCommand(const char* args);
- bool HandleInstanceUnbindCommand(const char* args);
- bool HandleInstanceStatsCommand(const char* args);
- bool HandleInstanceSaveDataCommand(const char * args);
-
- bool HandleListAurasCommand(const char * args);
- bool HandleListCreatureCommand(const char* args);
- bool HandleListItemCommand(const char* args);
- bool HandleListObjectCommand(const char* args);
-
bool HandleLookupAreaCommand(const char* args);
bool HandleLookupCreatureCommand(const char* args);
bool HandleLookupEventCommand(const char* args);
@@ -211,37 +184,11 @@ class ChatHandler
bool HandlePDumpLoadCommand(const char *args);
bool HandlePDumpWriteCommand(const char *args);
- bool HandleResetAchievementsCommand(const char * args);
- bool HandleResetAllCommand(const char * args);
- bool HandleResetHonorCommand(const char * args);
- bool HandleResetLevelCommand(const char * args);
- bool HandleResetSpellsCommand(const char* args);
- bool HandleResetStatsCommand(const char * args);
- bool HandleResetTalentsCommand(const char* args);
-
bool HandleSendItemsCommand(const char* args);
bool HandleSendMailCommand(const char* args);
bool HandleSendMessageCommand(const char * args);
bool HandleSendMoneyCommand(const char* args);
- bool HandleServerCorpsesCommand(const char* args);
- bool HandleServerExitCommand(const char* args);
- bool HandleServerIdleRestartCommand(const char* args);
- bool HandleServerIdleShutDownCommand(const char* args);
- bool HandleServerInfoCommand(const char* args);
- bool HandleServerMotdCommand(const char* args);
- bool HandleServerPLimitCommand(const char* args);
- bool HandleServerRestartCommand(const char* args);
- bool HandleServerSetLogLevelCommand(const char* args);
- bool HandleServerSetMotdCommand(const char* args);
- bool HandleServerShutDownCommand(const char* args);
- bool HandleServerShutDownCancelCommand(const char* args);
- bool HandleServerSetClosedCommand(const char* args);
- bool HandleServerToggleQueryLogging(const char* args);
-
- bool HandleServerSetLogFileLevelCommand(const char* args);
- bool HandleServerSetDiffTimeCommand(const char* args);
-
bool HandleUnBanAccountCommand(const char* args);
bool HandleUnBanAccountByCharCommand(const char* args);
bool HandleUnBanCharacterCommand(const char* args);
@@ -354,25 +301,8 @@ class ChatHandler
bool HandleBanHelper(BanMode mode, char const* args);
bool HandleBanInfoHelper(uint32 accountid, char const* accountname);
bool HandleUnBanHelper(BanMode mode, char const* args);
- void HandleCharacterLevel(Player* player, uint64 playerGuid, uint32 oldLevel, uint32 newLevel);
void HandleLearnSkillRecipesHelper(Player* player, uint32 skill_id);
- // Stores informations about a deleted character
- struct DeletedInfo
- {
- uint32 lowguid; ///< the low GUID from the character
- std::string name; ///< the character name
- uint32 accountId; ///< the account id
- std::string accountName; ///< the account name
- time_t deleteDate; ///< the date at which the character has been deleted
- };
-
- typedef std::list<DeletedInfo> DeletedInfoList;
- bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString = "");
- std::string GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const& itr_end);
- void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList);
- void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo);
-
private:
bool _HandleGMTicketResponseAppendCommand(const char* args, bool newLine);
diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp
index b2ac090c313..b05ba9b4194 100755
--- a/src/server/game/Chat/Commands/Level0.cpp
+++ b/src/server/game/Chat/Commands/Level0.cpp
@@ -80,29 +80,6 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/)
return true;
}
-bool ChatHandler::HandleServerInfoCommand(const char* /*args*/)
-{
- uint32 playersNum = sWorld->GetPlayerCount();
- uint32 maxPlayersNum = sWorld->GetMaxPlayerCount();
- uint32 activeClientsNum = sWorld->GetActiveSessionCount();
- uint32 queuedClientsNum = sWorld->GetQueuedSessionCount();
- uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount();
- uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount();
- std::string uptime = secsToTimeString(sWorld->GetUptime());
- uint32 updateTime = sWorld->GetUpdateTime();
-
- SendSysMessage(_FULLVERSION);
- PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum);
- PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
- PSendSysMessage(LANG_UPTIME, uptime.c_str());
- PSendSysMessage(LANG_UPDATE_DIFF, updateTime);
- //! Can't use sWorld->ShutdownMsg here in case of console command
- if (sWorld->IsShuttingDown())
- PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str());
-
- return true;
-}
-
bool ChatHandler::HandleDismountCommand(const char* /*args*/)
{
Player* player = m_session->GetPlayer();
@@ -150,10 +127,3 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/)
return true;
}
-/// Display the 'Message of the day' for the realm
-bool ChatHandler::HandleServerMotdCommand(const char* /*args*/)
-{
- PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd());
- return true;
-}
-
diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp
index 4359c5ff20c..b1e13b7d92d 100755
--- a/src/server/game/Chat/Commands/Level2.cpp
+++ b/src/server/game/Chat/Commands/Level2.cpp
@@ -458,190 +458,6 @@ bool ChatHandler::HandlePInfoCommand(const char* args)
return true;
}
-//rename characters
-bool ChatHandler::HandleCharacterRenameCommand(const char* args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- return false;
-
- if (target)
- {
- // check online security
- if (HasLowerSecurity(target, 0))
- return false;
-
- PSendSysMessage(LANG_RENAME_PLAYER, GetNameLink(target).c_str());
- target->SetAtLoginFlag(AT_LOGIN_RENAME);
- }
- else
- {
- // check offline security
- if (HasLowerSecurity(NULL, targetGuid))
- return false;
-
- std::string oldNameLink = playerLink(targetName);
-
- PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
-
- CharacterDatabase.Execute(stmt);
- }
-
- return true;
-}
-
-// customize characters
-bool ChatHandler::HandleCharacterCustomizeCommand(const char* args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- return false;
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
-
- if (target)
- {
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
- target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
-
- stmt->setUInt32(1, target->GetGUIDLow());
- }
- else
- {
- std::string oldNameLink = playerLink(targetName);
-
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
-
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
- }
-
- CharacterDatabase.Execute(stmt);
-
- return true;
-}
-
-bool ChatHandler::HandleCharacterChangeFactionCommand(const char* args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
-
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- return false;
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
-
- if (target)
- {
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
- target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
-
- stmt->setUInt32(1, target->GetGUIDLow());
- }
- else
- {
- std::string oldNameLink = playerLink(targetName);
-
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
-
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
- }
-
- CharacterDatabase.Execute(stmt);
-
- return true;
-}
-
-bool ChatHandler::HandleCharacterChangeRaceCommand(const char * args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- return false;
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE));
-
- if (target)
- {
- // TODO : add text into database
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER, GetNameLink(target).c_str());
- target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE);
-
- stmt->setUInt32(1, target->GetGUIDLow());
- }
- else
- {
- std::string oldNameLink = playerLink(targetName);
-
- // TODO : add text into database
- PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
-
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
- }
-
- CharacterDatabase.Execute(stmt);
-
- return true;
-}
-
-bool ChatHandler::HandleCharacterReputationCommand(const char* args)
-{
- Player* target;
- if (!extractPlayerTarget((char*)args, &target))
- return false;
-
- LocaleConstant loc = GetSessionDbcLocale();
-
- FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
- for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
- {
- const FactionState& faction = itr->second;
- FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID);
- char const* factionName = factionEntry ? factionEntry->name : "#Not found#";
- ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
- std::string rankName = GetTrinityString(ReputationRankStrIndex[rank]);
- std::ostringstream ss;
- if (m_session)
- ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r";
- else
- ss << faction.ID << " - " << factionName << ' ' << localeNames[loc];
-
- ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
-
- if (faction.Flags & FACTION_FLAG_VISIBLE)
- ss << GetTrinityString(LANG_FACTION_VISIBLE);
- if (faction.Flags & FACTION_FLAG_AT_WAR)
- ss << GetTrinityString(LANG_FACTION_ATWAR);
- if (faction.Flags & FACTION_FLAG_PEACE_FORCED)
- ss << GetTrinityString(LANG_FACTION_PEACE_FORCED);
- if (faction.Flags & FACTION_FLAG_HIDDEN)
- ss << GetTrinityString(LANG_FACTION_HIDDEN);
- if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED)
- ss << GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
- if (faction.Flags & FACTION_FLAG_INACTIVE)
- ss << GetTrinityString(LANG_FACTION_INACTIVE);
-
- SendSysMessage(ss.str().c_str());
- }
- return true;
-}
-
bool ChatHandler::HandleLookupEventCommand(const char* args)
{
if (!*args)
@@ -848,13 +664,6 @@ bool ChatHandler::LookupPlayerSearchCommand(PreparedQueryResult result, int32 li
return true;
}
-/// Triggering corpses expire check in world
-bool ChatHandler::HandleServerCorpsesCommand(const char* /*args*/)
-{
- sObjectAccessor->RemoveOldCorpses();
- return true;
-}
-
bool ChatHandler::HandleRepairitemsCommand(const char* args)
{
Player* target;
@@ -1130,43 +939,3 @@ bool ChatHandler::HandleLookupTitleCommand(const char* args)
SendSysMessage(LANG_COMMAND_NOTITLEFOUND);
return true;
}
-
-bool ChatHandler::HandleCharacterTitlesCommand(const char* args)
-{
- if (!*args)
- return false;
-
- Player* target;
- if (!extractPlayerTarget((char*)args, &target))
- return false;
-
- LocaleConstant loc = GetSessionDbcLocale();
- char const* targetName = target->GetName();
- char const* knownStr = GetTrinityString(LANG_KNOWN);
-
- // Search in CharTitles.dbc
- for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
- {
- CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
- if (titleInfo && target->HasTitle(titleInfo))
- {
- std::string name = titleInfo->name;
- if (name.empty())
- continue;
-
- char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
- ? GetTrinityString(LANG_ACTIVE)
- : "";
-
- char titleNameStr[80];
- snprintf(titleNameStr, 80, name.c_str(), targetName);
-
- // send title in "id (idx:idx) - [namedlink locale]" format
- if (m_session)
- PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr);
- else
- PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr);
- }
- }
- return true;
-}
diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp
index 2ae7e73b828..0386b8786b6 100755
--- a/src/server/game/Chat/Commands/Level3.cpp
+++ b/src/server/game/Chat/Commands/Level3.cpp
@@ -385,365 +385,6 @@ bool ChatHandler::HandleAddItemSetCommand(const char *args)
return true;
}
-bool ChatHandler::HandleListItemCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char* cId = extractKeyFromLink((char*)args, "Hitem");
- if (!cId)
- return false;
-
- uint32 item_id = atol(cId);
- if (!item_id)
- {
- PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id);
- if (!itemProto)
- {
- PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, item_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* c_count = strtok(NULL, " ");
- int _count = c_count ? atol(c_count) : 10;
-
- if (_count < 0)
- return false;
- uint32 count = uint32(_count);
-
- PreparedQueryResult result;
-
- // inventory case
- uint32 inv_count = 0;
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM);
- stmt->setUInt32(0, item_id);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- inv_count = (*result)[0].GetUInt64();
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY);
- stmt->setUInt32(0, item_id);
- stmt->setUInt32(1, count);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 item_bag = fields[1].GetUInt32();
- uint8 item_slot = fields[2].GetUInt8();
- uint32 owner_guid = fields[3].GetUInt32();
- uint32 owner_acc = fields[4].GetUInt32();
- std::string owner_name = fields[5].GetString();
-
- char const* item_pos = 0;
- if (Player::IsEquipmentPos(item_bag, item_slot))
- item_pos = "[equipped]";
- else if (Player::IsInventoryPos(item_bag, item_slot))
- item_pos = "[in inventory]";
- else if (Player::IsBankPos(item_bag, item_slot))
- item_pos = "[in bank]";
- else
- item_pos = "";
-
- PSendSysMessage(LANG_ITEMLIST_SLOT, item_guid, owner_name.c_str(), owner_guid, owner_acc, item_pos);
- }
- while (result->NextRow());
-
- uint32 res_count = uint32(result->GetRowCount());
-
- if (count > res_count)
- count -= res_count;
- else if (count)
- count = 0;
- }
-
- // mail case
- uint32 mail_count = 0;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM);
- stmt->setUInt32(0, item_id);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- mail_count = (*result)[0].GetUInt64();
-
- if (count > 0)
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY);
- stmt->setUInt32(0, item_id);
- stmt->setUInt32(1, count);
- result = CharacterDatabase.Query(stmt);
- }
- else
- result = PreparedQueryResult(NULL);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 item_s = fields[1].GetUInt32();
- uint32 item_r = fields[2].GetUInt32();
- uint32 item_s_acc = fields[3].GetUInt32();
- std::string item_s_name = fields[4].GetString();
- uint32 item_r_acc = fields[5].GetUInt32();
- std::string item_r_name = fields[6].GetString();
-
- char const* item_pos = "[in mail]";
-
- PSendSysMessage(LANG_ITEMLIST_MAIL, item_guid, item_s_name.c_str(), item_s, item_s_acc, item_r_name.c_str(), item_r, item_r_acc, item_pos);
- }
- while (result->NextRow());
-
- uint32 res_count = uint32(result->GetRowCount());
-
- if (count > res_count)
- count -= res_count;
- else if (count)
- count = 0;
- }
-
- // auction case
- uint32 auc_count = 0;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM);
- stmt->setUInt32(0, item_id);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- auc_count = (*result)[0].GetUInt64();
-
- if (count > 0)
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY);
- stmt->setUInt32(0, item_id);
- stmt->setUInt32(1, count);
- result = CharacterDatabase.Query(stmt);
- }
- else
- result = PreparedQueryResult(NULL);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 owner = fields[1].GetUInt32();
- uint32 owner_acc = fields[2].GetUInt32();
- std::string owner_name = fields[3].GetString();
-
- char const* item_pos = "[in auction]";
-
- PSendSysMessage(LANG_ITEMLIST_AUCTION, item_guid, owner_name.c_str(), owner, owner_acc, item_pos);
- }
- while (result->NextRow());
- }
-
- // guild bank case
- uint32 guild_count = 0;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM);
- stmt->setUInt32(0, item_id);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- guild_count = (*result)[0].GetUInt64();
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY);
- stmt->setUInt32(0, item_id);
- stmt->setUInt32(1, count);
- result = CharacterDatabase.Query(stmt);
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 item_guid = fields[0].GetUInt32();
- uint32 guild_guid = fields[1].GetUInt32();
- std::string guild_name = fields[2].GetString();
-
- char const* item_pos = "[in guild bank]";
-
- PSendSysMessage(LANG_ITEMLIST_GUILD, item_guid, guild_name.c_str(), guild_guid, item_pos);
- }
- while (result->NextRow());
-
- uint32 res_count = uint32(result->GetRowCount());
-
- if (count > res_count)
- count -= res_count;
- else if (count)
- count = 0;
- }
-
- if (inv_count + mail_count + auc_count + guild_count == 0)
- {
- SendSysMessage(LANG_COMMAND_NOITEMFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, item_id, inv_count + mail_count + auc_count + guild_count, inv_count, mail_count, auc_count, guild_count);
- return true;
-}
-
-bool ChatHandler::HandleListObjectCommand(const char *args)
-{
- if (!*args)
- return false;
-
- // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args, "Hgameobject_entry");
- if (!cId)
- return false;
-
- uint32 go_id = atol(cId);
- if (!go_id)
- {
- PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(go_id);
- if (!gInfo)
- {
- PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, go_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* c_count = strtok(NULL, " ");
- int count = c_count ? atol(c_count) : 10;
-
- if (count < 0)
- return false;
-
- QueryResult result;
-
- uint32 obj_count = 0;
- result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", go_id);
- if (result)
- obj_count = (*result)[0].GetUInt64();
-
- if (m_session)
- {
- Player* player = m_session->GetPlayer();
- result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
- player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), go_id, uint32(count));
- }
- else
- result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u",
- go_id, uint32(count));
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- float x = fields[1].GetFloat();
- float y = fields[2].GetFloat();
- float z = fields[3].GetFloat();
- int mapid = fields[4].GetUInt16();
- uint32 entry = fields[5].GetUInt32();
-
- if (m_session)
- PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapid);
- else
- PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapid);
- } while (result->NextRow());
- }
-
- PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, go_id, obj_count);
- return true;
-}
-
-bool ChatHandler::HandleListCreatureCommand(const char *args)
-{
- if (!*args)
- return false;
-
- // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
- char* cId = extractKeyFromLink((char*)args, "Hcreature_entry");
- if (!cId)
- return false;
-
- uint32 cr_id = atol(cId);
- if (!cr_id)
- {
- PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(cr_id);
- if (!cInfo)
- {
- PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, cr_id);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* c_count = strtok(NULL, " ");
- int count = c_count ? atol(c_count) : 10;
-
- if (count < 0)
- return false;
-
- QueryResult result;
-
- uint32 cr_count = 0;
- result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", cr_id);
- if (result)
- cr_count = (*result)[0].GetUInt64();
-
- if (m_session)
- {
- Player* player = m_session->GetPlayer();
- result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
- player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), cr_id, uint32(count));
- }
- else
- result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
- cr_id, uint32(count));
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
- uint32 guid = fields[0].GetUInt32();
- float x = fields[1].GetFloat();
- float y = fields[2].GetFloat();
- float z = fields[3].GetFloat();
- int mapid = fields[4].GetUInt16();
-
- if (m_session)
- PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapid);
- else
- PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapid);
- } while (result->NextRow());
- }
-
- PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, cr_id, cr_count);
- return true;
-}
-
bool ChatHandler::HandleLookupItemCommand(const char *args)
{
if (!*args)
@@ -1144,15 +785,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
@@ -1187,15 +833,20 @@ bool ChatHandler::HandleLookupQuestCommand(const char *args)
{
QuestStatus status = target->GetQuestStatus(qinfo->GetQuestId());
- if (status == QUEST_STATUS_COMPLETE)
+ switch (status)
{
- if (target->GetQuestRewardStatus(qinfo->GetQuestId()))
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
- else
+ case QUEST_STATUS_COMPLETE:
statusStr = GetTrinityString(LANG_COMMAND_QUEST_COMPLETE);
+ break;
+ case QUEST_STATUS_INCOMPLETE:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
+ break;
+ case QUEST_STATUS_REWARDED:
+ statusStr = GetTrinityString(LANG_COMMAND_QUEST_REWARDED);
+ break;
+ default:
+ break;
}
- else if (status == QUEST_STATUS_INCOMPLETE)
- statusStr = GetTrinityString(LANG_COMMAND_QUEST_ACTIVE);
}
if (m_session)
@@ -1730,7 +1381,7 @@ bool ChatHandler::HandleGuildUninviteCommand(const char *args)
if (!extractPlayerTarget((char*)args, &target, &target_guid))
return false;
- uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid);
+ uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);
if (!glId)
return false;
@@ -1756,7 +1407,7 @@ bool ChatHandler::HandleGuildRankCommand(const char *args)
if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
return false;
- uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromGuid(target_guid);
+ uint32 glId = target ? target->GetGuildId() : Player::GetGuildIdFromDB(target_guid);
if (!glId)
return false;
@@ -2188,47 +1839,6 @@ void ChatHandler::HandleCharacterLevel(Player* player, uint64 playerGuid, uint32
}
}
-bool ChatHandler::HandleCharacterLevelCommand(const char *args)
-{
- char* nameStr;
- char* levelStr;
- extractOptFirstArg((char*)args, &nameStr, &levelStr);
- if (!levelStr)
- return false;
-
- // exception opt second arg: .character level $name
- if (isalpha(levelStr[0]))
- {
- nameStr = levelStr;
- levelStr = NULL; // current level will used
- }
-
- Player* target;
- uint64 target_guid;
- std::string target_name;
- if (!extractPlayerTarget(nameStr, &target, &target_guid, &target_name))
- return false;
-
- int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(target_guid);
- int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
-
- if (newlevel < 1)
- return false; // invalid level
-
- if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
- newlevel = STRONG_MAX_LEVEL;
-
- HandleCharacterLevel(target, target_guid, oldlevel, newlevel);
-
- if (!m_session || m_session->GetPlayer() != target) // including player == NULL
- {
- std::string nameLink = playerLink(target_name);
- PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel);
- }
-
- return true;
-}
-
bool ChatHandler::HandleLevelUpCommand(const char *args)
{
char* nameStr;
@@ -2380,457 +1990,6 @@ bool ChatHandler::HandleChangeWeather(const char *args)
return true;
}
-bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
-{
- Unit* unit = getSelectedUnit();
- if (!unit)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- char const* talentStr = GetTrinityString(LANG_TALENT);
- char const* passiveStr = GetTrinityString(LANG_PASSIVE);
-
- Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras();
- PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
- for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
- {
- bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
-
- AuraApplication const* aurApp = itr->second;
- Aura const* aura = aurApp->GetBase();
- char const* name = aura->GetSpellInfo()->SpellName;
-
- std::ostringstream ss_name;
- ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
-
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (m_session ? ss_name.str().c_str() : name),
- aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
- aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""),
- (talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",
- GUID_LOPART(aura->GetCasterGUID()));
- }
- for (uint16 i = 0; i < TOTAL_AURAS; ++i)
- {
- Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i));
- if (uAuraList.empty())
- continue;
-
- PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
- for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
- {
- PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(),
- (*itr)->GetAmount());
- }
- }
- return true;
-}
-
-bool ChatHandler::HandleResetAchievementsCommand (const char * args)
-{
- Player* target;
- uint64 target_guid;
- if (!extractPlayerTarget((char*)args, &target, &target_guid))
- return false;
-
- if (target)
- target->GetAchievementMgr().Reset();
- else
- AchievementMgr::DeleteFromDB(GUID_LOPART(target_guid));
-
- return true;
-}
-
-bool ChatHandler::HandleResetHonorCommand (const char * args)
-{
- Player* target;
- if (!extractPlayerTarget((char*)args, &target))
- return false;
-
- target->SetCurrency(CURRENCY_TYPE_HONOR_POINTS, 0);
- target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
- target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
- target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
-
- return true;
-}
-
-static bool HandleResetStatsOrLevelHelper(Player* player)
-{
- ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(player->getClass());
- if (!cEntry)
- {
- sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass());
- return false;
- }
-
- uint8 powertype = cEntry->powerType;
-
- // reset m_form if no aura
- if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
- player->SetShapeshiftForm(FORM_NONE);
-
- player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
- player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH);
-
- player->setFactionForRace(player->getRace());
-
- player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powertype << 24)));
-
- // reset only if player not in some form;
- if (player->GetShapeshiftForm() == FORM_NONE)
- player->InitDisplayIds();
-
- player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
-
- player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
-
- //-1 is default value
- player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
-
- //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000);
- return true;
-}
-
-bool ChatHandler::HandleResetLevelCommand(const char * args)
-{
- Player* target;
- if (!extractPlayerTarget((char*)args, &target))
- return false;
-
- if (!HandleResetStatsOrLevelHelper(target))
- return false;
-
- uint8 oldLevel = target->getLevel();
-
- // set starting level
- uint32 start_level = target->getClass() != CLASS_DEATH_KNIGHT
- ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
- : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
-
- target->_ApplyAllLevelScaleItemMods(false);
- target->SetLevel(start_level);
- target->InitRunes();
- target->InitStatsForLevel(true);
- target->InitTaxiNodesForLevel();
- target->InitGlyphsForLevel();
- target->InitTalentForLevel();
- target->SetUInt32Value(PLAYER_XP, 0);
-
- target->_ApplyAllLevelScaleItemMods(true);
-
- // reset level for pet
- if (Pet* pet = target->GetPet())
- pet->SynchronizeLevelWithOwner();
-
- sScriptMgr->OnPlayerLevelChanged(target, oldLevel);
-
- return true;
-}
-
-bool ChatHandler::HandleResetStatsCommand(const char * args)
-{
- Player* target;
- if (!extractPlayerTarget((char*)args, &target))
- return false;
-
- if (!HandleResetStatsOrLevelHelper(target))
- return false;
-
- target->InitRunes();
- target->InitStatsForLevel(true);
- target->InitTaxiNodesForLevel();
- target->InitGlyphsForLevel();
- target->InitTalentForLevel();
-
- return true;
-}
-
-bool ChatHandler::HandleResetSpellsCommand(const char* args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- return false;
-
- if (target)
- {
- target->resetSpells(/* bool myClassOnly */);
-
- ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
- if (!m_session || m_session->GetPlayer() != target)
- PSendSysMessage(LANG_RESET_SPELLS_ONLINE, GetNameLink(target).c_str());
- }
- else
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
-
- CharacterDatabase.Execute(stmt);
-
- PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
- }
-
- return true;
-}
-
-bool ChatHandler::HandleResetTalentsCommand(const char* args)
-{
- Player* target;
- uint64 targetGuid;
- std::string targetName;
- if (!extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
- {
- // Try reset talents as Hunter Pet
- Creature* creature = getSelectedCreature();
- if (!*args && creature && creature->isPet())
- {
- Unit* owner = creature->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer()))
- {
- creature->ToPet()->resetTalents();
- owner->ToPlayer()->SendTalentsInfoData(true);
-
- ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS);
- if (!m_session || m_session->GetPlayer() != owner->ToPlayer())
- PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, GetNameLink(owner->ToPlayer()).c_str());
- }
- return true;
- }
-
- SendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (target)
- {
- target->ResetTalents(true);
- target->SendTalentsInfoData(false);
- ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
- if (!m_session || m_session->GetPlayer() != target)
- PSendSysMessage(LANG_RESET_TALENTS_ONLINE, GetNameLink(target).c_str());
-
- Pet* pet = target->GetPet();
- Pet::resetTalentsForAllPetsOf(target, pet);
- if (pet)
- target->SendTalentsInfoData(true);
- return true;
- }
- else if (targetGuid)
- {
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
-
- stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
- stmt->setUInt32(1, GUID_LOPART(targetGuid));
-
- CharacterDatabase.Execute(stmt);
-
- std::string nameLink = playerLink(targetName);
- PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
- return true;
- }
-
- SendSysMessage(LANG_NO_CHAR_SELECTED);
- SetSentErrorMessage(true);
- return false;
-}
-
-bool ChatHandler::HandleResetAllCommand(const char * args)
-{
- if (!*args)
- return false;
-
- std::string casename = args;
-
- AtLoginFlags atLogin;
-
- // Command specially created as single command to prevent using short case names
- if (casename == "spells")
- {
- atLogin = AT_LOGIN_RESET_SPELLS;
- sWorld->SendWorldText(LANG_RESETALL_SPELLS);
- if (!m_session)
- SendSysMessage(LANG_RESETALL_SPELLS);
- }
- else if (casename == "talents")
- {
- atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
- sWorld->SendWorldText(LANG_RESETALL_TALENTS);
- if (!m_session)
- SendSysMessage(LANG_RESETALL_TALENTS);
- }
- else
- {
- PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args);
- SetSentErrorMessage(true);
- return false;
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS);
-
- stmt->setUInt16(0, uint16(atLogin));
-
- CharacterDatabase.Execute(stmt);
-
- TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
- HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
- for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
- itr->second->SetAtLoginFlag(atLogin);
-
- return true;
-}
-
-bool ChatHandler::HandleServerShutDownCancelCommand(const char* /*args*/)
-{
- sWorld->ShutdownCancel();
- return true;
-}
-
-bool ChatHandler::HandleServerShutDownCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char* time_str = strtok ((char*) args, " ");
- char* exitcode_str = strtok (NULL, "");
-
- int32 time = atoi (time_str);
-
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
- return false;
-
- if (exitcode_str)
- {
- int32 exitcode = atoi (exitcode_str);
-
- // Handle atoi() errors
- if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
- return false;
-
- // Exit code should be in range of 0-125, 126-255 is used
- // in many shells for their own return codes and code > 255
- // is not supported in many others
- if (exitcode < 0 || exitcode > 125)
- return false;
-
- sWorld->ShutdownServ(time, 0, exitcode);
- }
- else
- sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE);
- return true;
-}
-
-bool ChatHandler::HandleServerRestartCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char* time_str = strtok ((char*) args, " ");
- char* exitcode_str = strtok (NULL, "");
-
- int32 time = atoi (time_str);
-
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
- return false;
-
- if (exitcode_str)
- {
- int32 exitcode = atoi (exitcode_str);
-
- // Handle atoi() errors
- if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
- return false;
-
- // Exit code should be in range of 0-125, 126-255 is used
- // in many shells for their own return codes and code > 255
- // is not supported in many others
- if (exitcode < 0 || exitcode > 125)
- return false;
-
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitcode);
- }
- else
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
- return true;
-}
-
-bool ChatHandler::HandleServerIdleRestartCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char* time_str = strtok ((char*) args, " ");
- char* exitcode_str = strtok (NULL, "");
-
- int32 time = atoi (time_str);
-
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
- return false;
-
- if (exitcode_str)
- {
- int32 exitcode = atoi (exitcode_str);
-
- // Handle atoi() errors
- if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
- return false;
-
- // Exit code should be in range of 0-125, 126-255 is used
- // in many shells for their own return codes and code > 255
- // is not supported in many others
- if (exitcode < 0 || exitcode > 125)
- return false;
-
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, exitcode);
- }
- else
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART|SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
- return true;
-}
-
-bool ChatHandler::HandleServerIdleShutDownCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char* time_str = strtok ((char*) args, " ");
- char* exitcode_str = strtok (NULL, "");
-
- int32 time = atoi (time_str);
-
- ///- Prevent interpret wrong arg value as 0 secs shutdown time
- if ((time == 0 && (time_str[0] != '0' || time_str[1] != '\0')) || time < 0)
- return false;
-
- if (exitcode_str)
- {
- int32 exitcode = atoi (exitcode_str);
-
- // Handle atoi() errors
- if (exitcode == 0 && (exitcode_str[0] != '0' || exitcode_str[1] != '\0'))
- return false;
-
- // Exit code should be in range of 0-125, 126-255 is used
- // in many shells for their own return codes and code > 255
- // is not supported in many others
- if (exitcode < 0 || exitcode > 125)
- return false;
-
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitcode);
- }
- else
- sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
- return true;
-}
bool ChatHandler::HandleBanAccountCommand(const char *args)
{
@@ -3752,277 +2911,6 @@ bool ChatHandler::HandleMovegensCommand(const char* /*args*/)
return true;
}
-bool ChatHandler::HandleServerPLimitCommand(const char *args)
-{
- if (*args)
- {
- char* param = strtok((char*)args, " ");
- if (!param)
- return false;
-
- int l = strlen(param);
-
- if (strncmp(param, "player", l) == 0)
- sWorld->SetPlayerSecurityLimit(SEC_PLAYER);
- else if (strncmp(param, "moderator", l) == 0)
- sWorld->SetPlayerSecurityLimit(SEC_MODERATOR);
- else if (strncmp(param, "gamemaster", l) == 0)
- sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER);
- else if (strncmp(param, "administrator", l) == 0)
- sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR);
- else if (strncmp(param, "reset", l) == 0)
- {
- sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100));
- sWorld->LoadDBAllowedSecurityLevel();
- }
- else
- {
- int val = atoi(param);
- if (val < 0)
- sWorld->SetPlayerSecurityLimit(AccountTypes(uint32(-val)));
- else
- sWorld->SetPlayerAmountLimit(uint32(val));
- }
- }
-
- uint32 pLimit = sWorld->GetPlayerAmountLimit();
- AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
- char const* secName = "";
- switch (allowedAccountType)
- {
- case SEC_PLAYER: secName = "Player"; break;
- case SEC_MODERATOR: secName = "Moderator"; break;
- case SEC_GAMEMASTER: secName = "Gamemaster"; break;
- case SEC_ADMINISTRATOR: secName = "Administrator"; break;
- default: secName = "<unknown>"; break;
- }
-
- PSendSysMessage("Player limits: amount %u, min. security level %s.", pLimit, secName);
-
- return true;
-}
-
-bool ChatHandler::HandleCastCommand(const char *args)
-{
- if (!*args)
- return false;
-
- Unit* target = getSelectedUnit();
-
- if (!target)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell)
- return false;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
- if (!spellInfo)
- {
- PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
- {
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* trig_str = strtok(NULL, " ");
- if (trig_str)
- {
- int l = strlen(trig_str);
- if (strncmp(trig_str, "triggered", l) != 0)
- return false;
- }
-
- bool triggered = (trig_str != NULL);
-
- m_session->GetPlayer()->CastSpell(target, spell, triggered);
-
- return true;
-}
-
-bool ChatHandler::HandleCastBackCommand(const char *args)
-{
- Creature* caster = getSelectedCreature();
-
- if (!caster)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell || !sSpellMgr->GetSpellInfo(spell))
- {
- PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* trig_str = strtok(NULL, " ");
- if (trig_str)
- {
- int l = strlen(trig_str);
- if (strncmp(trig_str, "triggered", l) != 0)
- return false;
- }
-
- bool triggered = (trig_str != NULL);
-
- caster->CastSpell(m_session->GetPlayer(), spell, triggered);
-
- return true;
-}
-
-bool ChatHandler::HandleCastDistCommand(const char *args)
-{
- if (!*args)
- return false;
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell)
- return false;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
- if (!spellInfo)
- {
- PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
- {
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
- SetSentErrorMessage(true);
- return false;
- }
-
- char *distStr = strtok(NULL, " ");
-
- float dist = 0;
-
- if (distStr)
- sscanf(distStr, "%f", &dist);
-
- char* trig_str = strtok(NULL, " ");
- if (trig_str)
- {
- int l = strlen(trig_str);
- if (strncmp(trig_str, "triggered", l) != 0)
- return false;
- }
-
- bool triggered = (trig_str != NULL);
-
- float x, y, z;
- m_session->GetPlayer()->GetClosePoint(x, y, z, dist);
-
- m_session->GetPlayer()->CastSpell(x, y, z, spell, triggered);
- return true;
-}
-
-bool ChatHandler::HandleCastTargetCommand(const char *args)
-{
- Creature* caster = getSelectedCreature();
-
- if (!caster)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- if (!caster->getVictim())
- {
- SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
- SetSentErrorMessage(true);
- return false;
- }
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell || !sSpellMgr->GetSpellInfo(spell))
- {
- PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* trig_str = strtok(NULL, " ");
- if (trig_str)
- {
- int l = strlen(trig_str);
- if (strncmp(trig_str, "triggered", l) != 0)
- return false;
- }
-
- bool triggered = (trig_str != NULL);
-
- caster->CastSpell(caster->getVictim(), spell, triggered);
-
- return true;
-}
-
-bool ChatHandler::HandleCastDestCommand(const char *args)
-{
- Unit* caster = getSelectedUnit();
- if (!caster)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell || !sSpellMgr->GetSpellInfo(spell))
- {
- PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
- SetSentErrorMessage(true);
- return false;
- }
-
- char* px = strtok(NULL, " ");
- char* py = strtok(NULL, " ");
- char* pz = strtok(NULL, " ");
-
- if (!px || !py || !pz)
- return false;
-
- float x = (float)atof(px);
- float y = (float)atof(py);
- float z = (float)atof(pz);
-
- char* trig_str = strtok(NULL, " ");
- if (trig_str)
- {
- int l = strlen(trig_str);
- if (strncmp(trig_str, "triggered", l) != 0)
- return false;
- }
-
- bool triggered = (trig_str != NULL);
-
- caster->CastSpell(x, y, z, spell, triggered);
-
- return true;
-}
-
/*
ComeToMe command REQUIRED for 3rd party scripting library to have access to PointMovementGenerator
Without this function 3rd party scripting library will get linking errors (unresolved external)
@@ -4049,196 +2937,6 @@ bool ChatHandler::HandleComeToMeCommand(const char *args)
return true;
}
-bool ChatHandler::HandleCastSelfCommand(const char *args)
-{
- if (!*args)
- return false;
-
- Unit* target = getSelectedUnit();
-
- if (!target)
- {
- SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
- SetSentErrorMessage(true);
- return false;
- }
-
- // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
- uint32 spell = extractSpellIdFromLink((char*)args);
- if (!spell)
- return false;
-
- SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
- if (!spellInfo)
- return false;
-
- if (!SpellMgr::IsSpellValid(spellInfo, m_session->GetPlayer()))
- {
- PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spell);
- SetSentErrorMessage(true);
- return false;
- }
-
- target->CastSpell(target, spell, false);
-
- return true;
-}
-
-std::string GetTimeString(uint64 time)
-{
- uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
- std::ostringstream ss;
- if (days) ss << days << "d ";
- if (hours) ss << hours << "h ";
- ss << minute << 'm';
- return ss.str();
-}
-
-bool ChatHandler::HandleInstanceListBindsCommand(const char* /*args*/)
-{
- Player* player = getSelectedPlayer();
- if (!player) player = m_session->GetPlayer();
- uint32 counter = 0;
- for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
- {
- Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
- for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
- {
- InstanceSave* save = itr->second.save;
- std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
- counter++;
- }
- }
- PSendSysMessage("player binds: %d", counter);
- counter = 0;
- Group* group = player->GetGroup();
- if (group)
- {
- for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
- {
- Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
- for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
- {
- InstanceSave* save = itr->second.save;
- std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
- counter++;
- }
- }
- }
- PSendSysMessage("group binds: %d", counter);
-
- return true;
-}
-
-bool ChatHandler::HandleInstanceUnbindCommand(const char *args)
-{
- if (!*args)
- return false;
-
- Player* player = getSelectedPlayer();
- if (!player)
- player = m_session->GetPlayer();
-
- char* map = strtok((char*)args, " ");
- char* pDiff = strtok(NULL, " ");
- int8 diff = -1;
- if (pDiff)
- diff = atoi(pDiff);
- uint16 counter = 0;
- uint16 MapId = 0;
-
- if (strcmp(map, "all"))
- {
- MapId = uint16(atoi(map));
- if (!MapId)
- return false;
- }
-
- for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
- {
- Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
- for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
- {
- InstanceSave* save = itr->second.save;
- if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty()))
- {
- std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
- PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
- player->UnbindInstance(itr, Difficulty(i));
- counter++;
- }
- else
- ++itr;
- }
- }
- PSendSysMessage("instances unbound: %d", counter);
- return true;
-}
-
-bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/)
-{
- PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances());
- PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances());
- PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves());
- PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal());
- PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal());
- return true;
-}
-
-bool ChatHandler::HandleInstanceSaveDataCommand(const char * /*args*/)
-{
- Player* player = m_session->GetPlayer();
-
- Map* map = player->GetMap();
- if (!map->IsDungeon())
- {
- PSendSysMessage("Map is not a dungeon.");
- SetSentErrorMessage(true);
- return false;
- }
-
- if (!((InstanceMap*)map)->GetInstanceScript())
- {
- PSendSysMessage("Map has no instance data.");
- SetSentErrorMessage(true);
- return false;
- }
-
- ((InstanceMap*)map)->GetInstanceScript()->SaveToDB();
- return true;
-}
-
-/// Define the 'Message of the day' for the realm
-bool ChatHandler::HandleServerSetMotdCommand(const char *args)
-{
- sWorld->SetMotd(args);
- PSendSysMessage(LANG_MOTD_NEW, args);
- return true;
-}
-
-/// Set whether we accept new clients
-bool ChatHandler::HandleServerSetClosedCommand(const char *args)
-{
- if (strncmp(args, "on", 3) == 0)
- {
- SendSysMessage(LANG_WORLD_CLOSED);
- sWorld->SetClosed(true);
- return true;
- }
- else if (strncmp(args, "off", 4) == 0)
- {
- SendSysMessage(LANG_WORLD_OPENED);
- sWorld->SetClosed(false);
- return true;
- }
-
- SendSysMessage(LANG_USE_BOL);
- SetSentErrorMessage(true);
- return false;
-}
-
//Send items by mail
bool ChatHandler::HandleSendItemsCommand(const char *args)
{
diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp
index 9737d4584ea..0c43c9ece0e 100755
--- a/src/server/game/Combat/ThreatManager.cpp
+++ b/src/server/game/Combat/ThreatManager.cpp
@@ -354,7 +354,9 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR
// list sorted and and we check current target, then this is best case
if (currentVictim == currentRef || currentRef->getThreat() <= 1.1f * currentVictim->getThreat())
{
- currentRef = currentVictim; // for second case
+ if (currentVictim != currentRef && attacker->canCreatureAttack(currentVictim->getTarget()))
+ currentRef = currentVictim; // for second case, if currentvictim is attackable
+
found = true;
break;
}
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index 4176d9f605b..9f534ab697d 100755
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -441,7 +441,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
uint32 Condition::GetMaxAvailableConditionTargets()
{
// returns number of targets which are available for given source type
- switch(SourceType)
+ switch (SourceType)
{
case CONDITION_SOURCE_TYPE_SPELL:
case CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET:
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index dcd189a05cb..e032335c3bc 100755
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -527,16 +527,27 @@ enum SummonPropFlags
enum VehicleSeatFlags
{
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_ENTER = 0x00000001,
+ VEHICLE_SEAT_FLAG_HAS_LOWER_ANIM_FOR_RIDE = 0x00000002,
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIM_ON_VOLUNTARY_EXIT = 0x00000008,
VEHICLE_SEAT_FLAG_HIDE_PASSENGER = 0x00000200, // Passenger is hidden
- VEHICLE_SEAT_FLAG_UNK1 = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
+ VEHICLE_SEAT_FLAG_ALLOW_TURNING = 0x00000400, // needed for CGCamera__SyncFreeLookFacing
VEHICLE_SEAT_FLAG_CAN_CONTROL = 0x00000800, // Lua_UnitInVehicleControlSeat
VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL = 0x00001000, // Can cast spells with SPELL_AURA_MOUNTED from seat (possibly 4.x only, 0 seats on 3.3.5a)
VEHICLE_SEAT_FLAG_UNCONTROLLED = 0x00002000, // can override !& VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT
VEHICLE_SEAT_FLAG_CAN_ATTACK = 0x00004000, // Can attack, cast spells and use items from vehicle
+ VEHICLE_SEAT_FLAG_SHOULD_USE_VEH_SEAT_EXIT_ANIMN_ON_FORCED_EXIT = 0x00008000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_VOLUNTARY_EXIT = 0x00040000,
+ VEHICLE_SEAT_FLAG_HAS_VEH_EXIT_ANIM_FORCED_EXIT = 0x00080000,
+ VEHICLE_SEAT_FLAG_REC_HAS_VEHICLE_ENTER_ANIM = 0x00400000,
+ VEHICLE_SEAT_FLAG_ENABLE_VEHICLE_ZOOM = 0x01000000,
VEHICLE_SEAT_FLAG_CAN_ENTER_OR_EXIT = 0x02000000, // Lua_CanExitVehicle - can enter and exit at free will
VEHICLE_SEAT_FLAG_CAN_SWITCH = 0x04000000, // Lua_CanSwitchVehicleSeats
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_ENTER = 0x08000000,
+ VEHICLE_SEAT_FLAG_HAS_START_WARITING_FOR_VEH_TRANSITION_ANIM_EXIT = 0x10000000,
VEHICLE_SEAT_FLAG_CAN_CAST = 0x20000000, // Lua_UnitHasVehicleUI
VEHICLE_SEAT_FLAG_UNK2 = 0x40000000, // checked in conjunction with 0x800 in CastSpell2
+ VEHICLE_SEAT_FLAG_ALLOWS_INTERACTION = 0x80000000,
};
enum VehicleSeatFlagsB
@@ -548,6 +559,7 @@ enum VehicleSeatFlagsB
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_2 = 0x00000040,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_3 = 0x00000100,
VEHICLE_SEAT_FLAG_B_USABLE_FORCED_4 = 0x02000000,
+ VEHICLE_SEAT_FLAG_B_CAN_SWITCH = 0x04000000,
VEHICLE_SEAT_FLAG_B_VEHICLE_PLAYERFRAME_UI = 0x80000000, // Lua_UnitHasVehiclePlayerFrameUI - actually checked for flagsb &~ 0x80000000
};
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp
index 973421bc2e3..80f62d9cedb 100755
--- a/src/server/game/DataStores/DBCStores.cpp
+++ b/src/server/game/DataStores/DBCStores.cpp
@@ -635,7 +635,7 @@ void LoadDBCStores(const std::string& dataPath)
// include existed nodes that have at least single not spell base (scripted) path
{
std::set<uint32> spellPaths;
- for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i)
+ for (uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i)
if (SpellEffectEntry const* sInfo = sSpellEffectStore.LookupEntry (i))
if (sInfo->Effect == SPELL_EFFECT_SEND_TAXI)
spellPaths.insert(sInfo->EffectMiscValue);
@@ -1166,11 +1166,3 @@ uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool i
return 0;
}
-// script support functions
-DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; }
-DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; }
-DBCStorage <FactionEntry> const* GetFactionStore() { return &sFactionStore; }
-DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore() { return &sCreatureDisplayInfoStore; }
-DBCStorage <EmotesEntry> const* GetEmotesStore() { return &sEmotesStore; }
-DBCStorage <EmotesTextEntry> const* GetEmotesTextStore() { return &sEmotesTextStore; }
-DBCStorage <AchievementEntry> const* GetAchievementStore() { return &sAchievementStore; }
diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h
index c22f2ccd625..d94b60c1384 100755
--- a/src/server/game/DataStores/DBCStores.h
+++ b/src/server/game/DataStores/DBCStores.h
@@ -214,13 +214,4 @@ extern DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore;
void LoadDBCStores(const std::string& dataPath);
-// script support functions
- DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore();
- DBCStorage <SpellRangeEntry> const* GetSpellRangeStore();
- DBCStorage <FactionEntry> const* GetFactionStore();
-// DBCStorage <ItemEntry> const* GetItemDisplayStore();
- DBCStorage <CreatureDisplayInfoEntry> const* GetCreatureDisplayStore();
- DBCStorage <EmotesEntry> const* GetEmotesStore();
- DBCStorage <EmotesTextEntry> const* GetEmotesTextStore();
- DBCStorage <AchievementEntry> const* GetAchievementStore();
#endif
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 47c298d7467..91f9104b0b1 100755
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -433,8 +433,8 @@ void LFGMgr::InitializeLockedDungeons(Player* player)
locktype = LFG_LOCKSTATUS_RAID_LOCKED;
else if (dungeon->difficulty > DUNGEON_DIFFICULTY_NORMAL && player->GetBoundInstance(dungeon->map, Difficulty(dungeon->difficulty)))
{
- 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;
+ //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;
@@ -791,7 +791,7 @@ LfgProposal* LFGMgr::FindNewGroups(LfgGuidList& check, LfgGuidList& all)
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::FindNewGroup: (%s) - all(%s)", ConcatenateGuids(check).c_str(), ConcatenateGuids(all).c_str());
LfgProposal* pProposal = NULL;
- if (!check.size() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal))
+ if (check.empty() || check.size() > MAXGROUPSIZE || !CheckCompatibility(check, pProposal))
return NULL;
// Try to match with queued groups
@@ -1417,6 +1417,10 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
waitTimesMap[(*it)->GetGUID()] = int32(joinTime - itQueue->second->joinTime);
}
+ // Set the dungeon difficulty
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId);
+ ASSERT(dungeon);
+
// Create a new group (if needed)
LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND);
Group* grp = pProposal->groupLowGuid ? sGroupMgr->GetGroupByGUID(pProposal->groupLowGuid) : NULL;
@@ -1427,6 +1431,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, uint64 guid, bool accept)
Group* group = player->GetGroup();
if (sendUpdate)
player->GetSession()->SendLfgUpdateProposal(proposalId, pProposal);
+
if (group)
{
player->GetSession()->SendLfgUpdateParty(updateData);
@@ -1478,14 +1483,16 @@ 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);
+
+ // Add the cooldown spell if queued for a random dungeon
+ if (dungeon->type == LFG_TYPE_RANDOM)
+ player->CastSpell(player, LFG_SPELL_DUNGEON_COOLDOWN, false);
}
- // Set the dungeon difficulty
- LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(pProposal->dungeonId);
- ASSERT(dungeon);
grp->SetDungeonDifficulty(Difficulty(dungeon->difficulty));
uint64 gguid = grp->GetGUID();
SetDungeon(gguid, dungeon->Entry());
@@ -1626,6 +1633,7 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
{
if (!grp)
return;
+
uint64 gguid = grp->GetGUID();
SetState(gguid, LFG_STATE_BOOT);
@@ -1635,7 +1643,6 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
pBoot->reason = reason;
pBoot->victim = victim;
pBoot->votedNeeded = GetVotesNeeded(gguid);
- PlayerSet players;
// Set votes
for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
@@ -1651,15 +1658,11 @@ void LFGMgr::InitBoot(Group* grp, uint64 kicker, uint64 victim, std::string reas
else
{
pBoot->votes[guid] = LFG_ANSWER_PENDING; // Other members need to vote
- players.insert(plrg);
+ plrg->GetSession()->SendLfgBootPlayer(pBoot);
}
}
}
- // Notify players
- for (PlayerSet::const_iterator it = players.begin(); it != players.end(); ++it)
- (*it)->GetSession()->SendLfgBootPlayer(pBoot);
-
m_Boots[grp->GetLowGUID()] = pBoot;
}
@@ -1748,14 +1751,7 @@ void LFGMgr::UpdateBoot(Player* player, bool accept)
void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/)
{
sLog->outDebug(LOG_FILTER_LFG, "LFGMgr::TeleportPlayer: [" UI64FMTD "] is being teleported %s", player->GetGUID(), out ? "out" : "in");
- if (out)
- {
- player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
- player->TeleportToBGEntryPoint();
- return;
- }
- // TODO Add support for LFG_TELEPORTERROR_FATIGUE
LfgTeleportError error = LFG_TELEPORTERROR_OK;
Group* grp = player->GetGroup();
@@ -1765,10 +1761,25 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
error = LFG_TELEPORTERROR_PLAYER_DEAD;
else if (player->IsFalling() || player->HasUnitState(UNIT_STATE_JUMPING))
error = LFG_TELEPORTERROR_FALLING;
+ else if (player->IsMirrorTimerActive(FATIGUE_TIMER))
+ error = LFG_TELEPORTERROR_FATIGUE;
else
{
- uint64 gguid = grp->GetGUID();
- LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(gguid));
+ LFGDungeonEntry const* dungeon = sLFGDungeonStore.LookupEntry(GetDungeon(grp->GetGUID()));
+
+ if (out)
+ {
+ // Player needs to be inside the LFG dungeon to be able to teleport out
+ if (dungeon && player->GetMapId() == uint32(dungeon->map))
+ {
+ player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
+ player->TeleportToBGEntryPoint();
+ }
+ else
+ player->GetSession()->SendLfgTeleportError(LFG_TELEPORTERROR_DONT_REPORT); // Not sure which error message to send
+
+ return;
+ }
if (!dungeon)
error = LFG_TELEPORTERROR_INVALID_LOCATION;
@@ -1817,7 +1828,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
if (error == LFG_TELEPORTERROR_OK)
{
- if (!player->GetMap()->IsDungeon() && !player->GetMap()->IsRaid())
+ if (!player->GetMap()->IsDungeon())
player->SetBattlegroundEntryPoint();
if (player->isInFlight())
diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h
index d10902b9553..f21818deb64 100755
--- a/src/server/game/DungeonFinding/LFGMgr.h
+++ b/src/server/game/DungeonFinding/LFGMgr.h
@@ -68,6 +68,7 @@ enum LfgTeleportError
LFG_TELEPORTERROR_OK = 0, // Internal use
LFG_TELEPORTERROR_PLAYER_DEAD = 1,
LFG_TELEPORTERROR_FALLING = 2,
+ LFG_TELEPORTERROR_DONT_REPORT = 3,
LFG_TELEPORTERROR_FATIGUE = 4,
LFG_TELEPORTERROR_INVALID_LOCATION = 6
};
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 6175addfae2..1fa7fe0ca9f 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -117,13 +117,14 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth
return;
}
+ uint32 state = sLFGMgr->GetState(gguid);
sLFGMgr->ClearState(guid);
sLFGMgr->SetState(guid, LFG_STATE_NONE);
if (Player* player = ObjectAccessor::FindPlayer(guid))
{
+ if (method == GROUP_REMOVEMETHOD_LEAVE && state != LFG_STATE_FINISHED_DUNGEON && player->HasAura(LFG_SPELL_DUNGEON_COOLDOWN))
+ player->CastSpell(player, LFG_SPELL_DUNGEON_DESERTER, false);
/*
- if (method == GROUP_REMOVEMETHOD_LEAVE)
- // Add deserter flag
else if (group->isLfgKickActive())
// Update internal kick cooldown of kicked
*/
@@ -134,7 +135,7 @@ void LFGGroupScript::OnRemoveMember(Group* group, uint64 guid, RemoveMethod meth
sLFGMgr->TeleportPlayer(player, true);
}
- if (sLFGMgr->GetState(gguid) != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon
+ if (state != LFG_STATE_FINISHED_DUNGEON)// Need more players to finish the dungeon
sLFGMgr->OfferContinue(group);
}
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index bbce6cf56c1..c7758bf5e55 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -486,7 +486,7 @@ void Creature::Update(uint32 diff)
break;
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_UNIT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (!linkedRespawntime) // Can respawn
Respawn();
else // the master is dead
@@ -1303,7 +1303,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap)
m_respawnDelay = data->spawntimesecs;
m_deathState = ALIVE;
- m_respawnTime = sObjectMgr->GetCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid);
if (m_respawnTime) // respawn on Update
{
m_deathState = DEAD;
@@ -1398,7 +1398,7 @@ void Creature::DeleteFromDB()
return;
}
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sObjectMgr->DeleteCreatureData(m_DBTableGuid);
SQLTransaction trans = WorldDatabase.BeginTransaction();
@@ -1598,7 +1598,7 @@ void Creature::Respawn(bool force)
if (getDeathState() == DEAD)
{
if (m_DBTableGuid)
- sObjectMgr->RemoveCreatureRespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid);
sLog->outStaticDebug("Respawning creature %s (GuidLow: %u, Full GUID: " UI64FMTD " Entry: %u)", GetName(), GetGUIDLow(), GetGUID(), GetEntry());
m_respawnTime = 0;
@@ -1676,11 +1676,15 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo)
// the check of mechanic immunity on DB (tested) because GetCreatureTemplate()->MechanicImmuneMask and m_spellImmune[IMMUNITY_MECHANIC] don't have same data.
bool immunedToAllEffects = true;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
+ if (!spellInfo->Effects[i].IsEffect())
+ continue;
if (!IsImmunedToSpellEffect(spellInfo, i))
{
immunedToAllEffects = false;
break;
}
+ }
if (immunedToAllEffects)
return true;
@@ -1727,6 +1731,8 @@ SpellInfo const* Creature::reachWithSpellAttack(Unit* victim)
break;
}
}
+ if (bcontinue)
+ continue;
if (bcontinue)
continue;
@@ -2014,7 +2020,7 @@ void Creature::SaveRespawnTime()
if (isSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData))
return;
- sObjectMgr->SaveCreatureRespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime);
}
// this should not be called by petAI or
@@ -2458,7 +2464,7 @@ bool Creature::SetWalk(bool enable)
if (!Unit::SetWalk(enable))
return false;
- WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_WALK_MODE : SMSG_MOVE_SPLINE_SET_RUN_MODE, 9);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_WALK_MODE : SMSG_SPLINE_MOVE_SET_RUN_MODE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
@@ -2474,7 +2480,7 @@ bool Creature::SetDisableGravity(bool disable, bool packetOnly/*=false*/)
if (!movespline->Initialized())
return true;
- WorldPacket data(disable ? SMSG_MOVE_SPLINE_DISABLE_GRAVITY : SMSG_MOVE_SPLINE_ENABLE_GRAVITY, 9);
+ WorldPacket data(disable ? SMSG_SPLINE_MOVE_GRAVITY_DISABLE : SMSG_SPLINE_MOVE_GRAVITY_ENABLE, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
@@ -2495,7 +2501,7 @@ bool Creature::SetHover(bool enable)
return true;
//! Not always a packet is sent
- WorldPacket data(enable ? SMSG_MOVE_SPLINE_SET_HOVER : SMSG_MOVE_SPLINE_UNSET_HOVER, 9);
+ WorldPacket data(enable ? SMSG_SPLINE_MOVE_SET_HOVER : SMSG_SPLINE_MOVE_UNSET_HOVER, 9);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
return true;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 906dc827d3f..1824e2c1b44 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -679,6 +679,11 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void GetHomePosition(float &x, float &y, float &z, float &ori) { m_homePosition.GetPosition(x, y, z, ori); }
Position GetHomePosition() { return m_homePosition; }
+ void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); }
+ void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); }
+ void GetTransportHomePosition(float &x, float &y, float &z, float &ori) { m_transportHomePosition.GetPosition(x, y, z, ori); }
+ Position GetTransportHomePosition() { return m_transportHomePosition; }
+
uint32 GetWaypointPath(){return m_path_id;}
void LoadPath(uint32 pathid) { m_path_id = pathid; }
@@ -752,6 +757,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
uint32 m_originalEntry;
Position m_homePosition;
+ Position m_transportHomePosition;
bool DisableReputationGain;
diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h
index 829eb73bf80..537bbd9c099 100755
--- a/src/server/game/Entities/Creature/TemporarySummon.h
+++ b/src/server/game/Entities/Creature/TemporarySummon.h
@@ -36,6 +36,7 @@ class TempSummon : public Creature
Unit* GetSummoner() const;
uint64 GetSummonerGUID() { return m_summonerGUID; }
TempSummonType const& GetSummonType() { return m_type; }
+ uint32 GetTimer() { return m_timer; }
const SummonPropertiesEntry* const m_Properties;
private:
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 7591359230a..2a74d262daf 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -338,7 +338,7 @@ void GameObject::Update(uint32 diff)
if (m_respawnTime <= now) // timer expired
{
uint64 dbtableHighGuid = MAKE_NEW_GUID(m_DBTableGuid, GetEntry(), HIGHGUID_GAMEOBJECT);
- time_t linkedRespawntime = sObjectMgr->GetLinkedRespawnTime(dbtableHighGuid, GetMap()->GetInstanceId());
+ time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
if (linkedRespawntime) // Can't respawn, the master is dead
{
uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
@@ -761,13 +761,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
else
{
m_respawnDelayTime = data->spawntimesecs;
- m_respawnTime = sObjectMgr->GetGORespawnTime(m_DBTableGuid, map->GetInstanceId());
+ m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid);
// ready to respawn
if (m_respawnTime && m_respawnTime <= time(NULL))
{
m_respawnTime = 0;
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
}
@@ -788,7 +788,7 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
void GameObject::DeleteFromDB()
{
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
sObjectMgr->DeleteGOData(m_DBTableGuid);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
@@ -863,7 +863,7 @@ Unit* GameObject::GetOwner() const
void GameObject::SaveRespawnTime()
{
if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault)
- sObjectMgr->SaveGORespawnTime(m_DBTableGuid, GetInstanceId(), m_respawnTime);
+ GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime);
}
bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const
@@ -908,7 +908,7 @@ void GameObject::Respawn()
if (m_spawnedByDefault && m_respawnTime > 0)
{
m_respawnTime = time(NULL);
- sObjectMgr->RemoveGORespawnTime(m_DBTableGuid, GetInstanceId());
+ GetMap()->RemoveGORespawnTime(m_DBTableGuid);
}
}
@@ -1711,7 +1711,13 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const
void GameObject::EventInform(uint32 eventId)
{
- if (eventId && m_zoneScript)
+ if (!eventId)
+ return;
+
+ if (AI())
+ AI()->EventInform(eventId);
+
+ if (m_zoneScript)
m_zoneScript->ProcessEvent(this, eventId);
}
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index d973c3ba4f8..248b080bfdd 100755
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -274,7 +274,7 @@ bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner)
for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
SetSpellCharges(i, itemProto->Spells[i].SpellCharges);
- SetUInt32Value(ITEM_FIELD_DURATION, abs(itemProto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, itemProto->Duration);
SetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME, 0);
return true;
}
@@ -420,7 +420,7 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, Field* fields, uint32 entr
// update duration if need, and remove if not need
if ((proto->Duration == 0) != (duration == 0))
{
- SetUInt32Value(ITEM_FIELD_DURATION, abs(proto->Duration));
+ SetUInt32Value(ITEM_FIELD_DURATION, proto->Duration);
need_save = true;
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 54570e9b708..d38e8c32e30 100755
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -242,6 +242,7 @@ class Item : public Object
bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_UNLOCKED); }
bool IsBag() const { return GetTemplate()->InventoryType == INVTYPE_BAG; }
+ bool IsCurrencyToken() const { return GetTemplate()->IsCurrencyToken(); }
bool IsNotEmptyBag() const;
bool IsBroken() const { return GetUInt32Value(ITEM_FIELD_MAXDURABILITY) > 0 && GetUInt32Value(ITEM_FIELD_DURABILITY) == 0; }
bool CanBeTraded(bool mail = false, bool trade = false) const;
diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h
index 048da0b231c..2da0e721a20 100755
--- a/src/server/game/Entities/Item/ItemPrototype.h
+++ b/src/server/game/Entities/Item/ItemPrototype.h
@@ -202,6 +202,12 @@ enum ItemFlagsExtra
ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND = 0x00020000,
};
+enum ItemFlagsCustom
+{
+ ITEM_FLAGS_CU_DURATION_REAL_TIME = 0x0001, // Item duration will tick even if player is offline
+ ITEM_FLAGS_CU_IGNORE_QUEST_STATUS = 0x0002, // No quest status will be checked when this item drops
+};
+
enum BAG_FAMILY_MASK
{
BAG_FAMILY_MASK_NONE = 0x00000000,
@@ -641,7 +647,7 @@ struct ItemTemplate
uint32 socketBonus; // id from SpellItemEnchantment.dbc
uint32 GemProperties; // id from GemProperties.dbc
float ArmorDamageModifier;
- int32 Duration; // negative = realtime, positive = ingame time
+ uint32 Duration;
uint32 ItemLimitCategory; // id from ItemLimitCategory.dbc
uint32 HolidayId; // id from Holidays.dbc
float StatScalingFactor;
@@ -661,6 +667,7 @@ struct ItemTemplate
uint32 FoodType;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
+ uint32 FlagsCu;
// helpers
bool CanChangeEquipStateInCombat() const
@@ -683,6 +690,8 @@ struct ItemTemplate
return false;
}
+ bool IsCurrencyToken() const { return BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS; }
+
uint32 GetMaxStackSize() const
{
return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable);
diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h
index 0d18a47885f..1a04f7b3053 100755
--- a/src/server/game/Entities/Object/Object.h
+++ b/src/server/game/Entities/Object/Object.h
@@ -34,11 +34,11 @@
#define CONTACT_DISTANCE 0.5f
#define INTERACTION_DISTANCE 5.0f
#define ATTACK_DISTANCE 5.0f
-#define MAX_VISIBILITY_DISTANCE 500.0f // max distance for visible objects
+#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects
#define SIGHT_RANGE_UNIT 50.0f
-#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
-#define DEFAULT_VISIBILITY_INSTANCE 120.0f // default visible distance in instances, 120 yards
-#define DEFAULT_VISIBILITY_BGARENAS 180.0f // default visible distance in BG/Arenas, 180 yards
+#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents
+#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards
+#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards
#define DEFAULT_WORLD_OBJECT_SIZE 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects
#define DEFAULT_COMBAT_REACH 1.5f
@@ -500,13 +500,13 @@ struct MovementInfo
t_seat = -1;
}
- uint32 GetMovementFlags() { return flags; }
+ uint32 GetMovementFlags() const { 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; }
+ uint16 GetExtraMovementFlags() const { return flags2; }
void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; }
bool HasExtraMovementFlag(uint16 flag) const { return flags2 & flag; }
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 6e988a79c29..5759a58a575 100755
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -153,6 +153,7 @@ class Pet : public Guardian
bool HaveInDiet(ItemTemplate const* item) const;
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel);
void SetDuration(int32 dur) { m_duration = dur; }
+ int32 GetDuration() { return m_duration; }
/*
bool UpdateStats(Stats stat);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e8d89110f82..ba7ca524521 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -3403,7 +3403,7 @@ void Player::SendInitialSpells()
uint16 spellCooldowns = m_spellCooldowns.size();
data << uint16(spellCooldowns);
- for (SpellCooldowns::const_iterator itr=m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
+ for (SpellCooldowns::const_iterator itr = m_spellCooldowns.begin(); itr != m_spellCooldowns.end(); ++itr)
{
SpellInfo const* sEntry = sSpellMgr->GetSpellInfo(itr->first);
if (!sEntry)
@@ -4828,7 +4828,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// bones will be deleted by corpse/bones deleting thread shortly
sObjectAccessor->ConvertCorpseForPlayer(playerguid);
- if (uint32 guildId = GetGuildIdFromGuid(playerguid))
+ if (uint32 guildId = GetGuildIdFromDB(playerguid))
if (Guild* guild = sGuildMgr->GetGuildById(guildId))
guild->DeleteMember(guid);
@@ -5176,8 +5176,8 @@ void Player::SetMovement(PlayerMovementType pType)
{
case MOVE_ROOT: data.Initialize(SMSG_MOVE_ROOT, GetPackGUID().size()+4); break;
case MOVE_UNROOT: data.Initialize(SMSG_MOVE_UNROOT, GetPackGUID().size()+4); break;
- case MOVE_WATER_WALK: data.Initialize(SMSG_MOVE_SPLINE_SET_WATER_WALK, GetPackGUID().size()+4); break;
- case MOVE_LAND_WALK: data.Initialize(SMSG_MOVE_SPLINE_SET_LAND_WALK, GetPackGUID().size()+4); break;
+ case MOVE_WATER_WALK: data.Initialize(SMSG_SPLINE_MOVE_SET_WATER_WALK, GetPackGUID().size()+4); break;
+ case MOVE_LAND_WALK: data.Initialize(SMSG_SPLINE_MOVE_SET_LAND_WALK, GetPackGUID().size()+4); break;
default:
sLog->outError("Player::SetMovement: Unsupported move type (%d), data not sent to client.", pType);
return;
@@ -7270,7 +7270,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
uint8 k_level = getLevel();
uint8 k_grey = Trinity::XP::GetGrayLevel(k_level);
- uint8 v_level = plrVictim->getLevel();
+ uint8 v_level = victim->getLevel();
if (v_level <= k_grey)
return false;
@@ -7281,7 +7281,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
// [15..28] Horde honor titles and player name
// [29..38] Other title and player name
// [39+] Nothing
- uint32 victim_title = plrVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
+ uint32 victim_title = victim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
// Get Killer titles, CharTitlesEntry::bit_index
// Ranks:
// title[1..14] -> rank[5..18]
@@ -7303,10 +7303,10 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto
// and those in a lifetime
ApplyModUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 1, true);
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, plrVictim->getClass());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, plrVictim->getRace());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS, victim->getClass());
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, victim->getRace());
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
- UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, plrVictim);
+ UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, victim);
}
else
{
@@ -7548,7 +7548,7 @@ uint32 Player::_GetCurrencyWeekCap(const CurrencyTypesEntry* currency) const
return cap;
}
-uint32 Player::GetGuildIdFromGuid(uint64 guid)
+uint32 Player::GetGuildIdFromDB(uint64 guid)
{
PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_GET_GUILD_ID);
stmt->setUInt64(0, guid);
@@ -8227,7 +8227,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply
if (CanUseAttackType(attType))
_ApplyWeaponDamage(slot, proto, ssv, apply);
-
}
void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply)
@@ -9157,7 +9156,6 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
loot->loot_type = loot_type;
WorldPacket data(SMSG_LOOT_RESPONSE, 8 + 1 + 50 + 1 + 1); // we guess size
-
data << uint64(guid);
data << uint8(loot_type);
data << LootView(*loot, this, permission);
@@ -10734,7 +10732,7 @@ InventoryResult Player::CanStoreItem_InSpecificSlot(uint8 bag, uint8 slot, ItemP
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// currencytoken case
- if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS))
+ if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->IsCurrencyToken()))
return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG;
// prevent cheating
@@ -11087,7 +11085,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
- else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ else if (pProto->IsCurrencyToken())
{
res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
@@ -11254,7 +11252,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des
return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;
}
}
- else if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ else if (pProto->IsCurrencyToken())
{
res = CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START, CURRENCYTOKEN_SLOT_END, dest, pProto, count, false, pItem, bag, slot);
if (res != EQUIP_ERR_OK)
@@ -11503,7 +11501,7 @@ InventoryResult Player::CanStoreItems(Item** pItems, int count) const
if (b_found)
continue;
- if (pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ if (pProto->IsCurrencyToken())
{
for (uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t)
{
@@ -12755,7 +12753,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12783,7 +12781,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12849,7 +12847,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ
{
ItemRemovedQuestCheck(pItem->GetEntry(), count - remcount);
pItem->SetCount(pItem->GetCount() - count + remcount);
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
return;
@@ -12924,6 +12922,11 @@ Item* Player::GetItemByEntry(uint32 entry) const
if (pItem->GetEntry() == entry)
return pItem;
+ for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i)
+ if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
+ if (pItem->GetEntry() == entry)
+ return pItem;
+
for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
if (Bag* pBag = GetBagByPos(i))
for (uint32 j = 0; j < pBag->GetBagSize(); ++j)
@@ -12957,7 +12960,7 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update)
ItemRemovedQuestCheck(pItem->GetEntry(), count);
pItem->SetCount(pItem->GetCount() - count);
count = 0;
- if (IsInWorld() & update)
+ if (IsInWorld() && update)
pItem->SendUpdateToPlayer(this);
pItem->SetState(ITEM_CHANGED, this);
}
@@ -13545,9 +13548,9 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint
}
case EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM: // no idea about this one...
{
- data << uint64(0);
- data << uint32(0);
- data << uint64(0);
+ data << uint64(0); // item guid
+ data << uint32(0); // slot
+ data << uint64(0); // container
break;
}
case EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED:
@@ -13653,7 +13656,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly)
Item* item = *itr;
++itr; // current element can be erased in UpdateDuration
- if ((realtimeonly && item->GetTemplate()->Duration < 0) || !realtimeonly)
+ if (!realtimeonly || item->GetTemplate()->FlagsCu & ITEM_FLAGS_CU_DURATION_REAL_TIME)
item->UpdateDuration(this, time);
}
}
@@ -14226,7 +14229,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created,
data << uint64(GetGUID()); // player GUID
data << uint32(received); // 0=looted, 1=from npc
data << uint32(created); // 0=received, 1=created
- data << uint32(1); // always 0x01 (probably meant to be count of listed items)
+ data << uint32(1); // bool print error to chat
data << uint8(item->GetBagSlot()); // bagslot
// item slot, but when added to stack: 0xFFFFFFFF
data << uint32((item->GetCount() == count) ? item->GetSlot() : -1);
@@ -20160,8 +20163,10 @@ void Player::PetSpellInitialize()
WorldPacket data(SMSG_PET_SPELLS, 8+2+4+4+4*MAX_UNIT_ACTION_BAR_INDEX+1+1);
data << uint64(pet->GetGUID());
data << uint16(pet->GetCreatureTemplate()->family); // creature family (required for pet talents)
- data << uint32(0);
- data << uint8(pet->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
+ data << uint32(pet->GetDuration());
+ data << uint8(pet->GetReactState());
+ data << uint8(charmInfo->GetCommandState());
+ data << uint16(0); // Flags, mostly unknown
// action bar loop
charmInfo->BuildActionBar(&data);
@@ -20194,22 +20199,33 @@ void Player::PetSpellInitialize()
for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr)
{
- time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
-
- data << uint32(itr->first); // spellid
- data << uint16(0); // spell category?
- data << uint32(cooldown); // cooldown
- data << uint32(0); // category cooldown
- }
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
- for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr)
- {
time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint32(itr->first); // spell ID
- data << uint32(itr->first); // spellid
- data << uint16(0); // spell category?
- data << uint32(0); // cooldown
- data << uint32(cooldown); // category cooldown
+ CreatureSpellCooldowns::const_iterator categoryitr = pet->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != pet->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > curTime) ? (categoryitr->second - curTime) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20245,24 +20261,24 @@ void Player::PossessSpellInitialize()
void Player::VehicleSpellInitialize()
{
- Creature* veh = GetVehicleCreatureBase();
- if (!veh)
+ Creature* vehicle = GetVehicleCreatureBase();
+ if (!vehicle)
return;
- uint8 cooldownCount = veh->m_CreatureSpellCooldowns.size() + veh->m_CreatureCategoryCooldowns.size();
+ uint8 cooldownCount = vehicle->m_CreatureSpellCooldowns.size();
WorldPacket data(SMSG_PET_SPELLS, 8 + 2 + 4 + 4 + 4 * 10 + 1 + 1 + cooldownCount * (4 + 2 + 4 + 4));
- data << uint64(veh->GetGUID());
- data << uint16(veh->GetCreatureTemplate()->family);
- data << uint32(0);
- // The following three segments are read as one uint32
- data << uint8(veh->GetReactState());
- data << uint8(0); // CommandState?
- data << uint16(0); // unk
+ data << uint64(vehicle->GetGUID()); // Guid
+ data << uint16(0); // Pet Family (0 for all vehicles)
+ data << uint32(vehicle->isSummon() ? vehicle->ToTempSummon()->GetTimer() : 0); // Duration
+ // The following three segments are read by the client as one uint32
+ data << uint8(vehicle->GetReactState()); // React State
+ data << uint8(0); // Command State
+ data << uint16(0x800); // DisableActions (set for all vehicles)
for (uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)
{
- uint32 spellId = veh->m_spells[i];
+ uint32 spellId = vehicle->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
@@ -20270,54 +20286,59 @@ void Player::VehicleSpellInitialize()
continue;
}
- ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(veh->GetEntry(), spellId);
- if (!sConditionMgr->IsObjectMeetToConditions(this, veh, conditions))
+ ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId);
+ if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions))
{
- sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", veh->ToCreature()->GetEntry(), spellId);
+ sLog->outDebug(LOG_FILTER_CONDITIONSYS, "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);
data << uint16(0) << uint8(0) << uint8(i+8);
continue;
}
if (spellInfo->IsPassive())
- {
- veh->CastSpell(veh, spellId, true);
- data << uint16(0) << uint8(0) << uint8(i+8);
- }
- else
- data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
+ vehicle->CastSpell(vehicle, spellId, true);
+
+ data << uint32(MAKE_UNIT_ACTION_BUTTON(spellId, i+8));
}
for (uint32 i = CREATURE_MAX_SPELLS; i < MAX_SPELL_CONTROL_BAR; ++i)
- data << uint16(0) << uint8(0) << uint8(i+8);
+ data << uint32(0);
- data << uint8(0);
- /*if (v23 > 0)
- {
- for (uint32 i = 0; i < v23; ++i)
- data << uint32(v16); // Some spellid?
- }*/
+ data << uint8(0); // Auras?
// Cooldowns
- data << cooldownCount;
+ data << uint8(cooldownCount);
time_t now = sWorld->GetGameTime();
- CreatureSpellCooldowns::const_iterator itr;
- for (itr = veh->m_CreatureSpellCooldowns.begin(); itr != veh->m_CreatureSpellCooldowns.end(); ++itr)
- {
- time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(cooldown); // spell cooldown
- data << uint32(0); // category cooldown
- }
- for (itr = veh->m_CreatureCategoryCooldowns.begin(); itr != veh->m_CreatureCategoryCooldowns.end(); ++itr)
+ for (CreatureSpellCooldowns::const_iterator itr = vehicle->m_CreatureSpellCooldowns.begin(); itr != vehicle->m_CreatureSpellCooldowns.end(); ++itr)
{
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
+ if (!spellInfo)
+ {
+ data << uint32(0);
+ data << uint16(0);
+ data << uint32(0);
+ data << uint32(0);
+ continue;
+ }
+
time_t cooldown = (itr->second > now) ? (itr->second - now) * IN_MILLISECONDS : 0;
- data << uint32(itr->first); // SpellId
- data << uint16(0); // unk
- data << uint32(0); // spell cooldown
- data << uint32(cooldown); // category cooldown
+ data << uint32(itr->first); // spell ID
+
+ CreatureSpellCooldowns::const_iterator categoryitr = vehicle->m_CreatureCategoryCooldowns.find(spellInfo->Category);
+ if (categoryitr != vehicle->m_CreatureCategoryCooldowns.end())
+ {
+ time_t categoryCooldown = (categoryitr->second > now) ? (categoryitr->second - now) * IN_MILLISECONDS : 0;
+ data << uint16(spellInfo->Category); // spell category
+ data << uint32(cooldown); // spell cooldown
+ data << uint32(categoryCooldown); // category cooldown
+ }
+ else
+ {
+ data << uint16(0);
+ data << uint32(cooldown);
+ data << uint32(0);
+ }
}
GetSession()->SendPacket(&data);
@@ -20356,7 +20377,7 @@ void Player::CharmSpellInitialize()
if (charm->GetTypeId() != TYPEID_PLAYER)
data << uint8(charm->ToCreature()->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0);
else
- data << uint8(0) << uint8(0) << uint16(0);
+ data << uint32(0);
charmInfo->BuildActionBar(&data);
@@ -20581,7 +20602,7 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
else
{
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_SIG_BY_GUID_TYPE);
- stmt->setUInt8(0, uint8(type));
+ stmt->setUInt8(1, uint8(type));
}
stmt->setUInt32(0, GUID_LOPART(guid));
@@ -22319,8 +22340,8 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3
data << uint32(time);
if (type == RAID_INSTANCE_WELCOME)
{
- data << uint8(0); // is your (1)
- data << uint8(0); // is extended (1), ignored if prev field is 0
+ data << uint8(0); // is locked
+ data << uint8(0); // is extended, ignored if prev field is 0
}
GetSession()->SendPacket(&data);
}
@@ -23366,7 +23387,7 @@ Player* Player::GetNextRandomRaidMember(float radius)
PartyResult Player::CanUninviteFromGroup() const
{
- const Group* grp = GetGroup();
+ Group const* grp = GetGroup();
if (!grp)
return ERR_NOT_IN_GROUP;
@@ -23389,8 +23410,12 @@ PartyResult Player::CanUninviteFromGroup() const
if (grp->isRollLootActive())
return ERR_PARTY_LFG_BOOT_LOOT_ROLLS;
+ // TODO: Should also be sent when anyone has recently left combat, with an aprox ~5 seconds timer.
+ for (GroupReference const* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
+ if (itr->getSource() && itr->getSource()->isInCombat())
+ return ERR_PARTY_LFG_BOOT_IN_COMBAT;
+
/* Missing support for these types
- return ERR_PARTY_LFG_BOOT_IN_COMBAT; // also have a cooldown (some secs after combat finish
return ERR_PARTY_LFG_BOOT_COOLDOWN_S;
return ERR_PARTY_LFG_BOOT_NOT_ELIGIBLE_S;
*/
@@ -25639,8 +25664,8 @@ void Player::SendMovementSetCanFly(bool apply)
void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)
{
WorldPacket data(apply ?
- SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY :
- SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, 12);
+ SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY :
+ SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25648,7 +25673,7 @@ void Player::SendMovementSetCanTransitionBetweenSwimAndFly(bool apply)
void Player::SendMovementSetHover(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_HOVERING : SMSG_MOVE_SPLINE_UNSET_HOVER, 12);
+ WorldPacket data(apply ? SMSG_MOVE_SET_HOVER : SMSG_MOVE_UNSET_HOVER, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25656,7 +25681,7 @@ void Player::SendMovementSetHover(bool apply)
void Player::SendMovementSetWaterWalking(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_WATER_WALK : SMSG_MOVE_SET_LAND_WALK, 12);
+ WorldPacket data(apply ? SMSG_MOVE_WATER_WALK : SMSG_MOVE_LAND_WALK, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
@@ -25664,7 +25689,7 @@ void Player::SendMovementSetWaterWalking(bool apply)
void Player::SendMovementSetFeatherFall(bool apply)
{
- WorldPacket data(apply ? SMSG_MOVE_SET_FEATHER_FALL : SMSG_MOVE_SET_NORMAL_FALL, 12);
+ WorldPacket data(apply ? SMSG_MOVE_FEATHER_FALL : SMSG_MOVE_NORMAL_FALL, 12);
data.append(GetPackGUID());
data << uint32(0); //! movement counter
SendDirectMessage(&data);
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 24a1c35b8e2..dbe9cd94a21 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1888,7 +1888,7 @@ class Player : public Unit, public GridObject<Player>
m_guildId = GuildId;
}
uint32 GetGuildId() { return m_guildId; }
- static uint32 GetGuildIdFromGuid(uint64 guid);
+ static uint32 GetGuildIdFromDB(uint64 guid);
void SetRank(uint8 rankId) { SetUInt32Value(PLAYER_GUILDRANK, rankId); }
uint8 GetRank() { return uint8(GetUInt32Value(PLAYER_GUILDRANK)); }
@@ -2049,6 +2049,7 @@ class Player : public Unit, public GridObject<Player>
StopMirrorTimer(BREATH_TIMER);
StopMirrorTimer(FIRE_TIMER);
}
+ bool IsMirrorTimerActive(MirrorTimerType type) { return m_MirrorTimer[type] == getMaxTimer(type); }
void SetMovement(PlayerMovementType pType);
diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp
index a00fcae1e09..ef3e1331a4c 100755
--- a/src/server/game/Entities/Transport/Transport.cpp
+++ b/src/server/game/Entities/Transport/Transport.cpp
@@ -656,6 +656,7 @@ uint32 Transport::AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y,
o + GetOrientation());
creature->SetHomePosition(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
+ creature->SetTransportHomePosition(creature->m_movementInfo.t_pos);
if (!creature->IsPositionValid())
{
@@ -698,11 +699,33 @@ void Transport::UpdateNPCPositions()
Creature* npc = *itr;
float x, y, z, o;
- o = GetOrientation() + npc->m_movementInfo.t_pos.m_orientation;
- x = GetPositionX() + (npc->m_movementInfo.t_pos.m_positionX * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionY * sin(GetOrientation() + M_PI));
- y = GetPositionY() + (npc->m_movementInfo.t_pos.m_positionY * cos(GetOrientation()) + npc->m_movementInfo.t_pos.m_positionX * sin(GetOrientation()));
- z = GetPositionZ() + npc->m_movementInfo.t_pos.m_positionZ;
- npc->SetHomePosition(x, y, z, o);
+ npc->m_movementInfo.t_pos.GetPosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
GetMap()->CreatureRelocation(npc, x, y, z, o, false);
+ npc->GetTransportHomePosition(x, y, z, o);
+ CalculatePassengerPosition(x, y, z, o);
+ npc->SetHomePosition(x, y, z, o);
}
}
+
+//! This method transforms supplied transport offsets into global coordinates
+void Transport::CalculatePassengerPosition(float& x, float& y, float& z, float& o)
+{
+ float inx = x, iny = y, inz = z, ino = o;
+ o = GetOrientation() + ino;
+ x = GetPositionX() + (inx * cos(GetOrientation()) + iny * sin(GetOrientation() + M_PI));
+ y = GetPositionY() + (iny * cos(GetOrientation()) + inx * sin(GetOrientation()));
+ z = GetPositionZ() + inz;
+}
+
+//! This method transforms supplied global coordinates into local offsets
+void Transport::CalculatePassengerOffset(float& x, float& y, float& z, float& o)
+{
+ o -= GetOrientation();
+ z -= GetPositionZ();
+ y -= GetPositionY(); // y = searchedY * cos(o) + searchedX * sin(o)
+ x -= GetPositionX(); // x = searchedX * cos(o) + searchedY * sin(o + pi)
+ float inx = x, iny = y;
+ y = (iny - inx * tan(GetOrientation())) / (cos(GetOrientation()) - sin(GetOrientation() + M_PI) * tan(GetOrientation()));
+ x = (inx - iny * sin(GetOrientation() + M_PI) / cos(GetOrientation())) / (cos(GetOrientation()) - tan(GetOrientation()) * sin(GetOrientation() + M_PI));
+}
diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h
index 518dcf6359d..4b0c42c9071 100755
--- a/src/server/game/Entities/Transport/Transport.h
+++ b/src/server/game/Entities/Transport/Transport.h
@@ -47,6 +47,8 @@ class Transport : public GameObject
uint32 AddNPCPassenger(uint32 tguid, uint32 entry, float x, float y, float z, float o, uint32 anim=0);
void UpdatePosition(MovementInfo* mi);
void UpdateNPCPositions();
+ void CalculatePassengerPosition(float& x, float& y, float& z, float& o);
+ void CalculatePassengerOffset(float& x, float& y, float& z, float& o);
void BuildStartMovePacket(Map const* targetMap);
void BuildStopMovePacket(Map const* targetMap);
uint32 GetScriptId() const { return ScriptId; }
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 347a51a67d9..5fe8f0bf657 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -396,10 +396,25 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
m_movesplineTimer.Reset(POSITION_UPDATE_DELAY);
Movement::Location loc = movespline->ComputePosition();
- 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);
+ if (HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
+ {
+ Position& pos = m_movementInfo.t_pos;
+ pos.m_positionX = loc.x;
+ pos.m_positionY = loc.y;
+ pos.m_positionZ = loc.z;
+ pos.m_orientation = loc.orientation;
+ if (Unit* vehicle = GetVehicleBase())
+ {
+ loc.x += vehicle->GetPositionX();
+ loc.y += vehicle->GetPositionY();
+ loc.z += vehicle->GetPositionZMinusOffset();
+ loc.orientation = vehicle->GetOrientation();
+ }
+ else if (Transport* trans = GetTransport())
+ trans->CalculatePassengerPosition(loc.x, loc.y, loc.z, loc.orientation);
+ }
+
+ UpdatePosition(loc.x, loc.y, loc.z, loc.orientation);
}
}
@@ -409,50 +424,6 @@ void Unit::DisableSpline()
movespline->_Interrupt();
}
-void Unit::SendMonsterMoveExitVehicle(Position const* newPos)
-{
- WorldPacket data(SMSG_MONSTER_MOVE, 1+12+4+1+4+4+4+12+GetPackGUID().size());
- data.append(GetPackGUID());
-
- data << uint8(GetTypeId() == TYPEID_PLAYER ? 1 : 0); // new in 3.1, bool
- data << GetPositionX() << GetPositionY() << GetPositionZ();
- data << getMSTime();
-
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << float(GetOrientation()); // guess
- data << uint32(SPLINEFLAG_EXIT_VEHICLE);
- data << uint32(0); // Time in between points
- data << uint32(1); // 1 single waypoint
- data << newPos->GetPositionX();
- data << newPos->GetPositionY();
- data << newPos->GetPositionZ();
-
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendMonsterMoveTransport(Unit* vehicleOwner)
-{
- // TODO: Turn into BuildMonsterMoveTransport packet and allow certain variables (for npc movement aboard vehicles)
- WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size() + 47);
- data.append(GetPackGUID());
- data.append(vehicleOwner->GetPackGUID());
- data << int8(GetTransSeat());
- data << uint8(0);
- data << GetPositionX() - vehicleOwner->GetPositionX();
- data << GetPositionY() - vehicleOwner->GetPositionY();
- data << GetPositionZ() - vehicleOwner->GetPositionZ();
- data << uint32(getMSTime()); // should be an increasing constant that indicates movement packet count
- data << uint8(SPLINETYPE_FACING_ANGLE);
- data << GetTransOffsetO(); // facing angle?
- data << uint32(SPLINEFLAG_TRANSPORT);
- data << uint32(GetTransTime()); // move time
- data << uint32(1); // amount of waypoints
- data << uint32(0); // waypoint X
- data << uint32(0); // waypoint Y
- data << uint32(0); // waypoint Z
- SendMessageToSet(&data, true);
-}
-
void Unit::resetAttackTimer(WeaponAttackType type)
{
m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]);
@@ -556,13 +527,7 @@ void Unit::DealDamageMods(Unit* victim, uint32 &damage, uint32* absorb)
if (absorb)
*absorb += damage;
damage = 0;
- return;
}
-
- uint32 originalDamage = damage;
-
- if (absorb && originalDamage > damage)
- *absorb += (originalDamage - damage);
}
uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
@@ -839,11 +804,6 @@ void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo
return;
}
- // TODO: this is a workaround and needs removal
- if (!originalCaster && GetTypeId() == TYPEID_UNIT && ToCreature()->isTotem() && IsControlledByPlayer())
- if (Unit* owner = GetOwner())
- originalCaster=owner->GetGUID();
-
// TODO: this is a workaround - not needed anymore, but required for some scripts :(
if (!originalCaster && triggeredByAura)
originalCaster = triggeredByAura->GetCasterGUID();
@@ -2503,12 +2463,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spell)
// Chance resist debuff
if (!spell->IsPositive())
{
- bool bNegativeAura = false;
+ bool bNegativeAura = true;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (spell->Effects[i].ApplyAuraName != 0)
+ if (spell->Effects[i].ApplyAuraName == 0)
{
- bNegativeAura = true;
+ bNegativeAura = false;
break;
}
}
@@ -2931,9 +2891,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
m_AutoRepeatFirstCast = true;
}
- AddUnitState(UNIT_STATE_CASTING);
- } break;
+ if (pSpell->m_spellInfo->CalcCastTime(this) > 0)
+ AddUnitState(UNIT_STATE_CASTING);
+ break;
+ }
case CURRENT_CHANNELED_SPELL:
{
// channel spells always break generic non-delayed and any channeled spells
@@ -2945,8 +2907,9 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75)
InterruptSpell(CURRENT_AUTOREPEAT_SPELL);
AddUnitState(UNIT_STATE_CASTING);
- } break;
+ break;
+ }
case CURRENT_AUTOREPEAT_SPELL:
{
// only Auto Shoot does not break anything
@@ -2958,12 +2921,11 @@ void Unit::SetCurrentCastedSpell(Spell* pSpell)
}
// special action: set first cast flag
m_AutoRepeatFirstCast = true;
- } break;
+ break;
+ }
default:
- {
- // other spell types don't break anything now
- } break;
+ break; // other spell types don't break anything now
}
// current spell (if it is still here) may be safely deleted now
@@ -3638,87 +3600,6 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId
// Call AfterDispel hook on AuraScript
aura->CallScriptAfterDispel(&dispelInfo);
- switch (aura->GetSpellInfo()->SpellFamilyName)
- {
- case SPELLFAMILY_WARLOCK:
- {
- // Unstable Affliction (crash if before removeaura?)
- if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x0100)
- {
- Unit* caster = aura->GetCaster();
- if (!caster)
- break;
- if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_0))
- {
- int32 damage = aurEff->GetAmount() * 9;
- // backfire damage and silence
- caster->CastCustomSpell(dispeller, 31117, &damage, NULL, NULL, true, NULL, aurEff);
- }
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- // Lifebloom
- if (aura->GetSpellInfo()->SpellFamilyFlags[1] & 0x10)
- {
- if (AuraEffect const* aurEff = aura->GetEffect(EFFECT_1))
- {
- // final heal
- int32 healAmount = aurEff->GetAmount();
- if (Unit* caster = aura->GetCaster())
- {
- healAmount = caster->SpellHealingBonusDone(this, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
- healAmount = this->SpellHealingBonusTaken(caster, aura->GetSpellInfo(), healAmount, HEAL, dispelInfo.GetRemovedCharges());
- }
- CastCustomSpell(this, 33778, &healAmount, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID());
-
- // mana
- if (Unit* caster = aura->GetCaster())
- {
- int32 mana = CalculatePctU(caster->GetCreateMana(), aura->GetSpellInfo()->ManaCostPercentage) * chargesRemoved / 2;
- caster->CastCustomSpell(caster, 64372, &mana, NULL, NULL, true, NULL, NULL, aura->GetCasterGUID());
- }
- }
- }
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- // Flame Shock
- if (aura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10000000)
- {
- if (Unit* caster = aura->GetCaster())
- {
- uint32 triggeredSpellId = 0;
- // Lava Flows
- if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 3087, 0))
- {
- switch (aurEff->GetId())
- {
- case 51482: // Rank 3
- triggeredSpellId = 65264;
- break;
- case 51481: // Rank 2
- triggeredSpellId = 65263;
- break;
- case 51480: // Rank 1
- triggeredSpellId = 64694;
- break;
- default:
- sLog->outError("Unit::RemoveAurasDueToSpellByDispel: Unknown rank of Lava Flows (%d) found", aurEff->GetId());
- }
- }
-
- if (triggeredSpellId)
- caster->CastSpell(caster, triggeredSpellId, true);
- }
- }
- break;
- }
- default:
- break;
- }
return;
}
else
@@ -8328,6 +8209,14 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(victim, 27526, true, castItem, triggeredByAura);
return true;
}
+ // Evasive Maneuvers
+ case 50240:
+ {
+ // Remove a Evasive Charge
+ Aura* charge = GetAura(50241);
+ if (charge->ModStackAmount(-1, AURA_REMOVE_BY_ENEMY_SPELL))
+ RemoveAurasDueToSpell(50240);
+ }
}
break;
case SPELLFAMILY_MAGE:
@@ -8982,12 +8871,6 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
CastSpell(this, 70721, true);
break;
}
- // Bloodthirst (($m/100)% of max health)
- case 23880:
- {
- basepoints0 = int32(CountPctFromMaxHealth(triggerAmount));
- break;
- }
// Shamanistic Rage triggered spell
case 30824:
{
@@ -10159,7 +10042,7 @@ Unit* Unit::GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo)
Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET);
for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
{
- if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner())
+ if (Unit* magnet = (*itr)->GetBase()->GetCaster())
if (spellInfo->CheckExplicitTarget(this, magnet) == SPELL_CAST_OK
&& spellInfo->CheckTarget(this, magnet, false) == SPELL_CAST_OK
&& _IsValidAttackTarget(magnet, spellInfo)
@@ -10801,6 +10684,15 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
int32 TakenTotal = 0;
float TakenTotalMod = 1.0f;
+ float TakenTotalCasterMod = 0.0f;
+
+ // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
+ AuraEffectList const& IgnoreResistAuras = caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
+ {
+ if ((*i)->GetMiscValue() & spellProto->GetSchoolMask())
+ TakenTotalCasterMod += (float((*i)->GetAmount())/100);
+ }
// from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN
// multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085)
@@ -10865,7 +10757,22 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui
TakenTotal+= int32(TakenAdvertisedBenefit * coeff * factorMod);
}
- float tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
+ float tmpDamage = 0.0f;
+
+ if (TakenTotalCasterMod)
+ {
+ if (TakenTotal < 0)
+ {
+ if (TakenTotalMod < 1)
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod));
+ else
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenTotal) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ }
+ else if (TakenTotalMod < 1)
+ tmpDamage = ((CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenTotal, TakenTotalCasterMod));
+ }
+ if (!tmpDamage)
+ tmpDamage = (float(pdamage) + TakenTotal) * TakenTotalMod;
return uint32(std::max(tmpDamage, 0.0f));
}
@@ -11575,6 +11482,8 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo)
{
// State/effect immunities applied by aura expect full spell immunity
// Ignore effects with mechanic, they are supposed to be checked separately
+ if (!spellInfo->Effects[i].IsEffect())
+ continue;
if (!IsImmunedToSpellEffect(spellInfo, i))
{
immuneToAllEffects = false;
@@ -11820,6 +11729,16 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
return 0;
int32 TakenFlatBenefit = 0;
+ float TakenTotalCasterMod = 0.0f;
+
+ // get all auras from caster that allow the spell to ignore resistance (sanctified wrath)
+ SpellSchoolMask attackSchoolMask = spellProto ? spellProto->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL;
+ AuraEffectList const& IgnoreResistAuras = attacker->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ for (AuraEffectList::const_iterator i = IgnoreResistAuras.begin(); i != IgnoreResistAuras.end(); ++i)
+ {
+ if ((*i)->GetMiscValue() & attackSchoolMask)
+ TakenTotalCasterMod += (float((*i)->GetAmount())/100);
+ }
// ..taken
AuraEffectList const& mDamageTaken = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
@@ -11904,7 +11823,22 @@ uint32 Unit::MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackT
AddPctN(TakenTotalMod, (*i)->GetAmount());
}
- float tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
+ float tmpDamage = 0.0f;
+
+ if (TakenTotalCasterMod)
+ {
+ if (TakenFlatBenefit < 0)
+ {
+ if (TakenTotalMod < 1)
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) * TakenTotalMod) + CalculatePctF(pdamage, TakenTotalCasterMod));
+ else
+ tmpDamage = ((float(CalculatePctF(pdamage, TakenTotalCasterMod) + TakenFlatBenefit) + CalculatePctF(pdamage, TakenTotalCasterMod)) * TakenTotalMod);
+ }
+ else if (TakenTotalMod < 1)
+ tmpDamage = ((CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod) * TakenTotalMod) + CalculatePctF(float(pdamage) + TakenFlatBenefit, TakenTotalCasterMod));
+ }
+ if (!tmpDamage)
+ tmpDamage = (float(pdamage) + TakenFlatBenefit) * TakenTotalMod;
// bonus result can be negative
return uint32(std::max(tmpDamage, 0.0f));
@@ -12730,7 +12664,7 @@ void Unit::UpdateSpeed(UnitMoveType mtype, bool forced)
{
// Set creature speed rate from CreatureInfo
if (GetTypeId() == TYPEID_UNIT)
- speed *= ToCreature()->GetCreatureTemplate()->speed_walk;
+ speed *= ToCreature()->GetCreatureTemplate()->speed_run; // at this point, MOVE_WALK is never reached
// Normalize speed by 191 aura SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED if need
// TODO: possible affect only on MOVE_RUN
@@ -12795,10 +12729,10 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
switch (mtype)
{
case MOVE_WALK:
- data.Initialize(SMSG_MOVE_SPLINE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);
break;
case MOVE_RUN:
- data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[2]);
data.WriteByteMask(bytes[1]);
@@ -12820,7 +12754,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data << float(GetSpeed(mtype));
break;
case MOVE_RUN_BACK:
- data.Initialize(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[4]);
data.WriteByteMask(bytes[0]);
data.WriteByteMask(bytes[6]);
@@ -12842,7 +12776,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data << float(GetSpeed(mtype));
break;
case MOVE_SWIM:
- data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[3]);
data.WriteByteMask(bytes[5]);
data.WriteByteMask(bytes[7]);
@@ -12863,7 +12797,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.WriteByteSeq(bytes[5]);
break;
case MOVE_SWIM_BACK:
- data.Initialize(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[3]);
data.WriteByteMask(bytes[5]);
data.WriteByteMask(bytes[4]);
@@ -12884,7 +12818,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.WriteByteSeq(bytes[5]);
break;
case MOVE_TURN_RATE:
- data.Initialize(SMSG_MOVE_SPLINE_SET_TURN_RATE, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_TURN_RATE, 1 + 8 + 4);
data.WriteByteMask(bytes[0]);
data.WriteByteMask(bytes[4]);
data.WriteByteMask(bytes[5]);
@@ -12905,7 +12839,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.WriteByteSeq(bytes[3]);
break;
case MOVE_FLIGHT:
- data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[2]);
data.WriteByteMask(bytes[3]);
data.WriteByteMask(bytes[5]);
@@ -12927,7 +12861,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.WriteByteSeq(bytes[4]);
break;
case MOVE_FLIGHT_BACK:
- data.Initialize(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, 1 + 8 + 4);
data.WriteByteMask(bytes[1]);
data.WriteByteMask(bytes[6]);
data.WriteByteMask(bytes[0]);
@@ -12948,7 +12882,7 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)
data.WriteByteSeq(bytes[3]);
break;
case MOVE_PITCH_RATE:
- data.Initialize(SMSG_MOVE_SPLINE_SET_PITCH_RATE, 1 + 8 + 4);
+ data.Initialize(SMSG_SPLINE_MOVE_SET_PITCH_RATE, 1 + 8 + 4);
data.WriteByteMask(bytes[7]);
data.WriteByteMask(bytes[2]);
data.WriteByteMask(bytes[3]);
@@ -13379,8 +13313,7 @@ void Unit::TauntFadeOut(Unit* taunter)
return;
}
- //m_ThreatManager.tauntFadeOut(taunter);
- target = m_ThreatManager.getHostilTarget();
+ target = creature->SelectVictim(); // might have more taunt auras remaining
if (target && target != taunter)
{
@@ -13464,7 +13397,7 @@ Unit* Creature::SelectVictim()
else
return NULL;
- if (target && _IsTargetAcceptable(target))
+ if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))
{
SetInFront(target);
return target;
@@ -13490,7 +13423,7 @@ Unit* Creature::SelectVictim()
{
target = SelectNearestTargetInAttackDistance(m_CombatDistance ? m_CombatDistance : ATTACK_DISTANCE);
- if (target && _IsTargetAcceptable(target))
+ if (target && _IsTargetAcceptable(target) && canCreatureAttack(target))
return target;
}
@@ -13672,7 +13605,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellProto, int32 & castTime, Spell
if (Player* modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CASTING_TIME, castTime, spell);
- if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && spellProto->SpellFamilyName)
+ if (!(spellProto->Attributes & (SPELL_ATTR0_ABILITY|SPELL_ATTR0_TRADESPELL)) && ((GetTypeId() == TYPEID_PLAYER && spellProto->SpellFamilyName) || GetTypeId() == TYPEID_UNIT))
castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED));
else if (spellProto->Attributes & SPELL_ATTR0_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG))
castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]);
@@ -15007,6 +14940,11 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
if (procSpell && (triggeredByAura->GetMiscValue() & procSpell->SchoolMask)) // School check
takeCharges = true;
break;
+ case SPELL_AURA_SPELL_MAGNET:
+ // Skip Melee hits and targets with magnet aura
+ if (procSpell && (triggeredByAura->GetBase()->GetUnitOwner()->ToUnit() == ToUnit())) // Magnet
+ takeCharges = true;
+ break;
case SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT:
case SPELL_AURA_MOD_POWER_COST_SCHOOL:
// Skip melee hits and spells ws wrong school or zero cost
@@ -15235,6 +15173,7 @@ void Unit::StopMoving()
return;
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(GetOrientation());
init.Launch();
}
@@ -16347,7 +16286,7 @@ void Unit::SetRooted(bool apply)
}
else
{
- WorldPacket data(SMSG_MOVE_SPLINE_ROOT, 8);
+ WorldPacket data(SMSG_SPLINE_MOVE_ROOT, 8);
data.append(GetPackGUID());
SendMessageToSet(&data, true);
ToCreature()->StopMoving();
@@ -16366,7 +16305,7 @@ void Unit::SetRooted(bool apply)
}
else
{
- WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8);
+ WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
data.append(GetPackGUID());
SendMessageToSet(&data, true);
}
@@ -16747,7 +16686,7 @@ Creature* Unit::GetVehicleCreatureBase() const
uint64 Unit::GetTransGUID() const
{
if (GetVehicle())
- return GetVehicle()->GetBase()->GetGUID();
+ return GetVehicleBase()->GetGUID();
if (GetTransport())
return GetTransport()->GetGUID();
@@ -17529,7 +17468,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
Creature* creature = ToCreature();
if (creature && creature->IsAIEnabled)
- creature->AI()->DoAction(EVENT_SPELLCLICK);
+ creature->AI()->OnSpellClick(clicker);
return true;
}
@@ -17649,11 +17588,12 @@ void Unit::_ExitVehicle(Position const* exitPosition)
Vehicle* vehicle = m_vehicle;
m_vehicle = NULL;
- SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
+ SetControlled(false, UNIT_STATE_ROOT); // SMSG_MOVE_FORCE_UNROOT, ~MOVEMENTFLAG_ROOT
Position pos;
- if (!exitPosition) // Exit position not specified
- vehicle->GetBase()->GetPosition(&pos);
+ if (!exitPosition) // Exit position not specified
+ vehicle->GetBase()->GetPosition(&pos); // This should use passenger's current position, leaving it as it is now
+ // because we calculate positions incorrect (sometimes under map)
else
pos = *exitPosition;
@@ -17663,19 +17603,22 @@ void Unit::_ExitVehicle(Position const* exitPosition)
ToPlayer()->SetFallInformation(0, GetPositionZ());
else if (HasUnitMovementFlag(MOVEMENTFLAG_ROOT))
{
- WorldPacket data(SMSG_MOVE_SPLINE_UNROOT, 8);
+ WorldPacket data(SMSG_SPLINE_MOVE_UNROOT, 8);
data.append(GetPackGUID());
SendMessageToSet(&data, false);
}
- SendMonsterMoveExitVehicle(&pos);
- Relocate(&pos);
+ Movement::MoveSplineInit init(*this);
+ init.MoveTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ());
+ init.SetFacing(GetOrientation());
+ init.SetTransportExit();
+ init.Launch();
+
+ //GetMotionMaster()->MoveFall(); // Enable this once passenger positions are calculater properly (see above)
if (Player* player = ToPlayer())
player->ResummonPetTemporaryUnSummonedIfAny();
- SendMovementFlagUpdate();
-
if (vehicle->GetBase()->HasUnitTypeMask(UNIT_MASK_MINION))
if (((Minion*)vehicle->GetBase())->GetOwner() == this)
vehicle->Dismiss();
@@ -17693,24 +17636,13 @@ void Unit::_ExitVehicle(Position const* exitPosition)
void Unit::BuildMovementPacket(ByteBuffer *data) const
{
- switch (GetTypeId())
- {
- case TYPEID_UNIT:
- if (CanFly())
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY);
- break;
- case TYPEID_PLAYER:
- // remove unknown, unused etc flags for now
- const_cast<Unit*>(this)->RemoveUnitMovementFlag(MOVEMENTFLAG_SPLINE_ENABLED);
- if (isInFlight())
- {
- WPAssert(const_cast<Unit*>(this)->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE);
- const_cast<Unit*>(this)->AddUnitMovementFlag(MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_SPLINE_ENABLED);
- }
- break;
- default:
- break;
- }
+ *data << uint32(GetUnitMovementFlags()); // movement flags
+ *data << uint16(GetExtraUnitMovementFlags()); // 2.3.0
+ *data << uint32(getMSTime()); // time / counter
+ *data << GetPositionX();
+ *data << GetPositionY();
+ *data << GetPositionZMinusOffset();
+ *data << GetOrientation();
bool onTransport = GetUnitMovementFlags() & MOVEMENTFLAG_ONTRANSPORT;
bool hasInterpolatedMovement = m_movementInfo.flags2 & MOVEMENTFLAG2_INTERPOLATED_MOVEMENT;
@@ -18116,6 +18048,7 @@ void Unit::SetInFront(Unit const* target)
void Unit::SetFacingTo(float ori)
{
Movement::MoveSplineInit init(*this);
+ init.MoveTo(GetPositionX(), GetPositionY(), GetPositionZMinusOffset());
init.SetFacing(ori);
init.Launch();
}
@@ -18187,7 +18120,7 @@ void Unit::SendMovementHover()
if (GetTypeId() == TYPEID_PLAYER)
ToPlayer()->SendMovementSetHover(HasUnitMovementFlag(MOVEMENTFLAG_HOVER));
- WorldPacket data(MSG_MOVE_HOVER, 64); // SMSG_MOVE_SET_HOVERING?
+ WorldPacket data(MSG_MOVE_HOVER, 64);
data.append(GetPackGUID());
BuildMovementPacket(&data);
SendMessageToSet(&data, false);
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 9d6c22ab8b5..6d188fe3593 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -735,19 +735,6 @@ enum MovementFlags2
MOVEMENTFLAG2_UNK16 = 0x00008000,
};
-enum SplineFlags
-{
- SPLINEFLAG_WALKMODE = 0x00001000,
- SPLINEFLAG_FLYING = 0x00002000,
- SPLINEFLAG_TRANSPORT = 0x00800000,
- SPLINEFLAG_EXIT_VEHICLE = 0x01000000,
-};
-
-enum SplineType
-{
- SPLINETYPE_FACING_ANGLE = 4,
-};
-
enum UnitTypeMask
{
UNIT_MASK_NONE = 0x00000000,
@@ -806,8 +793,8 @@ public:
m_dispeller(_dispeller), m_dispellerSpellId(_dispellerSpellId), m_chargesRemoved(_chargesRemoved) {}
Unit* GetDispeller() { return m_dispeller; }
- uint32 GetDispellerSpellId() { return m_dispellerSpellId; }
- uint8 GetRemovedCharges() { return m_chargesRemoved; }
+ uint32 GetDispellerSpellId() const { return m_dispellerSpellId; }
+ uint8 GetRemovedCharges() const { return m_chargesRemoved; }
void SetRemovedCharges(uint8 amount)
{
m_chargesRemoved = amount;
@@ -1350,10 +1337,10 @@ class Unit : public WorldObject
uint32 GetMaxHealth() const { return GetUInt32Value(UNIT_FIELD_MAXHEALTH); }
bool IsFullHealth() const { return GetHealth() == GetMaxHealth(); }
- bool HealthBelowPct(int32 pct) const { return GetHealth() * uint64(100) < GetMaxHealth() * uint64(pct); }
- bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return (int32(GetHealth()) - damage) * int64(100) < GetMaxHealth() * int64(pct); }
- bool HealthAbovePct(int32 pct) const { return GetHealth() * uint64(100) > GetMaxHealth() * uint64(pct); }
- bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return (GetHealth() + heal) * uint64(100) > GetMaxHealth() * uint64(pct); }
+ bool HealthBelowPct(int32 pct) const { return GetHealth() < CountPctFromMaxHealth(pct); }
+ bool HealthBelowPctDamaged(int32 pct, uint32 damage) const { return int64(GetHealth()) - int64(damage) < int64(CountPctFromMaxHealth(pct)); }
+ bool HealthAbovePct(int32 pct) const { return GetHealth() > CountPctFromMaxHealth(pct); }
+ bool HealthAbovePctHealed(int32 pct, uint32 heal) const { return uint64(GetHealth()) + uint64(heal) > CountPctFromMaxHealth(pct); }
float GetHealthPct() const { return GetMaxHealth() ? 100.f * GetHealth() / GetMaxHealth() : 0.0f; }
uint32 CountPctFromMaxHealth(int32 pct) const { return CalculatePctN(GetMaxHealth(), pct); }
uint32 CountPctFromCurHealth(int32 pct) const { return CalculatePctN(GetHealth(), pct); }
@@ -1632,9 +1619,7 @@ class Unit : public WorldObject
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 SendMovementFlagUpdate();
/*! These methods send the same packet to the client in apply and unapply case.
diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp
index 090a1db382a..eb50f3fe229 100755
--- a/src/server/game/Entities/Vehicle/Vehicle.cpp
+++ b/src/server/game/Entities/Vehicle/Vehicle.cpp
@@ -28,6 +28,7 @@
#include "ZoneScript.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
+#include "MoveSplineInit.h"
Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : _me(unit), _vehicleInfo(vehInfo), _usableSeatNum(0), _creatureEntry(creatureEntry)
{
@@ -338,7 +339,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
}
}
- if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_UNK1))
+ if (seat->second.SeatInfo->m_flags && !(seat->second.SeatInfo->m_flags & VEHICLE_SEAT_FLAG_ALLOW_TURNING))
unit->AddUnitState(UNIT_STATE_ONVEHICLE);
unit->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT);
@@ -364,7 +365,12 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
unit->SendClearTarget(); // SMSG_BREAK_TARGET
unit->SetControlled(true, UNIT_STATE_ROOT); // SMSG_FORCE_ROOT - In some cases we send SMSG_SPLINE_MOVE_ROOT here (for creatures)
// also adds MOVEMENTFLAG_ROOT
- unit->SendMonsterMoveTransport(_me); // SMSG_MONSTER_MOVE_TRANSPORT
+ Movement::MoveSplineInit init(*unit);
+ init.DisableTransportPathTransformations();
+ init.MoveTo(veSeat->m_attachmentOffsetX, veSeat->m_attachmentOffsetY, veSeat->m_attachmentOffsetZ);
+ init.SetFacing(0.0f);
+ init.SetTransportEnter();
+ init.Launch();
if (_me->GetTypeId() == TYPEID_UNIT)
{
@@ -372,7 +378,8 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId)
_me->ToCreature()->AI()->PassengerBoarded(unit, seat->first, true);
// update all passenger's positions
- RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
+ //Passenger's spline OR vehicle movement will update positions
+ //RelocatePassengers(_me->GetPositionX(), _me->GetPositionY(), _me->GetPositionZ(), _me->GetOrientation());
}
}
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 43381267545..71ce341185e 100755
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -461,7 +461,7 @@ void ObjectMgr::LoadCreatureTemplates()
creatureTemplate.SkinLootId = fields[48].GetUInt32();
for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- creatureTemplate.resistance[i] = fields[50 + i -1].GetInt16();
+ creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16();
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
creatureTemplate.spells[i] = fields[55 + i].GetUInt32();
@@ -1884,71 +1884,6 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data
}
}
-void ObjectMgr::LoadCreatureRespawnTimes()
-{
- uint32 oldMSTime = getMSTime();
-
- uint32 count = 0;
-
- PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS));
- if (!result)
- {
- sLog->outString(">> Loaded 0 creature respawn time.");
- sLog->outString();
- return;
- }
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 loguid = fields[0].GetUInt32();
- uint32 respawn_time = fields[1].GetUInt32();
- uint32 instance = fields[2].GetUInt32();
-
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- sLog->outString(">> Loaded %lu creature respawn times in %u ms", (unsigned long)_creatureRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime));
- sLog->outString();
-}
-
-void ObjectMgr::LoadGameobjectRespawnTimes()
-{
- uint32 oldMSTime = getMSTime();
-
- // Remove outdated data
- CharacterDatabase.DirectExecute("DELETE FROM gameobject_respawn WHERE respawnTime <= UNIX_TIMESTAMP(NOW())");
-
- uint32 count = 0;
-
- PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS));
- if (!result)
- {
- sLog->outString(">> Loaded 0 gameobject respawn times. DB table `gameobject_respawn` is empty!");
- sLog->outString();
- return;
- }
-
- do
- {
- Field* fields = result->Fetch();
-
- uint32 loguid = fields[0].GetUInt32();
- uint32 respawn_time = fields[1].GetUInt32();
- uint32 instance = fields[2].GetUInt32();
-
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = time_t(respawn_time);
-
- ++count;
- } while (result->NextRow());
-
- sLog->outString();
- sLog->outString(">> Loaded %lu gameobject respawn times in %u ms", (unsigned long)_goRespawnTimes.size(), GetMSTimeDiffToNow(oldMSTime));
-}
-
Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const
{
uint64 guid = MAKE_NEW_GUID(lowguid, 0, HIGHGUID_PLAYER);
@@ -2613,7 +2548,7 @@ void ObjectMgr::LoadItemTemplateAddon()
uint32 oldMSTime = getMSTime();
uint32 count = 0;
- QueryResult result = WorldDatabase.Query("SELECT Id, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon");
+ QueryResult result = WorldDatabase.Query("SELECT Id, FlagsCu, FoodType, MinMoneyLoot, MaxMoneyLoot, SpellPPMChance FROM item_template_addon");
if (result)
{
do
@@ -2626,16 +2561,8 @@ void ObjectMgr::LoadItemTemplateAddon()
continue;
}
- uint8 buyCount = fields[1].GetUInt8();
- if (!buyCount)
- {
- sLog->outErrorDb("Item %u has BuyCount set to 0, corrected to 1.", itemId);
- buyCount = 1;
- }
-
- uint8 foodType = fields[1].GetUInt8();
- uint32 minMoneyLoot = fields[2].GetUInt32();
- uint32 maxMoneyLoot = fields[3].GetUInt32();
+ uint32 minMoneyLoot = fields[3].GetUInt32();
+ uint32 maxMoneyLoot = fields[4].GetUInt32();
if (minMoneyLoot > maxMoneyLoot)
{
sLog->outErrorDb("Minimum money loot specified in `item_template_addon` for item %u was greater than maximum amount, swapping.", itemId);
@@ -2643,10 +2570,11 @@ void ObjectMgr::LoadItemTemplateAddon()
}
ItemTemplate& itemTemplate = _itemTemplateStore[itemId];
- itemTemplate.FoodType = foodType;
+ itemTemplate.FlagsCu = fields[1].GetUInt32();
+ itemTemplate.FoodType = fields[2].GetUInt8();
itemTemplate.MinMoneyLoot = minMoneyLoot;
itemTemplate.MaxMoneyLoot = maxMoneyLoot;
- itemTemplate.SpellPPMRate = fields[4].GetFloat();
+ itemTemplate.SpellPPMRate = fields[5].GetFloat();
++count;
} while (result->NextRow());
}
@@ -2739,6 +2667,7 @@ void ObjectMgr::LoadItemSetNames()
}
// 0 1 2
+ // 0 1 2
QueryResult result = WorldDatabase.Query("SELECT `entry`, `name`, `InventoryType` FROM `item_set_names`");
if (!result)
@@ -5043,11 +4972,11 @@ void ObjectMgr::LoadSpellScriptNames()
Field* fields = result->Fetch();
- int32 spellId = fields[0].GetInt32();
+ int32 spellId = fields[0].GetInt32();
const char *scriptName = fields[1].GetCString();
bool allRanks = false;
- if (spellId <=0)
+ if (spellId <= 0)
{
allRanks = true;
spellId = -spellId;
@@ -6783,7 +6712,7 @@ uint32 ObjectMgr::GetBaseXP(uint8 level)
return _baseXPTable[level] ? _baseXPTable[level] : 0;
}
-uint32 ObjectMgr::GetXPForLevel(uint8 level)
+uint32 ObjectMgr::GetXPForLevel(uint8 level) const
{
if (level < _playerXPperLevel.size())
return _playerXPperLevel[level];
@@ -7340,44 +7269,6 @@ void ObjectMgr::LoadNPCSpellClickSpells()
sLog->outString();
}
-void ObjectMgr::SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- if (!t)
- {
- // Delete only
- RemoveCreatureRespawnTime(loguid, instance);
- return;
- }
-
- // This function can be called from various map threads concurrently
- {
- _creatureRespawnTimesMutex.acquire();
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = t;
- _creatureRespawnTimesMutex.release();
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, uint32(t));
- stmt->setUInt32(2, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::RemoveCreatureRespawnTime(uint32 loguid, uint32 instance)
-{
- // This function can be called from various map threads concurrently
- {
- _creatureRespawnTimesMutex.acquire();
- _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0;
- _creatureRespawnTimesMutex.release();
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, instance);
- CharacterDatabase.Execute(stmt);
-}
-
void ObjectMgr::DeleteCreatureData(uint32 guid)
{
// remove mapid*cellid -> guid_set map
@@ -7388,81 +7279,6 @@ void ObjectMgr::DeleteCreatureData(uint32 guid)
_creatureDataStore.erase(guid);
}
-void ObjectMgr::SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t)
-{
- if (!t)
- {
- // Delete only
- RemoveGORespawnTime(loguid, instance);
- return;
- }
-
- // This function can be called from different map threads concurrently
- {
- _goRespawnTimesMutex.acquire();
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = t;
- _goRespawnTimesMutex.release();
- }
-
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt64(1, uint64(t));
- stmt->setUInt32(2, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::RemoveGORespawnTime(uint32 loguid, uint32 instance)
-{
- // This function can be called from different map threads concurrently
- {
- _goRespawnTimesMutex.acquire();
- _goRespawnTimes[MAKE_PAIR64(loguid, instance)] = 0;
- _goRespawnTimesMutex.release();
- }
-
- PreparedStatement *stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN);
- stmt->setUInt32(0, loguid);
- stmt->setUInt32(1, instance);
- CharacterDatabase.Execute(stmt);
-}
-
-void ObjectMgr::DeleteRespawnTimeForInstance(uint32 instance)
-{
- // This function can be called from different map threads concurrently
- RespawnTimes::iterator next;
-
- {
- _goRespawnTimesMutex.acquire();
- for (RespawnTimes::iterator itr = _goRespawnTimes.begin(); itr != _goRespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if (GUID_HIPART(itr->first) == instance)
- _goRespawnTimes.erase(itr);
- }
- _goRespawnTimesMutex.release();
- }
- {
- _creatureRespawnTimesMutex.acquire();
- for (RespawnTimes::iterator itr = _creatureRespawnTimes.begin(); itr != _creatureRespawnTimes.end(); itr = next)
- {
- next = itr;
- ++next;
-
- if (GUID_HIPART(itr->first) == instance)
- _creatureRespawnTimes.erase(itr);
- }
- _creatureRespawnTimesMutex.release();
- }
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE);
- stmt->setUInt32(0, instance);
- CharacterDatabase.Execute(stmt);
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE);
- stmt->setUInt32(0, instance);
- CharacterDatabase.Execute(stmt);
-}
-
void ObjectMgr::DeleteGOData(uint32 guid)
{
// remove mapid*cellid -> guid_set map
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 9ab7898573f..742259aa536 100755
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -367,8 +367,6 @@ struct CellObjectGuids
typedef UNORDERED_MAP<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap;
typedef UNORDERED_MAP<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids;
-typedef UNORDERED_MAP<uint64/*(instance, guid) pair*/, time_t> RespawnTimes;
-
// Trinity string ranges
#define MIN_TRINITY_STRING_ID 1 // 'trinity_string'
#define MAX_TRINITY_STRING_ID 2000000000
@@ -624,14 +622,14 @@ class ObjectMgr
Player* GetPlayerByLowGUID(uint32 lowguid) const;
GameObjectTemplate const* GetGameObjectTemplate(uint32 entry);
- GameObjectTemplateContainer const* GetGameObjectTemplates() { return &_gameObjectTemplateStore; }
+ GameObjectTemplateContainer const* GetGameObjectTemplates() const { return &_gameObjectTemplateStore; }
int LoadReferenceVendor(int32 vendor, int32 item_id, std::set<uint32> *skip_vendors);
void LoadGameObjectTemplate();
void AddGameobjectInfo(GameObjectTemplate* goinfo);
CreatureTemplate const* GetCreatureTemplate(uint32 entry);
- CreatureTemplateContainer const* GetCreatureTemplates() { return &_creatureTemplateStore; }
+ CreatureTemplateContainer const* GetCreatureTemplates() const { return &_creatureTemplateStore; }
CreatureModelInfo const* GetCreatureModelInfo(uint32 modelId);
CreatureModelInfo const* GetCreatureModelRandomGender(uint32* displayID);
static uint32 ChooseDisplayId(uint32 team, const CreatureTemplate* cinfo, const CreatureData* data = NULL);
@@ -640,7 +638,7 @@ class ObjectMgr
CreatureAddon const* GetCreatureAddon(uint32 lowguid);
CreatureAddon const* GetCreatureTemplateAddon(uint32 entry);
ItemTemplate const* GetItemTemplate(uint32 entry);
- ItemTemplateContainer const* GetItemTemplateStore() { return &_itemTemplateStore; }
+ ItemTemplateContainer const* GetItemTemplateStore() const { return &_itemTemplateStore; }
ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId)
{
@@ -863,13 +861,11 @@ class ObjectMgr
void LoadCreatures();
void LoadLinkedRespawn();
bool SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid);
- void LoadCreatureRespawnTimes();
void LoadCreatureAddons();
void LoadCreatureModelInfo();
void LoadEquipmentTemplates();
void LoadGameObjectLocales();
void LoadGameobjects();
- void LoadGameobjectRespawnTimes();
void LoadItemTemplates();
void LoadItemTemplateAddon();
void LoadItemScriptNames();
@@ -927,7 +923,7 @@ class ObjectMgr
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint8 level);
- uint32 GetXPForLevel(uint8 level);
+ uint32 GetXPForLevel(uint8 level) const;
int32 GetFishingBaseSkillLevel(uint32 entry) const
{
@@ -1059,36 +1055,6 @@ class ObjectMgr
void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance);
void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid);
- time_t GetLinkedRespawnTime(uint64 guid, uint32 instance)
- {
- uint64 linkedGuid = GetLinkedRespawnGuid(guid);
- switch (GUID_HIPART(linkedGuid))
- {
- case HIGHGUID_UNIT:
- return GetCreatureRespawnTime(GUID_LOPART(linkedGuid), instance);
- case HIGHGUID_GAMEOBJECT:
- return GetGORespawnTime(GUID_LOPART(linkedGuid), instance);
- default:
- return 0;
- }
- }
-
- time_t GetCreatureRespawnTime(uint32 loguid, uint32 instance)
- {
- TRINITY_GUARD(ACE_Thread_Mutex, _creatureRespawnTimesMutex);
- return _creatureRespawnTimes[MAKE_PAIR64(loguid, instance)];
- }
- void SaveCreatureRespawnTime(uint32 loguid, uint32 instance, time_t t);
- void RemoveCreatureRespawnTime(uint32 loguid, uint32 instance);
- time_t GetGORespawnTime(uint32 loguid, uint32 instance)
- {
- TRINITY_GUARD(ACE_Thread_Mutex, _goRespawnTimesMutex);
- return _goRespawnTimes[MAKE_PAIR64(loguid, instance)];
- }
- void SaveGORespawnTime(uint32 loguid, uint32 instance, time_t t);
- void RemoveGORespawnTime(uint32 loguid, uint32 instance);
- void DeleteRespawnTimeForInstance(uint32 instance);
-
// grid objects
void AddCreatureToGrid(uint32 guid, CreatureData const* data);
void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data);
@@ -1143,7 +1109,7 @@ class ObjectMgr
void LoadScriptNames();
ScriptNameContainer &GetScriptNames() { return _scriptNamesStore; }
- const char * GetScriptName(uint32 id) { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
+ const char * GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
uint32 GetScriptId(const char *name);
SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
@@ -1321,10 +1287,6 @@ class ObjectMgr
TrinityStringLocaleContainer _trinityStringLocaleStore;
GossipMenuItemsLocaleContainer _gossipMenuItemsLocaleStore;
PointOfInterestLocaleContainer _pointOfInterestLocaleStore;
- RespawnTimes _creatureRespawnTimes;
- ACE_Thread_Mutex _creatureRespawnTimesMutex;
- RespawnTimes _goRespawnTimes;
- ACE_Thread_Mutex _goRespawnTimesMutex;
CacheVendorItemContainer _cacheVendorItemStore;
CacheTrainerSpellContainer _cacheTrainerSpellStore;
@@ -1339,7 +1301,6 @@ class ObjectMgr
GO_TO_GO,
GO_TO_CREATURE, // GO is dependant on creature
};
-
HotfixData _hotfixData;
};
diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h
index 54bc1206e18..75df3e67c5a 100755
--- a/src/server/game/Grids/Notifiers/GridNotifiers.h
+++ b/src/server/game/Grids/Notifiers/GridNotifiers.h
@@ -1325,11 +1325,16 @@ namespace Trinity
{
public:
UnitAuraCheck(bool present, uint32 spellId, uint64 casterGUID = 0) : _present(present), _spellId(spellId), _casterGUID(casterGUID) {}
- bool operator()(Unit* unit)
+ bool operator()(Unit* unit) const
{
return unit->HasAura(_spellId, _casterGUID) == _present;
}
+ bool operator()(WorldObject* object) const
+ {
+ return object->ToUnit() && object->ToUnit()->HasAura(_spellId, _casterGUID) == _present;
+ }
+
private:
bool _present;
uint32 _spellId;
diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp
index 4c6b6249887..743d56886f0 100755
--- a/src/server/game/Groups/Group.cpp
+++ b/src/server/game/Groups/Group.cpp
@@ -556,7 +556,7 @@ bool Group::RemoveMember(uint64 guid, const RemoveMethod &method /*= GROUP_REMOV
roll->playerVote.erase(itr2);
- CountRollVote(guid, roll->itemGUID, GetMembersCount()-1, MAX_ROLL_TYPE);
+ CountRollVote(guid, roll->itemGUID, MAX_ROLL_TYPE);
}
// Update subgroups
@@ -763,7 +763,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r)
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.itemSlot); // slot
+ data << uint32(r.itemSlot); // itemslot
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
@@ -791,7 +791,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
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.itemSlot); // itemslot
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
@@ -805,20 +805,20 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p,
p->GetSession()->SendPacket(&data);
}
-void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
+void Group::SendLootRoll(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ROLL, (8+4+8+4+4+4+1+1+1));
- data << uint64(SourceGuid); // guid of the item rolled
- data << uint32(0); // unknown, maybe amount of players
- data << uint64(TargetGuid);
- 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 << uint8(RollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
- data << uint8(RollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
- data << uint8(0); // auto pass on NeedBeforeGreed loot because player cannot use the object
+ data << uint64(sourceGuid); // guid of the item rolled
+ data << uint32(roll.itemSlot); // slot
+ data << uint64(targetGuid);
+ data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
+ data << uint32(roll.itemRandomSuffix); // randomSuffix
+ data << uint32(roll.itemRandomPropId); // Item random property ID
+ data << uint8(rollNumber); // 0: "Need for: [item name]" > 127: "you passed on: [item name]" Roll number
+ data << uint8(rollType); // 0: "Need for: [item name]" 0: "You have selected need for [item name] 1: need roll 2: greed roll
+ data << uint8(0); // 1: "You automatically passed on: %s because you cannot loot that item." - Possibly used in need befor greed
- for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
+ for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
@@ -829,19 +829,19 @@ void Group::SendLootRoll(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber,
}
}
-void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r)
+void Group::SendLootRollWon(uint64 sourceGuid, uint64 targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ROLL_WON, (8+4+4+4+4+8+1+1));
- data << uint64(SourceGuid); // guid of the item rolled
- data << uint32(0); // unknown, maybe amount of players
- 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
- data << uint64(TargetGuid); // guid of the player who won.
- data << uint8(RollNumber); // rollnumber realted to SMSG_LOOT_ROLL
- data << uint8(RollType); // Rolltype related to SMSG_LOOT_ROLL
+ data << uint64(sourceGuid); // guid of the item rolled
+ data << uint32(roll.itemSlot); // slot
+ data << uint32(roll.itemid); // the itemEntryId for the item that shall be rolled for
+ data << uint32(roll.itemRandomSuffix); // randomSuffix
+ data << uint32(roll.itemRandomPropId); // Item random property
+ data << uint64(targetGuid); // guid of the player who won.
+ data << uint8(rollNumber); // rollnumber realted to SMSG_LOOT_ROLL
+ data << uint8(rollType); // rollType related to SMSG_LOOT_ROLL
- for (Roll::PlayerVote::const_iterator itr=r.playerVote.begin(); itr != r.playerVote.end(); ++itr)
+ for (Roll::PlayerVote::const_iterator itr = roll.playerVote.begin(); itr != roll.playerVote.end(); ++itr)
{
Player* p = ObjectAccessor::FindPlayer(itr->first);
if (!p || !p->GetSession())
@@ -852,11 +852,11 @@ void Group::SendLootRollWon(uint64 SourceGuid, uint64 TargetGuid, uint8 RollNumb
}
}
-void Group::SendLootAllPassed(uint32 numberOfPlayers, Roll const& roll)
+void Group::SendLootAllPassed(Roll const& roll)
{
WorldPacket data(SMSG_LOOT_ALL_PASSED, (8+4+4+4+4));
data << uint64(roll.itemGUID); // Guid of the item rolled
- data << uint32(numberOfPlayers); // The number of players rolling for it
+ data << uint32(roll.itemSlot); // Item loot slot
data << uint32(roll.itemid); // The itemEntryId for the item that shall be rolled for
data << uint32(roll.itemRandomPropId); // Item random property ID
data << uint32(roll.itemRandomSuffix); // Item random suffix ID
@@ -1099,7 +1099,7 @@ void Group::MasterLoot(Loot* /*loot*/, WorldObject* pLootedObject)
}
}
-void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choice)
+void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choice)
{
Rolls::iterator rollI = GetRoll(Guid);
if (rollI == RollId.end())
@@ -1140,7 +1140,7 @@ void Group::CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers
}
if (roll->totalPass + roll->totalNeed + roll->totalGreed >= roll->totalPlayersRolling)
- CountTheRoll(rollI, NumberOfPlayers);
+ CountTheRoll(rollI);
}
//called when roll timer expires
@@ -1149,7 +1149,7 @@ void Group::EndRoll(Loot* pLoot)
for (Rolls::iterator itr = RollId.begin(); itr != RollId.end();)
{
if ((*itr)->getLoot() == pLoot) {
- CountTheRoll(itr, GetMembersCount()); //i don't have to edit player votes, who didn't vote ... he will pass
+ CountTheRoll(itr); //i don't have to edit player votes, who didn't vote ... he will pass
itr = RollId.begin();
}
else
@@ -1157,7 +1157,7 @@ void Group::EndRoll(Loot* pLoot)
}
}
-void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
+void Group::CountTheRoll(Rolls::iterator rollI)
{
Roll* roll = *rollI;
if (!roll->isValid()) // is loot already deleted ?
@@ -1280,7 +1280,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, uint32 NumberOfPlayers)
}
else
{
- SendLootAllPassed(NumberOfPlayers, *roll);
+ SendLootAllPassed(*roll);
// remove is_blocked so that the item is lootable by all players
LootItem* item = &(roll->getLoot()->items[roll->itemSlot]);
@@ -2107,20 +2107,6 @@ bool Group::HasFreeSlotSubGroup(uint8 subgroup) const
return (m_subGroupsCounts && m_subGroupsCounts[subgroup] < MAXGROUPSIZE);
}
-Group::MemberSlotList const& Group::GetMemberSlots() const
-{
- return m_memberSlots;
-}
-
-GroupReference* Group::GetFirstMember()
-{
- return m_memberMgr.getFirst();
-}
-
-uint32 Group::GetMembersCount() const
-{
- return m_memberSlots.size();
-}
uint8 Group::GetMemberGroup(uint64 guid) const
{
diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h
index 08246614627..f909b755829 100755
--- a/src/server/game/Groups/Group.h
+++ b/src/server/game/Groups/Group.h
@@ -232,9 +232,11 @@ class Group
bool SameSubGroup(Player const* member1, Player const* member2) const;
bool HasFreeSlotSubGroup(uint8 subgroup) const;
- MemberSlotList const& GetMemberSlots() const;
- GroupReference* GetFirstMember();
- uint32 GetMembersCount() const;
+ MemberSlotList const& GetMemberSlots() const { return m_memberSlots; }
+ GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); }
+ GroupReference const* GetFirstMember() const { return m_memberMgr.getFirst(); }
+ uint32 GetMembersCount() const { return m_memberSlots.size(); }
+
uint8 GetMemberGroup(uint64 guid) const;
void ConvertToLFG();
@@ -279,14 +281,14 @@ class Group
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);
+ void SendLootAllPassed(Roll const& roll);
void SendLooter(Creature* creature, Player* pLooter);
void GroupLoot(Loot* loot, WorldObject* pLootedObject);
void NeedBeforeGreed(Loot* loot, WorldObject* pLootedObject);
void MasterLoot(Loot* loot, WorldObject* pLootedObject);
Rolls::iterator GetRoll(uint64 Guid);
- void CountTheRoll(Rolls::iterator roll, uint32 NumberOfPlayers);
- void CountRollVote(uint64 playerGUID, uint64 Guid, uint32 NumberOfPlayers, uint8 Choise);
+ void CountTheRoll(Rolls::iterator roll);
+ void CountRollVote(uint64 playerGUID, uint64 Guid, uint8 Choise);
void EndRoll(Loot* loot);
// related to disenchant rolls
diff --git a/src/server/game/Groups/GroupRefManager.h b/src/server/game/Groups/GroupRefManager.h
index 9bcc05f8724..d9fef8611de 100755
--- a/src/server/game/Groups/GroupRefManager.h
+++ b/src/server/game/Groups/GroupRefManager.h
@@ -28,7 +28,8 @@ class GroupReference;
class GroupRefManager : public RefManager<Group, Player>
{
public:
- GroupReference* getFirst() { return ((GroupReference*) RefManager<Group, Player>::getFirst()); }
+ GroupReference* getFirst() { return ((GroupReference*)RefManager<Group, Player>::getFirst()); }
+ GroupReference const* getFirst() const { return ((GroupReference const*)RefManager<Group, Player>::getFirst()); }
};
#endif
diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h
index 2048fd9cb0d..7960dd21035 100755
--- a/src/server/game/Groups/GroupReference.h
+++ b/src/server/game/Groups/GroupReference.h
@@ -35,6 +35,7 @@ class GroupReference : public Reference<Group, Player>
GroupReference() : Reference<Group, Player>(), iSubGroup(0) {}
~GroupReference() { unlink(); }
GroupReference* next() { return (GroupReference*)Reference<Group, Player>::next(); }
+ GroupReference const* next() const { return (GroupReference const*)Reference<Group, Player>::next(); }
uint8 getSubGroup() const { return iSubGroup; }
void setSubGroup(uint8 pSubGroup) { iSubGroup = pSubGroup; }
};
diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp
index dfeb3f7cad9..b57e9970dab 100755
--- a/src/server/game/Guilds/Guild.cpp
+++ b/src/server/game/Guilds/Guild.cpp
@@ -2093,7 +2093,7 @@ bool Guild::AddMember(uint64 guid, uint8 rankId)
if (player->GetGuildId() != 0)
return false;
}
- else if (Player::GetGuildIdFromGuid(guid) != 0)
+ else if (Player::GetGuildIdFromDB(guid) != 0)
return false;
// Remove all player signs from another petitions
diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp
index 27eb559fb68..95204dfa353 100755
--- a/src/server/game/Handlers/AuctionHouseHandler.cpp
+++ b/src/server/game/Handlers/AuctionHouseHandler.cpp
@@ -161,7 +161,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket & recv_data)
etime *= MINUTE;
- switch(etime)
+ switch (etime)
{
case 1*MIN_AUCTION_TIME:
case 2*MIN_AUCTION_TIME:
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 887bebe5656..1c79b20ce81 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1868,9 +1868,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
case RACE_NIGHTELF:
stmt->setUInt16(1, 113);
break;
- case RACE_WORGEN:
- trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 791, 300, 300)", lowGuid);
- break;
+ case RACE_WORGEN:
+ stmt->setUInt16(1, 791);
+ break;
case RACE_UNDEAD_PLAYER:
stmt->setUInt16(1, 673);
break;
@@ -1883,9 +1883,9 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recv_data)
case RACE_BLOODELF:
stmt->setUInt16(1, 137);
break;
- case RACE_GOBLIN:
- trans->PAppend("INSERT INTO `character_skills` (guid, skill, value, max) VALUES (%u, 792, 300, 300)", lowGuid);
- break;
+ case RACE_GOBLIN:
+ stmt->setUInt16(1, 792);
+ break;
}
trans->Append(stmt);
diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp
index d725419ac84..eadc0958518 100755
--- a/src/server/game/Handlers/GroupHandler.cpp
+++ b/src/server/game/Handlers/GroupHandler.cpp
@@ -458,24 +458,20 @@ void WorldSession::HandleLootMethodOpcode(WorldPacket & recv_data)
group->SendUpdate();
}
-void WorldSession::HandleLootRoll(WorldPacket &recv_data)
+void WorldSession::HandleLootRoll(WorldPacket& recvData)
{
+ uint64 guid;
+ uint32 itemSlot;
+ uint8 rollType;
+ recvData >> guid; // guid of the item rolled
+ recvData >> itemSlot;
+ recvData >> rollType; // 0: pass, 1: need, 2: greed
+
Group* group = GetPlayer()->GetGroup();
if (!group)
- {
- recv_data.rfinish();
return;
- }
- uint64 Guid;
- uint32 NumberOfPlayers;
- uint8 rollType;
- recv_data >> Guid; //guid of the item rolled
- recv_data >> NumberOfPlayers;
- recv_data >> rollType; //0: pass, 1: need, 2: greed
-
- // everything's fine, do it
- group->CountRollVote(GetPlayer()->GetGUID(), Guid, NumberOfPlayers, rollType);
+ group->CountRollVote(GetPlayer()->GetGUID(), guid, rollType);
switch (rollType)
{
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index 2d85a4cb689..5baa54a2779 100755
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -1369,6 +1369,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recv_data)
_player->ToggleMetaGemsActive(slot, true); //turn on all metagems (except for target item)
+ _player->RemoveTradeableItem(itemTarget);
itemTarget->ClearSoulboundTradeable(_player); // clear tradeable flag
}
diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp
index 82afdfb9044..9c66ca44383 100755
--- a/src/server/game/Handlers/LFGHandler.cpp
+++ b/src/server/game/Handlers/LFGHandler.cpp
@@ -529,7 +529,7 @@ void WorldSession::SendLfgBootPlayer(const LfgPlayerBoot* pBoot)
}
sLog->outDebug(LOG_FILTER_NETWORKIO, "SMSG_LFG_BOOT_PROPOSAL_UPDATE [" UI64FMTD "] inProgress: %u - didVote: %u - agree: %u - victim: [" UI64FMTD "] votes: %u - agrees: %u - left: %u - needed: %u - reason %s",
guid, uint8(pBoot->inProgress), uint8(playerVote != LFG_ANSWER_PENDING), uint8(playerVote == LFG_ANSWER_AGREE), pBoot->victim, votesNum, agreeNum, secsleft, pBoot->votedNeeded, pBoot->reason.c_str());
- WorldPacket data(SMSG_LFG_BOOT_PLAYER, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length());
+ WorldPacket data(SMSG_LFG_BOOT_PROPOSAL_UPDATE, 1 + 1 + 1 + 8 + 4 + 4 + 4 + 4 + pBoot->reason.length());
data << uint8(pBoot->inProgress); // Vote in progress
data << uint8(playerVote != LFG_ANSWER_PENDING); // Did Vote
data << uint8(playerVote == LFG_ANSWER_AGREE); // Agree
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index 8e4b41a9be4..339c7a44d9f 100755
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -220,16 +220,18 @@ void WorldSession::HandleLootOpcode(WorldPacket & recv_data)
GetPlayer()->InterruptNonMeleeSpells(false);
}
-void WorldSession::HandleLootReleaseOpcode(WorldPacket & recv_data)
+void WorldSession::HandleLootReleaseOpcode(WorldPacket& recvData)
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_LOOT_RELEASE");
// cheaters can modify lguid to prevent correct apply loot release code and re-loot
// use internal stored guid
- recv_data.read_skip<uint64>(); // guid;
+ uint64 guid;
+ recvData >> guid;
if (uint64 lguid = GetPlayer()->GetLootGUID())
- DoLootRelease(lguid);
+ if (lguid == guid)
+ DoLootRelease(lguid);
}
void WorldSession::DoLootRelease(uint64 lguid)
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 988857558c9..ce056d2729c 100755
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -107,7 +107,7 @@ void WorldSession::HandleSendMail(WorldPacket & recv_data)
uint32 reqmoney = cost + money;
- if (!player->HasEnoughMoney(reqmoney))
+ if (!player->HasEnoughMoney(reqmoney) && !player->isGameMaster())
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
return;
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index 247db1975a4..46e40e16c08 100755
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -494,7 +494,7 @@ void WorldSession::HandleZoneUpdateOpcode(WorldPacket & recv_data)
uint32 newZone;
recv_data >> newZone;
- sLog->outDetail("WORLD: Recvd ZONE_UPDATE: %u", newZone);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Recvd ZONE_UPDATE: %u", newZone);
// use server size data
uint32 newzone, newarea;
@@ -737,7 +737,7 @@ void WorldSession::HandleBugOpcode(WorldPacket & recv_data)
void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RECLAIM_CORPSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RECLAIM_CORPSE");
uint64 guid;
recv_data >> guid;
@@ -774,7 +774,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket &recv_data)
void WorldSession::HandleResurrectResponseOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_RESURRECT_RESPONSE");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_RESURRECT_RESPONSE");
uint64 guid;
uint8 status;
@@ -945,7 +945,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recv_data)
void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_UPDATE_ACCOUNT_DATA");
uint32 type, timestamp, decompressedSize;
recv_data >> type >> timestamp >> decompressedSize;
@@ -1000,7 +1000,7 @@ void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)
void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_REQUEST_ACCOUNT_DATA");
uint32 type;
recv_data >> type;
@@ -1079,12 +1079,12 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data)
void WorldSession::HandleCompleteCinematic(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Player is watching cinema");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_COMPLETE_CINEMATIC");
}
void WorldSession::HandleNextCinematicCamera(WorldPacket & /*recv_data*/)
{
- sLog->outStaticDebug("WORLD: Which movie to play");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_NEXT_CINEMATIC_CAMERA");
}
void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
@@ -1127,7 +1127,7 @@ void WorldSession::HandleMoveTimeSkippedOpcode(WorldPacket & recv_data)
void WorldSession::HandleFeatherFallAck(WorldPacket &recv_data)
{
- sLog->outStaticDebug("WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_MOVE_FEATHER_FALL_ACK");
// no used
recv_data.rfinish(); // prevent warnings spam
@@ -1215,13 +1215,17 @@ void WorldSession::HandleInspectOpcode(WorldPacket& recv_data)
{
uint64 guid;
recv_data >> guid;
- sLog->outStaticDebug("Inspected guid is " UI64FMTD, guid);
+
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_INSPECT");
_player->SetSelection(guid);
Player* player = ObjectAccessor::FindPlayer(guid);
- if (!player) // wrong player
+ if (!player)
+ {
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_INSPECT: No player found from GUID: " UI64FMTD, guid);
return;
+ }
uint32 talent_points = 41;
WorldPacket data(SMSG_INSPECT_TALENT, 8 + 4 + 1 + 1 + talent_points + 8 + 4 + 8 + 4);
@@ -1256,7 +1260,7 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
if (!player)
{
- sLog->outError("InspectHonorStats: WTF, player not found...");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "MSG_INSPECT_HONOR_STATS: No player found from GUID: " UI64FMTD, guid);
return;
}
@@ -1270,10 +1274,6 @@ void WorldSession::HandleInspectHonorStatsOpcode(WorldPacket& recv_data)
void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
{
- // write in client console: worldport 469 452 6454 2536 180 or /console worldport 469 452 6454 2536 180
- // Received opcode CMSG_WORLD_TELEPORT
- // Time is ***, map=469, x=452.000000, y=6454.000000, z=2536.000000, orient=3.141593
-
uint32 time;
uint32 mapid;
float PositionX;
@@ -1288,20 +1288,20 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recv_data)
recv_data >> PositionZ;
recv_data >> Orientation; // o (3.141593 = 180 degrees)
- //sLog->outDebug("Received opcode CMSG_WORLD_TELEPORT");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_WORLD_TELEPORT");
+
if (GetPlayer()->isInFlight())
{
sLog->outDebug(LOG_FILTER_NETWORKIO, "Player '%s' (GUID: %u) in flight, ignore worldport command.", GetPlayer()->GetName(), GetPlayer()->GetGUIDLow());
return;
}
- sLog->outStaticDebug("Time %u sec, map=%u, x=%f, y=%f, z=%f, orient=%f", time/1000, mapid, PositionX, PositionY, PositionZ, Orientation);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_WORLD_TELEPORT: Player = %s, Time = %u, map = %u, x = %f, y = %f, z = %f, o = %f", GetPlayer()->GetName(), time, mapid, PositionX, PositionY, PositionZ, Orientation);
if (AccountMgr::IsAdminAccount(GetSecurity()))
GetPlayer()->TeleportTo(mapid, PositionX, PositionY, PositionZ, Orientation);
else
SendNotification(LANG_YOU_NOT_HAVE_PERMISSION);
- sLog->outDebug(LOG_FILTER_NETWORKIO, "Received worldport command from player %s", GetPlayer()->GetName());
}
void WorldSession::HandleWhoisOpcode(WorldPacket& recv_data)
diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp
index 40d63235af3..598dafb200a 100755
--- a/src/server/game/Handlers/MovementHandler.cpp
+++ b/src/server/game/Handlers/MovementHandler.cpp
@@ -193,7 +193,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)
sLog->outDebug(LOG_FILTER_NETWORKIO, "CMSG_MOVE_TELEPORT_ACK");
BitStream mask = recv_data.ReadBitStream(8);
-
+
uint32 flags, time;
recv_data >> flags >> time;
@@ -264,6 +264,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
// ignore, waiting processing in WorldSession::HandleMoveWorldportAckOpcode and WorldSession::HandleMoveTeleportAck
if (plrMover && plrMover->IsBeingTeleported())
{
+ recvData.rfinish(); // prevent warnings spam
return;
}
@@ -302,16 +303,42 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recvData)
}
// if we boarded a transport, add us to it
- if (plrMover && !plrMover->GetTransport())
+ if (plrMover)
{
- // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
- for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ if (!plrMover->GetTransport())
{
- if ((*iter)->GetGUID() == movementInfo.t_guid)
+ // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just dismount if the guid can be found in the transport list
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
{
- plrMover->m_transport = (*iter);
- (*iter)->AddPassenger(plrMover);
- break;
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+ }
+ else if (plrMover->GetTransport()->GetGUID() != movementInfo.t_guid)
+ {
+ bool foundNewTransport = false;
+ plrMover->m_transport->RemovePassenger(plrMover);
+ for (MapManager::TransportSet::const_iterator iter = sMapMgr->m_Transports.begin(); iter != sMapMgr->m_Transports.end(); ++iter)
+ {
+ if ((*iter)->GetGUID() == movementInfo.t_guid)
+ {
+ foundNewTransport = true;
+ plrMover->m_transport = *iter;
+ (*iter)->AddPassenger(plrMover);
+ break;
+ }
+ }
+
+ if (!foundNewTransport)
+ {
+ plrMover->m_transport = NULL;
+ movementInfo.t_pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
+ movementInfo.t_time = 0;
+ movementInfo.t_seat = -1;
}
}
}
@@ -971,4 +998,4 @@ void WorldSession::WriteMovementInfo(WorldPacket &data, MovementInfo* mi)
WPError(false, "Incorrect sequence element detected at ReadMovementInfo");
}
}
-} \ No newline at end of file
+}
diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp
index 5f7e4ce04a8..3660bfbfcc7 100755
--- a/src/server/game/Handlers/PetHandler.cpp
+++ b/src/server/game/Handlers/PetHandler.cpp
@@ -344,9 +344,11 @@ void WorldSession::HandlePetActionHelper(Unit* pet, uint64 guid1, uint16 spellid
if (unit_target2->GetTypeId() == TYPEID_PLAYER)
pet->SendUpdateToPlayer((Player*)unit_target2);
}
+
if (Unit* powner = pet->GetCharmerOrOwner())
if (powner->GetTypeId() == TYPEID_PLAYER)
- pet->SendUpdateToPlayer(powner->ToPlayer());
+ pet->SendUpdateToPlayer(powner->ToPlayer());
+
result = SPELL_CAST_OK;
}
@@ -738,7 +740,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket)
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp
index f0e681b535c..c22fc309770 100755
--- a/src/server/game/Handlers/QueryHandler.cpp
+++ b/src/server/game/Handlers/QueryHandler.cpp
@@ -113,7 +113,7 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName);
}
}
- sLog->outDetail("WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry);
// guess size
WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100);
data << uint32(entry); // creature entry
@@ -184,7 +184,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
ObjectMgr::GetLocaleString(gl->CastBarCaption, loc_idx, CastBarCaption);
}
}
- sLog->outDetail("WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_GAMEOBJECT_QUERY '%s' - Entry: %u. ", info->name.c_str(), entry);
WorldPacket data (SMSG_GAMEOBJECT_QUERY_RESPONSE, 150);
data << uint32(entry);
data << uint32(info->type);
@@ -215,7 +215,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket & recv_data)
void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)
{
- sLog->outDetail("WORLD: Received MSG_CORPSE_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_CORPSE_QUERY");
Corpse* corpse = GetPlayer()->GetCorpse();
@@ -270,7 +270,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
uint64 guid;
recv_data >> textID;
- sLog->outDetail("WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_NPC_TEXT_QUERY ID '%u'", textID);
recv_data >> guid;
GetPlayer()->SetSelection(guid);
@@ -350,7 +350,7 @@ void WorldSession::HandleNpcTextQueryOpcode(WorldPacket & recv_data)
/// Only _static_ data is sent in this packet !!!
void WorldSession::HandlePageTextQueryOpcode(WorldPacket & recv_data)
{
- sLog->outDetail("WORLD: Received CMSG_PAGE_TEXT_QUERY");
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PAGE_TEXT_QUERY");
uint32 pageID;
recv_data >> pageID;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index ccd2e178f88..2998b8a1c75 100755
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -324,7 +324,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
_player->AddQuest(nextQuest, object);
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
@@ -343,7 +343,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket & recv_data)
// Send next quest
if (Quest const* nextQuest = _player->GetNextQuest(guid, quest))
{
- if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(quest, true))
+ if (nextQuest->IsAutoAccept() && _player->CanAddQuest(nextQuest, true) && _player->CanTakeQuest(nextQuest, true))
{
_player->AddQuest(nextQuest, object);
if (_player->CanCompleteQuest(nextQuest->GetQuestId()))
@@ -496,10 +496,9 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recv_data)
if (!_player->CanInteractWithQuestGiver(object))
return;
- Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
- if (quest)
+ if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
- if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId)==QUEST_STATUS_NONE)
+ if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE)
{
sLog->outError("Possible hacking attempt: Player %s [playerGuid: %u] tried to complete questId [entry: %u] without being in possession of the questId!",
_player->GetName(), _player->GetGUIDLow(), questId);
diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp
index c56d86d11db..5823a38fb42 100755
--- a/src/server/game/Handlers/SpellHandler.cpp
+++ b/src/server/game/Handlers/SpellHandler.cpp
@@ -100,7 +100,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
return;
}
- sLog->outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, castCount: %u, spellId: %u, Item: %u, glyphIndex: %u, data length = %i", bagIndex, slot, castCount, spellId, pItem->GetEntry(), glyphIndex, (uint32)recvPacket.size());
ItemTemplate const* proto = pItem->GetTemplate();
if (!proto)
@@ -176,7 +176,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)
{
- sLog->outDetail("WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "WORLD: CMSG_OPEN_ITEM packet, data length = %i", (uint32)recvPacket.size());
Player* pUser = _player;
@@ -669,13 +669,16 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
recvPacket >> z;
Unit* caster = ObjectAccessor::GetUnit(*_player, casterGuid);
- Spell* spell = caster ? caster->FindCurrentSpellBySpellId(spellId) : NULL;
- if (spell && spell->m_targets.HasDst())
- {
- Position pos = *spell->m_targets.GetDstPos();
- pos.Relocate(x, y, z);
- spell->m_targets.ModDst(pos);
- }
+ if (!caster)
+ return;
+
+ Spell* spell = caster->FindCurrentSpellBySpellId(spellId);
+ if (!spell || !spell->m_targets.HasDst())
+ return;
+
+ Position pos = *spell->m_targets.GetDstPos();
+ pos.Relocate(x, y, z);
+ spell->m_targets.ModDst(pos);
WorldPacket data(SMSG_SET_PROJECTILE_POSITION, 21);
data << uint64(casterGuid);
@@ -683,5 +686,5 @@ void WorldSession::HandleUpdateProjectilePosition(WorldPacket& recvPacket)
data << float(x);
data << float(y);
data << float(z);
- SendPacket(&data);
+ caster->SendMessageToSet(&data, true);
}
diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp
index 8078a91d082..59bb86cb68e 100755
--- a/src/server/game/Instances/InstanceSaveMgr.cpp
+++ b/src/server/game/Instances/InstanceSaveMgr.cpp
@@ -543,7 +543,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId)
if (iMap && iMap->IsDungeon())
((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY);
- sObjectMgr->DeleteRespawnTimeForInstance(instanceId); // even if map is not loaded
+ if (iMap)
+ iMap->DeleteRespawnTimes();
+ else
+ Map::DeleteRespawnTimesInDB(mapid, instanceId);
// Free up the instance id and allow it to be reused
sMapMgr->FreeInstanceId(instanceId);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 2100eb26346..24338d5f0ad 100755
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -356,18 +356,14 @@ bool LootItem::AllowedForPlayer(Player const* player) const
if ((pProto->Flags2 & ITEM_FLAGS_EXTRA_ALLIANCE_ONLY) && player->GetTeam() != ALLIANCE)
return false;
- if (needs_quest)
- {
- // Checking quests for quest-only drop (check only quests requirements in this case)
- if (!player->HasQuestForItem(itemid))
- return false;
- }
- else
- {
- // Not quest only drop (check quest starting items for already accepted non-repeatable quests)
- if (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE && !player->HasQuestForItem(itemid))
- return false;
- }
+ // check quest requirements
+ if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid)))
+ if (Group const* group = player->GetGroup())
+ {
+ if (pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT || ((pProto->Flags & ITEM_PROTO_FLAG_PARTY_LOOT) == 0 && (group->GetLootMethod() != MASTER_LOOT || group->GetLooterGuid() != player->GetGUID())))
+ return false;
+ }
+ else return false;
return true;
}
@@ -483,7 +479,7 @@ void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting)
if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player))
if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid))
- if (proto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)
+ if (proto->IsCurrencyToken())
player->StoreLootItem(i, this);
}
}
@@ -899,6 +895,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
}
LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT;
+ LootSlotType partySlotType = lv.permission == MASTER_PERMISSION ? LOOT_SLOT_TYPE_MASTER : (lv.permission == GROUP_PERMISSION ? LOOT_SLOT_TYPE_ROLL_ONGOING : slotType);
QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems();
QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow());
if (q_itr != lootPlayerQuestItems.end())
@@ -911,7 +908,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(l.items.size() + (qi - q_list->begin()));
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
@@ -929,7 +929,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(fi->index);
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
@@ -947,7 +950,10 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv)
{
b << uint8(ci->index);
b << item;
- b << uint8(slotType);
+ if (!item.freeforall)
+ b << uint8(partySlotType);
+ else
+ b << uint8(slotType);
++itemsShown;
}
}
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 073ceae5b62..8df8feb6cac 100755
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -1230,7 +1230,7 @@ bool GridMap::loadLiquidData(FILE* in, uint32 offset, uint32 /*size*/)
return true;
}
-uint16 GridMap::getArea(float x, float y)
+uint16 GridMap::getArea(float x, float y) const
{
if (!_areaMap)
return _gridArea;
@@ -1463,7 +1463,7 @@ float GridMap::getHeightFromUint16(float x, float y) const
return (float)((a * x) + (b * y) + c)*_gridIntHeightMultiplier + _gridHeight;
}
-float GridMap::getLiquidLevel(float x, float y)
+float GridMap::getLiquidLevel(float x, float y) const
{
if (!_liquidMap)
return _liquidLevel;
@@ -1483,7 +1483,7 @@ float GridMap::getLiquidLevel(float x, float y)
}
// Why does this return LIQUID data?
-uint8 GridMap::getTerrainType(float x, float y)
+uint8 GridMap::getTerrainType(float x, float y) const
{
if (!_liquidFlags)
return 0;
@@ -2633,7 +2633,7 @@ void InstanceMap::UnloadAll()
ASSERT(!HavePlayers());
if (m_resetAfterUnload == true)
- sObjectMgr->DeleteRespawnTimeForInstance(GetInstanceId());
+ DeleteRespawnTimes();
Map::UnloadAll();
}
@@ -2782,3 +2782,134 @@ void Map::UpdateIteratorBack(Player* player)
if (m_mapRefIter == player->GetMapRef())
m_mapRefIter = m_mapRefIter->nocheck_prev();
}
+
+void Map::SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime)
+{
+ if (!respawnTime)
+ {
+ // Delete only
+ RemoveCreatureRespawnTime(dbGuid);
+ return;
+ }
+
+ _creatureRespawnTimes[dbGuid] = respawnTime;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CREATURE_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt32(1, uint32(respawnTime));
+ stmt->setUInt16(2, GetId());
+ stmt->setUInt32(3, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::RemoveCreatureRespawnTime(uint32 dbGuid)
+{
+ _creatureRespawnTimes.erase(dbGuid);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt16(1, GetId());
+ stmt->setUInt32(2, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::SaveGORespawnTime(uint32 dbGuid, time_t respawnTime)
+{
+ if (!respawnTime)
+ {
+ // Delete only
+ RemoveGORespawnTime(dbGuid);
+ return;
+ }
+
+ _goRespawnTimes[dbGuid] = respawnTime;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GO_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt32(1, uint32(respawnTime));
+ stmt->setUInt16(2, GetId());
+ stmt->setUInt32(3, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::RemoveGORespawnTime(uint32 dbGuid)
+{
+ _goRespawnTimes.erase(dbGuid);
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN);
+ stmt->setUInt32(0, dbGuid);
+ stmt->setUInt16(1, GetId());
+ stmt->setUInt32(2, GetInstanceId());
+ CharacterDatabase.Execute(stmt);
+}
+
+void Map::LoadRespawnTimes()
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CREATURE_RESPAWNS);
+ stmt->setUInt16(0, GetId());
+ stmt->setUInt32(1, GetInstanceId());
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 loguid = fields[0].GetUInt32();
+ uint32 respawnTime = fields[1].GetUInt32();
+
+ _creatureRespawnTimes[loguid] = time_t(respawnTime);
+ } while (result->NextRow());
+ }
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GO_RESPAWNS);
+ stmt->setUInt16(0, GetId());
+ stmt->setUInt32(1, GetInstanceId());
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 loguid = fields[0].GetUInt32();
+ uint32 respawnTime = fields[1].GetUInt32();
+
+ _goRespawnTimes[loguid] = time_t(respawnTime);
+ } while (result->NextRow());
+ }
+}
+
+void Map::DeleteRespawnTimes()
+{
+ _creatureRespawnTimes.clear();
+ _goRespawnTimes.clear();
+
+ DeleteRespawnTimesInDB(GetId(), GetInstanceId());
+}
+
+void Map::DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId)
+{
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE);
+ stmt->setUInt16(0, mapId);
+ stmt->setUInt32(1, instanceId);
+ CharacterDatabase.Execute(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GO_RESPAWN_BY_INSTANCE);
+ stmt->setUInt16(0, mapId);
+ stmt->setUInt32(1, instanceId);
+ CharacterDatabase.Execute(stmt);
+}
+
+time_t Map::GetLinkedRespawnTime(uint64 guid) const
+{
+ uint64 linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid);
+ switch (GUID_HIPART(linkedGuid))
+ {
+ case HIGHGUID_UNIT:
+ return GetCreatureRespawnTime(GUID_LOPART(linkedGuid));
+ case HIGHGUID_GAMEOBJECT:
+ return GetGORespawnTime(GUID_LOPART(linkedGuid));
+ default:
+ break;
+ }
+
+ return time_t(0);
+}
+
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 6ba08646f25..6d526f23a94 100755
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -193,10 +193,10 @@ public:
bool loadData(char* filaname);
void unloadData();
- uint16 getArea(float x, float y);
- inline float getHeight(float x, float y) {return (this->*_gridGetHeight)(x, y);}
- float getLiquidLevel(float x, float y);
- uint8 getTerrainType(float x, float y);
+ uint16 getArea(float x, float y) const;
+ inline float getHeight(float x, float y) const {return (this->*_gridGetHeight)(x, y);}
+ float getLiquidLevel(float x, float y) const;
+ uint8 getTerrainType(float x, float y) const;
ZLiquidStatus getLiquidStatus(float x, float y, float z, uint8 ReqLiquidType, LiquidData* data = 0);
};
@@ -443,6 +443,38 @@ class Map : public GridRefManager<NGridType>
void Insert(const GameObjectModel& mdl) { _dynamicTree.insert(mdl); }
bool Contains(const GameObjectModel& mdl) const { return _dynamicTree.contains(mdl);}
bool getObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float& rx, float &ry, float& rz, float modifyDist);
+
+ /*
+ RESPAWN TIMES
+ */
+ time_t GetLinkedRespawnTime(uint64 guid) const;
+ time_t GetCreatureRespawnTime(uint32 dbGuid) const
+ {
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _creatureRespawnTimes.find(dbGuid);
+ if (itr != _creatureRespawnTimes.end())
+ return itr->second;
+
+ return time_t(0);
+ }
+
+ time_t GetGORespawnTime(uint32 dbGuid) const
+ {
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t>::const_iterator itr = _goRespawnTimes.find(dbGuid);
+ if (itr != _goRespawnTimes.end())
+ return itr->second;
+
+ return time_t(0);
+ }
+
+ void SaveCreatureRespawnTime(uint32 dbGuid, time_t respawnTime);
+ void RemoveCreatureRespawnTime(uint32 dbGuid);
+ void SaveGORespawnTime(uint32 dbGuid, time_t respawnTime);
+ void RemoveGORespawnTime(uint32 dbGuid);
+ void LoadRespawnTimes();
+ void DeleteRespawnTimes();
+
+ static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId);
+
private:
void LoadMapAndVMap(int gx, int gy);
void LoadVMap(int gx, int gy);
@@ -488,6 +520,7 @@ class Map : public GridRefManager<NGridType>
void ScriptsProcess();
void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff);
+
protected:
void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); }
@@ -570,6 +603,9 @@ class Map : public GridRefManager<NGridType>
else
m_activeNonPlayers.erase(obj);
}
+
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _creatureRespawnTimes;
+ UNORDERED_MAP<uint32 /*dbGUID*/, time_t> _goRespawnTimes;
};
enum InstanceResetMethod
diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp
index 5543251e115..2c1bdb00834 100755
--- a/src/server/game/Maps/MapInstanced.cpp
+++ b/src/server/game/Maps/MapInstanced.cpp
@@ -211,6 +211,8 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save,
InstanceMap* map = new InstanceMap(GetId(), GetGridExpiry(), InstanceId, difficulty, this);
ASSERT(map->IsDungeon());
+ map->LoadRespawnTimes();
+
bool load_data = save != NULL;
map->CreateInstanceData(load_data);
diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp
index ce93fe5af1a..8736c8b3782 100755
--- a/src/server/game/Maps/MapManager.cpp
+++ b/src/server/game/Maps/MapManager.cpp
@@ -110,6 +110,7 @@ Map* MapManager::CreateBaseMap(uint32 id)
else
{
map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY);
+ map->LoadRespawnTimes();
}
i_maps[id] = map;
}
diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h
index 1049325237a..aa07eef2204 100755
--- a/src/server/game/Maps/MapManager.h
+++ b/src/server/game/Maps/MapManager.h
@@ -71,7 +71,7 @@ class MapManager
void SetMapUpdateInterval(uint32 t)
{
- if (t > MIN_MAP_UPDATE_DELAY)
+ if (t < MIN_MAP_UPDATE_DELAY)
t = MIN_MAP_UPDATE_DELAY;
i_timer.SetInterval(t);
@@ -143,7 +143,7 @@ class MapManager
void RegisterInstanceId(uint32 instanceId);
void FreeInstanceId(uint32 instanceId);
- uint32 GetNextInstanceId() { return _nextInstanceId; };
+ uint32 GetNextInstanceId() const { return _nextInstanceId; };
void SetNextInstanceId(uint32 nextInstanceId) { _nextInstanceId = nextInstanceId; };
MapUpdater * GetMapUpdater() { return &m_updater; }
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 7b77ecaa17e..7d12f94d155 100755
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -3279,8 +3279,6 @@ enum SummonType
enum EventId
{
- EVENT_SPELLCLICK = 1001,
- EVENT_FALL_GROUND = 1002,
EVENT_CHARGE = 1003,
};
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index c0e1eb842ae..bc0570bb73b 100755
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -298,7 +298,7 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z)
}
}
-void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
+void MotionMaster::MoveLand(uint32 id, Position const& pos)
{
float x, y, z;
pos.GetPosition(x, y, z);
@@ -307,13 +307,12 @@ void MotionMaster::MoveLand(uint32 id, Position const& pos, float speed)
Movement::MoveSplineInit init(*_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)
+void MotionMaster::MoveTakeoff(uint32 id, Position const& pos)
{
float x, y, z;
pos.GetPosition(x, y, z);
@@ -322,7 +321,6 @@ void MotionMaster::MoveTakeoff(uint32 id, Position const& pos, float speed)
Movement::MoveSplineInit init(*_owner);
init.MoveTo(x,y,z);
- init.SetVelocity(speed);
init.SetAnimation(Movement::ToFly);
init.Launch();
Mutate(new EffectMovementGenerator(id), MOTION_SLOT_ACTIVE);
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index d6144bfcc3a..727f626cdea 100755
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -157,8 +157,8 @@ class MotionMaster //: private std::stack<MovementGenerator *>
void MovePoint(uint32 id, float x, float y, float z);
// These two movement types should only be used with creatures having landing/takeoff animations
- void MoveLand(uint32 id, Position const& pos, float speed);
- void MoveTakeoff(uint32 id, Position const& pos, float speed);
+ void MoveLand(uint32 id, Position const& pos);
+ void MoveTakeoff(uint32 id, Position const& pos);
void MoveCharge(float x, float y, float z, float speed = SPEED_CHARGE, uint32 id = EVENT_CHARGE);
void MoveKnockbackFrom(float srcX, float srcY, float speedXY, float speedZ);
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
index a922c937b5f..07a5761517e 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp
@@ -33,6 +33,7 @@ void PointMovementGenerator<T>::Initialize(T &unit)
unit.StopMoving();
unit.AddUnitState(UNIT_STATE_ROAMING|UNIT_STATE_ROAMING_MOVE);
+ i_recalculateSpeed = false;
Movement::MoveSplineInit init(unit);
init.MoveTo(i_x, i_y, i_z);
if (speed > 0.0f)
@@ -53,6 +54,17 @@ bool PointMovementGenerator<T>::Update(T &unit, const uint32 & /*diff*/)
}
unit.AddUnitState(UNIT_STATE_ROAMING_MOVE);
+
+ if (i_recalculateSpeed && !unit.movespline->Finalized())
+ {
+ i_recalculateSpeed = false;
+ Movement::MoveSplineInit init(unit);
+ init.MoveTo(i_x, i_y, i_z);
+ if (speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit
+ init.SetVelocity(speed);
+ init.Launch();
+ }
+
return !unit.movespline->Finalized();
}
@@ -81,11 +93,6 @@ 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);
- //}
if (unit.AI())
unit.AI()->MovementInform(POINT_MOTION_TYPE, id);
}
diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
index 13be9fee77b..d2833a5ee10 100755
--- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
+++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h
@@ -36,6 +36,8 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG
void MovementInform(T &);
+ void unitSpeedChanged() { i_recalculateSpeed = true; }
+
MovementGeneratorType GetMovementGeneratorType() { return POINT_MOTION_TYPE; }
bool GetDestination(float& x, float& y, float& z) const { x=i_x; y=i_y; z=i_z; return true; }
@@ -43,6 +45,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG
uint32 id;
float i_x, i_y, i_z;
float speed;
+ bool i_recalculateSpeed;
};
class AssistanceMovementGenerator : public PointMovementGenerator<Creature>
diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp
index 91b4ff08250..b1c25aedfd7 100644
--- a/src/server/game/Movement/Spline/MoveSpline.cpp
+++ b/src/server/game/Movement/Spline/MoveSpline.cpp
@@ -203,7 +203,7 @@ bool MoveSplineInitArgs::Validate() const
return false;\
}
CHECK(path.size() > 1);
- CHECK(velocity > 0.f);
+ CHECK(velocity > 0.1f);
CHECK(time_perc >= 0.f && time_perc <= 1.f);
//CHECK(_checkPathBounds());
return true;
diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h
index 33973064e09..cfc2fdee450 100644
--- a/src/server/game/Movement/Spline/MoveSplineFlag.h
+++ b/src/server/game/Movement/Spline/MoveSplineFlag.h
@@ -34,43 +34,43 @@ namespace Movement
{
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,
+ None = 0x00000000,
+ // x00-xFF(first byte) used as animation Ids storage in pair with Animation flag
+ Done = 0x00000100,
+ Falling = 0x00000200, // Affects elevation computation, can't be combined with Parabolic flag
+ No_Spline = 0x00000400,
+ Parabolic = 0x00000800, // Affects elevation computation, can't be combined with Falling flag
+ Walkmode = 0x00001000,
+ Flying = 0x00002000, // Smooth movement(Catmullrom interpolation mode), flying animation
+ OrientationFixed = 0x00004000, // Model orientation fixed
+ Final_Point = 0x00008000,
+ Final_Target = 0x00010000,
+ Final_Angle = 0x00020000,
+ Catmullrom = 0x00040000, // Used Catmullrom interpolation mode
+ Cyclic = 0x00080000, // Movement by cycled spline
+ Enter_Cycle = 0x00100000, // Everytimes appears with cyclic flag in monster move packet, erases first spline vertex after first cycle done
+ Animation = 0x00200000, // Plays animation after some time passed
+ Frozen = 0x00400000, // Will never arrive
+ TransportEnter = 0x00800000,
+ TransportExit = 0x01000000,
+ Unknown7 = 0x02000000,
+ Unknown8 = 0x04000000,
OrientationInversed = 0x08000000,
- Unknown10 = 0x10000000,
- Unknown11 = 0x20000000,
- Unknown12 = 0x40000000,
- Unknown13 = 0x80000000,
+ Unknown10 = 0x10000000,
+ Unknown11 = 0x20000000,
+ Unknown12 = 0x40000000,
+ Unknown13 = 0x80000000,
// Masks
- Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
+ Mask_Final_Facing = Final_Point | Final_Target | Final_Angle,
// animation ids stored here, see AnimType enum, used with Animation flag
- Mask_Animations = 0xFF,
+ Mask_Animations = 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,
+ Mask_CatmullRom = Flying | Catmullrom,
// Unused, not suported flags
- Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown5|Unknown6|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,
+ Mask_Unused = No_Spline|Enter_Cycle|Frozen|Unknown7|Unknown8|Unknown10|Unknown11|Unknown12|Unknown13,
};
inline uint32& raw() { return (uint32&)*this;}
@@ -98,14 +98,16 @@ namespace Movement
void operator &= (uint32 f) { raw() &= f;}
void operator |= (uint32 f) { raw() |= f;}
- void EnableAnimation(uint8 anim) { raw() = (raw() & ~(Mask_Animations|Falling|Parabolic)) | Animation|anim;}
- void EnableParabolic() { raw() = (raw() & ~(Mask_Animations|Falling|Animation)) | Parabolic;}
- void EnableFalling() { raw() = (raw() & ~(Mask_Animations|Parabolic|Animation)) | Falling;}
+ 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;}
+ void EnableFacingPoint() { raw() = (raw() & ~Mask_Final_Facing) | Final_Point; }
+ void EnableFacingAngle() { raw() = (raw() & ~Mask_Final_Facing) | Final_Angle; }
+ void EnableFacingTarget() { raw() = (raw() & ~Mask_Final_Facing) | Final_Target; }
+ void EnableTransportEnter() { raw() = (raw() & ~TransportExit) | TransportEnter; }
+ void EnableTransportExit() { raw() = (raw() & ~TransportEnter) | TransportExit; }
uint8 animId : 8;
bool done : 1;
@@ -123,8 +125,8 @@ namespace Movement
bool enter_cycle : 1;
bool animation : 1;
bool frozen : 1;
- bool unknown5 : 1;
- bool unknown6 : 1;
+ bool transportEnter: 1;
+ bool transportExit : 1;
bool unknown7 : 1;
bool unknown8 : 1;
bool orientationInversed : 1;
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index e586cb4f4f9..c539dd3cc39 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -20,6 +20,8 @@
#include "MoveSpline.h"
#include "MovementPacketBuilder.h"
#include "Unit.h"
+#include "Transport.h"
+#include "Vehicle.h"
namespace Movement
{
@@ -58,17 +60,26 @@ namespace Movement
{
MoveSpline& move_spline = *unit.movespline;
- Location real_position(unit.GetPositionX(),unit.GetPositionY(),unit.GetPositionZMinusOffset(),unit.GetOrientation());
- // there is a big chane that current position is unknown if current state is not finalized, need compute it
+ bool transport = false;
+ Location real_position(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZMinusOffset(), unit.GetOrientation());
+ // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
+ if (unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID())
+ {
+ transport = true;
+ real_position.x = unit.GetTransOffsetX();
+ real_position.y = unit.GetTransOffsetY();
+ real_position.z = unit.GetTransOffsetZ();
+ real_position.orientation = unit.GetTransOffsetO();
+ }
+
+ // there is a big chance 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();
+ // should i do the things that user should do? - no.
if (args.path.empty())
- {
- // should i do the things that user should do?
- MoveTo(real_position);
- }
+ return;
// corrent first vertex
args.path[0] = real_position;
@@ -82,7 +93,7 @@ namespace Movement
moveFlags |= (MOVEMENTFLAG_SPLINE_ENABLED|MOVEMENTFLAG_FORWARD);
- if (args.velocity == 0.f)
+ if (!args.HasVelocity)
args.velocity = unit.GetSpeed(SelectSpeedType(moveFlags));
if (!args.Validate())
@@ -94,14 +105,22 @@ namespace Movement
unit.m_movementInfo.SetMovementFlags((MovementFlags)moveFlags);
move_spline.Initialize(args);
- WorldPacket data(SMSG_MONSTER_MOVE, 64);
+ WorldPacket data(!transport ? SMSG_MONSTER_MOVE : SMSG_MONSTER_MOVE_TRANSPORT, 64);
data.append(unit.GetPackGUID());
+ if (transport)
+ {
+ data.appendPackGUID(unit.GetTransGUID());
+ data << int8(unit.GetTransSeat());
+ }
+
PacketBuilder::WriteMonsterMove(move_spline, data);
unit.SendMessageToSet(&data,true);
}
MoveSplineInit::MoveSplineInit(Unit& m) : unit(m)
{
+ // Elevators also use MOVEMENTFLAG_ONTRANSPORT but we do not keep track of their position changes
+ args.TransformForTransport = unit.HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT) && unit.GetTransGUID();
// mix existing state into new
args.flags.walkmode = unit.m_movementInfo.HasMovementFlag(MOVEMENTFLAG_WALKING);
args.flags.flying = unit.m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY|MOVEMENTFLAG_DISABLE_GRAVITY));
@@ -110,13 +129,48 @@ namespace Movement
void MoveSplineInit::SetFacing(const Unit * target)
{
args.flags.EnableFacingTarget();
- //args.facing.target = target->GetObjectGuid().GetRawValue();
- args.facing.target = target->GetUInt64Value(OBJECT_FIELD_GUID);
+ args.facing.target = target->GetGUID();
}
void MoveSplineInit::SetFacing(float angle)
{
+ if (args.TransformForTransport)
+ {
+ if (Unit* vehicle = unit.GetVehicleBase())
+ angle -= vehicle->GetOrientation();
+ else if (Transport* transport = unit.GetTransport())
+ angle -= transport->GetOrientation();
+ }
+
args.facing.angle = G3D::wrap(angle, 0.f, (float)G3D::twoPi());
args.flags.EnableFacingAngle();
}
+
+ void MoveSplineInit::MoveTo(Vector3 const& dest)
+ {
+ args.path_Idx_offset = 0;
+ args.path.resize(2);
+ TransportPathTransform transform(unit, args.TransformForTransport);
+ args.path[1] = transform(dest);
+ }
+
+ Vector3 TransportPathTransform::operator()(Vector3 input)
+ {
+ if (_transformForTransport)
+ {
+ if (Unit* vehicle = _owner.GetVehicleBase())
+ {
+ input.x -= vehicle->GetPositionX();
+ input.y -= vehicle->GetPositionY();
+ input.z -= vehicle->GetPositionZMinusOffset();
+ }
+ else if (Transport* transport = _owner.GetTransport())
+ {
+ float unused = 0.0f;
+ transport->CalculatePassengerOffset(input.x, input.y, input.z, unused);
+ }
+ }
+
+ return input;
+ }
}
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h
index 7ef6cd7a120..ef847809ac8 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.h
+++ b/src/server/game/Movement/Spline/MoveSplineInit.h
@@ -33,6 +33,19 @@ namespace Movement
FlyToGround = 3, // 463 = FlyToGround
};
+ // Transforms coordinates from global to transport offsets
+ class TransportPathTransform
+ {
+ public:
+ TransportPathTransform(Unit& owner, bool transformForTransport)
+ : _owner(owner), _transformForTransport(transformForTransport) { }
+ Vector3 operator()(Vector3 input);
+
+ private:
+ Unit& _owner;
+ bool _transformForTransport;
+ };
+
/* Initializes and launches spline movement
*/
class MoveSplineInit
@@ -96,6 +109,12 @@ namespace Movement
/* Enables falling mode. Disabled by default
*/
void SetFall();
+ /* Enters transport. Disabled by default
+ */
+ void SetTransportEnter();
+ /* Exits transport. Disabled by default
+ */
+ void SetTransportExit();
/* Inverses unit model orientation. Disabled by default
*/
void SetOrientationInversed();
@@ -112,40 +131,39 @@ namespace Movement
PointsArray& Path() { return args.path; }
+ /* Disables transport coordinate transformations for cases where raw offsets are available
+ */
+ void DisableTransportPathTransformations();
protected:
MoveSplineInitArgs args;
Unit& unit;
};
- inline void MoveSplineInit::SetFly() { args.flags.EnableFlying();}
+ 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::SetVelocity(float vel) { args.velocity = vel; args.HasVelocity = true; }
inline void MoveSplineInit::SetOrientationInversed() { args.flags.orientationInversed = true;}
+ inline void MoveSplineInit::SetTransportEnter() { args.flags.EnableTransportEnter(); }
+ inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); }
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());
+ args.path.resize(controls.size());
+ std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport));
}
inline void MoveSplineInit::MoveTo(float x, float y, float z)
{
- Vector3 v(x,y,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;
@@ -161,10 +179,14 @@ namespace Movement
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;
+ TransportPathTransform transform(unit, args.TransformForTransport);
+ Vector3 finalSpot = transform(spot);
+ args.facing.f.x = finalSpot.x;
+ args.facing.f.y = finalSpot.y;
+ args.facing.f.z = finalSpot.z;
args.flags.EnableFacingPoint();
}
+
+ inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; }
}
#endif // TRINITYSERVER_MOVESPLINEINIT_H
diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
index 26fbbdd0fcc..de02b35d0a0 100644
--- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h
+++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h
@@ -42,7 +42,8 @@ namespace Movement
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)
+ velocity(0.f), parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f),
+ HasVelocity(false), TransformForTransport(true)
{
path.reserve(path_capacity);
}
@@ -56,6 +57,8 @@ namespace Movement
float time_perc;
uint32 splineId;
float initialOrientation;
+ bool HasVelocity;
+ bool TransformForTransport;
/** Returns true to show that the arguments were configured correctly and MoveSpline initialization will succeed. */
bool Validate() const;
diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
index 0260767dbe2..8aef671d2d1 100644
--- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
+++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp
@@ -44,24 +44,12 @@ namespace Movement
void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, WorldPacket& data)
{
MoveSplineFlag splineflags = move_spline.splineflags;
- /*if (unit->HasUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT))
- {
- data.SetOpcode(SMSG_MONSTER_MOVE_TRANSPORT);
- if (unit->GetVehicle())
- data << unit->GetVehicle()->GetBase()->GetPackGUID();
- else if (unit->GetTransport())
- data << unit->GetTransport()->GetPackGUID();
- else
- data << uint64(0);
-
- data << int8(unit->GetTransSeat());
- }*/
- data << uint8(0);
+ data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40)
data << move_spline.spline.getPoint(move_spline.spline.first());
data << move_spline.GetId();
- switch(splineflags & MoveSplineFlag::Mask_Final_Facing)
+ switch (splineflags & MoveSplineFlag::Mask_Final_Facing)
{
case MoveSplineFlag::Final_Target:
data << uint8(MonsterMoveFacingTarget);
diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
index 465fca75030..dfdd4fc4ffc 100755
--- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp
@@ -166,8 +166,10 @@ bool OPvPCapturePoint::DelCreature(uint32 type)
//if (Map* map = sMapMgr->FindMap(cr->GetMapId()))
// map->Remove(cr, false);
// delete respawn time for this creature
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN_BY_GUID);
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN);
stmt->setUInt32(0, guid);
+ stmt->setUInt16(1, cr->GetMapId());
+ stmt->setUInt32(2, 0); // instance id, always 0 for world maps
CharacterDatabase.Execute(stmt);
cr->AddObjectToRemoveList();
diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp
index 26f4ad71cda..ff351f90f74 100755
--- a/src/server/game/Quests/QuestDef.cpp
+++ b/src/server/game/Quests/QuestDef.cpp
@@ -132,16 +132,16 @@ Quest::Quest(Field* questRecord)
ObjectiveText[i] = questRecord[128+i].GetString();
for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
- RewardCurrencyId[i] = questRecord[132+i].GetUInt32();
+ RewardCurrencyId[i] = questRecord[132+i].GetUInt16();
for (int i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
- RewardCurrencyCount[i] = questRecord[136+i].GetUInt32();
+ RewardCurrencyCount[i] = questRecord[136+i].GetUInt8();
for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
- RequiredCurrencyId[i] = questRecord[140+i].GetUInt32();
+ RequiredCurrencyId[i] = questRecord[140+i].GetUInt16();
for (int i = 0; i < QUEST_REQUIRED_CURRENCY_COUNT; ++i)
- RequiredCurrencyCount[i] = questRecord[144+i].GetUInt32();
+ RequiredCurrencyCount[i] = questRecord[144+i].GetUInt8();
QuestGiverTextWindow = questRecord[148].GetString();
QuestGiverTargetName = questRecord[149].GetString();
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index f64d0953e86..58b9c55cdd1 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -46,21 +46,27 @@ void AddSC_SmartSCripts();
//Commands
void AddSC_account_commandscript();
void AddSC_achievement_commandscript();
+void AddSC_cast_commandscript();
void AddSC_debug_commandscript();
void AddSC_event_commandscript();
void AddSC_gm_commandscript();
void AddSC_go_commandscript();
void AddSC_gobject_commandscript();
void AddSC_honor_commandscript();
+void AddSC_instance_commandscript();
void AddSC_learn_commandscript();
+void AddSC_list_commandscript();
void AddSC_misc_commandscript();
void AddSC_modify_commandscript();
void AddSC_npc_commandscript();
void AddSC_quest_commandscript();
void AddSC_reload_commandscript();
+void AddSC_reset_commandscript();
void AddSC_tele_commandscript();
+void AddSC_server_commandscript();
void AddSC_titles_commandscript();
void AddSC_wp_commandscript();
+void AddSC_character_commandscript();
#ifdef SCRIPTS
//world
@@ -648,21 +654,27 @@ void AddCommandScripts()
{
AddSC_account_commandscript();
AddSC_achievement_commandscript();
+ AddSC_cast_commandscript();
AddSC_debug_commandscript();
AddSC_event_commandscript();
AddSC_gm_commandscript();
AddSC_go_commandscript();
AddSC_gobject_commandscript();
AddSC_honor_commandscript();
+ AddSC_instance_commandscript();
AddSC_learn_commandscript();
+ AddSC_list_commandscript();
AddSC_misc_commandscript();
AddSC_modify_commandscript();
AddSC_npc_commandscript();
AddSC_quest_commandscript();
AddSC_reload_commandscript();
+ AddSC_reset_commandscript();
AddSC_tele_commandscript();
+ AddSC_server_commandscript();
AddSC_titles_commandscript();
AddSC_wp_commandscript();
+ AddSC_character_commandscript();
}
void AddWorldScripts()
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index bf701d41ec2..195dd9391bd 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -1041,7 +1041,6 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_LEARNED_DANCE_MOVES, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_LEVELUP_INFO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PLAYER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_LFG_BOOT_PROPOSAL_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_LFG_DISABLED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_LFG_JOIN_RESULT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1102,9 +1101,9 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_COLLISION_HEIGHT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVERING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_RUN_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1112,30 +1111,12 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_RUN_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_MODE, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleMovementOpcodes );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_TELEPORT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_MOVE_UPDATE_KNOCK_BACK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_MULTIPLE_PACKETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_NAME_QUERY_RESPONSE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
@@ -1297,16 +1278,32 @@ void InitOpcodes()
//DEFINE_OPCODE_HANDLER(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
- //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_COLLISION_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_DISABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_GRAVITY_ENABLE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_ROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FEATHER_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_LAND_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_NORMAL_FALL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_PITCH_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_RUN_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_SWIM_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_TURN_RATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_MODE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WALK_SPEED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_SET_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_START_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_STOP_SWIM, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+ //DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNROOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_FLYING, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_UNSET_HOVER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
//DEFINE_OPCODE_HANDLER(SMSG_SPLINE_MOVE_WATER_WALK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index 14f9687cdcd..4f6cda222e9 100755
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -792,7 +792,7 @@ enum Opcodes
SMSG_LEARNED_DANCE_MOVES = 0x0E05,
SMSG_LEARNED_SPELL = 0x58A2,
SMSG_LEVELUP_INFO = 0x0000,
- SMSG_LFG_BOOT_PLAYER = 0x0000,
+ SMSG_LFG_BOOT_PROPOSAL_UPDATE = 0x0000,
SMSG_LFG_DISABLED = 0x0000,
SMSG_LFG_JOIN_RESULT = 0x0000,
SMSG_LFG_OFFER_CONTINUE = 0x0000,
@@ -844,22 +844,21 @@ enum Opcodes
SMSG_MOUNTSPECIAL_ANIM = 0x0000,
SMSG_MOVE_DISABLE_COLLISION = 0x0000,
SMSG_MOVE_DISABLE_GRAVITY = 0x0000,
- SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,
SMSG_MOVE_ENABLE_COLLISION = 0x0000,
SMSG_MOVE_ENABLE_GRAVITY = 0x0000,
- SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,
+ SMSG_MOVE_FEATHER_FALL = 0x0000,
SMSG_MOVE_KNOCK_BACK = 0x0000,
+ SMSG_MOVE_LAND_WALK = 0x0000,
+ SMSG_MOVE_NORMAL_FALL = 0x0000,
SMSG_MOVE_ROOT = 0x0000,
SMSG_MOVE_SET_ACTIVE_MOVER = 0x0000,
SMSG_MOVE_SET_CAN_FLY = 0x0000,
+ SMSG_MOVE_SET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,
SMSG_MOVE_SET_COLLISION_HEIGHT = 0x0000,
SMSG_MOVE_SET_COMPOUND_STATE = 0x0000,
- SMSG_MOVE_SET_FEATHER_FALL = 0x0000,
SMSG_MOVE_SET_FLIGHT_BACK_SPEED = 0x0000,
SMSG_MOVE_SET_FLIGHT_SPEED = 0x0000,
- SMSG_MOVE_SET_HOVERING = 0x0000,
- SMSG_MOVE_SET_LAND_WALK = 0x0000,
- SMSG_MOVE_SET_NORMAL_FALL = 0x0000,
+ SMSG_MOVE_SET_HOVER = 0x0000,
SMSG_MOVE_SET_PITCH_RATE = 0x0000,
SMSG_MOVE_SET_RUN_BACK_SPEED = 0x0000,
SMSG_MOVE_SET_RUN_SPEED = 0x0000,
@@ -869,42 +868,16 @@ enum Opcodes
SMSG_MOVE_SET_VEHICLE_REC_ID = 0x0000,
SMSG_MOVE_SET_WALK_IN_AIR = 0x0000,
SMSG_MOVE_SET_WALK_SPEED = 0x0000,
- SMSG_MOVE_SET_WATER_WALK = 0x0000,
SMSG_MOVE_SKIP_TIME = 0x0000,
- SMSG_MOVE_SPLINE_DISABLE_COLLISION = 0x0000,
- SMSG_MOVE_SPLINE_DISABLE_GRAVITY = 0x0000,
- SMSG_MOVE_SPLINE_ENABLE_COLLISION = 0x0000,
- SMSG_MOVE_SPLINE_ENABLE_GRAVITY = 0x0000,
- SMSG_MOVE_SPLINE_ROOT = 0x0000,
- SMSG_MOVE_SPLINE_SET_FEATHER_FALL = 0x0000,
- SMSG_MOVE_SPLINE_SET_FLIGHT_BACK_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_FLIGHT_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_FLYING = 0x0000,
- SMSG_MOVE_SPLINE_SET_HOVER = 0x0000,
- SMSG_MOVE_SPLINE_SET_LAND_WALK = 0x0000,
- SMSG_MOVE_SPLINE_SET_NORMAL_FALL = 0x0000,
- SMSG_MOVE_SPLINE_SET_PITCH_RATE = 0x0000,
- SMSG_MOVE_SPLINE_SET_RUN_BACK_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_RUN_MODE = 0x0000,
- SMSG_MOVE_SPLINE_SET_RUN_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_SWIM_BACK_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_SWIM_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_TURN_RATE = 0x0000,
- SMSG_MOVE_SPLINE_SET_WALK_MODE = 0x0000,
- SMSG_MOVE_SPLINE_SET_WALK_SPEED = 0x0000,
- SMSG_MOVE_SPLINE_SET_WATER_WALK = 0x0000,
- SMSG_MOVE_SPLINE_START_SWIM = 0x0000,
- SMSG_MOVE_SPLINE_STOP_SWIM = 0x0000,
- SMSG_MOVE_SPLINE_UNROOT = 0x0000,
- SMSG_MOVE_SPLINE_UNSET_FLYING = 0x0000,
- SMSG_MOVE_SPLINE_UNSET_HOVER = 0x0000,
SMSG_MOVE_TELEPORT = 0x0000,
SMSG_MOVE_UNROOT = 0x0000,
SMSG_MOVE_UNSET_CAN_FLY = 0x0000,
- SMSG_MOVE_UNSET_HOVERING = 0x0000,
+ SMSG_MOVE_UNSET_CAN_TRANSITION_BETWEEN_SWIM_AND_FLY = 0x0000,
+ SMSG_MOVE_UNSET_HOVER = 0x0000,
SMSG_MOVE_UNSET_WALK_IN_AIR = 0x0000,
SMSG_MOVE_UPDATE_KNOCK_BACK = 0x0000,
SMSG_MOVE_UPDATE_TELEPORT = 0x0000,
+ SMSG_MOVE_WATER_WALK = 0x0000,
SMSG_MULTIPLE_PACKETS = 0x0000,
SMSG_NAME_QUERY_RESPONSE = 0x6E04,
SMSG_NEW_TAXI_PATH = 0x0000,
@@ -1046,6 +1019,33 @@ enum Opcodes
SMSG_SPELL_START = 0x6415,
SMSG_SPELL_UPDATE_CHAIN_TARGETS = 0x0000,
SMSG_SPIRIT_HEALER_CONFIRM = 0x0000,
+ SMSG_SPLINE_MOVE_COLLISION_DISABLE = 0x0000,
+ SMSG_SPLINE_MOVE_COLLISION_ENABLE = 0x0000,
+ SMSG_SPLINE_MOVE_GRAVITY_DISABLE = 0x0000,
+ SMSG_SPLINE_MOVE_GRAVITY_ENABLE = 0x0000,
+ SMSG_SPLINE_MOVE_ROOT = 0x0000,
+ SMSG_SPLINE_MOVE_SET_FEATHER_FALL = 0x0000,
+ SMSG_SPLINE_MOVE_SET_FLIGHT_BACK_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_FLIGHT_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_FLYING = 0x0000,
+ SMSG_SPLINE_MOVE_SET_HOVER = 0x0000,
+ SMSG_SPLINE_MOVE_SET_LAND_WALK = 0x0000,
+ SMSG_SPLINE_MOVE_SET_NORMAL_FALL = 0x0000,
+ SMSG_SPLINE_MOVE_SET_PITCH_RATE = 0x0000,
+ SMSG_SPLINE_MOVE_SET_RUN_BACK_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_RUN_MODE = 0x0000,
+ SMSG_SPLINE_MOVE_SET_RUN_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_SWIM_BACK_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_SWIM_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_TURN_RATE = 0x0000,
+ SMSG_SPLINE_MOVE_SET_WALK_MODE = 0x0000,
+ SMSG_SPLINE_MOVE_SET_WALK_SPEED = 0x0000,
+ SMSG_SPLINE_MOVE_SET_WATER_WALK = 0x0000,
+ SMSG_SPLINE_MOVE_START_SWIM = 0x0000,
+ SMSG_SPLINE_MOVE_STOP_SWIM = 0x0000,
+ SMSG_SPLINE_MOVE_UNROOT = 0x0000,
+ SMSG_SPLINE_MOVE_UNSET_FLYING = 0x0000,
+ SMSG_SPLINE_MOVE_UNSET_HOVER = 0x0000,
SMSG_STABLE_RESULT = 0x0000,
SMSG_STANDSTATE_UPDATE = 0x6F04,
SMSG_START_MIRROR_TIMER = 0x0000,
@@ -1112,7 +1112,7 @@ enum SessionStatus
STATUS_AUTHED = 0, // Player authenticated (_player == NULL, m_playerRecentlyLogout = false or will be reset before handler call, m_GUID have garbage)
STATUS_LOGGEDIN, // Player in game (_player != NULL, m_GUID == _player->GetGUID(), inWorld())
STATUS_TRANSFER, // Player transferring to another map (_player != NULL, m_GUID == _player->GetGUID(), !inWorld())
- STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player!= NULL or _player == NULL && m_playerRecentlyLogout, m_GUID store last _player guid)
+ STATUS_LOGGEDIN_OR_RECENTLY_LOGGOUT, // _player != NULL or _player == NULL && m_playerRecentlyLogout && m_playerLogout, m_GUID store last _player guid)
STATUS_NEVER, // Opcode not accepted from client (deprecated or server side only)
STATUS_UNHANDLED, // Opcode not handled yet
};
diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp
new file mode 100644
index 00000000000..cb6dcdbdb9e
--- /dev/null
+++ b/src/server/game/Server/Protocol/PacketLog.cpp
@@ -0,0 +1,62 @@
+/*
+ * 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/>.
+ */
+
+#include "PacketLog.h"
+#include "Config.h"
+#include "ByteBuffer.h"
+#include "WorldPacket.h"
+
+PacketLog::PacketLog() : _file(NULL)
+{
+ Initialize();
+}
+
+PacketLog::~PacketLog()
+{
+ if (_file)
+ fclose(_file);
+
+ _file = NULL;
+}
+
+void PacketLog::Initialize()
+{
+ std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
+
+ if (!logsDir.empty())
+ if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
+ logsDir.push_back('/');
+
+ std::string logname = ConfigMgr::GetStringDefault("PacketLogFile", "");
+ if (!logname.empty())
+ _file = fopen((logsDir + logname).c_str(), "wb");
+}
+
+void PacketLog::LogPacket(WorldPacket const& packet, Direction direction)
+{
+ ByteBuffer data(4+4+4+1+packet.size());
+ data << int32(packet.GetOpcode());
+ data << int32(packet.size());
+ data << uint32(time(NULL));
+ data << uint8(direction);
+
+ for (uint32 i = 0; i < packet.size(); i++)
+ data << const_cast<WorldPacket&>(packet)[i];
+
+ fwrite(data.contents(), 1, data.size(), _file);
+ fflush(_file);
+}
diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/PacketLog.h
index fb344f195de..b899daae198 100755..100644
--- a/src/server/game/Server/Protocol/WorldLog.h
+++ b/src/server/game/Server/Protocol/PacketLog.h
@@ -1,6 +1,5 @@
/*
* 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
@@ -16,46 +15,36 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/// \addtogroup u2w
-/// @{
-/// \file
-
-#ifndef TRINITY_WORLDLOG_H
-#define TRINITY_WORLDLOG_H
+#ifndef TRINITY_PACKETLOG_H
+#define TRINITY_PACKETLOG_H
#include "Common.h"
#include <ace/Singleton.h>
-#include "Errors.h"
-#include <stdarg.h>
+enum Direction
+{
+ CLIENT_TO_SERVER,
+ SERVER_TO_CLIENT
+};
+
+class WorldPacket;
-/// %Log packets to a file
-class WorldLog
+class PacketLog
{
- friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>;
+ friend class ACE_Singleton<PacketLog, ACE_Thread_Mutex>;
private:
- WorldLog();
- ~WorldLog();
- WorldLog(const WorldLog &);
- WorldLog& operator=(const WorldLog &);
- ACE_Thread_Mutex Lock;
+ PacketLog();
+ ~PacketLog();
public:
void Initialize();
- /// Is the world logger active?
- bool LogWorld(void) const { return (i_file != NULL); }
- /// %Log to the file
- void outLog(char const* fmt, ...);
- void outTimestampLog(char const* fmt, ...);
+ bool CanLogPacket() const { return (_file != NULL); }
+ void LogPacket(WorldPacket const& packet, Direction direction);
private:
- FILE* i_file;
-
- bool m_dbWorld;
+ FILE* _file;
};
-#define sWorldLog ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance()
+#define sPacketLog ACE_Singleton<PacketLog, ACE_Thread_Mutex>::instance()
#endif
-/// @}
-
diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp
deleted file mode 100755
index 38b13dff095..00000000000
--- a/src/server/game/Server/Protocol/WorldLog.cpp
+++ /dev/null
@@ -1,114 +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/>.
- */
-
-/** \file
- \ingroup u2w
-*/
-
-#include "WorldLog.h"
-#include "Config.h"
-#include "Log.h"
-#include "DatabaseWorkerPool.h"
-
-WorldLog::WorldLog() : i_file(NULL)
-{
- Initialize();
-}
-
-WorldLog::~WorldLog()
-{
- if (i_file != NULL)
- fclose(i_file);
-
- i_file = NULL;
-}
-
-/// Open the log file (if specified so in the configuration file)
-void WorldLog::Initialize()
-{
- std::string logsDir = ConfigMgr::GetStringDefault("LogsDir", "");
-
- if (!logsDir.empty())
- {
- if ((logsDir.at(logsDir.length()-1) != '/') && (logsDir.at(logsDir.length()-1) != '\\'))
- logsDir.push_back('/');
- }
-
- std::string logname = ConfigMgr::GetStringDefault("WorldLogFile", "");
- if (!logname.empty())
- {
- i_file = fopen((logsDir+logname).c_str(), "w");
- }
-
- m_dbWorld = ConfigMgr::GetBoolDefault("LogDB.World", false); // can be VERY heavy if enabled
-}
-
-void WorldLog::outTimestampLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- Log::outTimestamp(i_file);
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
-
-void WorldLog::outLog(char const* fmt, ...)
-{
- if (LogWorld())
- {
- TRINITY_GUARD(ACE_Thread_Mutex, Lock);
- ASSERT(i_file);
-
- va_list args;
- va_start(args, fmt);
- vfprintf(i_file, fmt, args);
- //fprintf(i_file, "\n");
- va_end(args);
-
- fflush(i_file);
- }
-
- if (sLog->GetLogDB() && m_dbWorld)
- {
- va_list ap2;
- va_start(ap2, fmt);
- char nnew_str[MAX_QUERY_LEN];
- vsnprintf(nnew_str, MAX_QUERY_LEN, fmt, ap2);
- sLog->outDB(LOG_TYPE_WORLD, nnew_str);
- va_end(ap2);
- }
-}
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 0f41ea1ca37..9b6eaaea6c3 100755
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -218,7 +218,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet)
/// Logging helper for unexpected opcodes
void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason)
{
- sLog->outError("SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION (account: %u, guidlow: %u, char: %s): received unexpected opcode %s (0x%.4X, status: %s) %s",
GetAccountId(), m_GUIDLow, _player ? _player->GetName() : "<none>",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), status, reason);
}
@@ -226,7 +226,7 @@ void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status,
/// Logging helper for unexpected opcodes
void WorldSession::LogUnprocessedTail(WorldPacket* packet)
{
- sLog->outError("SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
+ sLog->outDebug(LOG_FILTER_NETWORKIO, "SESSION: opcode %s (0x%.4X) have unprocessed tail data (read stop at %u from %u)",
LookupOpcodeName(packet->GetOpcode()), packet->GetOpcode(), uint32(packet->rpos()), uint32(packet->wpos()));
packet->print_storage();
}
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index c7c19eeeacd..c1d1cb5d53c 100755
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -333,7 +333,7 @@ class WorldSession
void LoadTutorialsData();
void SendTutorialsData();
void SaveTutorialsData(SQLTransaction& trans);
- uint32 GetTutorialInt(uint8 index) { return m_Tutorials[index]; }
+ uint32 GetTutorialInt(uint8 index) const { return m_Tutorials[index]; }
void SetTutorialInt(uint8 index, uint32 value)
{
if (m_Tutorials[index] != value)
@@ -400,8 +400,8 @@ class WorldSession
}
// Recruit-A-Friend Handling
- uint32 GetRecruiterId() { return recruiterId; }
- bool IsARecruiter() { return isRecruiter; }
+ uint32 GetRecruiterId() const { return recruiterId; }
+ bool IsARecruiter() const { return isRecruiter; }
public: // opcodes handlers
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 5f55ddbc254..c2a02d6f12c 100755
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -42,7 +42,7 @@
#include "WorldSession.h"
#include "WorldSocketMgr.h"
#include "Log.h"
-#include "WorldLog.h"
+#include "PacketLog.h"
#include "ScriptMgr.h"
#include "AccountMgr.h"
@@ -78,7 +78,7 @@ struct ServerPktHeader
return 2+(isLargePacket()?3:2);
}
- bool isLargePacket()
+ bool isLargePacket() const
{
return size > 0x7FFF;
}
@@ -152,7 +152,7 @@ const std::string& WorldSocket::GetRemoteAddress (void) const
return m_Address;
}
-int WorldSocket::SendPacket(const WorldPacket& pct)
+int WorldSocket::SendPacket(WorldPacket const& pct)
{
ACE_GUARD_RETURN (LockType, Guard, m_OutBufferLock, -1);
@@ -160,24 +160,8 @@ int WorldSocket::SendPacket(const WorldPacket& pct)
return -1;
// Dump outgoing packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("SERVER:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- pct.size(),
- LookupOpcodeName (pct.GetOpcode()),
- pct.GetOpcode());
-
- uint32 p = 0;
- while (p < pct.size())
- {
- for (uint32 j = 0; j < 16 && p < pct.size(); j++)
- sWorldLog->outLog("%.2X ", const_cast<WorldPacket&>(pct)[p++]);
-
- sWorldLog->outLog("\n");
- }
- sWorldLog->outLog("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(pct, SERVER_TO_CLIENT);
sLog->outOpCode(uint32(pct.GetOpcode()), LookupOpcodeName(pct.GetOpcode()), true);
@@ -668,7 +652,7 @@ int WorldSocket::schedule_wakeup_output (GuardType& g)
return 0;
}
-int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
+int WorldSocket::ProcessIncoming(WorldPacket* new_pct)
{
ACE_ASSERT (new_pct);
@@ -681,24 +665,8 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
return -1;
// Dump received packet.
- if (sWorldLog->LogWorld())
- {
- sWorldLog->outTimestampLog ("CLIENT:\nSOCKET: %u\nLENGTH: %u\nOPCODE: %s (0x%.4X)\nDATA:\n",
- (uint32) get_handle(),
- new_pct->size(),
- LookupOpcodeName (new_pct->GetOpcode()),
- new_pct->GetOpcode());
-
- uint32 p = 0;
- while (p < new_pct->size())
- {
- for (uint32 j = 0; j < 16 && p < new_pct->size(); j++)
- sWorldLog->outLog ("%.2X ", (*new_pct)[p++]);
-
- sWorldLog->outLog ("\n");
- }
- sWorldLog->outLog ("\n");
- }
+ if (sPacketLog->CanLogPacket())
+ sPacketLog->LogPacket(*new_pct, CLIENT_TO_SERVER);
sLog->outOpCode(uint32(Opcodes(opcode)), LookupOpcodeName(Opcodes(opcode)), false);
@@ -808,7 +776,7 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
LocaleConstant locale;
std::string account;
SHA1Hash sha;
- BigNumber v, s, g, N, k;
+ BigNumber k;
WorldPacket addonsData;
recvPacket.read_skip<uint32>();
@@ -891,21 +859,9 @@ int WorldSocket::HandleAuthSession(WorldPacket& recvPacket)
if (expansion > world_expansion)
expansion = world_expansion;
- N.SetHexStr("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7");
- g.SetDword(7);
-
- v.SetHexStr(fields[4].GetCString());
- s.SetHexStr(fields[5].GetCString());
-
- const char* sStr = s.AsHexStr(); //Must be freed by OPENSSL_free()
- const char* vStr = v.AsHexStr(); //Must be freed by OPENSSL_free()
-
sLog->outStaticDebug("WorldSocket::HandleAuthSession: (s,v) check s: %s v: %s",
- sStr,
- vStr);
-
- OPENSSL_free((void*) sStr);
- OPENSSL_free((void*) vStr);
+ fields[5].GetCString(),
+ fields[4].GetCString());
///- Re-check ip locking (same check as in realmd).
if (fields[3].GetUInt8() == 1) // if ip is locked
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index 7cff80cf6a0..7817e5e0d4d 100755
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -831,33 +831,18 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool create, bool load)
m_amplitude = 1 * IN_MILLISECONDS;
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_PERIODIC_ENERGIZE:
case SPELL_AURA_OBS_MOD_HEALTH:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
case SPELL_AURA_PERIODIC_LEECH:
case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
case SPELL_AURA_PERIODIC_MANA_LEECH:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
case SPELL_AURA_POWER_BURN:
- m_isPeriodic = true;
- break;
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- if (GetId() == 51912)
- m_amplitude = 3000;
- m_isPeriodic = true;
- break;
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
case SPELL_AURA_PERIODIC_DUMMY:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
m_isPeriodic = true;
break;
- case SPELL_AURA_DUMMY:
- // Haunting Spirits - perdiodic trigger demon
- if (GetId() == 7057)
- {
- m_isPeriodic = true;
- m_amplitude = irand (0, 60) + 30;
- m_amplitude *= IN_MILLISECONDS;
- }
- break;
default:
break;
}
@@ -1153,14 +1138,6 @@ void AuraEffect::UpdatePeriodic(Unit* caster)
{
switch (GetAuraType())
{
- case SPELL_AURA_DUMMY:
- // Haunting Spirits
- if (GetId() == 7057)
- {
- m_amplitude = irand (0, 60) + 30;
- m_amplitude *= IN_MILLISECONDS;
- }
- break;
case SPELL_AURA_PERIODIC_DUMMY:
switch (GetSpellInfo()->SpellFamilyName)
{
@@ -1362,11 +1339,6 @@ void AuraEffect::PeriodicTick(AuraApplication * aurApp, Unit* caster) const
case SPELL_AURA_POWER_BURN:
HandlePeriodicPowerBurnAuraTick(target, caster);
break;
- case SPELL_AURA_DUMMY:
- // Haunting Spirits
- if (GetId() == 7057)
- target->CastSpell((Unit*)NULL, GetAmount(), true);
- break;
default:
break;
}
@@ -3352,9 +3324,11 @@ void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const* aurApp,
{
target->SetCanFly(apply);
if (!apply)
+ {
target->RemoveUnitMovementFlag(MOVEMENTFLAG_FLYING);
target->AddUnitMovementFlag(MOVEMENTFLAG_FALLING);
target->m_movementInfo.SetFallTime(0);
+ }
Player* player = target->ToPlayer();
if (!player)
@@ -3431,41 +3405,244 @@ void AuraEffect::HandleModStateImmunityMask(AuraApplication const* aurApp, uint8
return;
Unit* target = aurApp->GetTarget();
+ std::list <AuraType> aura_immunity_list;
+ uint32 mechanic_immunity_list = 0;
+ int32 miscVal = GetMiscValue();
- std::list <AuraType> immunity_list;
- if (GetMiscValue() & (1<<10))
- immunity_list.push_back(SPELL_AURA_MOD_STUN);
- if (GetMiscValue() & (1<<1))
- immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ switch (miscVal)
+ {
+ case 96:
+ case 1615:
+ {
+ if (GetAmount())
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 679:
+ {
+ if (GetId() == 57742)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 1557:
+ {
+ if (GetId() == 64187)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_STUN);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ }
+ else
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 1614:
+ case 1694:
+ {
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT);
+ break;
+ }
+ case 1630:
+ {
+ if (!GetAmount())
+ {
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_ATTACK_ME, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_TAUNT);
+ }
+ else
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 477:
+ case 1733:
+ {
+ if (!GetAmount())
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_ROOT)
+ | (1 << MECHANIC_FEAR) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_SLEEP) | (1 << MECHANIC_CHARM)
+ | (1 << MECHANIC_SAPPED) | (1 << MECHANIC_HORROR)
+ | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_DISORIENTED)
+ | (1 << MECHANIC_FREEZE) | (1 << MECHANIC_TURN);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_ROOT, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FEAR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SLEEP, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_CHARM, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SAPPED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_HORROR, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_TURN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ }
+ break;
+ }
+ case 878:
+ {
+ if (GetAmount() == 1)
+ {
+ mechanic_immunity_list = (1 << MECHANIC_SNARE) | (1 << MECHANIC_STUN)
+ | (1 << MECHANIC_DISORIENTED) | (1 << MECHANIC_FREEZE);
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_SNARE, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_STUN, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_DISORIENTED, apply);
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, MECHANIC_FREEZE, apply);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ }
+ break;
+ }
+ default:
+ break;
+ }
- // These flag can be recognized wrong:
- if (GetMiscValue() & (1<<6))
- immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
- if (GetMiscValue() & (1<<0))
- immunity_list.push_back(SPELL_AURA_MOD_ROOT);
- if (GetMiscValue() & (1<<2))
- immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
- if (GetMiscValue() & (1<<9))
- immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ if (aura_immunity_list.empty())
+ {
+ if (miscVal & (1<<10))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ if (miscVal & (1<<1))
+ aura_immunity_list.push_back(SPELL_AURA_TRANSFORM);
- // an exception for Bladestorm
- if ((GetMiscValue() & (1<<7)) && (GetId() != 46924))
- immunity_list.push_back(SPELL_AURA_MOD_DISARM);
+ // These flag can be recognized wrong:
+ if (miscVal & (1<<6))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ if (miscVal & (1<<0))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ if (miscVal & (1<<2))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ if (miscVal & (1<<9))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+ if (miscVal & (1<<7))
+ aura_immunity_list.push_back(SPELL_AURA_MOD_DISARM);
+ }
// apply immunities
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
+ for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)
target->ApplySpellImmune(GetId(), IMMUNITY_STATE, *iter, apply);
- // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
- if (apply && GetId() == 46924)
- {
- target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
- target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
- }
-
if (apply && GetSpellInfo()->AttributesEx & SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY)
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
+ {
+ target->RemoveAurasWithMechanic(mechanic_immunity_list, AURA_REMOVE_BY_DEFAULT, GetId());
+ for (std::list <AuraType>::iterator iter = aura_immunity_list.begin(); iter != aura_immunity_list.end(); ++iter)
target->RemoveAurasByType(*iter);
+ }
}
void AuraEffect::HandleModMechanicImmunity(AuraApplication const* aurApp, uint8 mode, bool apply) const
@@ -4861,38 +5038,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
if (Unit* spellTarget = ObjectAccessor::GetUnit(*target, target->ToPlayer()->GetComboTarget()))
target->CastSpell(spellTarget, 51699, true);
break;
- case 28832: // Mark of Korth'azz
- case 28833: // Mark of Blaumeux
- case 28834: // Mark of Rivendare
- case 28835: // Mark of Zeliek
- if (caster) // actually we can also use cast(this, originalcasterguid)
- {
- int32 damage;
- switch (GetBase()->GetStackAmount())
- {
- case 1: damage = 0; break;
- case 2: damage = 500; break;
- case 3: damage = 1000; break;
- case 4: damage = 1500; break;
- case 5: damage = 4000; break;
- case 6: damage = 12000; break;
- default:damage = 20000 + 1000 * (GetBase()->GetStackAmount() - 7); break;
- }
- if (damage)
- caster->CastCustomSpell(28836, SPELLVALUE_BASE_POINT0, damage, target);
- }
- break;
- case 63322: // Saronite Vapors
- {
- if (caster)
- {
- int32 mana = int32(GetAmount() * pow(2.0f, GetBase()->GetStackAmount())); // mana restore - bp * 2^stackamount
- int32 damage = mana * 2; // damage
- caster->CastCustomSpell(target, 63337, &mana, NULL, NULL, true);
- caster->CastCustomSpell(target, 63338, &damage, NULL, NULL, true);
- }
- break;
- }
case 71563:
if (Aura* newAura = target->AddAura(71564, target))
newAura->SetStackAmount(newAura->GetSpellInfo()->StackAmount);
@@ -4986,57 +5131,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
}
break;
- case SPELLFAMILY_MAGE:
- // Living Bomb
- if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
- {
- AuraRemoveMode removeMode = aurApp->GetRemoveMode();
- if (caster && (removeMode == AURA_REMOVE_BY_ENEMY_SPELL || removeMode == AURA_REMOVE_BY_EXPIRE))
- caster->CastSpell(target, GetAmount(), true);
- }
- break;
- case SPELLFAMILY_PRIEST:
- // Vampiric Touch
- if (m_spellInfo->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && GetEffIndex() == 0)
- if (AuraEffect const* aurEff = GetBase()->GetEffect(1))
- {
- int32 damage = aurEff->GetAmount() * 8;
- // backfire damage
- target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL, GetCasterGUID());
- }
- break;
- case SPELLFAMILY_WARLOCK:
- // Haunt
- if (m_spellInfo->SpellFamilyFlags[1] & 0x40000)
- if (caster)
- target->CastCustomSpell(caster, 48210, &m_amount, 0, 0, true, NULL, this, GetCasterGUID());
- break;
- case SPELLFAMILY_DRUID:
- // Lifebloom
- if (GetSpellInfo()->SpellFamilyFlags[1] & 0x10)
- {
- // Final heal only on duration end
- if (aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
- return;
-
- // final heal
- int32 stack = GetBase()->GetStackAmount();
- int32 heal = m_amount;
- if (caster)
- {
- heal = caster->SpellHealingBonusDone(target, GetSpellInfo(), heal, HEAL, stack);
- heal = target->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, HEAL, stack);
- }
- target->CastCustomSpell(target, 33778, &heal, &stack, NULL, true, NULL, this, GetCasterGUID());
-
- // restore mana
- if (caster)
- {
- int32 returnmana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2;
- caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID());
- }
- }
- break;
case SPELLFAMILY_DEATHKNIGHT:
// Summon Gargoyle (Dismiss Gargoyle at remove)
if (GetId() == 61777)
@@ -5044,7 +5138,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
break;
case SPELLFAMILY_ROGUE:
// Tricks of the trade
- switch(GetId())
+ switch (GetId())
{
case 59628: //Tricks of the trade buff on rogue (6sec duration)
target->SetReducedThreatPercent(0,0);
@@ -5112,48 +5206,6 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
target->SetEntry(apply ? 17654 : 17326);
break;
}
- //Summon Fire Elemental
- case 40133:
- {
- if (!caster)
- break;
-
- Unit* owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- if (apply)
- owner->CastSpell(owner, 8985, true);
- else
- owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- }
- break;
- }
- //Summon Earth Elemental
- case 40132 :
- {
- if (!caster)
- break;
-
- Unit* owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- if (apply)
- owner->CastSpell(owner, 19704, true);
- else
- owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- }
- break;
- }
- case 57723: // Exhaustion
- case 57724: // Sated
- {
- switch (GetId())
- {
- case 57723: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 32182, apply); break; // Heroism
- case 57724: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 2825, apply); break; // Bloodlust
- }
- break;
- }
case 57819: // Argent Champion
case 57820: // Ebon Champion
case 57821: // Champion of the Kirin Tor
@@ -5246,69 +5298,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool
}
case SPELLFAMILY_DRUID:
{
- if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
- break;
- switch (GetId())
- {
- case 52610: // Savage Roar
- {
- uint32 spellId = 62071;
- if (apply)
- {
- if (target->GetShapeshiftForm() != FORM_CAT)
- break;
-
- target->CastSpell(target, spellId, true, NULL, NULL, GetCasterGUID());
- break;
- }
- target->RemoveAurasDueToSpell(spellId);
- break;
- }
- case 61336: // Survival Instincts
- {
- if (!(mode & AURA_EFFECT_HANDLE_REAL))
- break;
-
- if (apply)
- {
- if (!target->IsInFeralForm())
- break;
-
- int32 bp0 = int32(target->CountPctFromMaxHealth(GetAmount()));
- target->CastCustomSpell(target, 50322, &bp0, NULL, NULL, true);
- }
- else
- target->RemoveAurasDueToSpell(50322);
- break;
- }
- }
- // Predatory Strikes
- if (target->GetTypeId() == TYPEID_PLAYER && GetSpellInfo()->SpellIconID == 1563)
- {
- target->ToPlayer()->UpdateAttackPowerAndDamage();
- }
+ //if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ //break;
break;
}
case SPELLFAMILY_SHAMAN:
{
- if (!(mode & AURA_EFFECT_HANDLE_REAL))
- break;
- // Sentry Totem
- if (GetId() == 6495 && caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (apply)
- {
- if (uint64 guid = caster->m_SummonSlot[4])
- {
- if (Creature* totem = caster->GetMap()->GetCreature(guid))
- if (totem->isTotem())
- caster->ToPlayer()->CastSpell(totem, 6277, true);
- }
- }
- else
- caster->ToPlayer()->StopCastingBindSight();
- return;
- }
+ //if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ //break;
break;
}
case SPELLFAMILY_PALADIN:
@@ -5941,14 +5938,6 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster)
if (caster)
caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, int32(target->CountPctFromMaxHealth(21)), target, true, NULL, this);
return;
- // Detonate Mana
- case 27819:
- if (int32 mana = (int32)(target->GetMaxPower(POWER_MANA) / 10))
- {
- mana = target->ModifyPower(POWER_MANA, -mana);
- target->CastCustomSpell(27820, SPELLVALUE_BASE_POINT0, -mana*10, target, true, NULL, this);
- }
- return;
// Inoculate Nestlewood Owlkin
case 29528:
if (target->GetTypeId() != TYPEID_UNIT) // prevent error reports in case ignored player target
@@ -6613,33 +6602,6 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con
target->AddThreat(caster, float(gainedAmount) * 0.5f, GetSpellInfo()->GetSchoolMask(), GetSpellInfo());
}
- // spell-specific code
- switch (GetId())
- {
- case 31447: // Mark of Kaz'rogal
- if (target->GetPower(powerType) == 0)
- {
- target->CastSpell(target, 31463, true, 0, this);
- // Remove aura
- GetBase()->SetDuration(0);
- }
- break;
- case 32960: // Mark of Kazzak
- {
- int32 modifier = int32(target->GetPower(powerType) * 0.05f);
- target->ModifyPower(powerType, -modifier);
-
- if (target->GetPower(powerType) == 0)
- {
- target->CastSpell(target, 32961, true, 0, this);
- // Remove aura
- GetBase()->SetDuration(0);
- }
- break;
- }
- default:
- break;
- }
// Drain Mana
if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK
&& m_spellInfo->SpellFamilyFlags[0] & 0x00000010)
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 58c8ce5c558..6a8ac5d4eef 100755
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1236,19 +1236,6 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b
caster->CastCustomSpell(caster, 75999, &heal, NULL, NULL, true, NULL, GetEffect(0));
}
}
- // Renew
- else if (GetSpellInfo()->SpellFamilyFlags[0] & 0x00000040 && GetEffect(0))
- {
- // Empowered Renew
- if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1))
- {
- uint32 damage = caster->SpellHealingBonusDone(target, GetSpellInfo(), GetEffect(0)->GetAmount(), HEAL);
- damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, HEAL);
-
- int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * int32(damage) / 100;
- caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
- }
- }
// Power Word: Shield
else if (m_spellInfo->SpellFamilyFlags[0] & 0x1 && m_spellInfo->SpellFamilyFlags[2] & 0x400 && GetEffect(0))
{
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index d833782bc76..54b3ae310e2 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -828,7 +828,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
break;
}
- switch(targetType.GetSelectionCategory())
+ switch (targetType.GetSelectionCategory())
{
case TARGET_SELECT_CATEGORY_CHANNEL:
SelectImplicitChannelTargets(effIndex, targetType);
@@ -846,7 +846,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
switch (targetType.GetObjectType())
{
case TARGET_OBJECT_TYPE_SRC:
- switch(targetType.GetReferenceType())
+ switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_CASTER:
m_targets.SetSrc(*m_caster);
@@ -857,7 +857,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
}
break;
case TARGET_OBJECT_TYPE_DEST:
- switch(targetType.GetReferenceType())
+ switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_CASTER:
SelectImplicitCasterDestTargets(effIndex, targetType);
@@ -874,7 +874,7 @@ void Spell::SelectEffectImplicitTargets(SpellEffIndex effIndex, SpellImplicitTar
}
break;
default:
- switch(targetType.GetReferenceType())
+ switch (targetType.GetReferenceType())
{
case TARGET_REFERENCE_TYPE_CASTER:
SelectImplicitCasterObjectTargets(effIndex, targetType);
@@ -915,17 +915,25 @@ void Spell::SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTa
switch (targetType.GetTarget())
{
case TARGET_UNIT_CHANNEL_TARGET:
+ {
+ WorldObject* target = ObjectAccessor::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID());
+ CallScriptObjectTargetSelectHandlers(target, effIndex);
// unit target may be no longer avalible - teleported out of map for example
- if (Unit* target = Unit::GetUnit(*m_caster, channeledSpell->m_targets.GetUnitTargetGUID()))
- AddUnitTarget(target, 1 << effIndex);
+ if (target && target->ToUnit())
+ AddUnitTarget(target->ToUnit(), 1 << effIndex);
else
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell target for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
break;
+ }
case TARGET_DEST_CHANNEL_TARGET:
if (channeledSpell->m_targets.HasDst())
m_targets.SetDst(channeledSpell->m_targets);
else if (WorldObject* target = ObjectAccessor::GetWorldObject(*m_caster, channeledSpell->m_targets.GetObjectTargetGUID()))
- m_targets.SetDst(*target);
+ {
+ CallScriptObjectTargetSelectHandlers(target, effIndex);
+ if (target)
+ m_targets.SetDst(*target);
+ }
else
sLog->outDebug(LOG_FILTER_SPELLS_AURAS, "SPELL: cannot find channel spell destination for spell ID %u, effect %u", m_spellInfo->Id, effIndex);
break;
@@ -1003,6 +1011,8 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
return;
}
+ CallScriptObjectTargetSelectHandlers(target, effIndex);
+
switch (targetType.GetObjectType())
{
case TARGET_OBJECT_TYPE_UNIT:
@@ -1042,7 +1052,9 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
{
Trinity::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
- SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, radius);
+ SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
+
+ CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
if (!targets.empty())
{
@@ -1070,8 +1082,6 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
gObjTargets.push_back(gObjTarget);
}
- CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
-
for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
AddUnitTarget(*itr, effMask, false);
@@ -1206,6 +1216,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
default:
break;
}
+
+ CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
+
std::list<Unit*> unitTargets;
std::list<GameObject*> gObjTargets;
// for compability with older code - add only unit and go targets
@@ -1287,18 +1300,6 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth
power = POWER_HEALTH;
}
- else if (m_spellInfo->SpellFamilyFlags[2] == 0x0100) // Starfall
- {
- // Remove targets not in LoS or in stealth
- for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end();)
- {
- if ((*itr)->HasStealthAura() || (*itr)->HasInvisibilityAura() || !(*itr)->IsWithinLOSInMap(m_caster))
- itr = unitTargets.erase(itr);
- else
- ++itr;
- }
- break;
- }
else
break;
@@ -1339,6 +1340,11 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
}
}
+ // todo: move to scripts, but we must call it before resize list by MaxAffectedTargets
+ // Intimidating Shout
+ if (m_spellInfo->Id == 5246 && effIndex != EFFECT_0)
+ unitTargets.remove(m_targets.GetUnitTarget());
+
// Other special target selection goes here
if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
{
@@ -1347,13 +1353,9 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
if ((*j)->IsAffectingSpell(m_spellInfo))
maxTargets += (*j)->GetAmount();
- if (m_spellInfo->Id == 5246) //Intimidating Shout
- unitTargets.remove(m_targets.GetUnitTarget());
Trinity::Containers::RandomResizeList(unitTargets, maxTargets);
}
- CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
-
for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
AddUnitTarget(*itr, effMask, false);
}
@@ -1369,6 +1371,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
Trinity::Containers::RandomResizeList(gObjTargets, maxTargets);
}
+
for (std::list<GameObject*>::iterator itr = gObjTargets.begin(); itr != gObjTargets.end(); ++itr)
AddGOTarget(*itr, effMask);
}
@@ -1376,7 +1379,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge
void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
- switch(targetType.GetTarget())
+ switch (targetType.GetTarget())
{
case TARGET_DEST_CASTER:
m_targets.SetDst(*m_caster);
@@ -1441,7 +1444,7 @@ void Spell::SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplici
void Spell::SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
WorldObject* target = m_targets.GetObjectTarget();
- switch(targetType.GetTarget())
+ switch (targetType.GetTarget())
{
case TARGET_DEST_TARGET_ENEMY:
case TARGET_DEST_TARGET_ANY:
@@ -1474,7 +1477,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
if (!m_targets.HasDst())
m_targets.SetDst(*m_caster);
- switch(targetType.GetTarget())
+ switch (targetType.GetTarget())
{
case TARGET_DEST_DYNOBJ_ENEMY:
case TARGET_DEST_DYNOBJ_ALLY:
@@ -1500,27 +1503,27 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT
void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
- switch(targetType.GetTarget())
+ WorldObject* target = NULL;
+ bool checkIfValid = true;
+
+ switch (targetType.GetTarget())
{
case TARGET_UNIT_CASTER:
- AddUnitTarget(m_caster, 1 << effIndex, false);
+ target = m_caster;
+ checkIfValid = false;
break;
case TARGET_UNIT_MASTER:
- if (Unit* owner = m_caster->GetCharmerOrOwner())
- AddUnitTarget(owner, 1 << effIndex);
+ target = m_caster->GetCharmerOrOwner();
break;
case TARGET_UNIT_PET:
- if (Guardian* pet = m_caster->GetGuardianPet())
- AddUnitTarget(pet, 1 << effIndex);
+ target = m_caster->GetGuardianPet();
break;
case TARGET_UNIT_SUMMONER:
if (m_caster->isSummon())
- if (Unit* unit = m_caster->ToTempSummon()->GetSummoner())
- AddUnitTarget(unit, 1 << effIndex);
+ target = m_caster->ToTempSummon()->GetSummoner();
break;
case TARGET_UNIT_VEHICLE:
- if (Unit *vehicle = m_caster->GetVehicleBase())
- AddUnitTarget(vehicle, 1 << effIndex);
+ target = m_caster->GetVehicleBase();
break;
case TARGET_UNIT_PASSENGER_0:
case TARGET_UNIT_PASSENGER_1:
@@ -1531,26 +1534,38 @@ void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImpli
case TARGET_UNIT_PASSENGER_6:
case TARGET_UNIT_PASSENGER_7:
if (m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->IsVehicle())
- if (Unit *unit = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0))
- AddUnitTarget(unit, 1 << effIndex);
+ target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
break;
default:
break;
}
+
+ CallScriptObjectTargetSelectHandlers(target, effIndex);
+
+ if (target && target->ToUnit())
+ AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
}
void Spell::SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType)
{
ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
- if (Unit* unit = m_targets.GetUnitTarget())
- AddUnitTarget(unit, 1 << effIndex, true, false);
- else if (GameObject* gobj = m_targets.GetGOTarget())
- AddGOTarget(gobj, 1 << effIndex);
- else
- AddItemTarget(m_targets.GetItemTarget(), 1 << effIndex);
- if (WorldObject* target = m_targets.GetObjectTarget())
+ WorldObject* target = m_targets.GetObjectTarget();
+
+ CallScriptObjectTargetSelectHandlers(target, effIndex);
+
+ if (target)
+ {
+ if (Unit* unit = target->ToUnit())
+ AddUnitTarget(unit, 1 << effIndex, true, false);
+ else if (GameObject* gobj = target->ToGameObject())
+ AddGOTarget(gobj, 1 << effIndex);
+
SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
+ }
+ // Script hook can remove object target and we would wrongly land here
+ else if (Item* item = m_targets.GetItemTarget())
+ AddItemTarget(item, 1 << effIndex);
}
void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, WorldObject* target, uint32 effMask)
@@ -1571,14 +1586,15 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg
SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType()
, m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
+ // Chain primary target is added earlier
+ CallScriptObjectAreaTargetSelectHandlers(targets, effIndex);
+
// for backward compability
std::list<Unit*> unitTargets;
for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
if (Unit* unitTarget = (*itr)->ToUnit())
unitTargets.push_back(unitTarget);
- CallScriptAfterUnitTargetSelectHandlers(unitTargets, effIndex);
-
for (std::list<Unit*>::iterator itr = unitTargets.begin(); itr != unitTargets.end(); ++itr)
AddUnitTarget(*itr, effMask, false);
}
@@ -1741,9 +1757,12 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
case SPELL_EFFECT_SUMMON_PLAYER:
if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection())
{
- Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
- if (target)
- AddUnitTarget(target, 1 << effIndex, false);
+ WorldObject* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection());
+
+ CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex));
+
+ if (target && target->ToPlayer())
+ AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
}
return;
default:
@@ -1759,6 +1778,8 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
if (!targetMask)
return;
+ WorldObject* target = NULL;
+
switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
{
// add explicit object target or self to the target map
@@ -1767,40 +1788,46 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK))
{
if (Unit* unitTarget = m_targets.GetUnitTarget())
- AddUnitTarget(unitTarget, 1 << effIndex, false);
+ target = unitTarget;
else if (targetMask & TARGET_FLAG_CORPSE_MASK)
{
if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
{
// TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead
if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
- AddUnitTarget(owner, 1 << effIndex, false);
+ target = owner;
}
}
else //if (targetMask & TARGET_FLAG_UNIT_MASK)
- {
- AddUnitTarget(m_caster, 1 << effIndex, false);
- }
+ target = m_caster;
}
if (targetMask & TARGET_FLAG_ITEM_MASK)
{
if (Item* itemTarget = m_targets.GetItemTarget())
AddItemTarget(itemTarget, 1 << effIndex);
+ return;
}
if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
- {
- if (GameObject* gObjTarget = m_targets.GetGOTarget())
- AddGOTarget(gObjTarget, 1 << effIndex);
- }
+ target = m_targets.GetGOTarget();
break;
// add self to the target map
case EFFECT_IMPLICIT_TARGET_CASTER:
if (targetMask & TARGET_FLAG_UNIT_MASK)
- AddUnitTarget(m_caster, 1 << effIndex, false);
+ target = m_caster;
break;
default:
break;
}
+
+ CallScriptObjectTargetSelectHandlers(target, SpellEffIndex(effIndex));
+
+ if (target)
+ {
+ if (target->ToUnit())
+ AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
+ else if (target->ToGameObject())
+ AddGOTarget(target->ToGameObject(), 1 << effIndex);
+ }
}
uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList)
@@ -2474,12 +2501,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
}
- // Haunt
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1))
- {
- AuraEffect* aurEff = m_spellAura->GetEffect(1);
- aurEff->SetAmount(CalculatePctU(aurEff->GetAmount(), damageInfo.damage));
- }
+
m_damage = damageInfo.damage;
@@ -2548,12 +2570,31 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA
return SPELL_MISS_EVADE;
// For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
+ if (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo)))
+ return SPELL_MISS_IMMUNE;
+
// disable effects to which unit is immune
+ SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
- if (effectMask & (1 << effectNumber) && unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
- effectMask &= ~(1 << effectNumber);
- if (!effectMask || (m_spellInfo->Speed && (unit->IsImmunedToDamage(m_spellInfo) || unit->IsImmunedToSpell(m_spellInfo))))
- return SPELL_MISS_IMMUNE;
+ {
+ if (effectMask & (1 << effectNumber))
+ if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber))
+ effectMask &= ~(1 << effectNumber);
+ else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
+ {
+ int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
+ debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
+
+ if (debuff_resist_chance > 0)
+ if (irand(0,10000) <= (debuff_resist_chance * 100))
+ {
+ effectMask &= ~(1 << effectNumber);
+ returnVal = SPELL_MISS_RESIST;
+ }
+ }
+ }
+ if (!effectMask)
+ return returnVal;
PrepareScriptHitHandlers();
CallScriptBeforeHitHandlers();
@@ -3855,7 +3896,7 @@ void Spell::SendSpellStart()
data << uint8(0); // unkByte
// if (unkByte == 2)
// data.append(0);
-
+
}
m_caster->SendMessageToSet(&data, true);
@@ -3876,6 +3917,7 @@ void Spell::SendSpellGo()
castFlags |= CAST_FLAG_PENDING;
+
if ((m_caster->GetTypeId() == TYPEID_PLAYER ||
(m_caster->GetTypeId() == TYPEID_UNIT && m_caster->ToCreature()->isPet()))
&& m_spellInfo->PowerType != POWER_HEALTH)
@@ -4804,19 +4846,9 @@ SpellCastResult Spell::CheckCast(bool strict)
if (!(m_spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && VMAP::VMapFactory::checkSpellForLoS(m_spellInfo->Id) && !m_caster->IsWithinLOSInMap(target))
return SPELL_FAILED_LINE_OF_SIGHT;
}
- else
- {
- if (m_caster->GetTypeId() == TYPEID_PLAYER) // Target - is player caster
- {
- // Lay on Hands - cannot be self-cast on paladin with Forbearance or after using Avenging Wrath
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && m_spellInfo->SpellFamilyFlags[0] & 0x0008000)
- if (target->HasAura(61988)) // Immunity shield marker
- return SPELL_FAILED_TARGET_AURASTATE;
- }
- }
}
- //Check for line of sight for spells with dest
+ // Check for line of sight for spells with dest
if (m_targets.HasDst())
{
float x, y, z;
@@ -4915,7 +4947,9 @@ SpellCastResult Spell::CheckCast(bool strict)
bool hasDispellableAura = false;
bool hasNonDispelEffect = false;
- for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
+ uint32 dispelMask = 0;
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ {
if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
{
if (m_spellInfo->Effects[i].IsTargetingArea() || m_spellInfo->AttributesEx & SPELL_ATTR1_MELEE_COMBAT_START)
@@ -4923,28 +4957,28 @@ SpellCastResult Spell::CheckCast(bool strict)
hasDispellableAura = true;
break;
}
- if (Unit* target = m_targets.GetUnitTarget())
- {
- DispelChargesList dispelList;
- uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
- target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
- if (!dispelList.empty())
- {
- hasDispellableAura = true;
- break;
- }
- }
+
+ dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
}
else if (m_spellInfo->Effects[i].IsEffect())
{
hasNonDispelEffect = true;
break;
}
+ }
- if (!hasNonDispelEffect && !hasDispellableAura && m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL) && !IsTriggered())
- return SPELL_FAILED_NOTHING_TO_DISPEL;
+ if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
+ {
+ if (Unit* target = m_targets.GetUnitTarget())
+ {
+ DispelChargesList dispelList;
+ target->GetDispellableAuraList(m_caster, dispelMask, dispelList);
+ if (dispelList.empty())
+ return SPELL_FAILED_NOTHING_TO_DISPEL;
+ }
+ }
- for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
// for effects of spells that have only one target
switch (m_spellInfo->Effects[i].Effect)
@@ -5285,10 +5319,6 @@ SpellCastResult Spell::CheckCast(bool strict)
}
case SPELL_EFFECT_LEAP_BACK:
{
- // Spell 781 (Disengage) requires player to be in combat
- if (m_caster->GetTypeId() == TYPEID_PLAYER && m_spellInfo->Id == 781 && !m_caster->isInCombat())
- return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
-
if (m_caster->HasUnitState(UNIT_STATE_ROOT))
{
if (m_caster->GetTypeId() == TYPEID_PLAYER)
@@ -5310,66 +5340,10 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
- for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
switch (m_spellInfo->Effects[i].ApplyAuraName)
{
- case SPELL_AURA_DUMMY:
- {
- //custom check
- switch (m_spellInfo->Id)
- {
- // Tag Murloc
- case 30877:
- {
- Unit* target = m_targets.GetUnitTarget();
- if (!target || target->GetEntry() != 17326)
- return SPELL_FAILED_BAD_TARGETS;
- break;
- }
- case 61336:
- if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_caster->ToPlayer()->IsInFeralForm())
- return SPELL_FAILED_ONLY_SHAPESHIFT;
- break;
- case 1515:
- {
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return SPELL_FAILED_BAD_TARGETS;
-
- if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget()->GetTypeId() == TYPEID_PLAYER)
- return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
-
- Creature* target = m_targets.GetUnitTarget()->ToCreature();
-
- if (target->getLevel() > m_caster->getLevel())
- return SPELL_FAILED_HIGHLEVEL;
-
- // use SMSG_PET_TAME_FAILURE?
- if (!target->GetCreatureTemplate()->isTameable (m_caster->ToPlayer()->CanTameExoticPets()))
- return SPELL_FAILED_BAD_TARGETS;
-
- if (m_caster->GetPetGUID())
- return SPELL_FAILED_ALREADY_HAVE_SUMMON;
-
- if (m_caster->GetCharmGUID())
- return SPELL_FAILED_ALREADY_HAVE_CHARM;
-
- break;
- }
- case 44795: // Parachute
- {
- float x, y, z;
- m_caster->GetPosition(x, y, z);
- float ground_Z = m_caster->GetMap()->GetHeight(m_caster->GetPhaseMask(), x, y, z);
- if (fabs(ground_Z - z) < 0.1f)
- return SPELL_FAILED_DONT_REPORT;
- break;
- }
- default:
- break;
- }
- break;
- }
case SPELL_AURA_MOD_POSSESS_PET:
{
if (m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -7047,15 +7021,29 @@ void Spell::CallScriptAfterHitHandlers()
}
}
-void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex)
+void Spell::CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex)
{
for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
{
- (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT);
- std::list<SpellScript::UnitTargetHandler>::iterator hookItrEnd = (*scritr)->OnUnitTargetSelect.end(), hookItr = (*scritr)->OnUnitTargetSelect.begin();
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
+ std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
for (; hookItr != hookItrEnd; ++hookItr)
if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex))
- (*hookItr).Call(*scritr, unitTargets);
+ (*hookItr).Call(*scritr, targets);
+
+ (*scritr)->_FinishScriptCall();
+ }
+}
+
+void Spell::CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex)
+{
+ for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
+ {
+ (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
+ std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
+ for (; hookItr != hookItrEnd; ++hookItr)
+ if ((*hookItr).IsEffectAffected(m_spellInfo, effIndex))
+ (*hookItr).Call(*scritr, target);
(*scritr)->_FinishScriptCall();
}
@@ -7089,12 +7077,6 @@ void Spell::PrepareTriggersExecutedOnHit()
// todo: move this to scripts
switch (m_spellInfo->SpellFamilyName)
{
- case SPELLFAMILY_GENERIC:
- {
- if (m_spellInfo->Mechanic == MECHANIC_BANDAGE) // Bandages
- m_preCastSpell = 11196; // Recently Bandaged
- break;
- }
case SPELLFAMILY_MAGE:
{
// Permafrost
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 777d151440c..50510397056 100755
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -629,7 +629,8 @@ class Spell
void CallScriptBeforeHitHandlers();
void CallScriptOnHitHandlers();
void CallScriptAfterHitHandlers();
- void CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTargets, SpellEffIndex effIndex);
+ void CallScriptObjectAreaTargetSelectHandlers(std::list<WorldObject*>& targets, SpellEffIndex effIndex);
+ void CallScriptObjectTargetSelectHandlers(WorldObject*& target, SpellEffIndex effIndex);
std::list<SpellScript*> m_loadedScripts;
struct HitTriggerSpell
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index ca3c4197fc3..aba486b0df9 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -366,43 +366,6 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
return;
break;
}
- case 33671: // gruul's shatter
- case 50811: // krystallus shatter ( Normal )
- case 61547: // krystallus shatter ( Heroic )
- {
- // don't damage self and only players
- if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster);
- if (!radius)
- return;
- float distance = m_caster->GetDistance2d(unitTarget);
- damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * ((radius - distance)/radius));
- break;
- }
- // Loken Pulsing Shockwave
- case 59837:
- case 52942:
- {
- // don't damage self and only players
- if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- float radius = m_spellInfo->Effects[EFFECT_0].CalcRadius(m_caster);
- if (!radius)
- return;
- float distance = m_caster->GetDistance2d(unitTarget);
- damage = (distance > radius) ? 0 : int32(m_spellInfo->Effects[EFFECT_0].CalcValue(m_caster) * distance);
- break;
- }
- // TODO: add spell specific target requirement hook for spells
- // Shadowbolts only affects targets with Shadow Mark (Gothik)
- case 27831:
- case 55638:
- if (!unitTarget->HasAura(27825))
- return;
- break;
// Gargoyle Strike
case 51963:
{
@@ -415,11 +378,8 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex)
}
case SPELLFAMILY_WARRIOR:
{
- // Bloodthirst
- if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
- ApplyPctF(damage, m_caster->GetTotalAttackPowerValue(BASE_ATTACK));
// Shield Slam
- else if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209)
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x200 && m_spellInfo->Category == 1209)
{
uint8 level = m_caster->getLevel();
uint32 block_value = m_caster->GetShieldBlockValue(uint32(float(level) * 24.5f), uint32(float(level) * 34.5f));
@@ -2863,6 +2823,7 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex)
// add new enchanting if equipped
item_owner->ApplyEnchantment(itemTarget, PERM_ENCHANTMENT_SLOT, true);
+ item_owner->RemoveTradeableItem(itemTarget);
itemTarget->ClearSoulboundTradeable(item_owner);
}
}
@@ -2927,6 +2888,7 @@ void Spell::EffectEnchantItemPrismatic(SpellEffIndex effIndex)
// add new enchanting if equipped
item_owner->ApplyEnchantment(itemTarget, PRISMATIC_ENCHANTMENT_SLOT, true);
+ item_owner->RemoveTradeableItem(itemTarget);
itemTarget->ClearSoulboundTradeable(item_owner);
}
@@ -3275,6 +3237,14 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);
}
}
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x8000000) // Mocking Blow
+ {
+ if (unitTarget->IsImmunedToSpellEffect(m_spellInfo,EFFECT_1) || unitTarget->GetTypeId() == TYPEID_PLAYER)
+ {
+ m_damage = 0;
+ return;
+ }
+ }
break;
}
case SPELLFAMILY_ROGUE:
@@ -3375,7 +3345,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Blood Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
{
- AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f);
+ float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()) / 2.0f;
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
+ AddPctF(bonusPct, aurEff->GetAmount());
+ AddPctF(totalDamagePercentMod, bonusPct);
// Glyph of Blood Strike
if (m_caster->GetAuraEffect(59332, EFFECT_0))
@@ -3402,7 +3376,11 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
if (roll_chance_i(aurEff->GetAmount()))
consumeDiseases = false;
- AddPctF(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f);
+ float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID(), consumeDiseases) / 2.0f;
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
+ AddPctF(bonusPct, aurEff->GetAmount());
+ AddPctF(totalDamagePercentMod, bonusPct);
break;
}
// Blood-Caked Strike - Blood-Caked Blade
@@ -3414,7 +3392,12 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)
// Heart Strike
if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
{
- AddPctN(totalDamagePercentMod, m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID()));
+ float bonusPct = m_spellInfo->Effects[EFFECT_2].CalcValue() * unitTarget->GetDiseasesByCaster(m_caster->GetGUID());
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = m_caster->GetAuraEffect(64736, EFFECT_0))
+ AddPctF(bonusPct, aurEff->GetAmount());
+
+ AddPctF(totalDamagePercentMod, bonusPct);
break;
}
break;
@@ -3524,15 +3507,6 @@ void Spell::EffectHealMaxHealth(SpellEffIndex /*effIndex*/)
return;
int32 addhealth = 0;
- if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN) // Lay on Hands
- {
- if (m_caster->GetGUID() == unitTarget->GetGUID())
- {
- m_caster->CastSpell(m_caster, 25771, true); // Forbearance
- m_caster->CastSpell(m_caster, 61988, true); // Immune shield marker (serverside)
- m_caster->CastSpell(m_caster, 61987, true); // Avenging Wrath marker
- }
- }
// damage == 0 - heal for caster max health
if (damage == 0)
@@ -3763,12 +3737,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (!itemTarget && m_caster->GetTypeId() != TYPEID_PLAYER)
return;
- uint32 spell_id = 0;
- switch (urand(1, 5))
- {
- case 1: spell_id = 8854; break;
- default: spell_id = 8855; break;
- }
+ uint32 spell_id = roll_chance_i(20) ? 8854 : 8855;
m_caster->CastSpell(m_caster, spell_id, true, NULL);
return;
@@ -3815,10 +3784,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
unitTarget->HandleEmoteCommand(EMOTE_STATE_DANCE);
return;
}
- // Escape artist
- case 20589:
- m_caster->RemoveMovementImpairingAuras();
- return;
// Decimate
case 28374:
case 54426:
@@ -3849,15 +3814,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
DoCreateItem(effIndex, item);
break;
}
- // Improved Sprint
- case 30918:
- {
- // Removes snares and roots.
- unitTarget->RemoveMovementImpairingAuras();
- break;
- }
- // Spirit Walk
- case 58876:
+ case 20589: // Escape artist
+ case 30918: // Improved Sprint
{
// Removes snares and roots.
unitTarget->RemoveMovementImpairingAuras();
@@ -3875,96 +3833,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
}
}
break;
- case 48025: // Headless Horseman's Mount
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = true;
- uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId());
- if (v_map != 530 && v_map != 571)
- canFly = false;
-
- if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197))
- canFly = false;
-
- float x, y, z;
- unitTarget->GetPosition(x, y, z);
- uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag);
- if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING))
- {
- case 75: unitTarget->CastSpell(unitTarget, 51621, true); break;
- case 150: unitTarget->CastSpell(unitTarget, 48024, true); break;
- case 225:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 51617, true);
- else
- unitTarget->CastSpell(unitTarget, 48024, true);
- }break;
- case 300:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 48023, true);
- else
- unitTarget->CastSpell(unitTarget, 48024, true);
- }break;
- }
- return;
- }
- case 47977: // Magic Broom
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = true;
- uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId());
- if (v_map != 530 && v_map != 571)
- canFly = false;
-
- if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197))
- canFly = false;
-
- float x, y, z;
- unitTarget->GetPosition(x, y, z);
- uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag);
- if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING))
- {
- case 75: unitTarget->CastSpell(unitTarget, 42680, true); break;
- case 150: unitTarget->CastSpell(unitTarget, 42683, true); break;
- case 225:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 42667, true);
- else
- unitTarget->CastSpell(unitTarget, 42683, true);
- }break;
- case 300:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 42668, true);
- else
- unitTarget->CastSpell(unitTarget, 42683, true);
- }break;
- }
- return;
- }
// Mug Transformation
case 41931:
{
@@ -4156,25 +4024,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (unitTarget)
unitTarget->CastSpell(m_caster, damage, true);
return;
- // Winged Steed of the Ebon Blade
- case 54729:
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill
- if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING))
- {
- if (skillval >= 300)
- unitTarget->CastSpell(unitTarget, 54727, true);
- else
- unitTarget->CastSpell(unitTarget, 54726, true);
- }
- return;
- }
case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
{
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT || m_caster->GetTypeId() != TYPEID_PLAYER)
@@ -4257,188 +4106,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
m_caster->CastSpell(m_caster, 63919, true);
return;
}
- case 71342: // Big Love Rocket
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = true;
- uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId());
- if (v_map != 530 && v_map != 571)
- canFly = false;
-
- if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197))
- canFly = false;
-
- float x, y, z;
- unitTarget->GetPosition(x, y, z);
- uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag);
- if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING))
- {
- case 0: unitTarget->CastSpell(unitTarget, 71343, true); break;
- case 75: unitTarget->CastSpell(unitTarget, 71344, true); break;
- case 150: unitTarget->CastSpell(unitTarget, 71345, true); break;
- case 225:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 71346, true);
- else
- unitTarget->CastSpell(unitTarget, 71345, true);
- }break;
- case 300:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 71347, true);
- else
- unitTarget->CastSpell(unitTarget, 71345, true);
- }break;
- }
- return;
- }
- case 72286: // Invincible
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = true;
- uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId());
- if (v_map != 530 && v_map != 571)
- canFly = false;
-
- if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197))
- canFly = false;
-
- float x, y, z;
- unitTarget->GetPosition(x, y, z);
- uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag);
- if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING))
- {
- case 75: unitTarget->CastSpell(unitTarget, 72281, true); break;
- case 150: unitTarget->CastSpell(unitTarget, 72282, true); break;
- case 225:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 72283, true);
- else
- unitTarget->CastSpell(unitTarget, 72282, true);
- }break;
- case 300:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 72284, true);
- else
- unitTarget->CastSpell(unitTarget, 72282, true);
- }break;
- }
- return;
- }
- case 74856: // Blazing Hippogryph
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill
- if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING))
- {
- if (skillval >= 300)
- unitTarget->CastSpell(unitTarget, 74855, true);
- else
- unitTarget->CastSpell(unitTarget, 74854, true);
- }
- return;
- }
- case 75614: // Celestial Steed
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts and client crashes upon dismounting
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill and zone
- bool canFly = true;
- uint32 v_map = GetVirtualMapForMapAndZone(unitTarget->GetMapId(), unitTarget->GetZoneId());
- if (v_map != 530 && v_map != 571)
- canFly = false;
-
- if (canFly && v_map == 571 && !unitTarget->ToPlayer()->HasSpell(54197))
- canFly = false;
-
- float x, y, z;
- unitTarget->GetPosition(x, y, z);
- uint32 areaFlag = unitTarget->GetBaseMap()->GetAreaFlag(x, y, z);
- AreaTableEntry const* pArea = sAreaStore.LookupEntry(areaFlag);
- if (!pArea || (canFly && (pArea->flags & AREA_FLAG_NO_FLY_ZONE)))
- canFly = false;
-
- switch (unitTarget->ToPlayer()->GetBaseSkillValue(SKILL_RIDING))
- {
- case 75: unitTarget->CastSpell(unitTarget, 75619, true); break;
- case 150: unitTarget->CastSpell(unitTarget, 75620, true); break;
- case 225:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 75617, true);
- else
- unitTarget->CastSpell(unitTarget, 75620, true);
- }
- break;
- case 300:
- {
- if (canFly)
- unitTarget->CastSpell(unitTarget, 75618, true);
- else
- unitTarget->CastSpell(unitTarget, 75620, true);
- }
- break;
- case 375:
- if (canFly)
- unitTarget->CastSpell(unitTarget, 76153, true);
- else
- unitTarget->CastSpell(unitTarget, 75620, true);
- break;
- }
- return;
- }
- case 75973: // X-53 Touring Rocket
- {
- if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Prevent stacking of mounts
- unitTarget->RemoveAurasByType(SPELL_AURA_MOUNTED);
-
- // Triggered spell id dependent on riding skill
- if (uint16 skillval = unitTarget->ToPlayer()->GetSkillValue(SKILL_RIDING))
- {
- if (skillval >= 375)
- unitTarget->CastSpell(unitTarget, 76154, true);
- else if (skillval >= 300)
- unitTarget->CastSpell(unitTarget, 75972, true);
- else
- unitTarget->CastSpell(unitTarget, 75957, true);
- }
- return;
- }
case 59317: // Teleporting
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
@@ -5058,16 +4725,14 @@ void Spell::EffectDisEnchant(SpellEffIndex /*effIndex*/)
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
return;
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- Player* p_caster = (Player*)m_caster;
if (!itemTarget || !itemTarget->GetTemplate()->DisenchantID)
return;
- p_caster->UpdateCraftSkill(m_spellInfo->Id);
-
- m_caster->ToPlayer()->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
+ if (Player* caster = m_caster->ToPlayer())
+ {
+ caster->UpdateCraftSkill(m_spellInfo->Id);
+ caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
+ }
// item will be removed at disenchanting end
}
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 183ca747b37..bb4815d5fc1 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -452,6 +452,7 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster, int32 const* bp, Unit const
if (!basePointsPerLevel && (_spellInfo->Attributes & SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION && _spellInfo->SpellLevel) &&
Effect != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE &&
Effect != SPELL_EFFECT_KNOCK_BACK &&
+ Effect != SPELL_EFFECT_ADD_EXTRA_ATTACKS &&
ApplyAuraName != SPELL_AURA_MOD_SPEED_ALWAYS &&
ApplyAuraName != SPELL_AURA_MOD_SPEED_NOT_STACK &&
ApplyAuraName != SPELL_AURA_MOD_INCREASE_SPEED &&
@@ -1810,6 +1811,7 @@ AuraStateType SpellInfo::GetAuraState() const
switch (Id)
{
case 71465: // Divine Surge
+ case 50241: // Evasive Charges
return AURA_STATE_UNKNOWN22;
default:
break;
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 117953f2bc0..439b0c91324 100755
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -2960,8 +2960,10 @@ void SpellMgr::LoadDbcDataCorrections()
switch (spellInfo->Id)
{
- case 40244: case 40245: // Simon Game Visual
- case 40246: case 40247: // Simon Game Visual
+ case 40244: // Simon Game Visual
+ case 40245: // Simon Game Visual
+ case 40246: // Simon Game Visual
+ case 40247: // Simon Game Visual
case 42835: // Spout, remove damage effect, only anim is needed
spellInfo->Effect[0] = 0;
break;
@@ -2973,7 +2975,6 @@ void SpellMgr::LoadDbcDataCorrections()
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)
case 2895: // Wrath of Air Totem rank 1 (Aura)
@@ -3045,6 +3046,9 @@ void SpellMgr::LoadDbcDataCorrections()
case 48246: // Ball of Flame
spellInfo->MaxAffectedTargets = 1;
break;
+ case 36384: // Skartax Purple Beam
+ spellInfo->MaxAffectedTargets = 2;
+ break;
case 41376: // Spite
case 39992: // Needle Spine
case 29576: // Multi-Shot
@@ -3084,7 +3088,7 @@ void SpellMgr::LoadDbcDataCorrections()
case 50312: // Unholy Frenzy
spellInfo->MaxAffectedTargets = 15;
break;
- case 33711: //Murmur's Touch
+ case 33711: // Murmur's Touch
case 38794:
spellInfo->MaxAffectedTargets = 1;
spellInfo->EffectTriggerSpell[0] = 33760;
@@ -3125,6 +3129,9 @@ void SpellMgr::LoadDbcDataCorrections()
case 51852: // The Eye of Acherus (no spawn in phase 2 in db)
spellInfo->EffectMiscValue[0] |= 1;
break;
+ case 51912: // Crafty's Ultra-Advanced Proto-Typical Shortening Blaster
+ spellInfo->EffectAmplitude[0] = 3000;
+ break;
case 29809: // Desecration Arm - 36 instead of 37 - typo? :/
spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_7_YARDS;
break;
@@ -3238,6 +3245,9 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectDieSides[0] = 0; // was 1, that should probably mean seat 0, but instead it's treated as spell 1
spellInfo->EffectBasePoints[0] = 52391; // Ride Vehicle (forces seat 0)
break;
+ case 45602: // Ride Carpet
+ spellInfo->EffectBasePoints[EFFECT_0] = 0; // force seat 0, vehicle doesn't have the required seat flags for "no seat specified (-1)"
+ break;
case 64745: // Item - Death Knight T8 Tank 4P Bonus
case 64936: // Item - Warrior T8 Protection 4P Bonus
spellInfo->EffectBasePoints[0] = 100; // 100% chance of procc'ing, not -10% (chance calculated in PrepareTriggersExecutedOnHit)
@@ -3252,9 +3262,16 @@ void SpellMgr::LoadDbcDataCorrections()
case 53313: // Entangling Roots (Rank 8) -- Nature's Grasp Proc
spellInfo->CastingTimeIndex = 1;
break;
+ case 59414: // Pulsing Shockwave Aura (Loken)
+ // this flag breaks movement, remove it
+ spellInfo->AttributesEx &= ~SPELL_ATTR1_CHANNELED_1;
+ break;
case 61719: // Easter Lay Noblegarden Egg Aura - Interrupt flags copied from aura which this aura is linked with
spellInfo->AuraInterruptFlags = AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE;
break;
+ case 70650: // Death Knight T10 Tank 2P Bonus
+ spellInfo->EffectApplyAuraName[0] = SPELL_AURA_ADD_PCT_MODIFIER;
+ break;
// ULDUAR SPELLS
//
case 62374: // Pursued (Flame Leviathan)
@@ -3293,11 +3310,6 @@ void SpellMgr::LoadDbcDataCorrections()
// that will be clear if we get more spells with problem like this
spellInfo->AttributesEx |= SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY;
break;
- case 62584: // Lifebinder's Gift
- case 64185: // Lifebinder's Gift
- spellInfo->EffectImplicitTargetB[1] = TARGET_UNIT_NEARBY_ENTRY;
- spellInfo->EffectImplicitTargetB[2] = TARGET_UNIT_NEARBY_ENTRY;
- break;
case 62301: // Cosmic Smash (Algalon the Observer)
spellInfo->MaxAffectedTargets = 1;
break;
@@ -3429,7 +3441,7 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_200_YARDS; // 200yd
break;
case 70598: // Sindragosa's Fury
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
+ spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DEST;
break;
case 69846: // Frost Bomb
spellInfo->speed = 0.0f; // This spell's summon happens instantly
@@ -3539,11 +3551,6 @@ void SpellMgr::LoadDbcDataCorrections()
switch (spellInfo->SpellFamilyName)
{
- case SPELLFAMILY_DRUID:
- // Starfall Target Selection
- if (spellInfo->SpellFamilyFlags[2] & 0x100)
- spellInfo->MaxAffectedTargets = 2;
- break;
case SPELLFAMILY_PALADIN:
// Seals of the Pure should affect Seal of Righteousness
if (spellInfo->SpellIconID == 25 && spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp
index e6ce80c20f0..d0ae6fe3098 100755
--- a/src/server/game/Spells/SpellScript.cpp
+++ b/src/server/game/Spells/SpellScript.cpp
@@ -203,52 +203,106 @@ void SpellScript::HitHandler::Call(SpellScript* spellScript)
(spellScript->*pHitHandlerScript)();
}
-SpellScript::UnitTargetHandler::UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType)
- : _SpellScript::EffectHook(_effIndex), targetType(_targetType)
+SpellScript::TargetHook::TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area)
+ : _SpellScript::EffectHook(_effectIndex), targetType(_targetType), area(_area)
{
- pUnitTargetHandlerScript = _pUnitTargetHandlerScript;
}
-std::string SpellScript::UnitTargetHandler::ToString()
+std::string SpellScript::TargetHook::ToString()
{
std::ostringstream oss;
oss << "Index: " << EffIndexToString() << " Target: " << targetType;
return oss.str();
}
-bool SpellScript::UnitTargetHandler::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex)
+bool SpellScript::TargetHook::CheckEffect(SpellInfo const* spellEntry, uint8 effIndex)
{
if (!targetType)
return false;
- return (effIndex == EFFECT_ALL) || (spellEntry->Effects[effIndex].TargetA.GetTarget() == targetType || spellEntry->Effects[effIndex].TargetB.GetTarget() == targetType);
+
+ if (spellEntry->Effects[effIndex].TargetA.GetTarget() != targetType &&
+ spellEntry->Effects[effIndex].TargetB.GetTarget() != targetType)
+ return false;
+
+ SpellImplicitTargetInfo targetInfo(targetType);
+ switch (targetInfo.GetSelectionCategory())
+ {
+ case TARGET_SELECT_CATEGORY_CHANNEL: // SINGLE
+ return !area;
+ case TARGET_SELECT_CATEGORY_NEARBY: // BOTH
+ return true;
+ case TARGET_SELECT_CATEGORY_CONE: // AREA
+ case TARGET_SELECT_CATEGORY_AREA: // AREA
+ return area;
+ case TARGET_SELECT_CATEGORY_DEFAULT:
+ switch (targetInfo.GetObjectType())
+ {
+ case TARGET_OBJECT_TYPE_SRC: // EMPTY
+ case TARGET_OBJECT_TYPE_DEST: // EMPTY
+ return false;
+ default:
+ switch (targetInfo.GetReferenceType())
+ {
+ case TARGET_REFERENCE_TYPE_CASTER: // SINGLE
+ return !area;
+ case TARGET_REFERENCE_TYPE_TARGET: // BOTH
+ return true;
+ }
+ break;
+ }
+ break;
+ }
+
+ return false;
+}
+
+SpellScript::ObjectAreaTargetSelectHandler::ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
+ : TargetHook(_effIndex, _targetType, true)
+{
+ pObjectAreaTargetSelectHandlerScript = _pObjectAreaTargetSelectHandlerScript;
+}
+
+void SpellScript::ObjectAreaTargetSelectHandler::Call(SpellScript* spellScript, std::list<WorldObject*>& targets)
+{
+ (spellScript->*pObjectAreaTargetSelectHandlerScript)(targets);
}
-void SpellScript::UnitTargetHandler::Call(SpellScript* spellScript, std::list<Unit*>& unitTargets)
+SpellScript::ObjectTargetSelectHandler::ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType)
+ : TargetHook(_effIndex, _targetType, false)
{
- (spellScript->*pUnitTargetHandlerScript)(unitTargets);
+ pObjectTargetSelectHandlerScript = _pObjectTargetSelectHandlerScript;
+}
+
+void SpellScript::ObjectTargetSelectHandler::Call(SpellScript* spellScript, WorldObject*& target)
+{
+ (spellScript->*pObjectTargetSelectHandlerScript)(target);
}
bool SpellScript::_Validate(SpellInfo const* entry)
{
- for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr)
+ for (std::list<EffectHandler>::iterator itr = OnEffectLaunch.begin(); itr != OnEffectLaunch.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunch` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
- for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr)
+ for (std::list<EffectHandler>::iterator itr = OnEffectLaunchTarget.begin(); itr != OnEffectLaunchTarget.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectLaunchTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
- for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr)
+ for (std::list<EffectHandler>::iterator itr = OnEffectHit.begin(); itr != OnEffectHit.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHit` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
- for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr)
+ for (std::list<EffectHandler>::iterator itr = OnEffectHitTarget.begin(); itr != OnEffectHitTarget.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectHitTarget` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
- for (std::list<UnitTargetHandler>::iterator itr = OnUnitTargetSelect.begin(); itr != OnUnitTargetSelect.end(); ++itr)
+ for (std::list<ObjectAreaTargetSelectHandler>::iterator itr = OnObjectAreaTargetSelect.begin(); itr != OnObjectAreaTargetSelect.end(); ++itr)
+ if (!(*itr).GetAffectedEffectsMask(entry))
+ sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectAreaTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+
+ for (std::list<ObjectTargetSelectHandler>::iterator itr = OnObjectTargetSelect.begin(); itr != OnObjectTargetSelect.end(); ++itr)
if (!(*itr).GetAffectedEffectsMask(entry))
- sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnUnitTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
+ sLog->outError("TSCR: Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnObjectTargetSelect` of SpellScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str());
return _SpellScript::_Validate(entry);
}
diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h
index 7b194b7827f..376e7f18edc 100755
--- a/src/server/game/Spells/SpellScript.h
+++ b/src/server/game/Spells/SpellScript.h
@@ -131,7 +131,8 @@ enum SpellScriptHookType
SPELL_SCRIPT_HOOK_BEFORE_HIT,
SPELL_SCRIPT_HOOK_HIT,
SPELL_SCRIPT_HOOK_AFTER_HIT,
- SPELL_SCRIPT_HOOK_UNIT_TARGET_SELECT,
+ SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT,
+ SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT,
SPELL_SCRIPT_HOOK_CHECK_CAST,
SPELL_SCRIPT_HOOK_BEFORE_CAST,
SPELL_SCRIPT_HOOK_ON_CAST,
@@ -154,7 +155,8 @@ class SpellScript : public _SpellScript
typedef void(CLASSNAME::*SpellEffectFnType)(SpellEffIndex); \
typedef void(CLASSNAME::*SpellHitFnType)(); \
typedef void(CLASSNAME::*SpellCastFnType)(); \
- typedef void(CLASSNAME::*SpellUnitTargetFnType)(std::list<Unit*>&); \
+ typedef void(CLASSNAME::*SpellObjectAreaTargetSelectFnType)(std::list<WorldObject*>&); \
+ typedef void(CLASSNAME::*SpellObjectTargetSelectFnType)(WorldObject*&);
SPELLSCRIPT_FUNCTION_TYPE_DEFINES(SpellScript)
@@ -196,16 +198,33 @@ class SpellScript : public _SpellScript
SpellHitFnType pHitHandlerScript;
};
- class UnitTargetHandler : public _SpellScript::EffectHook
+ class TargetHook : public _SpellScript::EffectHook
{
public:
- UnitTargetHandler(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType);
+ TargetHook(uint8 _effectIndex, uint16 _targetType, bool _area);
+ bool CheckEffect(SpellInfo const* spellEntry, uint8 effIndex);
std::string ToString();
- bool CheckEffect(SpellInfo const* spellEntry, uint8 targetType);
- void Call(SpellScript* spellScript, std::list<Unit*>& unitTargets);
- private:
- SpellUnitTargetFnType pUnitTargetHandlerScript;
+ protected:
uint16 targetType;
+ bool area;
+ };
+
+ class ObjectAreaTargetSelectHandler : public TargetHook
+ {
+ public:
+ ObjectAreaTargetSelectHandler(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
+ void Call(SpellScript* spellScript, std::list<WorldObject*>& targets);
+ private:
+ SpellObjectAreaTargetSelectFnType pObjectAreaTargetSelectHandlerScript;
+ };
+
+ class ObjectTargetSelectHandler : public TargetHook
+ {
+ public:
+ ObjectTargetSelectHandler(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType);
+ void Call(SpellScript* spellScript, WorldObject*& targets);
+ private:
+ SpellObjectTargetSelectFnType pObjectTargetSelectHandlerScript;
};
#define SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \
@@ -213,7 +232,8 @@ class SpellScript : public _SpellScript
class CheckCastHandlerFunction : public SpellScript::CheckCastHandler { public: CheckCastHandlerFunction(SpellCheckCastFnType _checkCastHandlerScript) : SpellScript::CheckCastHandler((SpellScript::SpellCheckCastFnType)_checkCastHandlerScript) {} }; \
class EffectHandlerFunction : public SpellScript::EffectHandler { public: EffectHandlerFunction(SpellEffectFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName) : SpellScript::EffectHandler((SpellScript::SpellEffectFnType)_pEffectHandlerScript, _effIndex, _effName) {} }; \
class HitHandlerFunction : public SpellScript::HitHandler { public: HitHandlerFunction(SpellHitFnType _pHitHandlerScript) : SpellScript::HitHandler((SpellScript::SpellHitFnType)_pHitHandlerScript) {} }; \
- class UnitTargetHandlerFunction : public SpellScript::UnitTargetHandler { public: UnitTargetHandlerFunction(SpellUnitTargetFnType _pUnitTargetHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::UnitTargetHandler((SpellScript::SpellUnitTargetFnType)_pUnitTargetHandlerScript, _effIndex, _targetType) {} }; \
+ class ObjectAreaTargetSelectHandlerFunction : public SpellScript::ObjectAreaTargetSelectHandler { public: ObjectAreaTargetSelectHandlerFunction(SpellObjectAreaTargetSelectFnType _pObjectAreaTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectAreaTargetSelectHandler((SpellScript::SpellObjectAreaTargetSelectFnType)_pObjectAreaTargetSelectHandlerScript, _effIndex, _targetType) {} }; \
+ class ObjectTargetSelectHandlerFunction : public SpellScript::ObjectTargetSelectHandler { public: ObjectTargetSelectHandlerFunction(SpellObjectTargetSelectFnType _pObjectTargetSelectHandlerScript, uint8 _effIndex, uint16 _targetType) : SpellScript::ObjectTargetSelectHandler((SpellScript::SpellObjectTargetSelectFnType)_pObjectTargetSelectHandlerScript, _effIndex, _targetType) {} };
#define PrepareSpellScript(CLASSNAME) SPELLSCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) SPELLSCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME)
public:
@@ -267,15 +287,21 @@ class SpellScript : public _SpellScript
// where function is: void function()
#define SpellHitFn(F) HitHandlerFunction(&F)
- // example: OnUnitTargetSelect += SpellUnitTargetFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
- // where function is void function(std::list<Unit*>& targetList)
- HookList<UnitTargetHandler> OnUnitTargetSelect;
- #define SpellUnitTargetFn(F, I, N) UnitTargetHandlerFunction(&F, I, N)
+ // example: OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
+ // where function is void function(std::list<WorldObject*>& targets)
+ HookList<ObjectAreaTargetSelectHandler> OnObjectAreaTargetSelect;
+ #define SpellObjectAreaTargetSelectFn(F, I, N) ObjectAreaTargetSelectHandlerFunction(&F, I, N)
+
+ // example: OnObjectTargetSelect += SpellObjectTargetSelectFn(class::function, EffectIndexSpecifier, TargetsNameSpecifier);
+ // where function is void function(WorldObject*& target)
+ HookList<ObjectTargetSelectHandler> OnObjectTargetSelect;
+ #define SpellObjectTargetSelectFn(F, I, N) ObjectTargetSelectHandlerFunction(&F, I, N)
// hooks are executed in following order, at specified event of spell:
// 1. BeforeCast - executed when spell preparation is finished (when cast bar becomes full) before cast is handled
// 2. OnCheckCast - allows to override result of CheckCast function
- // 3. OnUnitTargetSelect - executed just before adding selected targets to final target list
+ // 3a. OnObjectAreaTargetSelect - executed just before adding selected targets to final target list (for area targets)
+ // 3b. OnObjectTargetSelect - executed just before adding selected target to final target list (for single unit targets)
// 4. OnCast - executed just before spell is launched (creates missile) or executed
// 5. AfterCast - executed after spell missile is launched and immediate spell actions are done
// 6. OnEffectLaunch - executed just before specified effect handler call - when spell missile is launched
@@ -302,7 +328,7 @@ class SpellScript : public _SpellScript
// -shadowstep - explicit target is the unit you want to go behind of
// -chain heal - explicit target is the unit to be healed first
// -holy nova/arcane explosion - explicit target = NULL because target you are selecting doesn't affect how spell targets are selected
- // you can determine if spell requires explicit targets by dbc columns:
+ // you can determine if spell requires explicit targets by dbc columns:
// - Targets - mask of explicit target types
// - ImplicitTargetXX set to TARGET_XXX_TARGET_YYY, _TARGET_ here means that explicit target is used by the effect, so spell needs one too
diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp
index 0734e0a0f63..54e56174b1a 100644
--- a/src/server/game/Warden/Warden.cpp
+++ b/src/server/game/Warden/Warden.cpp
@@ -188,11 +188,14 @@ std::string Warden::Penalty(WardenCheck* check /*= NULL*/)
std::string accountName;
AccountMgr::GetName(_session->GetAccountId(), accountName);
std::stringstream banReason;
- banReason << "Warden Anticheat Violation: " << check->Comment << " (CheckId: " << check->CheckId << ")";
+ banReason << "Warden Anticheat Violation";
+ // Check can be NULL, for example if the client sent a wrong signature in the warden packet (CHECKSUM FAIL)
+ if (check)
+ banReason << ": " << check->Comment << " (CheckId: " << check->CheckId << ")";
+
sWorld->BanAccount(BAN_ACCOUNT, accountName, duration.str(), banReason.str(),"Server");
return "Ban";
- break;
}
default:
break;
@@ -208,7 +211,7 @@ void WorldSession::HandleWardenDataOpcode(WorldPacket& recvData)
sLog->outDebug(LOG_FILTER_WARDEN, "Got packet, opcode %02X, size %u", opcode, uint32(recvData.size()));
recvData.hexlike();
- switch(opcode)
+ switch (opcode)
{
case WARDEN_CMSG_MODULE_MISSING:
_warden->SendModuleToClient();
diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp
index f4c7a5069cf..abd7ff8f87d 100644
--- a/src/server/game/Warden/WardenCheckMgr.cpp
+++ b/src/server/game/Warden/WardenCheckMgr.cpp
@@ -121,7 +121,7 @@ void WardenCheckMgr::LoadWardenChecks()
if (checkType == MPQ_CHECK || checkType == MEM_CHECK)
{
- WardenCheckResult *wr = new WardenCheckResult();
+ WardenCheckResult* wr = new WardenCheckResult();
wr->Result.SetHexStr(checkResult.c_str());
int len = checkResult.size() / 2;
if (wr->Result.GetNumBytes() < len)
diff --git a/src/server/game/Warden/WardenMac.cpp b/src/server/game/Warden/WardenMac.cpp
index a60ae765013..3cc95b9f3f7 100644
--- a/src/server/game/Warden/WardenMac.cpp
+++ b/src/server/game/Warden/WardenMac.cpp
@@ -43,8 +43,8 @@ void WardenMac::Init(WorldSession *pClient, BigNumber *K)
_session = pClient;
// Generate Warden Key
SHA1Randx WK(K->AsByteArray(), K->GetNumBytes());
- WK.generate(_inputKey, 16);
- WK.generate(_outputKey, 16);
+ WK.Generate(_inputKey, 16);
+ WK.Generate(_outputKey, 16);
/*
Seed: 4D808D2C77D905C41A6380EC08586AFE (0x05 packet)
Hash: <?> (0x04 packet)
@@ -222,7 +222,7 @@ void WardenMac::HandleData(ByteBuffer &buff)
// return;
//}
- bool found = false;
+ //bool found = false;
std::string str = "Test string!";
@@ -238,7 +238,7 @@ void WardenMac::HandleData(ByteBuffer &buff)
if (memcmp(sha1Hash, sha1.GetDigest(), 20))
{
sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: SHA1 hash is wrong!");
- found = true;
+ //found = true;
}
MD5_CTX ctx;
@@ -253,7 +253,7 @@ void WardenMac::HandleData(ByteBuffer &buff)
if (memcmp(ourMD5Hash, theirsMD5Hash, 16))
{
sLog->outDebug(LOG_FILTER_WARDEN, "Handle data failed: MD5 hash is wrong!");
- found = true;
+ //found = true;
}
_session->KickPlayer();
diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp
index a7485d7da51..9aa439ec8c0 100644
--- a/src/server/game/Warden/WardenWin.cpp
+++ b/src/server/game/Warden/WardenWin.cpp
@@ -47,8 +47,8 @@ void WardenWin::Init(WorldSession* session, BigNumber *k)
_session = session;
// Generate Warden Key
SHA1Randx WK(k->AsByteArray(), k->GetNumBytes());
- WK.generate(_inputKey, 16);
- WK.generate(_outputKey, 16);
+ WK.Generate(_inputKey, 16);
+ WK.Generate(_outputKey, 16);
memcpy(_seed, Module.Seed, 16);
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index a3b9054bd68..fc46d8d2d60 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1023,6 +1023,7 @@ void World::LoadConfigSettings(bool reload)
m_bool_configs[CONFIG_BG_XP_FOR_KILL] = ConfigMgr::GetBoolDefault("Battleground.GiveXPForKills", false);
m_int_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = ConfigMgr::GetIntDefault ("Arena.MaxRatingDifference", 150);
m_int_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = ConfigMgr::GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS);
+ m_int_configs[CONFIG_ARENA_RATED_UPDATE_TIMER] = ConfigMgr::GetIntDefault ("Arena.RatedUpdateTimer", 5 * IN_MILLISECONDS);
m_bool_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = ConfigMgr::GetBoolDefault("Arena.AutoDistributePoints", false);
m_int_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = ConfigMgr::GetIntDefault ("Arena.AutoDistributeInterval", 7);
m_bool_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = ConfigMgr::GetBoolDefault("Arena.QueueAnnouncer.Enable", false);
@@ -1413,15 +1414,9 @@ void World::SetInitialWorldSettings()
sLog->outString("Loading Creature Addon Data...");
sObjectMgr->LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures()
- sLog->outString("Loading Creature Respawn Data..."); // must be after PackInstances()
- sObjectMgr->LoadCreatureRespawnTimes();
-
sLog->outString("Loading Gameobject Data...");
sObjectMgr->LoadGameobjects();
- sLog->outString("Loading Gameobject Respawn Data..."); // must be after PackInstances()
- sObjectMgr->LoadGameobjectRespawnTimes();
-
sLog->outString("Loading Creature Linked Respawn...");
sObjectMgr->LoadLinkedRespawn(); // must be after LoadCreatures(), LoadGameObjects()
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 51f384770da..450183226fc 100755
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -289,6 +289,7 @@ enum WorldIntConfigs
CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH,
CONFIG_ARENA_MAX_RATING_DIFFERENCE,
CONFIG_ARENA_RATING_DISCARD_TIMER,
+ CONFIG_ARENA_RATED_UPDATE_TIMER,
CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS,
CONFIG_ARENA_SEASON_ID,
CONFIG_ARENA_START_RATING,
diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt
index 86fe984e197..c27b51a1ca2 100644
--- a/src/server/scripts/Commands/CMakeLists.txt
+++ b/src/server/scripts/Commands/CMakeLists.txt
@@ -12,30 +12,30 @@ set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
Commands/cs_account.cpp
Commands/cs_achievement.cpp
+ Commands/cs_cast.cpp
+ Commands/cs_character.cpp
Commands/cs_debug.cpp
Commands/cs_event.cpp
Commands/cs_gm.cpp
Commands/cs_go.cpp
Commands/cs_gobject.cpp
Commands/cs_honor.cpp
+ Commands/cs_instance.cpp
Commands/cs_learn.cpp
+ Commands/cs_list.cpp
Commands/cs_misc.cpp
Commands/cs_modify.cpp
Commands/cs_npc.cpp
Commands/cs_quest.cpp
Commands/cs_reload.cpp
+ Commands/cs_reset.cpp
Commands/cs_tele.cpp
+ Commands/cs_server.cpp
Commands/cs_titles.cpp
Commands/cs_wp.cpp
-# Commands/cs_character.cpp
-# Commands/cs_list.cpp
# Commands/cs_lookup.cpp
# Commands/cs_pdump.cpp
# Commands/cs_guild.cpp
-# Commands/cs_cast.cpp
-# Commands/cs_reset.cpp
-# Commands/cs_instance.cpp
-# Commands/cs_server.cpp
# Commands/cs_channel.cpp
# Commands/cs_pet.cpp
# Commands/cs_ticket.cpp
diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp
new file mode 100644
index 00000000000..33983411427
--- /dev/null
+++ b/src/server/scripts/Commands/cs_cast.cpp
@@ -0,0 +1,310 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: cast_commandscript
+%Complete: 100
+Comment: All cast related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+
+class cast_commandscript : public CommandScript
+{
+public:
+ cast_commandscript() : CommandScript("cast_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand castCommandTable[] =
+ {
+ { "back", SEC_ADMINISTRATOR, false, &HandleCastBackCommand, "", NULL },
+ { "dist", SEC_ADMINISTRATOR, false, &HandleCastDistCommand, "", NULL },
+ { "self", SEC_ADMINISTRATOR, false, &HandleCastSelfCommand, "", NULL },
+ { "target", SEC_ADMINISTRATOR, false, &HandleCastTargetCommad, "", NULL },
+ { "dest", SEC_ADMINISTRATOR, false, &HandleCastDestCommand, "", NULL },
+ { "", SEC_ADMINISTRATOR, false, &HandleCastCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ static ChatCommand commandTable[] =
+ {
+ { "cast", SEC_ADMINISTRATOR, false, NULL, "", castCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ static bool HandleCastCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ Unit* target = handler->getSelectedUnit();
+ if (!target)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId)
+ return false;
+
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ if (!spellInfo)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* triggeredStr = strtok(NULL, " ");
+ if (triggeredStr)
+ {
+ int l = strlen(triggeredStr);
+ if (strncmp(triggeredStr, "triggered", l) != 0)
+ return false;
+ }
+
+ bool triggered = (triggeredStr != NULL);
+
+ handler->GetSession()->GetPlayer()->CastSpell(target, spellId, triggered);
+
+ return true;
+ }
+
+ static bool HandleCastBackCommand(ChatHandler* handler, char const* args)
+ {
+ Creature* caster = handler->getSelectedCreature();
+ if (!caster)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* triggeredStr = strtok(NULL, " ");
+ if (triggeredStr)
+ {
+ int l = strlen(triggeredStr);
+ if (strncmp(triggeredStr, "triggered", l) != 0)
+ return false;
+ }
+
+ bool triggered = (triggeredStr != NULL);
+
+ caster->CastSpell(handler->GetSession()->GetPlayer(), spellId, triggered);
+
+ return true;
+ }
+
+ static bool HandleCastDistCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId)
+ return false;
+
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ if (!spellInfo)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* distStr = strtok(NULL, " ");
+
+ float dist = 0;
+
+ if (distStr)
+ sscanf(distStr, "%f", &dist);
+
+ char* triggeredStr = strtok(NULL, " ");
+ if (triggeredStr)
+ {
+ int l = strlen(triggeredStr);
+ if (strncmp(triggeredStr, "triggered", l) != 0)
+ return false;
+ }
+
+ bool triggered = (triggeredStr != NULL);
+
+ float x, y, z;
+ handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist);
+
+ handler->GetSession()->GetPlayer()->CastSpell(x, y, z, spellId, triggered);
+
+ return true;
+ }
+
+ static bool HandleCastSelfCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ Unit* target = handler->getSelectedUnit();
+ if (!target)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId)
+ return false;
+
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
+ if (!spellInfo)
+ return false;
+
+ if (!SpellMgr::IsSpellValid(spellInfo, handler->GetSession()->GetPlayer()))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_SPELL_BROKEN, spellId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ target->CastSpell(target, spellId, false);
+
+ return true;
+ }
+
+ static bool HandleCastTargetCommad(ChatHandler* handler, char const* args)
+ {
+ Creature* caster = handler->getSelectedCreature();
+ if (!caster)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!caster->getVictim())
+ {
+ handler->SendSysMessage(LANG_SELECTED_TARGET_NOT_HAVE_VICTIM);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* triggeredStr = strtok(NULL, " ");
+ if (triggeredStr)
+ {
+ int l = strlen(triggeredStr);
+ if (strncmp(triggeredStr, "triggered", l) != 0)
+ return false;
+ }
+
+ bool triggered = (triggeredStr != NULL);
+
+ caster->CastSpell(caster->getVictim(), spellId, triggered);
+
+ return true;
+ }
+
+ static bool HandleCastDestCommand(ChatHandler* handler, char const* args)
+ {
+ Unit* caster = handler->getSelectedUnit();
+ if (!caster)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
+ uint32 spellId = handler->extractSpellIdFromLink((char*)args);
+ if (!spellId || !sSpellMgr->GetSpellInfo(spellId))
+ {
+ handler->PSendSysMessage(LANG_COMMAND_NOSPELLFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* posX = strtok(NULL, " ");
+ char* posY = strtok(NULL, " ");
+ char* posZ = strtok(NULL, " ");
+
+ if (!posX || !posY || !posZ)
+ return false;
+
+ float x = float(atof(posX));
+ float y = float(atof(posY));
+ float z = float(atof(posZ));
+
+ char* triggeredStr = strtok(NULL, " ");
+ if (triggeredStr)
+ {
+ int l = strlen(triggeredStr);
+ if (strncmp(triggeredStr, "triggered", l) != 0)
+ return false;
+ }
+
+ bool triggered = (triggeredStr != NULL);
+
+ caster->CastSpell(x, y, z, spellId, triggered);
+
+ return true;
+ }
+};
+
+void AddSC_cast_commandscript()
+{
+ new cast_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
new file mode 100644
index 00000000000..e6d397ead2b
--- /dev/null
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -0,0 +1,679 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: character_commandscript
+%Complete: 100
+Comment: All character related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "AccountMgr.h"
+#include "ObjectMgr.h"
+
+class character_commandscript : public CommandScript
+{
+public:
+ character_commandscript() : CommandScript("character_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand characterDeletedCommandTable[] =
+ {
+ { "delete", SEC_CONSOLE, true, &HandleCharacterDeletedDeleteCommand, "", NULL },
+ { "list", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedListCommand, "", NULL },
+ { "restore", SEC_ADMINISTRATOR, true, &HandleCharacterDeletedRestoreCommand, "", NULL },
+ { "old", SEC_CONSOLE, true, &HandleCharacterDeletedOldCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand characterCommandTable[] =
+ {
+ { "customize", SEC_GAMEMASTER, true, &HandleCharacterCustomizeCommand, "", NULL },
+ { "changefaction", SEC_GAMEMASTER, true, &HandleCharacterChangeFactionCommand, "", NULL },
+ { "changerace", SEC_GAMEMASTER, true, &HandleCharacterChangeRaceCommand, "", NULL },
+ { "deleted", SEC_GAMEMASTER, true, NULL, "", characterDeletedCommandTable},
+ { "erase", SEC_CONSOLE, true, &HandleCharacterEraseCommand, "", NULL },
+ { "level", SEC_ADMINISTRATOR, true, &HandleCharacterLevelCommand, "", NULL },
+ { "rename", SEC_GAMEMASTER, true, &HandleCharacterRenameCommand, "", NULL },
+ { "reputation", SEC_GAMEMASTER, true, &HandleCharacterReputationCommand, "", NULL },
+ { "titles", SEC_GAMEMASTER, true, &HandleCharacterTitlesCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "character", SEC_GAMEMASTER, true, NULL, "", characterCommandTable},
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ // Stores informations about a deleted character
+ struct DeletedInfo
+ {
+ uint32 lowGuid; ///< the low GUID from the character
+ std::string name; ///< the character name
+ uint32 accountId; ///< the account id
+ std::string accountName; ///< the account name
+ time_t deleteDate; ///< the date at which the character has been deleted
+ };
+
+ typedef std::list<DeletedInfo> DeletedInfoList;
+
+ /**
+ * Collects all GUIDs (and related info) from deleted characters which are still in the database.
+ *
+ * @param foundList a reference to an std::list which will be filled with info data
+ * @param searchString the search string which either contains a player GUID or a part fo the character-name
+ * @return returns false if there was a problem while selecting the characters (e.g. player name not normalizeable)
+ */
+ static bool GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString)
+ {
+ PreparedQueryResult result;
+ PreparedStatement* stmt;
+ if (!searchString.empty())
+ {
+ // search by GUID
+ if (isNumeric(searchString.c_str()))
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID);
+ stmt->setUInt32(0, uint32(atoi(searchString.c_str())));
+ result = CharacterDatabase.Query(stmt);
+ }
+ // search by name
+ else
+ {
+ if (!normalizePlayerName(searchString))
+ return false;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME);
+ stmt->setString(0, searchString);
+ result = CharacterDatabase.Query(stmt);
+ }
+ }
+ else
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO);
+ result = CharacterDatabase.Query(stmt);
+ }
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+
+ DeletedInfo info;
+
+ info.lowGuid = fields[0].GetUInt32();
+ info.name = fields[1].GetString();
+ info.accountId = fields[2].GetUInt32();
+
+ // account name will be empty for not existed account
+ AccountMgr::GetName(info.accountId, info.accountName);
+ info.deleteDate = time_t(fields[3].GetUInt32());
+ foundList.push_back(info);
+ }
+ while (result->NextRow());
+ }
+
+ return true;
+ }
+
+ /**
+ * Shows all deleted characters which matches the given search string, expected non empty list
+ *
+ * @see HandleCharacterDeletedListCommand
+ * @see HandleCharacterDeletedRestoreCommand
+ * @see HandleCharacterDeletedDeleteCommand
+ * @see DeletedInfoList
+ *
+ * @param foundList contains a list with all found deleted characters
+ */
+ static void HandleCharacterDeletedListHelper(DeletedInfoList const& foundList, ChatHandler* handler)
+ {
+ if (!handler->GetSession())
+ {
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER);
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
+ }
+
+ for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
+ {
+ std::string dateStr = TimeToTimestampStr(itr->deleteDate);
+
+ if (!handler->GetSession())
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE,
+ itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
+ itr->accountId, dateStr.c_str());
+ else
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT,
+ itr->lowGuid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
+ itr->accountId, dateStr.c_str());
+ }
+
+ if (!handler->GetSession())
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
+ }
+
+ /**
+ * Restore a previously deleted character
+ *
+ * @see HandleCharacterDeletedListHelper
+ * @see HandleCharacterDeletedRestoreCommand
+ * @see HandleCharacterDeletedDeleteCommand
+ * @see DeletedInfoList
+ *
+ * @param delInfo the informations about the character which will be restored
+ */
+ static void HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo, ChatHandler* handler)
+ {
+ if (delInfo.accountName.empty()) // account not exist
+ {
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
+ return;
+ }
+
+ // check character count
+ uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId);
+ if (charcount >= 10)
+ {
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
+ return;
+ }
+
+ if (sObjectMgr->GetPlayerGUIDByName(delInfo.name))
+ {
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowGuid, delInfo.accountId);
+ return;
+ }
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO);
+ stmt->setString(0, delInfo.name);
+ stmt->setUInt32(1, delInfo.accountId);
+ stmt->setUInt32(2, delInfo.lowGuid);
+ CharacterDatabase.Execute(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
+ stmt->setUInt32(0, delInfo.lowGuid);
+ if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
+ sWorld->AddCharacterNameData(delInfo.lowGuid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8());
+ }
+
+ static bool HandleCharacterTitlesCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ Player* target;
+ if (!handler->extractPlayerTarget((char*)args, &target))
+ return false;
+
+ LocaleConstant loc = handler->GetSessionDbcLocale();
+ char const* targetName = target->GetName();
+ char const* knownStr = handler->GetTrinityString(LANG_KNOWN);
+
+ // Search in CharTitles.dbc
+ for (uint32 id = 0; id < sCharTitlesStore.GetNumRows(); id++)
+ {
+ CharTitlesEntry const* titleInfo = sCharTitlesStore.LookupEntry(id);
+
+ if (titleInfo && target->HasTitle(titleInfo))
+ {
+ std::string name = titleInfo->name;
+ if (name.empty())
+ continue;
+
+ char const* activeStr = target && target->GetUInt32Value(PLAYER_CHOSEN_TITLE) == titleInfo->bit_index
+ ? handler->GetTrinityString(LANG_ACTIVE)
+ : "";
+
+ char titleNameStr[80];
+ snprintf(titleNameStr, 80, name.c_str(), targetName);
+
+ // send title in "id (idx:idx) - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_TITLE_LIST_CHAT, id, titleInfo->bit_index, id, titleNameStr, localeNames[loc], knownStr, activeStr);
+ else
+ handler->PSendSysMessage(LANG_TITLE_LIST_CONSOLE, id, titleInfo->bit_index, name.c_str(), localeNames[loc], knownStr, activeStr);
+ }
+ }
+
+ return true;
+ }
+
+ //rename characters
+ static bool HandleCharacterRenameCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ return false;
+
+ if (target)
+ {
+ // check online security
+ if (handler->HasLowerSecurity(target, 0))
+ return false;
+
+ handler->PSendSysMessage(LANG_RENAME_PLAYER, handler->GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_RENAME);
+ }
+ else
+ {
+ // check offline security
+ if (handler->HasLowerSecurity(NULL, targetGuid))
+ return false;
+
+ std::string oldNameLink = handler->playerLink(targetName);
+ handler->PSendSysMessage(LANG_RENAME_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_RENAME));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ CharacterDatabase.Execute(stmt);
+ }
+
+ return true;
+ }
+
+ static bool HandleCharacterLevelCommand(ChatHandler* handler, char const* args)
+ {
+ char* nameStr;
+ char* levelStr;
+ handler->extractOptFirstArg((char*)args, &nameStr, &levelStr);
+ if (!levelStr)
+ return false;
+
+ // exception opt second arg: .character level $name
+ if (isalpha(levelStr[0]))
+ {
+ nameStr = levelStr;
+ levelStr = NULL; // current level will used
+ }
+
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget(nameStr, &target, &targetGuid, &targetName))
+ return false;
+
+ int32 oldlevel = target ? target->getLevel() : Player::GetLevelFromDB(targetGuid);
+ int32 newlevel = levelStr ? atoi(levelStr) : oldlevel;
+
+ if (newlevel < 1)
+ return false; // invalid level
+
+ if (newlevel > STRONG_MAX_LEVEL) // hardcoded maximum level
+ newlevel = STRONG_MAX_LEVEL;
+
+ handler->HandleCharacterLevel(target, targetGuid, oldlevel, newlevel);
+ if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target) // including player == NULL
+ {
+ std::string nameLink = handler->playerLink(targetName);
+ handler->PSendSysMessage(LANG_YOU_CHANGE_LVL, nameLink.c_str(), newlevel);
+ }
+
+ return true;
+ }
+
+ // customize characters
+ static bool HandleCharacterCustomizeCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ return false;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_CUSTOMIZE));
+ if (target)
+ {
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE);
+ stmt->setUInt32(1, target->GetGUIDLow());
+ }
+ else
+ {
+ std::string oldNameLink = handler->playerLink(targetName);
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+ }
+ CharacterDatabase.Execute(stmt);
+
+ return true;
+ }
+
+ static bool HandleCharacterChangeFactionCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ return false;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_FACTION));
+ if (target)
+ {
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CHANGE_FACTION);
+ stmt->setUInt32(1, target->GetGUIDLow());
+ }
+ else
+ {
+ std::string oldNameLink = handler->playerLink(targetName);
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ }
+ CharacterDatabase.Execute(stmt);
+
+ return true;
+ }
+
+ static bool HandleCharacterChangeRaceCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ return false;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_CHANGE_RACE));
+ if (target)
+ {
+ // TODO : add text into database
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER, handler->GetNameLink(target).c_str());
+ target->SetAtLoginFlag(AT_LOGIN_CHANGE_RACE);
+ stmt->setUInt32(1, target->GetGUIDLow());
+ }
+ else
+ {
+ std::string oldNameLink = handler->playerLink(targetName);
+ // TODO : add text into database
+ handler->PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldNameLink.c_str(), GUID_LOPART(targetGuid));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ }
+ CharacterDatabase.Execute(stmt);
+
+ return true;
+ }
+
+ static bool HandleCharacterReputationCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ if (!handler->extractPlayerTarget((char*)args, &target))
+ return false;
+
+ LocaleConstant loc = handler->GetSessionDbcLocale();
+
+ FactionStateList const& targetFSL = target->GetReputationMgr().GetStateList();
+ for (FactionStateList::const_iterator itr = targetFSL.begin(); itr != targetFSL.end(); ++itr)
+ {
+ FactionState const& faction = itr->second;
+ FactionEntry const* factionEntry = sFactionStore.LookupEntry(faction.ID);
+ char const* factionName = factionEntry ? factionEntry->name : "#Not found#";
+ ReputationRank rank = target->GetReputationMgr().GetRank(factionEntry);
+ std::string rankName = handler->GetTrinityString(ReputationRankStrIndex[rank]);
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << faction.ID << " - |cffffffff|Hfaction:" << faction.ID << "|h[" << factionName << ' ' << localeNames[loc] << "]|h|r";
+ else
+ ss << faction.ID << " - " << factionName << ' ' << localeNames[loc];
+
+ ss << ' ' << rankName << " (" << target->GetReputationMgr().GetReputation(factionEntry) << ')';
+
+ if (faction.Flags & FACTION_FLAG_VISIBLE)
+ ss << handler->GetTrinityString(LANG_FACTION_VISIBLE);
+ if (faction.Flags & FACTION_FLAG_AT_WAR)
+ ss << handler->GetTrinityString(LANG_FACTION_ATWAR);
+ if (faction.Flags & FACTION_FLAG_PEACE_FORCED)
+ ss << handler->GetTrinityString(LANG_FACTION_PEACE_FORCED);
+ if (faction.Flags & FACTION_FLAG_HIDDEN)
+ ss << handler->GetTrinityString(LANG_FACTION_HIDDEN);
+ if (faction.Flags & FACTION_FLAG_INVISIBLE_FORCED)
+ ss << handler->GetTrinityString(LANG_FACTION_INVISIBLE_FORCED);
+ if (faction.Flags & FACTION_FLAG_INACTIVE)
+ ss << handler->GetTrinityString(LANG_FACTION_INACTIVE);
+
+ handler->SendSysMessage(ss.str().c_str());
+ }
+
+ return true;
+ }
+
+ /**
+ * Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string
+ *
+ * @see HandleCharacterDeletedListHelper
+ * @see HandleCharacterDeletedRestoreCommand
+ * @see HandleCharacterDeletedDeleteCommand
+ * @see DeletedInfoList
+ *
+ * @param args the search string which either contains a player GUID or a part fo the character-name
+ */
+ static bool HandleCharacterDeletedListCommand(ChatHandler* handler, char const* args)
+ {
+ DeletedInfoList foundList;
+ if (!GetDeletedCharacterInfoList(foundList, args))
+ return false;
+
+ // if no characters have been found, output a warning
+ if (foundList.empty())
+ {
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
+ return false;
+ }
+
+ HandleCharacterDeletedListHelper(foundList, handler);
+
+ return true;
+ }
+
+ /**
+ * Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string
+ *
+ * The command automatically calls '.character deleted list' command with the search string to show all restored characters.
+ *
+ * @see HandleCharacterDeletedRestoreHelper
+ * @see HandleCharacterDeletedListCommand
+ * @see HandleCharacterDeletedDeleteCommand
+ *
+ * @param args the search string which either contains a player GUID or a part of the character-name
+ */
+ static bool HandleCharacterDeletedRestoreCommand(ChatHandler* handler, char const* args)
+ {
+ // It is required to submit at least one argument
+ if (!*args)
+ return false;
+
+ std::string searchString;
+ std::string newCharName;
+ uint32 newAccount = 0;
+
+ // GCC by some strange reason fail build code without temporary variable
+ std::istringstream params(args);
+ params >> searchString >> newCharName >> newAccount;
+
+ DeletedInfoList foundList;
+ if (!GetDeletedCharacterInfoList(foundList, searchString))
+ return false;
+
+ if (foundList.empty())
+ {
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
+ return false;
+ }
+
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_RESTORE);
+ HandleCharacterDeletedListHelper(foundList, handler);
+
+ if (newCharName.empty())
+ {
+ // Drop not existed account cases
+ for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
+ HandleCharacterDeletedRestoreHelper(*itr, handler);
+ }
+ else if (foundList.size() == 1 && normalizePlayerName(newCharName))
+ {
+ DeletedInfo delInfo = foundList.front();
+
+ // update name
+ delInfo.name = newCharName;
+
+ // if new account provided update deleted info
+ if (newAccount && newAccount != delInfo.accountId)
+ {
+ delInfo.accountId = newAccount;
+ AccountMgr::GetName(newAccount, delInfo.accountName);
+ }
+
+ HandleCharacterDeletedRestoreHelper(delInfo, handler);
+ }
+ else
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME);
+
+ return true;
+ }
+
+ /**
+ * Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string
+ *
+ * @see Player::GetDeletedCharacterGUIDs
+ * @see Player::DeleteFromDB
+ * @see HandleCharacterDeletedListCommand
+ * @see HandleCharacterDeletedRestoreCommand
+ *
+ * @param args the search string which either contains a player GUID or a part fo the character-name
+ */
+ static bool HandleCharacterDeletedDeleteCommand(ChatHandler* handler, char const* args)
+ {
+ // It is required to submit at least one argument
+ if (!*args)
+ return false;
+
+ DeletedInfoList foundList;
+ if (!GetDeletedCharacterInfoList(foundList, args))
+ return false;
+
+ if (foundList.empty())
+ {
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
+ return false;
+ }
+
+ handler->SendSysMessage(LANG_CHARACTER_DELETED_DELETE);
+ HandleCharacterDeletedListHelper(foundList, handler);
+
+ // Call the appropriate function to delete them (current account for deleted characters is 0)
+ for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
+ Player::DeleteFromDB(itr->lowGuid, 0, false, true);
+
+ return true;
+ }
+
+ /**
+ * Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago
+ *
+ * @see Player::DeleteOldCharacters
+ * @see Player::DeleteFromDB
+ * @see HandleCharacterDeletedDeleteCommand
+ * @see HandleCharacterDeletedListCommand
+ * @see HandleCharacterDeletedRestoreCommand
+ *
+ * @param args the search string which either contains a player GUID or a part fo the character-name
+ */
+ static bool HandleCharacterDeletedOldCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS);
+
+ char* daysStr = strtok((char*)args, " ");
+ if (daysStr)
+ {
+ if (!isNumeric(daysStr))
+ return false;
+
+ keepDays = atoi(daysStr);
+ if (keepDays < 0)
+ return false;
+ }
+ // config option value 0 -> disabled and can't be used
+ else if (keepDays <= 0)
+ return false;
+
+ Player::DeleteOldCharacters(uint32(keepDays));
+
+ return true;
+ }
+
+ static bool HandleCharacterEraseCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* characterName_str = strtok((char*)args, " ");
+ if (!characterName_str)
+ return false;
+
+ std::string characterName = characterName_str;
+ if (!normalizePlayerName(characterName))
+ return false;
+
+ uint64 characterGuid;
+ uint32 accountId;
+
+ Player* player = sObjectAccessor->FindPlayerByName(characterName.c_str());
+ if (player)
+ {
+ characterGuid = player->GetGUID();
+ accountId = player->GetSession()->GetAccountId();
+ player->GetSession()->KickPlayer();
+ }
+ else
+ {
+ characterGuid = sObjectMgr->GetPlayerGUIDByName(characterName);
+ if (!characterGuid)
+ {
+ handler->PSendSysMessage(LANG_NO_PLAYER, characterName.c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+ accountId = sObjectMgr->GetPlayerAccountIdByGUID(characterGuid);
+ }
+
+ std::string accountName;
+ AccountMgr::GetName(accountId, accountName);
+
+ Player::DeleteFromDB(characterGuid, accountId, true, true);
+ handler->PSendSysMessage(LANG_CHARACTER_DELETED, characterName.c_str(), GUID_LOPART(characterGuid), accountName.c_str(), accountId);
+
+ return true;
+ }
+};
+
+void AddSC_character_commandscript()
+{
+ new character_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp
new file mode 100644
index 00000000000..f51727af2ef
--- /dev/null
+++ b/src/server/scripts/Commands/cs_instance.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: instance_commandscript
+%Complete: 100
+Comment: All instance related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "Group.h"
+#include "InstanceSaveMgr.h"
+#include "InstanceScript.h"
+#include "MapManager.h"
+
+class instance_commandscript : public CommandScript
+{
+public:
+ instance_commandscript() : CommandScript("instance_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand instanceCommandTable[] =
+ {
+ { "listbinds", SEC_ADMINISTRATOR, false, &HandleInstanceListBindsCommand, "", NULL },
+ { "unbind", SEC_ADMINISTRATOR, false, &HandleInstanceUnbindCommand, "", NULL },
+ { "stats", SEC_ADMINISTRATOR, true, &HandleInstanceStatsCommand, "", NULL },
+ { "savedata", SEC_ADMINISTRATOR, false, &HandleInstanceSaveDataCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "instance", SEC_ADMINISTRATOR, true, NULL, "", instanceCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ return commandTable;
+ }
+
+ static std::string GetTimeString(uint64 time)
+ {
+ uint64 days = time / DAY, hours = (time % DAY) / HOUR, minute = (time % HOUR) / MINUTE;
+ std::ostringstream ss;
+ if (days)
+ ss << days << "d ";
+ if (hours)
+ ss << hours << "h ";
+ ss << minute << 'm';
+ return ss.str();
+ }
+
+ static bool HandleInstanceListBindsCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ Player* player = handler->getSelectedPlayer();
+ if (!player)
+ player = handler->GetSession()->GetPlayer();
+
+ uint32 counter = 0;
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
+ for (Player::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ {
+ InstanceSave* save = itr->second.save;
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ counter++;
+ }
+ }
+ handler->PSendSysMessage("player binds: %d", counter);
+
+ counter = 0;
+ if (Group* group = player->GetGroup())
+ {
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Group::BoundInstancesMap &binds = group->GetBoundInstances(Difficulty(i));
+ for (Group::BoundInstancesMap::const_iterator itr = binds.begin(); itr != binds.end(); ++itr)
+ {
+ InstanceSave* save = itr->second.save;
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ handler->PSendSysMessage("map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ counter++;
+ }
+ }
+ }
+ handler->PSendSysMessage("group binds: %d", counter);
+
+ return true;
+ }
+
+ static bool HandleInstanceUnbindCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ Player* player = handler->getSelectedPlayer();
+ if (!player)
+ player = handler->GetSession()->GetPlayer();
+
+ char* map = strtok((char*)args, " ");
+ char* pDiff = strtok(NULL, " ");
+ int8 diff = -1;
+ if (pDiff)
+ diff = atoi(pDiff);
+ uint16 counter = 0;
+ uint16 MapId = 0;
+
+ if (strcmp(map, "all"))
+ {
+ MapId = uint16(atoi(map));
+ if (!MapId)
+ return false;
+ }
+
+ for (uint8 i = 0; i < MAX_DIFFICULTY; ++i)
+ {
+ Player::BoundInstancesMap &binds = player->GetBoundInstances(Difficulty(i));
+ for (Player::BoundInstancesMap::iterator itr = binds.begin(); itr != binds.end();)
+ {
+ InstanceSave* save = itr->second.save;
+ if (itr->first != player->GetMapId() && (!MapId || MapId == itr->first) && (diff == -1 || diff == save->GetDifficulty()))
+ {
+ std::string timeleft = GetTimeString(save->GetResetTime() - time(NULL));
+ handler->PSendSysMessage("unbinding map: %d inst: %d perm: %s diff: %d canReset: %s TTR: %s", itr->first, save->GetInstanceId(), itr->second.perm ? "yes" : "no", save->GetDifficulty(), save->CanReset() ? "yes" : "no", timeleft.c_str());
+ player->UnbindInstance(itr, Difficulty(i));
+ counter++;
+ }
+ else
+ ++itr;
+ }
+ }
+ handler->PSendSysMessage("instances unbound: %d", counter);
+
+ return true;
+ }
+
+ static bool HandleInstanceStatsCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ handler->PSendSysMessage("instances loaded: %d", sMapMgr->GetNumInstances());
+ handler->PSendSysMessage("players in instances: %d", sMapMgr->GetNumPlayersInInstances());
+ handler->PSendSysMessage("instance saves: %d", sInstanceSaveMgr->GetNumInstanceSaves());
+ handler->PSendSysMessage("players bound: %d", sInstanceSaveMgr->GetNumBoundPlayersTotal());
+ handler->PSendSysMessage("groups bound: %d", sInstanceSaveMgr->GetNumBoundGroupsTotal());
+
+ return true;
+ }
+
+ static bool HandleInstanceSaveDataCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ Map* map = player->GetMap();
+ if (!map->IsDungeon())
+ {
+ handler->PSendSysMessage("Map is not a dungeon.");
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (!((InstanceMap*)map)->GetInstanceScript())
+ {
+ handler->PSendSysMessage("Map has no instance data.");
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ ((InstanceMap*)map)->GetInstanceScript()->SaveToDB();
+
+ return true;
+ }
+};
+
+void AddSC_instance_commandscript()
+{
+ new instance_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
new file mode 100644
index 00000000000..8dd7f8e2cde
--- /dev/null
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -0,0 +1,469 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: list_commandscript
+%Complete: 100
+Comment: All list related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "SpellAuraEffects.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+
+class list_commandscript : public CommandScript
+{
+public:
+ list_commandscript() : CommandScript("list_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand listCommandTable[] =
+ {
+ { "creature", SEC_ADMINISTRATOR, true, &HandleListCreatureCommand, "", NULL },
+ { "item", SEC_ADMINISTRATOR, true, &HandleListItemCommand, "", NULL },
+ { "object", SEC_ADMINISTRATOR, true, &HandleListObjectCommand, "", NULL },
+ { "auras", SEC_ADMINISTRATOR, false, &HandleListAurasCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ static ChatCommand commandTable[] =
+ {
+ { "list", SEC_ADMINISTRATOR, true, NULL, "", listCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ static bool HandleListCreatureCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hcreature_entry:creature_id|h[name]|h|r
+ char* id = handler->extractKeyFromLink((char*)args, "Hcreature_entry");
+ if (!id)
+ return false;
+
+ uint32 creatureId = atol(id);
+ if (!creatureId)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ CreatureTemplate const* cInfo = sObjectMgr->GetCreatureTemplate(creatureId);
+ if (!cInfo)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_INVALIDCREATUREID, creatureId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* countStr = strtok(NULL, " ");
+ uint32 count = countStr ? atol(countStr) : 10;
+
+ if (count < 0)
+ return false;
+
+ QueryResult result;
+
+ uint32 creatureCount = 0;
+ result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM creature WHERE id='%u'", creatureId);
+ if (result)
+ creatureCount = (*result)[0].GetUInt64();
+
+ if (handler->GetSession())
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM creature WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
+ player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), creatureId, count);
+ }
+ else
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map FROM creature WHERE id = '%u' LIMIT %u",
+ creatureId, count);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+ uint16 mapId = fields[4].GetUInt16();
+
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId);
+ else
+ handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId);
+ }
+ while (result->NextRow());
+ }
+
+ handler->PSendSysMessage(LANG_COMMAND_LISTCREATUREMESSAGE, creatureId, creatureCount);
+
+ return true;
+ }
+
+ static bool HandleListItemCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* id = handler->extractKeyFromLink((char*)args, "Hitem");
+ if (!id)
+ return false;
+
+ uint32 itemId = atol(id);
+ if (!itemId)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId);
+ if (!itemTemplate)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_ITEMIDINVALID, itemId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* countStr = strtok(NULL, " ");
+ uint32 count = countStr ? atol(countStr) : 10;
+
+ if (count < 0)
+ return false;
+
+ PreparedQueryResult result;
+
+ // inventory case
+ uint32 inventoryCount = 0;
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_COUNT_ITEM);
+ stmt->setUInt32(0, itemId);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ inventoryCount = (*result)[0].GetUInt64();
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_INVENTORY_ITEM_BY_ENTRY);
+ stmt->setUInt32(0, itemId);
+ stmt->setUInt32(1, count);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemGuid = fields[0].GetUInt32();
+ uint32 itemBag = fields[1].GetUInt32();
+ uint8 itemSlot = fields[2].GetUInt8();
+ uint32 ownerGuid = fields[3].GetUInt32();
+ uint32 ownerAccountId = fields[4].GetUInt32();
+ std::string ownerName = fields[5].GetString();
+
+ char const* itemPos = 0;
+ if (Player::IsEquipmentPos(itemBag, itemSlot))
+ itemPos = "[equipped]";
+ else if (Player::IsInventoryPos(itemBag, itemSlot))
+ itemPos = "[in inventory]";
+ else if (Player::IsBankPos(itemBag, itemSlot))
+ itemPos = "[in bank]";
+ else
+ itemPos = "";
+
+ handler->PSendSysMessage(LANG_ITEMLIST_SLOT, itemGuid, ownerName.c_str(), ownerGuid, ownerAccountId, itemPos);
+ }
+ while (result->NextRow());
+
+ uint32 resultCount = uint32(result->GetRowCount());
+
+ if (count > resultCount)
+ count -= resultCount;
+ else if (count)
+ count = 0;
+ }
+
+ // mail case
+ uint32 mailCount = 0;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_COUNT_ITEM);
+ stmt->setUInt32(0, itemId);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ mailCount = (*result)[0].GetUInt64();
+
+ if (count > 0)
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL_ITEMS_BY_ENTRY);
+ stmt->setUInt32(0, itemId);
+ stmt->setUInt32(1, count);
+ result = CharacterDatabase.Query(stmt);
+ }
+ else
+ result = PreparedQueryResult(NULL);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemGuid = fields[0].GetUInt32();
+ uint32 itemSender = fields[1].GetUInt32();
+ uint32 itemReceiver = fields[2].GetUInt32();
+ uint32 itemSenderAccountId = fields[3].GetUInt32();
+ std::string itemSenderName = fields[4].GetString();
+ uint32 itemReceiverAccount = fields[5].GetUInt32();
+ std::string itemReceiverName = fields[6].GetString();
+
+ char const* itemPos = "[in mail]";
+
+ handler->PSendSysMessage(LANG_ITEMLIST_MAIL, itemGuid, itemSenderName.c_str(), itemSender, itemSenderAccountId, itemReceiverName.c_str(), itemReceiver, itemReceiverAccount, itemPos);
+ }
+ while (result->NextRow());
+
+ uint32 resultCount = uint32(result->GetRowCount());
+
+ if (count > resultCount)
+ count -= resultCount;
+ else if (count)
+ count = 0;
+ }
+
+ // auction case
+ uint32 auctionCount = 0;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_COUNT_ITEM);
+ stmt->setUInt32(0, itemId);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ auctionCount = (*result)[0].GetUInt64();
+
+ if (count > 0)
+ {
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_AUCTIONHOUSE_ITEM_BY_ENTRY);
+ stmt->setUInt32(0, itemId);
+ stmt->setUInt32(1, count);
+ result = CharacterDatabase.Query(stmt);
+ }
+ else
+ result = PreparedQueryResult(NULL);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemGuid = fields[0].GetUInt32();
+ uint32 owner = fields[1].GetUInt32();
+ uint32 ownerAccountId = fields[2].GetUInt32();
+ std::string ownerName = fields[3].GetString();
+
+ char const* itemPos = "[in auction]";
+
+ handler->PSendSysMessage(LANG_ITEMLIST_AUCTION, itemGuid, ownerName.c_str(), owner, ownerAccountId, itemPos);
+ }
+ while (result->NextRow());
+ }
+
+ // guild bank case
+ uint32 guildCount = 0;
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_COUNT_ITEM);
+ stmt->setUInt32(0, itemId);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ guildCount = (*result)[0].GetUInt64();
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GUILD_BANK_ITEM_BY_ENTRY);
+ stmt->setUInt32(0, itemId);
+ stmt->setUInt32(1, count);
+ result = CharacterDatabase.Query(stmt);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 itemGuid = fields[0].GetUInt32();
+ uint32 guildGuid = fields[1].GetUInt32();
+ std::string guildName = fields[2].GetString();
+
+ char const* itemPos = "[in guild bank]";
+
+ handler->PSendSysMessage(LANG_ITEMLIST_GUILD, itemGuid, guildName.c_str(), guildGuid, itemPos);
+ }
+ while (result->NextRow());
+
+ uint32 resultCount = uint32(result->GetRowCount());
+
+ if (count > resultCount)
+ count -= resultCount;
+ else if (count)
+ count = 0;
+ }
+
+ if (inventoryCount + mailCount + auctionCount + guildCount == 0)
+ {
+ handler->SendSysMessage(LANG_COMMAND_NOITEMFOUND);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ handler->PSendSysMessage(LANG_COMMAND_LISTITEMMESSAGE, itemId, inventoryCount + mailCount + auctionCount + guildCount, inventoryCount, mailCount, auctionCount, guildCount);
+
+ return true;
+ }
+
+ static bool HandleListObjectCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ // number or [name] Shift-click form |color|Hgameobject_entry:go_id|h[name]|h|r
+ char* id = handler->extractKeyFromLink((char*)args, "Hgameobject_entry");
+ if (!id)
+ return false;
+
+ uint32 gameObjectId = atol(id);
+ if (!gameObjectId)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ GameObjectTemplate const* gInfo = sObjectMgr->GetGameObjectTemplate(gameObjectId);
+ if (!gInfo)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LISTOBJINVALIDID, gameObjectId);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char* countStr = strtok(NULL, " ");
+ uint32 count = countStr ? atol(countStr) : 10;
+
+ if (count < 0)
+ return false;
+
+ QueryResult result;
+
+ uint32 objectCount = 0;
+ result = WorldDatabase.PQuery("SELECT COUNT(guid) FROM gameobject WHERE id='%u'", gameObjectId);
+ if (result)
+ objectCount = (*result)[0].GetUInt64();
+
+ if (handler->GetSession())
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id, (POW(position_x - '%f', 2) + POW(position_y - '%f', 2) + POW(position_z - '%f', 2)) AS order_ FROM gameobject WHERE id = '%u' ORDER BY order_ ASC LIMIT %u",
+ player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), gameObjectId, count);
+ }
+ else
+ result = WorldDatabase.PQuery("SELECT guid, position_x, position_y, position_z, map, id FROM gameobject WHERE id = '%u' LIMIT %u",
+ gameObjectId, count);
+
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 guid = fields[0].GetUInt32();
+ float x = fields[1].GetFloat();
+ float y = fields[2].GetFloat();
+ float z = fields[3].GetFloat();
+ uint16 mapId = fields[4].GetUInt16();
+ uint32 entry = fields[5].GetUInt32();
+
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_GO_LIST_CHAT, guid, entry, guid, gInfo->name.c_str(), x, y, z, mapId);
+ else
+ handler->PSendSysMessage(LANG_GO_LIST_CONSOLE, guid, gInfo->name.c_str(), x, y, z, mapId);
+ }
+ while (result->NextRow());
+ }
+
+ handler->PSendSysMessage(LANG_COMMAND_LISTOBJMESSAGE, gameObjectId, objectCount);
+
+ return true;
+ }
+
+ static bool HandleListAurasCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ Unit* unit = handler->getSelectedUnit();
+ if (!unit)
+ {
+ handler->SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ char const* talentStr = handler->GetTrinityString(LANG_TALENT);
+ char const* passiveStr = handler->GetTrinityString(LANG_PASSIVE);
+
+ Unit::AuraApplicationMap const& auras = unit->GetAppliedAuras();
+ handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, auras.size());
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
+
+ AuraApplication const* aurApp = itr->second;
+ Aura const* aura = aurApp->GetBase();
+ char const* name = aura->GetSpellInfo()->SpellName;
+
+ std::ostringstream ss_name;
+ ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
+
+ handler->PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), (handler->GetSession() ? ss_name.str().c_str() : name),
+ aurApp->GetEffectMask(), aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
+ aura->GetDuration(), aura->GetMaxDuration(), (aura->IsPassive() ? passiveStr : ""),
+ (talent ? talentStr : ""), IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",
+ GUID_LOPART(aura->GetCasterGUID()));
+ }
+
+ for (uint16 i = 0; i < TOTAL_AURAS; ++i)
+ {
+ Unit::AuraEffectList const& auraList = unit->GetAuraEffectsByType(AuraType(i));
+ if (auraList.empty())
+ continue;
+
+ handler->PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, auraList.size(), i);
+
+ for (Unit::AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end(); ++itr)
+ handler->PSendSysMessage(LANG_COMMAND_TARGET_AURASIMPLE, (*itr)->GetId(), (*itr)->GetEffIndex(), (*itr)->GetAmount());
+ }
+
+ return true;
+ }
+};
+
+void AddSC_list_commandscript()
+{
+ new list_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 2deac95d287..4aa61bbc297 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -135,15 +135,14 @@ public:
else
handler->PSendSysMessage("no VMAP available for area info");
- /*handler->PSendSysMessage(LANG_MAP_POSITION,
- object->GetMapId(), (mapEntry ? mapEntry->name[handler->GetSessionDbcLocale()] : "<unknown>"),
- zoneId, (zoneEntry ? zoneEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
- areaId, (areaEntry ? areaEntry->area_name[handler->GetSessionDbcLocale()] : "<unknown>"),
+ handler->PSendSysMessage(LANG_MAP_POSITION,
+ object->GetMapId(), (mapEntry ? mapEntry->name : "<unknown>"),
+ zoneId, (zoneEntry ? zoneEntry->area_name : "<unknown>"),
+ areaId, (areaEntry ? areaEntry->area_name : "<unknown>"),
object->GetPhaseMask(),
object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), object->GetOrientation(),
cell.GridX(), cell.GridY(), cell.CellX(), cell.CellY(), object->GetInstanceId(),
zoneX, zoneY, groundZ, floorZ, haveMap, haveVMap);
- */
LiquidData liquidStatus;
ZLiquidStatus status = map->getLiquidStatus(object->GetPositionX(), object->GetPositionY(), object->GetPositionZ(), MAP_ALL_LIQUIDS, &liquidStatus);
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 0de3637586c..57d13fd2fa1 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -64,15 +64,14 @@ public:
{ "standstate", SEC_GAMEMASTER, false, &HandleModifyStandStateCommand, "", NULL },
{ "phase", SEC_ADMINISTRATOR, false, &HandleModifyPhaseCommand, "", NULL },
{ "gender", SEC_GAMEMASTER, false, &HandleModifyGenderCommand, "", NULL },
- { "collision", SEC_GAMEMASTER, false, &HandleModifyCollisionCommand, "", NULL },
- { "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable },
+ { "speed", SEC_MODERATOR, false, NULL, "", modifyspeedCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
{
{ "morph", SEC_GAMEMASTER, false, &HandleModifyMorphCommand, "", NULL },
{ "demorph", SEC_GAMEMASTER, false, &HandleDeMorphCommand, "", NULL },
- { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
+ { "modify", SEC_MODERATOR, false, NULL, "", modifyCommandTable },
{ NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -1391,7 +1390,7 @@ public:
if (!target)
target = handler->GetSession()->GetPlayer();
- // check online security
+ // check online security
else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0))
return false;
@@ -1399,88 +1398,6 @@ public:
return true;
}
-
- static bool HandleModifyCollisionCommand(ChatHandler* handler, const char* args)
- {
- if (!*args)
- return false;
-
- Player* target = handler->getSelectedPlayer();
-
- if (!target)
- {
- handler->PSendSysMessage(LANG_PLAYER_NOT_FOUND);
- handler->SetSentErrorMessage(true);
- return false;
- }
-
- std::string param = (char*)args;
-
- if (param == "on")
- {
- // enable collision
- WorldPacket data;
- uint64 guid = target->GetGUID();
- uint8* bytes = (uint8*)&guid;
-
- data.Initialize(SMSG_MOVE_SPLINE_ENABLE_COLLISION, 1 + 8);
- data.WriteByteMask(bytes[7]);
- data.WriteByteMask(bytes[5]);
- data.WriteByteMask(bytes[4]);
- data.WriteByteMask(bytes[0]);
- data.WriteByteMask(bytes[1]);
- data.WriteByteMask(bytes[6]);
- data.WriteByteMask(bytes[2]);
- data.WriteByteMask(bytes[3]);
-
- data.WriteByteSeq(bytes[6]);
- data.WriteByteSeq(bytes[3]);
- data.WriteByteSeq(bytes[2]);
- data.WriteByteSeq(bytes[7]);
- data.WriteByteSeq(bytes[4]);
- data.WriteByteSeq(bytes[1]);
- data.WriteByteSeq(bytes[5]);
- data.WriteByteSeq(bytes[0]);
-
- target->SendMessageToSet(&data, true);
- handler->SendSysMessage("Enabled Collision");
- return true;
- }
-
- if (param == "off")
- {
- // disable collision
- WorldPacket data;
- uint64 guid = target->GetGUID();
- uint8* bytes = (uint8*)&guid;
-
- data.Initialize(SMSG_MOVE_SPLINE_DISABLE_COLLISION, 1 + 8);
- data.WriteByteMask(bytes[4]);
- data.WriteByteMask(bytes[7]);
- data.WriteByteMask(bytes[5]);
- data.WriteByteMask(bytes[3]);
- data.WriteByteMask(bytes[2]);
- data.WriteByteMask(bytes[1]);
- data.WriteByteMask(bytes[6]);
- data.WriteByteMask(bytes[0]);
-
- data.WriteByteSeq(bytes[6]);
- data.WriteByteSeq(bytes[0]);
- data.WriteByteSeq(bytes[5]);
- data.WriteByteSeq(bytes[4]);
- data.WriteByteSeq(bytes[7]);
- data.WriteByteSeq(bytes[3]);
- data.WriteByteSeq(bytes[1]);
- data.WriteByteSeq(bytes[2]);
-
- target->SendMessageToSet(&data, true);
- handler->SendSysMessage("Disabled Collision");
- return true;
- }
-
- return false;
- }
-
};
void AddSC_modify_commandscript()
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
new file mode 100644
index 00000000000..a8294dc9ddb
--- /dev/null
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -0,0 +1,310 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: reset_commandscript
+%Complete: 100
+Comment: All reset related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "ObjectAccessor.h"
+
+class reset_commandscript : public CommandScript
+{
+public:
+ reset_commandscript() : CommandScript("reset_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand resetCommandTable[] =
+ {
+ { "achievements", SEC_ADMINISTRATOR, true, &HandleResetAchievementsCommand, "", NULL },
+ { "honor", SEC_ADMINISTRATOR, true, &HandleResetHonorCommand, "", NULL },
+ { "level", SEC_ADMINISTRATOR, true, &HandleResetLevelCommand, "", NULL },
+ { "spells", SEC_ADMINISTRATOR, true, &HandleResetSpellsCommand, "", NULL },
+ { "stats", SEC_ADMINISTRATOR, true, &HandleResetStatsCommand, "", NULL },
+ { "talents", SEC_ADMINISTRATOR, true, &HandleResetTalentsCommand, "", NULL },
+ { "all", SEC_ADMINISTRATOR, true, &HandleResetAllCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ static ChatCommand commandTable[] =
+ {
+ { "reset", SEC_ADMINISTRATOR, true, NULL, "", resetCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ static bool HandleResetAchievementsCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid))
+ return false;
+
+ if (target)
+ target->GetAchievementMgr().Reset();
+ else
+ AchievementMgr::DeleteFromDB(GUID_LOPART(targetGuid));
+
+ return true;
+ }
+
+ static bool HandleResetHonorCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ if (!handler->extractPlayerTarget((char*)args, &target))
+ return false;
+
+ target->SetUInt32Value(PLAYER_FIELD_KILLS, 0);
+ target->SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, 0);
+ target->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL);
+
+ return true;
+ }
+
+ static bool HandleResetStatsOrLevelHelper(Player* player)
+ {
+ ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(player->getClass());
+ if (!classEntry)
+ {
+ sLog->outError("Class %u not found in DBC (Wrong DBC files?)", player->getClass());
+ return false;
+ }
+
+ uint8 powerType = classEntry->powerType;
+
+ // reset m_form if no aura
+ if (!player->HasAuraType(SPELL_AURA_MOD_SHAPESHIFT))
+ player->SetShapeshiftForm(FORM_NONE);
+
+ player->SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE);
+ player->SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH);
+
+ player->setFactionForRace(player->getRace());
+
+ player->SetUInt32Value(UNIT_FIELD_BYTES_0, ((player->getRace()) | (player->getClass() << 8) | (player->getGender() << 16) | (powerType << 24)));
+
+ // reset only if player not in some form;
+ if (player->GetShapeshiftForm() == FORM_NONE)
+ player->InitDisplayIds();
+
+ player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP);
+
+ player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
+
+ //-1 is default value
+ player->SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));
+
+ //player->SetUInt32Value(PLAYER_FIELD_BYTES, 0xEEE00000);
+ return true;
+ }
+
+ static bool HandleResetLevelCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ if (!handler->extractPlayerTarget((char*)args, &target))
+ return false;
+
+ if (!HandleResetStatsOrLevelHelper(target))
+ return false;
+
+ uint8 oldLevel = target->getLevel();
+
+ // set starting level
+ uint32 startLevel = target->getClass() != CLASS_DEATH_KNIGHT
+ ? sWorld->getIntConfig(CONFIG_START_PLAYER_LEVEL)
+ : sWorld->getIntConfig(CONFIG_START_HEROIC_PLAYER_LEVEL);
+
+ target->_ApplyAllLevelScaleItemMods(false);
+ target->SetLevel(startLevel);
+ target->InitRunes();
+ target->InitStatsForLevel(true);
+ target->InitTaxiNodesForLevel();
+ target->InitGlyphsForLevel();
+ target->InitTalentForLevel();
+ target->SetUInt32Value(PLAYER_XP, 0);
+
+ target->_ApplyAllLevelScaleItemMods(true);
+
+ // reset level for pet
+ if (Pet* pet = target->GetPet())
+ pet->SynchronizeLevelWithOwner();
+
+ sScriptMgr->OnPlayerLevelChanged(target, oldLevel);
+
+ return true;
+ }
+
+ static bool HandleResetSpellsCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ return false;
+
+ if (target)
+ {
+ target->resetSpells(/* bool myClassOnly */);
+
+ ChatHandler(target).SendSysMessage(LANG_RESET_SPELLS);
+ if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)
+ handler->PSendSysMessage(LANG_RESET_SPELLS_ONLINE, handler->GetNameLink(target).c_str());
+ }
+ else
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_RESET_SPELLS));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ CharacterDatabase.Execute(stmt);
+
+ handler->PSendSysMessage(LANG_RESET_SPELLS_OFFLINE, targetName.c_str());
+ }
+
+ return true;
+ }
+
+ static bool HandleResetStatsCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ if (!handler->extractPlayerTarget((char*)args, &target))
+ return false;
+
+ if (!HandleResetStatsOrLevelHelper(target))
+ return false;
+
+ target->InitRunes();
+ target->InitStatsForLevel(true);
+ target->InitTaxiNodesForLevel();
+ target->InitGlyphsForLevel();
+ target->InitTalentForLevel();
+
+ return true;
+ }
+
+ static bool HandleResetTalentsCommand(ChatHandler* handler, char const* args)
+ {
+ Player* target;
+ uint64 targetGuid;
+ std::string targetName;
+ if (!handler->extractPlayerTarget((char*)args, &target, &targetGuid, &targetName))
+ {
+ // Try reset talents as Hunter Pet
+ Creature* creature = handler->getSelectedCreature();
+ if (!*args && creature && creature->isPet())
+ {
+ Unit* owner = creature->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER && creature->ToPet()->IsPermanentPetFor(owner->ToPlayer()))
+ {
+ creature->ToPet()->resetTalents();
+ owner->ToPlayer()->SendTalentsInfoData(true);
+
+ ChatHandler(owner->ToPlayer()).SendSysMessage(LANG_RESET_PET_TALENTS);
+ if (!handler->GetSession() || handler->GetSession()->GetPlayer() != owner->ToPlayer())
+ handler->PSendSysMessage(LANG_RESET_PET_TALENTS_ONLINE, handler->GetNameLink(owner->ToPlayer()).c_str());
+ }
+ return true;
+ }
+
+ handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ if (target)
+ {
+ target->ResetTalents(true);
+ target->SendTalentsInfoData(false);
+ ChatHandler(target).SendSysMessage(LANG_RESET_TALENTS);
+ if (!handler->GetSession() || handler->GetSession()->GetPlayer() != target)
+ handler->PSendSysMessage(LANG_RESET_TALENTS_ONLINE, handler->GetNameLink(target).c_str());
+
+ Pet* pet = target->GetPet();
+ Pet::resetTalentsForAllPetsOf(target, pet);
+ if (pet)
+ target->SendTalentsInfoData(true);
+ return true;
+ }
+ else if (targetGuid)
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG);
+ stmt->setUInt16(0, uint16(AT_LOGIN_NONE | AT_LOGIN_RESET_PET_TALENTS));
+ stmt->setUInt32(1, GUID_LOPART(targetGuid));
+ CharacterDatabase.Execute(stmt);
+
+ std::string nameLink = handler->playerLink(targetName);
+ handler->PSendSysMessage(LANG_RESET_TALENTS_OFFLINE, nameLink.c_str());
+ return true;
+ }
+
+ handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ static bool HandleResetAllCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ std::string caseName = args;
+
+ AtLoginFlags atLogin;
+
+ // Command specially created as single command to prevent using short case names
+ if (caseName == "spells")
+ {
+ atLogin = AT_LOGIN_RESET_SPELLS;
+ sWorld->SendWorldText(LANG_RESETALL_SPELLS);
+ if (!handler->GetSession())
+ handler->SendSysMessage(LANG_RESETALL_SPELLS);
+ }
+ else if (caseName == "talents")
+ {
+ atLogin = AtLoginFlags(AT_LOGIN_RESET_TALENTS | AT_LOGIN_RESET_PET_TALENTS);
+ sWorld->SendWorldText(LANG_RESETALL_TALENTS);
+ if (!handler->GetSession())
+ handler->SendSysMessage(LANG_RESETALL_TALENTS);
+ }
+ else
+ {
+ handler->PSendSysMessage(LANG_RESETALL_UNKNOWN_CASE, args);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ALL_AT_LOGIN_FLAGS);
+ stmt->setUInt16(0, uint16(atLogin));
+ CharacterDatabase.Execute(stmt);
+
+ TRINITY_READ_GUARD(HashMapHolder<Player>::LockType, *HashMapHolder<Player>::GetLock());
+ HashMapHolder<Player>::MapType const& plist = sObjectAccessor->GetPlayers();
+ for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr)
+ itr->second->SetAtLoginFlag(atLogin);
+
+ return true;
+ }
+};
+
+void AddSC_reset_commandscript()
+{
+ new reset_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
new file mode 100644
index 00000000000..8f10af5fe2a
--- /dev/null
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -0,0 +1,445 @@
+/*
+ * 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/>.
+ */
+
+/* ScriptData
+Name: server_commandscript
+%Complete: 100
+Comment: All server related commands
+Category: commandscripts
+EndScriptData */
+
+#include "ScriptMgr.h"
+#include "Chat.h"
+#include "SystemConfig.h"
+#include "Config.h"
+#include "ObjectAccessor.h"
+
+class server_commandscript : public CommandScript
+{
+public:
+ server_commandscript() : CommandScript("server_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand serverIdleRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &HandleServerIdleRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverIdleShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &HandleServerIdleShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverRestartCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &HandleServerRestartCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverShutdownCommandTable[] =
+ {
+ { "cancel", SEC_ADMINISTRATOR, true, &HandleServerShutDownCancelCommand, "", NULL },
+ { "" , SEC_ADMINISTRATOR, true, &HandleServerShutDownCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverSetCommandTable[] =
+ {
+ { "difftime", SEC_CONSOLE, true, &HandleServerSetDiffTimeCommand, "", NULL },
+ { "loglevel", SEC_CONSOLE, true, &HandleServerSetLogLevelCommand, "", NULL },
+ { "logfilelevel", SEC_CONSOLE, true, &HandleServerSetLogFileLevelCommand, "", NULL },
+ { "motd", SEC_ADMINISTRATOR, true, &HandleServerSetMotdCommand, "", NULL },
+ { "closed", SEC_ADMINISTRATOR, true, &HandleServerSetClosedCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand serverCommandTable[] =
+ {
+ { "corpses", SEC_GAMEMASTER, true, &HandleServerCorpsesCommand, "", NULL },
+ { "exit", SEC_CONSOLE, true, &HandleServerExitCommand, "", NULL },
+ { "idlerestart", SEC_ADMINISTRATOR, true, NULL, "", serverIdleRestartCommandTable },
+ { "idleshutdown", SEC_ADMINISTRATOR, true, NULL, "", serverIdleShutdownCommandTable },
+ { "info", SEC_PLAYER, true, &HandleServerInfoCommand, "", NULL },
+ { "motd", SEC_PLAYER, true, &HandleServerMotdCommand, "", NULL },
+ { "plimit", SEC_ADMINISTRATOR, true, &HandleServerPLimitCommand, "", NULL },
+ { "restart", SEC_ADMINISTRATOR, true, NULL, "", serverRestartCommandTable },
+ { "shutdown", SEC_ADMINISTRATOR, true, NULL, "", serverShutdownCommandTable },
+ { "set", SEC_ADMINISTRATOR, true, NULL, "", serverSetCommandTable },
+ { "togglequerylog", SEC_CONSOLE, true, &HandleServerToggleQueryLogging, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+
+ static ChatCommand commandTable[] =
+ {
+ { "server", SEC_ADMINISTRATOR, true, NULL, "", serverCommandTable },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ // Triggering corpses expire check in world
+ static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/, char const* /*args*/)
+ {
+ sObjectAccessor->RemoveOldCorpses();
+ return true;
+ }
+
+ static bool HandleServerInfoCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ uint32 playersNum = sWorld->GetPlayerCount();
+ uint32 maxPlayersNum = sWorld->GetMaxPlayerCount();
+ uint32 activeClientsNum = sWorld->GetActiveSessionCount();
+ uint32 queuedClientsNum = sWorld->GetQueuedSessionCount();
+ uint32 maxActiveClientsNum = sWorld->GetMaxActiveSessionCount();
+ uint32 maxQueuedClientsNum = sWorld->GetMaxQueuedSessionCount();
+ std::string uptime = secsToTimeString(sWorld->GetUptime());
+ uint32 updateTime = sWorld->GetUpdateTime();
+
+ handler->SendSysMessage(_FULLVERSION);
+ handler->PSendSysMessage(LANG_CONNECTED_PLAYERS, playersNum, maxPlayersNum);
+ handler->PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum);
+ handler->PSendSysMessage(LANG_UPTIME, uptime.c_str());
+ handler->PSendSysMessage(LANG_UPDATE_DIFF, updateTime);
+ // Can't use sWorld->ShutdownMsg here in case of console command
+ if (sWorld->IsShuttingDown())
+ handler->PSendSysMessage(LANG_SHUTDOWN_TIMELEFT, secsToTimeString(sWorld->GetShutDownTimeLeft()).c_str());
+
+ return true;
+ }
+ // Display the 'Message of the day' for the realm
+ static bool HandleServerMotdCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ handler->PSendSysMessage(LANG_MOTD_CURRENT, sWorld->GetMotd());
+ return true;
+ }
+
+ static bool HandleServerPLimitCommand(ChatHandler* handler, char const* args)
+ {
+ if (*args)
+ {
+ char* paramStr = strtok((char*)args, " ");
+ if (!paramStr)
+ return false;
+
+ int32 limit = strlen(paramStr);
+
+ if (strncmp(paramStr, "player", limit) == 0)
+ sWorld->SetPlayerSecurityLimit(SEC_PLAYER);
+ else if (strncmp(paramStr, "moderator", limit) == 0)
+ sWorld->SetPlayerSecurityLimit(SEC_MODERATOR);
+ else if (strncmp(paramStr, "gamemaster", limit) == 0)
+ sWorld->SetPlayerSecurityLimit(SEC_GAMEMASTER);
+ else if (strncmp(paramStr, "administrator", limit) == 0)
+ sWorld->SetPlayerSecurityLimit(SEC_ADMINISTRATOR);
+ else if (strncmp(paramStr, "reset", limit) == 0)
+ {
+ sWorld->SetPlayerAmountLimit(ConfigMgr::GetIntDefault("PlayerLimit", 100));
+ sWorld->LoadDBAllowedSecurityLevel();
+ }
+ else
+ {
+ int32 value = atoi(paramStr);
+ if (value < 0)
+ sWorld->SetPlayerSecurityLimit(AccountTypes(-value));
+ else
+ sWorld->SetPlayerAmountLimit(uint32(value));
+ }
+ }
+
+ uint32 playerAmountLimit = sWorld->GetPlayerAmountLimit();
+ AccountTypes allowedAccountType = sWorld->GetPlayerSecurityLimit();
+ char const* secName = "";
+ switch (allowedAccountType)
+ {
+ case SEC_PLAYER:
+ secName = "Player";
+ break;
+ case SEC_MODERATOR:
+ secName = "Moderator";
+ break;
+ case SEC_GAMEMASTER:
+ secName = "Gamemaster";
+ break;
+ case SEC_ADMINISTRATOR:
+ secName = "Administrator";
+ break;
+ default:
+ secName = "<unknown>";
+ break;
+ }
+ handler->PSendSysMessage("Player limits: amount %u, min. security level %s.", playerAmountLimit, secName);
+
+ return true;
+ }
+
+ static bool HandleServerShutDownCancelCommand(ChatHandler* /*handler*/, char const* /*args*/)
+ {
+ sWorld->ShutdownCancel();
+
+ return true;
+ }
+
+ static bool HandleServerShutDownCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* timeStr = strtok((char*) args, " ");
+ char* exitCodeStr = strtok(NULL, "");
+
+ int32 time = atoi(timeStr);
+
+ // Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
+ return false;
+
+ if (exitCodeStr)
+ {
+ int32 exitCode = atoi(exitCodeStr);
+
+ // Handle atoi() errors
+ if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitCode < 0 || exitCode > 125)
+ return false;
+
+ sWorld->ShutdownServ(time, 0, exitCode);
+ }
+ else
+ sWorld->ShutdownServ(time, 0, SHUTDOWN_EXIT_CODE);
+
+ return true;
+ }
+
+ static bool HandleServerRestartCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* timeStr = strtok((char*) args, " ");
+ char* exitCodeStr = strtok(NULL, "");
+
+ int32 time = atoi(timeStr);
+
+ // Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
+ return false;
+
+ if (exitCodeStr)
+ {
+ int32 exitCode = atoi(exitCodeStr);
+
+ // Handle atoi() errors
+ if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitCode < 0 || exitCode > 125)
+ return false;
+
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, exitCode);
+ }
+ else
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART, RESTART_EXIT_CODE);
+
+ return true;
+ }
+
+ static bool HandleServerIdleRestartCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* timeStr = strtok((char*) args, " ");
+ char* exitCodeStr = strtok(NULL, "");
+
+ int32 time = atoi(timeStr);
+
+ // Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
+ return false;
+
+ if (exitCodeStr)
+ {
+ int32 exitCode = atoi(exitCodeStr);
+
+ // Handle atoi() errors
+ if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitCode < 0 || exitCode > 125)
+ return false;
+
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, exitCode);
+ }
+ else
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_RESTART | SHUTDOWN_MASK_IDLE, RESTART_EXIT_CODE);
+ return true;
+ }
+
+ static bool HandleServerIdleShutDownCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* timeStr = strtok((char*) args, " ");
+ char* exitCodeStr = strtok(NULL, "");
+
+ int32 time = atoi(timeStr);
+
+ // Prevent interpret wrong arg value as 0 secs shutdown time
+ if ((time == 0 && (timeStr[0] != '0' || timeStr[1] != '\0')) || time < 0)
+ return false;
+
+ if (exitCodeStr)
+ {
+ int32 exitCode = atoi(exitCodeStr);
+
+ // Handle atoi() errors
+ if (exitCode == 0 && (exitCodeStr[0] != '0' || exitCodeStr[1] != '\0'))
+ return false;
+
+ // Exit code should be in range of 0-125, 126-255 is used
+ // in many shells for their own return codes and code > 255
+ // is not supported in many others
+ if (exitCode < 0 || exitCode > 125)
+ return false;
+
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, exitCode);
+ }
+ else
+ sWorld->ShutdownServ(time, SHUTDOWN_MASK_IDLE, SHUTDOWN_EXIT_CODE);
+ return true;
+ }
+
+ // Exit the realm
+ static bool HandleServerExitCommand(ChatHandler* handler, char const* /*args*/)
+ {
+ handler->SendSysMessage(LANG_COMMAND_EXIT);
+ World::StopNow(SHUTDOWN_EXIT_CODE);
+ return true;
+ }
+
+ // Define the 'Message of the day' for the realm
+ static bool HandleServerSetMotdCommand(ChatHandler* handler, char const* args)
+ {
+ sWorld->SetMotd(args);
+ handler->PSendSysMessage(LANG_MOTD_NEW, args);
+ return true;
+ }
+
+ // Set whether we accept new clients
+ static bool HandleServerSetClosedCommand(ChatHandler* handler, char const* args)
+ {
+ if (strncmp(args, "on", 3) == 0)
+ {
+ handler->SendSysMessage(LANG_WORLD_CLOSED);
+ sWorld->SetClosed(true);
+ return true;
+ }
+ else if (strncmp(args, "off", 4) == 0)
+ {
+ handler->SendSysMessage(LANG_WORLD_OPENED);
+ sWorld->SetClosed(false);
+ return true;
+ }
+
+ handler->SendSysMessage(LANG_USE_BOL);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+
+ // Set the level of logging
+ static bool HandleServerSetLogFileLevelCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* newLevel = strtok((char*)args, " ");
+ if (!newLevel)
+ return false;
+
+ sLog->SetLogFileLevel(newLevel);
+ return true;
+ }
+
+ // Set the level of logging
+ static bool HandleServerSetLogLevelCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* newLevel = strtok((char*)args, " ");
+ if (!newLevel)
+ return false;
+
+ sLog->SetLogLevel(newLevel);
+ return true;
+ }
+
+ // set diff time record interval
+ static bool HandleServerSetDiffTimeCommand(ChatHandler* /*handler*/, char const* args)
+ {
+ if (!*args)
+ return false;
+
+ char* newTimeStr = strtok((char*)args, " ");
+ if (!newTimeStr)
+ return false;
+
+ int32 newTime = atoi(newTimeStr);
+ if (newTime < 0)
+ return false;
+
+ sWorld->SetRecordDiffInterval(newTime);
+ printf("Record diff every %u ms\n", newTime);
+
+ return true;
+ }
+
+ // toggle sql driver query logging
+ static bool HandleServerToggleQueryLogging(ChatHandler* handler, char const* /*args*/)
+ {
+ sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging());
+
+ if (sLog->GetSQLDriverQueryLogging())
+ handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED);
+ else
+ handler->PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED);
+ return true;
+ }
+};
+
+void AddSC_server_commandscript()
+{
+ new server_commandscript();
+}
diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp
index ca7c3af7fde..8f390d17cd4 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -97,15 +97,16 @@ public:
if (!*args)
return false;
- std::string name = args;
-
- if (!sObjectMgr->DeleteGameTele(name))
+ // id, or string, or [name] Shift-click form |color|Htele:id|h[name]|h|r
+ GameTele const* tele = handler->extractGameTeleFromLink((char*)args);
+ if (!tele)
{
handler->SendSysMessage(LANG_COMMAND_TELE_NOTFOUND);
handler->SetSentErrorMessage(true);
return false;
}
-
+ std::string name = tele->name;
+ sObjectMgr->DeleteGameTele(name);
handler->SendSysMessage(LANG_COMMAND_TP_DELETED);
return true;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
index 0279f3e2834..015c13d1098 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockSpire/boss_pyroguard_emberseer.cpp
@@ -64,7 +64,7 @@ public:
void Reset()
{
- if(instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)
+ if (instance->GetBossState(DATA_PYROGAURD_EMBERSEER) == IN_PROGRESS)
OpenDoors(false);
instance->SetBossState(DATA_PYROGAURD_EMBERSEER,NOT_STARTED);
// respawn any dead Blackhand Incarcerators
diff --git a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
index 63e753a18ba..676cd7be4f0 100644
--- a/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
+++ b/src/server/scripts/EasternKingdoms/ShadowfangKeep/shadowfang_keep.cpp
@@ -27,7 +27,11 @@ EndScriptData */
npc_shadowfang_prisoner
EndContentData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedGossip.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "ScriptedEscortAI.h"
#include "shadowfang_keep.h"
@@ -193,8 +197,48 @@ public:
};
+class spell_shadowfang_keep_haunting_spirits : public SpellScriptLoader
+{
+ public:
+ spell_shadowfang_keep_haunting_spirits() : SpellScriptLoader("spell_shadowfang_keep_haunting_spirits") { }
+
+ class spell_shadowfang_keep_haunting_spirits_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_shadowfang_keep_haunting_spirits_AuraScript);
+
+ void CalcPeriodic(AuraEffect const* /*aurEff*/, bool& isPeriodic, int32& amplitude)
+ {
+ isPeriodic = true;
+ amplitude = (irand(0, 60) + 30) * IN_MILLISECONDS;
+ }
+
+ void HandleDummyTick(AuraEffect const* aurEff)
+ {
+ GetTarget()->CastSpell((Unit*)NULL, aurEff->GetAmount(), true);
+ }
+
+ void HandleUpdatePeriodic(AuraEffect* aurEff)
+ {
+ aurEff->CalculatePeriodic(GetCaster());
+ }
+
+ void Register()
+ {
+ DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleDummyTick, EFFECT_0, SPELL_AURA_DUMMY);
+ OnEffectUpdatePeriodic += AuraEffectUpdatePeriodicFn(spell_shadowfang_keep_haunting_spirits_AuraScript::HandleUpdatePeriodic, EFFECT_0, SPELL_AURA_DUMMY);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_shadowfang_keep_haunting_spirits_AuraScript();
+ }
+};
+
void AddSC_shadowfang_keep()
{
new npc_shadowfang_prisoner();
new npc_arugal_voidwalker();
+ new spell_shadowfang_keep_haunting_spirits();
}
diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
index b5698d851f8..4fcfa8a046e 100644
--- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
+++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp
@@ -23,7 +23,10 @@ SDComment:
SDCategory: Zul'Aman
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "zulaman.h"
#define YELL_AGGRO "Da shadow gonna fall on you... "
@@ -47,54 +50,58 @@ EndScriptData */
//Defines for various powers he uses after using soul drain
-//Druid
-#define SPELL_DR_LIFEBLOOM 43421
-#define SPELL_DR_THORNS 43420
-#define SPELL_DR_MOONFIRE 43545
-
-//Hunter
-#define SPELL_HU_EXPLOSIVE_TRAP 43444
-#define SPELL_HU_FREEZING_TRAP 43447
-#define SPELL_HU_SNAKE_TRAP 43449
-
-//Mage
-#define SPELL_MG_FIREBALL 41383
-#define SPELL_MG_FROSTBOLT 43428
-#define SPELL_MG_FROST_NOVA 43426
-#define SPELL_MG_ICE_LANCE 43427
-
-//Paladin
-#define SPELL_PA_CONSECRATION 43429
-#define SPELL_PA_HOLY_LIGHT 43451
-#define SPELL_PA_AVENGING_WRATH 43430
-
-//Priest
-#define SPELL_PR_HEAL 41372
-#define SPELL_PR_MIND_CONTROL 43550
-#define SPELL_PR_MIND_BLAST 41374
-#define SPELL_PR_SW_DEATH 41375
-#define SPELL_PR_PSYCHIC_SCREAM 43432
-#define SPELL_PR_PAIN_SUPP 44416
-
-//Rogue
-#define SPELL_RO_BLIND 43433
-#define SPELL_RO_SLICE_DICE 43457
-#define SPELL_RO_WOUND_POISON 39665
-
-//Shaman
-#define SPELL_SH_FIRE_NOVA 43436
-#define SPELL_SH_HEALING_WAVE 43548
-#define SPELL_SH_CHAIN_LIGHT 43435
-
-//Warlock
-#define SPELL_WL_CURSE_OF_DOOM 43439
-#define SPELL_WL_RAIN_OF_FIRE 43440
-#define SPELL_WL_UNSTABLE_AFFL 35183
-
-//Warrior
-#define SPELL_WR_SPELL_REFLECT 43443
-#define SPELL_WR_WHIRLWIND 43442
-#define SPELL_WR_MORTAL_STRIKE 43441
+enum Spells
+{
+ // Druid
+ SPELL_DR_THORNS = 43420,
+ SPELL_DR_LIFEBLOOM = 43421,
+ SPELL_DR_MOONFIRE = 43545,
+
+ // Hunter
+ SPELL_HU_EXPLOSIVE_TRAP = 43444,
+ SPELL_HU_FREEZING_TRAP = 43447,
+ SPELL_HU_SNAKE_TRAP = 43449,
+
+ // Mage
+ SPELL_MG_FIREBALL = 41383,
+ SPELL_MG_FROST_NOVA = 43426,
+ SPELL_MG_ICE_LANCE = 43427,
+ SPELL_MG_FROSTBOLT = 43428,
+
+ // Paladin
+ SPELL_PA_CONSECRATION = 43429,
+ SPELL_PA_AVENGING_WRATH = 43430,
+ SPELL_PA_HOLY_LIGHT = 43451,
+
+ // Priest
+ SPELL_PR_HEAL = 41372,
+ SPELL_PR_MIND_BLAST = 41374,
+ SPELL_PR_SW_DEATH = 41375,
+ SPELL_PR_PSYCHIC_SCREAM = 43432,
+ SPELL_PR_MIND_CONTROL = 43550,
+ SPELL_PR_PAIN_SUPP = 44416,
+
+ // Rogue
+ SPELL_RO_BLIND = 43433,
+ SPELL_RO_SLICE_DICE = 43457,
+ SPELL_RO_WOUND_POISON = 43461,
+
+ // Shaman
+ SPELL_SH_CHAIN_LIGHT = 43435,
+ SPELL_SH_FIRE_NOVA = 43436,
+ SPELL_SH_HEALING_WAVE = 43548,
+
+ // Warlock
+ SPELL_WL_CURSE_OF_DOOM = 43439,
+ SPELL_WL_RAIN_OF_FIRE = 43440,
+ SPELL_WL_UNSTABLE_AFFL = 43522,
+ SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523,
+
+ // Warrior
+ SPELL_WR_MORTAL_STRIKE = 43441,
+ SPELL_WR_WHIRLWIND = 43442,
+ SPELL_WR_SPELL_REFLECT = 43443
+};
#define ORIENT 1.5696f
#define POS_Y 921.2795f
@@ -936,6 +943,40 @@ class boss_koragg : public CreatureScript
}
};
+class spell_hexlord_unstable_affliction : public SpellScriptLoader
+{
+ public:
+ spell_hexlord_unstable_affliction() : SpellScriptLoader("spell_hexlord_unstable_affliction") { }
+
+ class spell_hexlord_unstable_affliction_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hexlord_unstable_affliction_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_WL_UNSTABLE_AFFL_DISPEL))
+ return false;
+ return true;
+ }
+
+ void HandleDispel(DispelInfo* dispelInfo)
+ {
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(dispelInfo->GetDispeller(), SPELL_WL_UNSTABLE_AFFL_DISPEL, true, NULL, GetEffect(EFFECT_0));
+ }
+
+ void Register()
+ {
+ AfterDispel += AuraDispelFn(spell_hexlord_unstable_affliction_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hexlord_unstable_affliction_AuraScript();
+ }
+};
+
void AddSC_boss_hex_lord_malacrass()
{
new boss_hexlord_malacrass();
@@ -947,5 +988,6 @@ void AddSC_boss_hex_lord_malacrass()
new boss_fenstalker();
new boss_koragg();
new boss_alyson_antille();
+ new spell_hexlord_unstable_affliction();
}
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
index a86b2b8b17a..a70d05fa0ef 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/blackfathom_deeps.cpp
@@ -15,11 +15,13 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedGossip.h"
#include "blackfathom_deeps.h"
#include "ScriptedEscortAI.h"
-enum eSpells
+enum Spells
{
SPELL_BLESSING_OF_BLACKFATHOM = 8733,
SPELL_RAVAGE = 8391,
@@ -94,11 +96,11 @@ public:
uint32 frostNovaTimer;
uint32 frostBoltVolleyTimer;
- bool bFlee;
+ bool Flee;
void Reset()
{
- bFlee = false;
+ Flee = false;
ravageTimer = urand(5000, 8000);
frostNovaTimer = urand(9000, 12000);
@@ -140,7 +142,7 @@ public:
{
if (ravageTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_RAVAGE);
+ DoCastVictim(SPELL_RAVAGE);
ravageTimer = urand(9000, 14000);
} else ravageTimer -= diff;
break;
@@ -148,9 +150,9 @@ public:
case NPC_MURKSHALLOW_SOFTSHELL:
case NPC_BARBED_CRUSTACEAN:
{
- if (!bFlee && HealthBelowPct(15))
+ if (!Flee && HealthBelowPct(15))
{
- bFlee = true;
+ Flee = true;
me->DoFleeToGetAssistance();
}
break;
@@ -160,10 +162,7 @@ public:
if (frostBoltVolleyTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- {
- if (target)
- DoCast(target, SPELL_FROST_BOLT_VOLLEY);
- }
+ DoCast(target, SPELL_FROST_BOLT_VOLLEY);
frostBoltVolleyTimer = urand(5000, 8000);
}
else frostBoltVolleyTimer -= diff;
@@ -190,7 +189,7 @@ public:
};
};
-enum eMorridune
+enum Morridune
{
SAY_MORRIDUNE_1 = -1048003,
SAY_MORRIDUNE_2 = -1048004
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
index 32a6bcbde77..7071395812e 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_aku_mai.cpp
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
@@ -42,14 +43,14 @@ public:
}
uint32 poisonCloudTimer;
- bool bIsEnraged;
+ bool IsEnraged;
InstanceScript* instance;
void Reset()
{
poisonCloudTimer = urand(5000, 9000);
- bIsEnraged = false;
+ IsEnraged = false;
if (instance)
instance->SetData(TYPE_AKU_MAI, NOT_STARTED);
}
@@ -77,10 +78,10 @@ public:
poisonCloudTimer = urand(25000, 50000);
} else poisonCloudTimer -= diff;
- if (!bIsEnraged && HealthBelowPct(30))
+ if (!IsEnraged && HealthBelowPct(30))
{
DoCast(me, SPELL_FRENZIED_RAGE);
- bIsEnraged = true;
+ IsEnraged = true;
}
DoMeleeAttackIfReady();
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
index 5a60a849b75..1488772dc8a 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_gelihast.cpp
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
index 7ee17172102..1c754b78672 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/boss_kelris.cpp
@@ -15,7 +15,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "blackfathom_deeps.h"
enum Spells
diff --git a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
index ea33499a960..236c7b1ba69 100644
--- a/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
+++ b/src/server/scripts/Kalimdor/BlackfathomDeeps/instance_blackfathom_deeps.cpp
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Blackfathom Deeps
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "InstanceScript.h"
#include "blackfathom_deeps.h"
#define MAX_ENCOUNTER 4
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
index 85f82c62079..222626240ea 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_anetheron.cpp
@@ -15,42 +15,30 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
-#define SPELL_CARRION_SWARM 31306
-#define SPELL_SLEEP 31298
-#define SPELL_VAMPIRIC_AURA 38196
-#define SPELL_INFERNO 31299
-
-#define SAY_ONDEATH "The clock... is still... ticking."
-#define SOUND_ONDEATH 10982
-
-#define SAY_ONSLAY1 "Your hopes are lost!"
-#define SAY_ONSLAY2 "Scream for me!"
-#define SAY_ONSLAY3 "Pity, no time for a slow death!"
-#define SOUND_ONSLAY1 10981
-#define SOUND_ONSLAY2 11038
-#define SOUND_ONSLAY3 11039
-
-#define SAY_SWARM1 "The swarm is eager to feed!"
-#define SAY_SWARM2 "Pestilence upon you!"
-#define SOUND_SWARM1 10979
-#define SOUND_SWARM2 11037
-
-#define SAY_SLEEP1 "You look tired..."
-#define SAY_SLEEP2 "Sweet dreams..."
-#define SOUND_SLEEP1 10978
-#define SOUND_SLEEP2 11545
-
-#define SAY_INFERNO1 "Let fire rain from above!"
-#define SAY_INFERNO2 "Earth and sky shall burn!"
-#define SOUND_INFERNO1 10980
-#define SOUND_INFERNO2 11036
+enum Spells
+{
+ SPELL_CARRION_SWARM = 31306,
+ SPELL_SLEEP = 31298,
+ SPELL_VAMPIRIC_AURA = 38196,
+ SPELL_INFERNO = 31299,
+ SPELL_IMMOLATION = 31303,
+ SPELL_INFERNO_EFFECT = 31302,
+};
-#define SAY_ONAGGRO "You are defenders of a doomed world! Flee here, and perhaps you will prolong your pathetic lives!"
-#define SOUND_ONAGGRO 10977
+enum Texts
+{
+ SAY_ONDEATH = 0,
+ SAY_ONSLAY = 1,
+ SAY_SWARM = 2,
+ SAY_SLEEP = 3,
+ SAY_INFERNO = 4,
+ SAY_ONAGGRO = 5,
+};
class boss_anetheron : public CreatureScript
{
@@ -92,27 +80,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
- DoPlaySoundToSet(me, SOUND_ONAGGRO);
- me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
- switch (urand(0, 2))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_ONSLAY1);
- me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_ONSLAY2);
- me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
- break;
- case 2:
- DoPlaySoundToSet(me, SOUND_ONSLAY3);
- me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -130,8 +103,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_ANETHERONEVENT, DONE);
- DoPlaySoundToSet(me, SOUND_ONDEATH);
- me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -169,17 +141,7 @@ public:
DoCast(target, SPELL_CARRION_SWARM);
SwarmTimer = urand(45000, 60000);
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_SWARM1);
- me->MonsterYell(SAY_SWARM1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_SWARM2);
- me->MonsterYell(SAY_SWARM2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_SWARM);
} else SwarmTimer -= diff;
if (SleepTimer <= diff)
@@ -190,17 +152,7 @@ public:
target->CastSpell(target, SPELL_SLEEP, true);
}
SleepTimer = 60000;
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_SLEEP1);
- me->MonsterYell(SAY_SLEEP1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_SLEEP2);
- me->MonsterYell(SAY_SLEEP2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_SLEEP);
} else SleepTimer -= diff;
if (AuraTimer <= diff)
{
@@ -211,17 +163,7 @@ public:
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO);
InfernoTimer = 45000;
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_INFERNO1);
- me->MonsterYell(SAY_INFERNO1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_INFERNO2);
- me->MonsterYell(SAY_INFERNO2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_INFERNO);
} else InfernoTimer -= diff;
DoMeleeAttackIfReady();
@@ -230,9 +172,6 @@ public:
};
-#define SPELL_IMMOLATION 31303
-#define SPELL_INFERNO_EFFECT 31302
-
class mob_towering_infernal : public CreatureScript
{
public:
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
index f07aaaa1f2a..ee988accbac 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp
@@ -23,56 +23,57 @@ SDComment: Doomfires not completely offlike due to core limitations for random m
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "hyjal.h"
#include "SpellAuras.h"
#include "hyjal_trash.h"
-//text id -1534018 are the text used when previous events complete. Not part of this script.
-#define SAY_AGGRO -1534019
-#define SAY_DOOMFIRE1 -1534020
-#define SAY_DOOMFIRE2 -1534021
-#define SAY_AIR_BURST1 -1534022
-#define SAY_AIR_BURST2 -1534023
-#define SAY_SLAY1 -1534024
-#define SAY_SLAY2 -1534025
-#define SAY_SLAY3 -1534026
-#define SAY_ENRAGE -1534027
-#define SAY_DEATH -1534028
-#define SAY_SOUL_CHARGE1 -1534029
-#define SAY_SOUL_CHARGE2 -1534030
-
-#define SPELL_DENOUEMENT_WISP 32124
-#define SPELL_ANCIENT_SPARK 39349
-#define SPELL_PROTECTION_OF_ELUNE 38528
-
-#define SPELL_DRAIN_WORLD_TREE 39140
-#define SPELL_DRAIN_WORLD_TREE_2 39141
-
-#define SPELL_FINGER_OF_DEATH 31984
-#define SPELL_HAND_OF_DEATH 35354
-#define SPELL_AIR_BURST 32014
-#define SPELL_GRIP_OF_THE_LEGION 31972
-#define SPELL_DOOMFIRE_STRIKE 31903 //summons two creatures
-#define SPELL_DOOMFIRE_SPAWN 32074
-#define SPELL_DOOMFIRE 31945
-#define SPELL_SOUL_CHARGE_YELLOW 32045
-#define SPELL_SOUL_CHARGE_GREEN 32051
-#define SPELL_SOUL_CHARGE_RED 32052
-#define SPELL_UNLEASH_SOUL_YELLOW 32054
-#define SPELL_UNLEASH_SOUL_GREEN 32057
-#define SPELL_UNLEASH_SOUL_RED 32053
-#define SPELL_FEAR 31970
-
-#define CREATURE_ARCHIMONDE 17968
-#define CREATURE_DOOMFIRE 18095
-#define CREATURE_DOOMFIRE_SPIRIT 18104
-#define CREATURE_ANCIENT_WISP 17946
-#define CREATURE_CHANNEL_TARGET 22418
-
-#define NORDRASSIL_X 5503.713f
-#define NORDRASSIL_Y -3523.436f
-#define NORDRASSIL_Z 1608.781f
+enum Texts
+{
+ SAY_AGGRO = 1,
+ SAY_DOOMFIRE = 2,
+ SAY_AIR_BURST = 3,
+ SAY_SLAY = 4,
+ SAY_ENRAGE = 5,
+ SAY_DEATH = 6,
+ SAY_SOUL_CHARGE = 7,
+};
+
+enum Spells
+{
+ SPELL_DENOUEMENT_WISP = 32124,
+ SPELL_ANCIENT_SPARK = 39349,
+ SPELL_PROTECTION_OF_ELUNE = 38528,
+
+ SPELL_DRAIN_WORLD_TREE = 39140,
+ SPELL_DRAIN_WORLD_TREE_2 = 39141,
+
+ SPELL_FINGER_OF_DEATH = 31984,
+ SPELL_HAND_OF_DEATH = 35354,
+ SPELL_AIR_BURST = 32014,
+ SPELL_GRIP_OF_THE_LEGION = 31972,
+ SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
+ SPELL_DOOMFIRE_SPAWN = 32074,
+ SPELL_DOOMFIRE = 31945,
+ SPELL_SOUL_CHARGE_YELLOW = 32045,
+ SPELL_SOUL_CHARGE_GREEN = 32051,
+ SPELL_SOUL_CHARGE_RED = 32052,
+ SPELL_UNLEASH_SOUL_YELLOW = 32054,
+ SPELL_UNLEASH_SOUL_GREEN = 32057,
+ SPELL_UNLEASH_SOUL_RED = 32053,
+ SPELL_FEAR = 31970,
+};
+
+enum Summons
+{
+ CREATURE_DOOMFIRE = 18095,
+ CREATURE_DOOMFIRE_SPIRIT = 18104,
+ CREATURE_ANCIENT_WISP = 17946,
+ CREATURE_CHANNEL_TARGET = 22418,
+};
+
+Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
class mob_ancient_wisp : public CreatureScript
{
@@ -258,11 +259,11 @@ public:
uint32 GripOfTheLegionTimer;
uint32 DoomfireTimer;
uint32 SoulChargeTimer;
- uint32 SoulChargeCount;
+ uint8 SoulChargeCount;
uint32 MeleeRangeCheckTimer;
uint32 HandOfDeathTimer;
uint32 SummonWispTimer;
- uint32 WispCount;
+ uint8 WispCount;
uint32 EnrageTimer;
uint32 CheckDistanceTimer;
@@ -303,7 +304,7 @@ public:
void EnterCombat(Unit* /*who*/)
{
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
- DoScriptText(SAY_AGGRO, me);
+ Talk(SAY_AGGRO);
DoZoneInCombat();
if (instance)
@@ -312,7 +313,7 @@ public:
void KilledUnit(Unit* victim)
{
- DoScriptText(RAND(SAY_SLAY1, SAY_SLAY2, SAY_SLAY3), me);
+ Talk(SAY_SLAY);
if (victim && (victim->GetTypeId() == TYPEID_PLAYER))
GainSoulCharge(CAST_PLR(victim));
@@ -346,7 +347,7 @@ public:
void JustDied(Unit* killer)
{
hyjal_trashAI::JustDied(killer);
- DoScriptText(SAY_DEATH, me);
+ Talk(SAY_DEATH);
if (instance)
instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
@@ -488,7 +489,7 @@ public:
{
if (!IsChanneling)
{
- Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 1200000);
+ Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
if (temp)
WorldTreeGUID = temp->GetGUID();
@@ -525,14 +526,14 @@ public:
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
Enraged = true;
- DoScriptText(SAY_ENRAGE, me);
+ Talk(SAY_ENRAGE);
}
} else EnrageTimer -= diff;
if (CheckDistanceTimer <= diff)
{
// To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
- Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NORDRASSIL_X, NORDRASSIL_Y, NORDRASSIL_Z, 0, TEMPSUMMON_TIMED_DESPAWN, 2000);
+ Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
if (Check)
{
Check->SetVisible(false);
@@ -542,7 +543,7 @@ public:
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
Enraged = true;
- DoScriptText(SAY_ENRAGE, me);
+ Talk(SAY_ENRAGE);
}
}
CheckDistanceTimer = 5000;
@@ -598,11 +599,7 @@ public:
if (AirBurstTimer <= diff)
{
- if (urand(0, 1))
- DoScriptText(SAY_AIR_BURST1, me);
- else
- DoScriptText(SAY_AIR_BURST2, me);
-
+ Talk(SAY_AIR_BURST);
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
AirBurstTimer = urand(25000, 40000);
} else AirBurstTimer -= diff;
@@ -615,11 +612,7 @@ public:
if (DoomfireTimer <= diff)
{
- if (urand(0, 1))
- DoScriptText(SAY_DOOMFIRE1, me);
- else
- DoScriptText(SAY_DOOMFIRE2, me);
-
+ Talk(SAY_DOOMFIRE);
Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
if (!temp)
temp = me->getVictim();
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
index a9e0c866ab9..bfdaed35dd4 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_azgalor.cpp
@@ -15,33 +15,31 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
-#define SPELL_RAIN_OF_FIRE 31340
-#define SPELL_DOOM 31347
-#define SPELL_HOWL_OF_AZGALOR 31344
-#define SPELL_CLEAVE 31345
-#define SPELL_BERSERK 26662
-
-#define SAY_ONDEATH "Your time is almost... up"
-#define SOUND_ONDEATH 11002
-
-#define SAY_ONSLAY1 "Reesh, hokta!"
-#define SAY_ONSLAY2 "Don't fight it"
-#define SAY_ONSLAY3 "No one is going to save you"
-#define SOUND_ONSLAY1 11001
-#define SOUND_ONSLAY2 11048
-#define SOUND_ONSLAY3 11047
-
-#define SAY_DOOM1 "Just a taste... of what awaits you"
-#define SAY_DOOM2 "Suffer you despicable insect!"
-#define SOUND_DOOM1 11046
-#define SOUND_DOOM2 11000
+enum Spells
+{
+ SPELL_RAIN_OF_FIRE = 31340,
+ SPELL_DOOM = 31347,
+ SPELL_HOWL_OF_AZGALOR = 31344,
+ SPELL_CLEAVE = 31345,
+ SPELL_BERSERK = 26662,
+
+ SPELL_THRASH = 12787,
+ SPELL_CRIPPLE = 31406,
+ SPELL_WARSTOMP = 31408,
+};
-#define SAY_ONAGGRO "Abandon all hope! The legion has returned to finish what was begun so many years ago. This time there will be no escape!"
-#define SOUND_ONAGGRO 10999
+enum Texts
+{
+ SAY_ONDEATH = 0,
+ SAY_ONSLAY = 1,
+ SAY_DOOM = 2, // Not used?
+ SAY_ONAGGRO = 3,
+};
class boss_azgalor : public CreatureScript
{
@@ -88,27 +86,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
- DoPlaySoundToSet(me, SOUND_ONAGGRO);
- me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
- switch (urand(0, 2))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_ONSLAY1);
- me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_ONSLAY2);
- me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
- break;
- case 2:
- DoPlaySoundToSet(me, SOUND_ONSLAY3);
- me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -126,7 +109,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_AZGALOREVENT, DONE);
- DoPlaySoundToSet(me, SOUND_ONDEATH);
+ Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -196,10 +179,6 @@ public:
};
-#define SPELL_THRASH 12787
-#define SPELL_CRIPPLE 31406
-#define SPELL_WARSTOMP 31408
-
class mob_lesser_doomguard : public CreatureScript
{
public:
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
index 407faa19eaa..29eff68dfbd 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_kazrogal.cpp
@@ -15,30 +15,32 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
+#include "SpellScript.h"
#include "hyjal.h"
#include "hyjal_trash.h"
-#define SPELL_CLEAVE 31436
-#define SPELL_WARSTOMP 31480
-#define SPELL_MARK 31447
-
-#define SOUND_ONDEATH 11018
-
-#define SAY_ONSLAY1 "Shaza-Kiel!"
-#define SAY_ONSLAY2 "You... are nothing!"
-#define SAY_ONSLAY3 "Miserable nuisance!"
-#define SOUND_ONSLAY1 11017
-#define SOUND_ONSLAY2 11053
-#define SOUND_ONSLAY3 11054
+enum Spells
+{
+ SPELL_CLEAVE = 31436,
+ SPELL_WARSTOMP = 31480,
+ SPELL_MARK = 31447,
+ SPELL_MARK_DAMAGE = 31463
+};
-#define SAY_MARK1 "Your death will be a painful one."
-#define SAY_MARK2 "You... are marked."
-#define SOUND_MARK1 11016
-#define SOUND_MARK2 11052
+enum Texts
+{
+ SAY_ONSLAY = 0,
+ SAY_MARK = 1,
+ SAY_ONAGGRO = 2,
+};
-#define SAY_ONAGGRO "Cry for mercy! Your meaningless lives will soon be forfeit."
-#define SOUND_ONAGGRO 11015
+enum Sounds
+{
+ SOUND_ONDEATH = 11018,
+};
class boss_kazrogal : public CreatureScript
{
@@ -80,27 +82,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
- DoPlaySoundToSet(me, SOUND_ONAGGRO);
- me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
- switch (urand(0, 2))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_ONSLAY1);
- me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_ONSLAY2);
- me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
- break;
- case 2:
- DoPlaySoundToSet(me, SOUND_ONSLAY3);
- me->MonsterYell(SAY_ONSLAY3, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -162,37 +149,15 @@ public:
WarStompTimer = 60000;
} else WarStompTimer -= diff;
- if (me->HasAura(SPELL_MARK))
- me->RemoveAurasDueToSpell(SPELL_MARK);
if (MarkTimer <= diff)
{
- //cast dummy, useful for bos addons
- me->CastCustomSpell(me, SPELL_MARK, NULL, NULL, NULL, false, NULL, NULL, me->GetGUID());
+ DoCastAOE(SPELL_MARK);
- std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
- for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
- {
- Unit* target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
- if (target && target->GetTypeId() == TYPEID_PLAYER && target->getPowerType() == POWER_MANA)
- {
- target->CastSpell(target, SPELL_MARK, true);//only cast on mana users
- }
- }
MarkTimerBase -= 5000;
if (MarkTimerBase < 5500)
MarkTimerBase = 5500;
MarkTimer = MarkTimerBase;
- switch (urand(0, 2))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_MARK1);
- me->MonsterYell(SAY_MARK1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_MARK2);
- me->MonsterYell(SAY_MARK2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_MARK);
} else MarkTimer -= diff;
DoMeleeAttackIfReady();
@@ -201,7 +166,79 @@ public:
};
+class MarkTargetFilter
+{
+ public:
+ bool operator()(WorldObject* target) const
+ {
+ if (Unit* unit = target->ToUnit())
+ return unit->getPowerType() != POWER_MANA;
+ return false;
+ }
+};
+
+class spell_mark_of_kazrogal : public SpellScriptLoader
+{
+ public:
+ spell_mark_of_kazrogal() : SpellScriptLoader("spell_mark_of_kazrogal") { }
+
+ class spell_mark_of_kazrogal_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_mark_of_kazrogal_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(MarkTargetFilter());
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_kazrogal_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ class spell_mark_of_kazrogal_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mark_of_kazrogal_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MARK_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ Unit* target = GetTarget();
+
+ if (target->GetPower(POWER_MANA) == 0)
+ {
+ target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff);
+ // Remove aura
+ SetDuration(0);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazrogal_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_mark_of_kazrogal_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_mark_of_kazrogal_AuraScript();
+ }
+};
+
void AddSC_boss_kazrogal()
{
new boss_kazrogal();
+ new spell_mark_of_kazrogal();
}
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
index 5d7ee1fe194..09c8c1605b3 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_rage_winterchill.cpp
@@ -15,36 +15,27 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
-#define SPELL_FROST_ARMOR 31256
-#define SPELL_DEATH_AND_DECAY 31258
-
-#define SPELL_FROST_NOVA 31250
-#define SPELL_ICEBOLT 31249
-
-#define SAY_ONDEATH "You have won this battle, but not... the... war"
-#define SOUND_ONDEATH 11026
-
-#define SAY_ONSLAY1 "All life must perish!"
-#define SAY_ONSLAY2 "Victory to the Legion!"
-#define SOUND_ONSLAY1 11025
-#define SOUND_ONSLAY2 11057
-
-#define SAY_DECAY1 "Crumble and rot!"
-#define SAY_DECAY2 "Ashes to ashes, dust to dust"
-#define SOUND_DECAY1 11023
-#define SOUND_DECAY2 11055
-
-#define SAY_NOVA1 "Succumb to the icy chill... of death!"
-#define SAY_NOVA2 "It will be much colder in your grave"
-#define SOUND_NOVA1 11024
-#define SOUND_NOVA2 11058
+enum Spells
+{
+ SPELL_FROST_ARMOR = 31256,
+ SPELL_DEATH_AND_DECAY = 31258,
+ SPELL_FROST_NOVA = 31250,
+ SPELL_ICEBOLT = 31249,
+};
-#define SAY_ONAGGRO "The Legion's final conquest has begun! Once again the subjugation of this world is within our grasp. Let none survive!"
-#define SOUND_ONAGGRO 11022
+enum Texts
+{
+ SAY_ONDEATH = 0,
+ SAY_ONSLAY = 1,
+ SAY_DECAY = 2,
+ SAY_NOVA = 3,
+ SAY_ONAGGRO = 4,
+};
class boss_rage_winterchill : public CreatureScript
{
@@ -86,23 +77,12 @@ public:
{
if (instance && IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
- DoPlaySoundToSet(me, SOUND_ONAGGRO);
- me->MonsterYell(SAY_ONAGGRO, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONAGGRO);
}
void KilledUnit(Unit* /*victim*/)
{
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_ONSLAY1);
- me->MonsterYell(SAY_ONSLAY1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_ONSLAY2);
- me->MonsterYell(SAY_ONSLAY2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_ONSLAY);
}
void WaypointReached(uint32 waypointId)
@@ -120,8 +100,7 @@ public:
hyjal_trashAI::JustDied(killer);
if (instance && IsEvent)
instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE);
- DoPlaySoundToSet(me, SOUND_ONDEATH);
- me->MonsterYell(SAY_ONDEATH, LANG_UNIVERSAL, 0);
+ Talk(SAY_ONDEATH);
}
void UpdateAI(const uint32 diff)
@@ -162,33 +141,13 @@ public:
{
DoCast(me->getVictim(), SPELL_DEATH_AND_DECAY);
DecayTimer = 60000+rand()%20000;
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_DECAY1);
- me->MonsterYell(SAY_DECAY1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_DECAY2);
- me->MonsterYell(SAY_DECAY2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_DECAY);
} else DecayTimer -= diff;
if (NovaTimer <= diff)
{
DoCast(me->getVictim(), SPELL_FROST_NOVA);
NovaTimer = 30000+rand()%15000;
- switch (urand(0, 1))
- {
- case 0:
- DoPlaySoundToSet(me, SOUND_NOVA1);
- me->MonsterYell(SAY_NOVA1, LANG_UNIVERSAL, 0);
- break;
- case 1:
- DoPlaySoundToSet(me, SOUND_NOVA2);
- me->MonsterYell(SAY_NOVA2, LANG_UNIVERSAL, 0);
- break;
- }
+ Talk(SAY_NOVA);
} else NovaTimer -= diff;
if (IceboltTimer <= diff)
{
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp
index 22307468f14..1be8f8e058f 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp
@@ -29,7 +29,9 @@ npc_thrall
npc_tyrande_whisperwind
EndContentData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedGossip.h"
#include "hyjalAI.h"
#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore."
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
index e045d3cbf05..6d62072608d 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.h
@@ -21,7 +21,7 @@
#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy."
-enum eTypes
+enum Types
{
WORLD_STATE_WAVES = 2842,
WORLD_STATE_ENEMY = 2453,
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
index 2f6bbb7edb5..a407f86ba70 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp
@@ -23,17 +23,22 @@ SDComment:
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedEscortAI.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "Cell.h"
+#include "CellImpl.h"
#include "hyjalAI.h"
#include "hyjal_trash.h"
-#include "MapManager.h"
-#include "Language.h"
-#include "Chat.h"
-#include "Object.h"
-
-#define SPAWN_GARG_GATE 0
-#define SPAWN_WYRM_GATE 1
-#define SPAWN_NEAR_TOWER 2
+
+enum Spawns
+{
+ SPAWN_GARG_GATE = 0,
+ SPAWN_WYRM_GATE = 1,
+ SPAWN_NEAR_TOWER = 2,
+};
#define YELL_HURRY "Hurry, we don't have much time"
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
index b32288ca43a..68efa94d98b 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h
@@ -24,43 +24,49 @@
#define HYJAL_AI_MAX_SPELLS 3
-// Trash Mobs summoned in waves
-#define NECROMANCER 17899//done
-#define ABOMINATION 17898//done
-#define GHOUL 17895//done
-#define BANSHEE 17905//done
-#define CRYPT_FIEND 17897//done
-#define GARGOYLE 17906//done
-#define FROST_WYRM 17907//done
-#define GIANT_INFERNAL 17908//done
-#define FEL_STALKER 17916//done
-
-#define JAINA 17772
-#define THRALL 17852
-#define TYRANDE 17948
-
-#define ANCIENT_VEIN 185557
-#define FLAMEOBJECT 182592
-
-// Bosses summoned after every 8 waves
-#define RAGE_WINTERCHILL 17767
-#define ANETHERON 17808
-#define KAZROGAL 17888
-#define AZGALOR 17842
-#define ARCHIMONDE 17968
-
-#define SPELL_TELEPORT_VISUAL 41232
-#define SPELL_MASS_TELEPORT 16807
-
-//Spells for Jaina
-#define SPELL_BRILLIANCE_AURA 31260 // The database must handle this spell via creature_addon(it should, but is removed in evade..)
-#define SPELL_BLIZZARD 31266
-#define SPELL_PYROBLAST 31263
-#define SPELL_SUMMON_ELEMENTALS 31264
-
-//Thrall spells
-#define SPELL_CHAIN_LIGHTNING 31330
-#define SPELL_SUMMON_DIRE_WOLF 31331
+enum CreaturesIds
+{
+ // Trash Mobs summoned in waves
+ NECROMANCER = 17899,
+ ABOMINATION = 17898,
+ GHOUL = 17895,
+ BANSHEE = 17905,
+ CRYPT_FIEND = 17897,
+ GARGOYLE = 17906,
+ FROST_WYRM = 17907,
+ GIANT_INFERNAL = 17908,
+ FEL_STALKER = 17916,
+
+ JAINA = 17772,
+ THRALL = 17852,
+ TYRANDE = 17948,
+
+ ANCIENT_VEIN = 185557,
+ FLAMEOBJECT = 182592,
+
+ // Bosses summoned after every 8 waves
+ RAGE_WINTERCHILL = 17767,
+ ANETHERON = 17808,
+ KAZROGAL = 17888,
+ AZGALOR = 17842,
+ ARCHIMONDE = 17968,
+};
+
+enum SpellIds
+{
+ SPELL_TELEPORT_VISUAL = 41232,
+ SPELL_MASS_TELEPORT = 16807,
+
+ //Spells for Jaina
+ SPELL_BRILLIANCE_AURA = 31260, // The database must handle this spell via creature_addon(it should, but is removed in evade..)
+ SPELL_BLIZZARD = 31266,
+ SPELL_PYROBLAST = 31263,
+ SPELL_SUMMON_ELEMENTALS = 31264,
+
+ //Thrall spells
+ SPELL_CHAIN_LIGHTNING = 31330,
+ SPELL_SUMMON_DIRE_WOLF = 31331,
+};
struct Wave
{
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
index 840aa5de081..d3218e1729e 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp
@@ -15,16 +15,35 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
#include "hyjal.h"
#include "hyjal_trash.h"
#include "hyjalAI.h"
-#define SPELL_METEOR 33814 //infernal visual
-#define SPELL_IMMOLATION 37059
-#define SPELL_FLAME_BUFFET 31724
-#define NPC_TRIGGER 21987 //World Trigger (Tiny)
-#define MODEL_INVIS 11686 //invisible model
+enum Spells
+{
+ SPELL_METEOR = 33814, //infernal visual
+ SPELL_IMMOLATION = 37059,
+ SPELL_FLAME_BUFFET = 31724,
+ NPC_TRIGGER = 21987, //World Trigger (Tiny)
+ MODEL_INVIS = 11686, //invisible model
+ SPELL_DISEASE_CLOUD = 31607,
+ SPELL_KNOCKDOWN = 31610,
+ SPELL_FRENZY = 31540,
+ SPELL_RAISE_DEAD_1 = 31617,
+ SPELL_RAISE_DEAD_2 = 31624,
+ SPELL_RAISE_DEAD_3 = 31625,
+ SPELL_SHADOW_BOLT = 31627,
+ SPELL_BANSHEE_CURSE = 31651,
+ SPELL_BANSHEE_WAIL = 38183,
+ SPELL_ANTI_MAGIC_SHELL = 31662,
+ SPELL_WEB = 28991,
+ SPELL_MANA_BURN = 31729,
+ SPELL_FROST_BREATH = 31688,
+ SPELL_GARGOYLE_STRIKE = 31664,
+ SPELL_EXPLODING_SHOT = 7896,
+};
float HordeWPs[8][3]=//basic waypoints from spawn to leader
{
@@ -522,9 +541,6 @@ public:
}
};
-#define SPELL_DISEASE_CLOUD 31607
-#define SPELL_KNOCKDOWN 31610
-
class mob_abomination : public CreatureScript
{
public:
@@ -623,8 +639,6 @@ public:
};
-#define SPELL_FRENZY 31540
-
class mob_ghoul : public CreatureScript
{
public:
@@ -727,11 +741,6 @@ public:
};
-#define SPELL_RAISE_DEAD_1 31617
-#define SPELL_RAISE_DEAD_2 31624
-#define SPELL_RAISE_DEAD_3 31625
-#define SPELL_SHADOW_BOLT 31627
-
class mob_necromancer : public CreatureScript
{
public:
@@ -859,10 +868,6 @@ public:
};
-#define SPELL_BANSHEE_CURSE 31651
-#define SPELL_BANSHEE_WAIL 38183
-#define SPELL_ANTI_MAGIC_SHELL 31662
-
class mob_banshee : public CreatureScript
{
public:
@@ -966,8 +971,6 @@ public:
};
-#define SPELL_WEB 28991
-
class mob_crypt_fiend : public CreatureScript
{
public:
@@ -1058,8 +1061,6 @@ public:
};
-#define SPELL_MANA_BURN 31729
-
class mob_fel_stalker : public CreatureScript
{
public:
@@ -1150,8 +1151,6 @@ public:
};
-#define SPELL_FROST_BREATH 31688
-
class mob_frost_wyrm : public CreatureScript
{
public:
@@ -1264,8 +1263,6 @@ public:
};
-#define SPELL_GARGOYLE_STRIKE 31664
-
class mob_gargoyle : public CreatureScript
{
public:
@@ -1402,8 +1399,6 @@ public:
};
-#define SPELL_EXPLODING_SHOT 7896
-
class alliance_rifleman : public CreatureScript
{
public:
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
index ad8ebdb370a..69bb8285404 100644
--- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
+++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp
@@ -23,15 +23,16 @@ SDComment: Instance Data Scripts and functions to acquire mobs and set encounter
SDCategory: Caverns of Time, Mount Hyjal
EndScriptData */
-#include "ScriptPCH.h"
-#include "hyjal.h"
+#include "ScriptMgr.h"
+#include "InstanceScript.h"
+#include "ScriptedCreature.h"
#include "hyjal_trash.h"
-enum eEnums
+enum Misc
{
MAX_ENCOUNTER = 5,
- GO_ANCIENT_GEM = 185557
+ GO_ANCIENT_GEM = 185557,
};
/* Battle of Mount Hyjal encounters:
0 - Rage Winterchill event
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 d7043965271..b23d15cd1b5 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_celebras_the_cursed.cpp
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
enum Spells
{
@@ -46,15 +47,15 @@ public:
{
celebras_the_cursedAI(Creature* creature) : ScriptedAI(creature) {}
- uint32 Wrath_Timer;
- uint32 EntanglingRoots_Timer;
- uint32 CorruptForces_Timer;
+ uint32 WrathTimer;
+ uint32 EntanglingRootsTimer;
+ uint32 CorruptForcesTimer;
void Reset()
{
- Wrath_Timer = 8000;
- EntanglingRoots_Timer = 2000;
- CorruptForces_Timer = 30000;
+ WrathTimer = 8000;
+ EntanglingRootsTimer = 2000;
+ CorruptForcesTimer = 30000;
}
void EnterCombat(Unit* /*who*/) { }
@@ -70,32 +71,30 @@ public:
return;
//Wrath
- if (Wrath_Timer <= diff)
+ if (WrathTimer <= diff)
{
- Unit* target = NULL;
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_WRATH);
- Wrath_Timer = 8000;
+ WrathTimer = 8000;
}
- else Wrath_Timer -= diff;
+ else WrathTimer -= diff;
//EntanglingRoots
- if (EntanglingRoots_Timer <= diff)
+ if (EntanglingRootsTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_ENTANGLINGROOTS);
- EntanglingRoots_Timer = 20000;
+ DoCastVictim(SPELL_ENTANGLINGROOTS);
+ EntanglingRootsTimer = 20000;
}
- else EntanglingRoots_Timer -= diff;
+ else EntanglingRootsTimer -= diff;
//CorruptForces
- if (CorruptForces_Timer <= diff)
+ if (CorruptForcesTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_CORRUPT_FORCES);
- CorruptForces_Timer = 20000;
+ CorruptForcesTimer = 20000;
}
- else CorruptForces_Timer -= diff;
+ else CorruptForcesTimer -= diff;
DoMeleeAttackIfReady();
}
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
index ea419793ae8..b4128ea80ee 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_landslide.cpp
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
enum Spells
{
@@ -46,15 +47,15 @@ public:
{
boss_landslideAI(Creature* creature) : ScriptedAI(creature) {}
- uint32 KnockAway_Timer;
- uint32 Trample_Timer;
- uint32 Landslide_Timer;
+ uint32 KnockAwayTimer;
+ uint32 TrampleTimer;
+ uint32 LandslideTimer;
void Reset()
{
- KnockAway_Timer = 8000;
- Trample_Timer = 2000;
- Landslide_Timer = 0;
+ KnockAwayTimer = 8000;
+ TrampleTimer = 2000;
+ LandslideTimer = 0;
}
void EnterCombat(Unit* /*who*/)
@@ -66,32 +67,32 @@ public:
if (!UpdateVictim())
return;
- //KnockAway_Timer
- if (KnockAway_Timer <= diff)
+ //KnockAwayTimer
+ if (KnockAwayTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_KNOCKAWAY);
- KnockAway_Timer = 15000;
+ DoCastVictim(SPELL_KNOCKAWAY);
+ KnockAwayTimer = 15000;
}
- else KnockAway_Timer -= diff;
+ else KnockAwayTimer -= diff;
- //Trample_Timer
- if (Trample_Timer <= diff)
+ //TrampleTimer
+ if (TrampleTimer <= diff)
{
DoCast(me, SPELL_TRAMPLE);
- Trample_Timer = 8000;
+ TrampleTimer = 8000;
}
- else Trample_Timer -= diff;
+ else TrampleTimer -= diff;
//Landslide
if (HealthBelowPct(50))
{
- if (Landslide_Timer <= diff)
+ if (LandslideTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCast(me, SPELL_LANDSLIDE);
- Landslide_Timer = 60000;
+ LandslideTimer = 60000;
}
- else Landslide_Timer -= diff;
+ else LandslideTimer -= diff;
}
DoMeleeAttackIfReady();
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
index 18ce7be0f0a..ece3ff83776 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_noxxion.cpp
@@ -23,7 +23,9 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+
enum Spells
{
SPELL_TOXICVOLLEY = 21687,
@@ -44,24 +46,22 @@ public:
{
boss_noxxionAI(Creature* creature) : ScriptedAI(creature) {}
- uint32 ToxicVolley_Timer;
- uint32 Uppercut_Timer;
- uint32 Adds_Timer;
- uint32 Invisible_Timer;
+ uint32 ToxicVolleyTimer;
+ uint32 UppercutTimer;
+ uint32 AddsTimer;
+ uint32 InvisibleTimer;
bool Invisible;
void Reset()
{
- ToxicVolley_Timer = 7000;
- Uppercut_Timer = 16000;
- Adds_Timer = 19000;
- Invisible_Timer = 15000; //Too much too low?
+ ToxicVolleyTimer = 7000;
+ UppercutTimer = 16000;
+ AddsTimer = 19000;
+ InvisibleTimer = 15000; //Too much too low?
Invisible = false;
}
- void EnterCombat(Unit* /*who*/)
- {
- }
+ void EnterCombat(Unit* /*who*/) {}
void SummonAdds(Unit* victim)
{
@@ -71,7 +71,7 @@ public:
void UpdateAI(const uint32 diff)
{
- if (Invisible && Invisible_Timer <= diff)
+ if (Invisible && InvisibleTimer <= diff)
{
//Become visible again
me->setFaction(14);
@@ -83,7 +83,7 @@ public:
}
else if (Invisible)
{
- Invisible_Timer -= diff;
+ InvisibleTimer -= diff;
//Do nothing while invisible
return;
}
@@ -92,24 +92,24 @@ public:
if (!UpdateVictim())
return;
- //ToxicVolley_Timer
- if (ToxicVolley_Timer <= diff)
+ //ToxicVolleyTimer
+ if (ToxicVolleyTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_TOXICVOLLEY);
- ToxicVolley_Timer = 9000;
+ DoCastVictim(SPELL_TOXICVOLLEY);
+ ToxicVolleyTimer = 9000;
}
- else ToxicVolley_Timer -= diff;
+ else ToxicVolleyTimer -= diff;
- //Uppercut_Timer
- if (Uppercut_Timer <= diff)
+ //UppercutTimer
+ if (UppercutTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_UPPERCUT);
- Uppercut_Timer = 12000;
+ DoCastVictim(SPELL_UPPERCUT);
+ UppercutTimer = 12000;
}
- else Uppercut_Timer -= diff;
+ else UppercutTimer -= diff;
- //Adds_Timer
- if (!Invisible && Adds_Timer <= diff)
+ //AddsTimer
+ if (!Invisible && AddsTimer <= diff)
{
//Interrupt any spell casting
//me->m_canMove = true;
@@ -124,11 +124,11 @@ public:
SummonAdds(me->getVictim());
SummonAdds(me->getVictim());
Invisible = true;
- Invisible_Timer = 15000;
+ InvisibleTimer = 15000;
- Adds_Timer = 40000;
+ AddsTimer = 40000;
}
- else Adds_Timer -= diff;
+ else AddsTimer -= diff;
DoMeleeAttackIfReady();
}
diff --git a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
index 039d30071d2..1f887d7ce64 100644
--- a/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
+++ b/src/server/scripts/Kalimdor/Maraudon/boss_princess_theradras.cpp
@@ -23,7 +23,8 @@ SDComment:
SDCategory: Maraudon
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
enum Spells
{
@@ -47,17 +48,17 @@ public:
{
boss_ptheradrasAI(Creature* creature) : ScriptedAI(creature) {}
- uint32 Dustfield_Timer;
- uint32 Boulder_Timer;
- uint32 Thrash_Timer;
- uint32 RepulsiveGaze_Timer;
+ uint32 DustfieldTimer;
+ uint32 BoulderTimer;
+ uint32 ThrashTimer;
+ uint32 RepulsiveGazeTimer;
void Reset()
{
- Dustfield_Timer = 8000;
- Boulder_Timer = 2000;
- Thrash_Timer = 5000;
- RepulsiveGaze_Timer = 23000;
+ DustfieldTimer = 8000;
+ BoulderTimer = 2000;
+ ThrashTimer = 5000;
+ RepulsiveGazeTimer = 23000;
}
void EnterCombat(Unit* /*who*/) {}
@@ -72,40 +73,38 @@ public:
if (!UpdateVictim())
return;
- //Dustfield_Timer
- if (Dustfield_Timer <= diff)
+ //DustfieldTimer
+ if (DustfieldTimer <= diff)
{
DoCast(me, SPELL_DUSTFIELD);
- Dustfield_Timer = 14000;
+ DustfieldTimer = 14000;
}
- else Dustfield_Timer -= diff;
+ else DustfieldTimer -= diff;
- //Boulder_Timer
- if (Boulder_Timer <= diff)
+ //BoulderTimer
+ if (BoulderTimer <= diff)
{
- Unit* target = NULL;
- target = SelectTarget(SELECT_TARGET_RANDOM, 0);
- if (target)
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_BOULDER);
- Boulder_Timer = 10000;
+ BoulderTimer = 10000;
}
- else Boulder_Timer -= diff;
+ else BoulderTimer -= diff;
- //RepulsiveGaze_Timer
- if (RepulsiveGaze_Timer <= diff)
+ //RepulsiveGazeTimer
+ if (RepulsiveGazeTimer <= diff)
{
- DoCast(me->getVictim(), SPELL_REPULSIVEGAZE);
- RepulsiveGaze_Timer = 20000;
+ DoCastVictim(SPELL_REPULSIVEGAZE);
+ RepulsiveGazeTimer = 20000;
}
- else RepulsiveGaze_Timer -= diff;
+ else RepulsiveGazeTimer -= diff;
- //Thrash_Timer
- if (Thrash_Timer <= diff)
+ //ThrashTimer
+ if (ThrashTimer <= diff)
{
DoCast(me, SPELL_THRASH);
- Thrash_Timer = 18000;
+ ThrashTimer = 18000;
}
- else Thrash_Timer -= diff;
+ else ThrashTimer -= diff;
DoMeleeAttackIfReady();
}
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
index 6e6e089ba02..1fdf941d75c 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/boss_onyxia.cpp
@@ -25,10 +25,15 @@ SDComment: <Known bugs>
SDCategory: Onyxia's Lair
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
#include "onyxias_lair.h"
-enum eYells
+enum Yells
{
SAY_AGGRO = -1249000,
SAY_KILL = -1249001,
@@ -37,7 +42,7 @@ enum eYells
EMOTE_BREATH = -1249004,
};
-enum eSpells
+enum Spells
{
// Phase 1 spells
SPELL_WING_BUFFET = 18500,
@@ -67,15 +72,15 @@ enum eSpells
SPELL_BELLOWING_ROAR = 18431,
};
-struct sOnyxMove
+struct OnyxMove
{
- uint32 uiLocId;
- uint32 uiLocIdEnd;
- uint32 uiSpellId;
+ uint8 LocId;
+ uint8 LocIdEnd;
+ uint32 SpellId;
float fX, fY, fZ;
};
-static sOnyxMove aMoveData[]=
+static OnyxMove MoveData[8]=
{
{0, 1, SPELL_BREATH_WEST_TO_EAST, -33.5561f, -182.682f, -56.9457f}, //west
{1, 0, SPELL_BREATH_EAST_TO_WEST, -31.4963f, -250.123f, -55.1278f}, //east
@@ -87,11 +92,11 @@ static sOnyxMove aMoveData[]=
{7, 6, SPELL_BREATH_NORTH_TO_SOUTH, 22.8763f, -217.152f, -55.0548f}, //north
};
-const Position MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f};
+Position const MiddleRoomLocation = {-23.6155f, -215.357f, -55.7344f, 0.0f};
-const Position Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f};
+Position const Phase2Location = {-80.924f, -214.299f, -82.942f, 0.0f};
-static Position aSpawnLocations[3]=
+Position const SpawnLocations[3]=
{
//Whelps
{-30.127f, -254.463f, -89.440f, 0.0f},
@@ -121,58 +126,58 @@ public:
InstanceScript* instance;
SummonList Summons;
- uint32 m_uiPhase;
+ uint32 Phase;
- uint32 m_uiFlameBreathTimer;
- uint32 m_uiCleaveTimer;
- uint32 m_uiTailSweepTimer;
- uint32 m_uiWingBuffetTimer;
+ uint32 FlameBreathTimer;
+ uint32 CleaveTimer;
+ uint32 TailSweepTimer;
+ uint32 WingBuffetTimer;
- uint32 m_uiMovePoint;
- uint32 m_uiMovementTimer;
- sOnyxMove* m_pPointData;
+ uint8 MovePoint;
+ uint32 MovementTimer;
+ OnyxMove* PointData;
- uint32 m_uiFireballTimer;
- uint32 m_uiWhelpTimer;
- uint32 m_uiLairGuardTimer;
- uint32 m_uiDeepBreathTimer;
+ uint32 FireballTimer;
+ uint32 WhelpTimer;
+ uint32 LairGuardTimer;
+ uint32 DeepBreathTimer;
- uint32 m_uiBellowingRoarTimer;
+ uint32 BellowingRoarTimer;
- uint8 m_uiSummonWhelpCount;
- bool m_bIsMoving;
+ uint8 SummonWhelpCount;
+ bool IsMoving;
void Reset()
{
if (!IsCombatMovementAllowed())
SetCombatMovement(true);
- m_uiPhase = PHASE_START;
+ Phase = PHASE_START;
- m_uiFlameBreathTimer = urand(10000, 20000);
- m_uiTailSweepTimer = urand(15000, 20000);
- m_uiCleaveTimer = urand(2000, 5000);
- m_uiWingBuffetTimer = urand(10000, 20000);
+ FlameBreathTimer = urand(10000, 20000);
+ TailSweepTimer = urand(15000, 20000);
+ CleaveTimer = urand(2000, 5000);
+ WingBuffetTimer = urand(10000, 20000);
- m_uiMovePoint = urand(0, 5);
- m_uiMovementTimer = 14000;
- m_pPointData = GetMoveData();
+ MovePoint = urand(0, 5);
+ MovementTimer = 14000;
+ PointData = GetMoveData();
- m_uiFireballTimer = 15000;
- m_uiWhelpTimer = 60000;
- m_uiLairGuardTimer = 60000;
- m_uiDeepBreathTimer = 85000;
+ FireballTimer = 15000;
+ WhelpTimer = 60000;
+ LairGuardTimer = 60000;
+ DeepBreathTimer = 85000;
- m_uiBellowingRoarTimer = 30000;
+ BellowingRoarTimer = 30000;
Summons.DespawnAll();
- m_uiSummonWhelpCount = 0;
- m_bIsMoving = false;
+ SummonWhelpCount = 0;
+ IsMoving = false;
if (instance)
{
instance->SetData(DATA_ONYXIA, NOT_STARTED);
- instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
+ instance->SetData(DATA_ONYXIA_PHASE, Phase);
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
}
@@ -206,7 +211,7 @@ public:
switch (summoned->GetEntry())
{
case NPC_WHELP:
- ++m_uiSummonWhelpCount;
+ ++SummonWhelpCount;
break;
case NPC_LAIRGUARD:
summoned->setActive(true);
@@ -225,17 +230,17 @@ public:
DoScriptText(SAY_KILL, me);
}
- void SpellHit(Unit* /*pCaster*/, const SpellInfo* pSpell)
+ void SpellHit(Unit* /*pCaster*/, const SpellInfo* Spell)
{
- if (pSpell->Id == SPELL_BREATH_EAST_TO_WEST ||
- pSpell->Id == SPELL_BREATH_WEST_TO_EAST ||
- pSpell->Id == SPELL_BREATH_SE_TO_NW ||
- pSpell->Id == SPELL_BREATH_NW_TO_SE ||
- pSpell->Id == SPELL_BREATH_SW_TO_NE ||
- pSpell->Id == SPELL_BREATH_NE_TO_SW)
+ if (Spell->Id == SPELL_BREATH_EAST_TO_WEST ||
+ Spell->Id == SPELL_BREATH_WEST_TO_EAST ||
+ Spell->Id == SPELL_BREATH_SE_TO_NW ||
+ Spell->Id == SPELL_BREATH_NW_TO_SE ||
+ Spell->Id == SPELL_BREATH_SW_TO_NE ||
+ Spell->Id == SPELL_BREATH_NE_TO_SW)
{
- m_pPointData = GetMoveData();
- m_uiMovePoint = m_pPointData->uiLocIdEnd;
+ PointData = GetMoveData();
+ MovePoint = PointData->LocIdEnd;
me->SetSpeed(MOVE_FLIGHT, 1.5f);
me->GetMotionMaster()->MovePoint(8, MiddleRoomLocation);
@@ -249,16 +254,16 @@ public:
switch (id)
{
case 8:
- m_pPointData = GetMoveData();
- if (m_pPointData)
+ PointData = GetMoveData();
+ if (PointData)
{
me->SetSpeed(MOVE_FLIGHT, 1.0f);
- me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
+ me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
}
break;
case 9:
me->GetMotionMaster()->MoveChase(me->getVictim());
- m_uiBellowingRoarTimer = 1000;
+ BellowingRoarTimer = 1000;
break;
case 10:
me->SetCanFly(true);
@@ -266,39 +271,39 @@ public:
me->SetSpeed(MOVE_FLIGHT, 1.0f);
DoScriptText(SAY_PHASE_2_TRANS, me);
if (instance)
- instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
- m_uiWhelpTimer = 5000;
- m_uiLairGuardTimer = 15000;
+ instance->SetData(DATA_ONYXIA_PHASE, Phase);
+ WhelpTimer = 5000;
+ LairGuardTimer = 15000;
break;
case 11:
- if (m_pPointData)
- me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
+ if (PointData)
+ me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MoveIdle();
break;
default:
- m_bIsMoving = false;
+ IsMoving = false;
break;
}
}
}
- void SpellHitTarget(Unit* target, const SpellInfo* pSpell)
+ void SpellHitTarget(Unit* target, const SpellInfo* Spell)
{
//Workaround - Couldn't find a way to group this spells (All Eruption)
- if (((pSpell->Id >= 17086 && pSpell->Id <= 17095) ||
- (pSpell->Id == 17097) ||
- (pSpell->Id >= 18351 && pSpell->Id <= 18361) ||
- (pSpell->Id >= 18564 && pSpell->Id <= 18576) ||
- (pSpell->Id >= 18578 && pSpell->Id <= 18607) ||
- (pSpell->Id == 18609) ||
- (pSpell->Id >= 18611 && pSpell->Id <= 18628) ||
- (pSpell->Id >= 21132 && pSpell->Id <= 21133) ||
- (pSpell->Id >= 21135 && pSpell->Id <= 21139) ||
- (pSpell->Id >= 22191 && pSpell->Id <= 22202) ||
- (pSpell->Id >= 22267 && pSpell->Id <= 22268)) &&
+ if (((Spell->Id >= 17086 && Spell->Id <= 17095) ||
+ (Spell->Id == 17097) ||
+ (Spell->Id >= 18351 && Spell->Id <= 18361) ||
+ (Spell->Id >= 18564 && Spell->Id <= 18576) ||
+ (Spell->Id >= 18578 && Spell->Id <= 18607) ||
+ (Spell->Id == 18609) ||
+ (Spell->Id >= 18611 && Spell->Id <= 18628) ||
+ (Spell->Id >= 21132 && Spell->Id <= 21133) ||
+ (Spell->Id >= 21135 && Spell->Id <= 21139) ||
+ (Spell->Id >= 22191 && Spell->Id <= 22202) ||
+ (Spell->Id >= 22267 && Spell->Id <= 22268)) &&
(target->GetTypeId() == TYPEID_PLAYER))
{
if (instance)
@@ -308,14 +313,14 @@ public:
}
}
- sOnyxMove* GetMoveData()
+ OnyxMove* GetMoveData()
{
- uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove);
+ uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
- for (uint32 i = 0; i < uiMaxCount; ++i)
+ for (uint8 i = 0; i < MaxCount; ++i)
{
- if (aMoveData[i].uiLocId == m_uiMovePoint)
- return &aMoveData[i];
+ if (MoveData[i].LocId == MovePoint)
+ return &MoveData[i];
}
return NULL;
@@ -323,84 +328,84 @@ public:
void SetNextRandomPoint()
{
- uint32 uiMaxCount = sizeof(aMoveData)/sizeof(sOnyxMove);
+ uint8 MaxCount = sizeof(MoveData)/sizeof(OnyxMove);
- uint32 iTemp = rand()%(uiMaxCount-1);
+ uint8 iTemp = urand(0, MaxCount-1);
- if (iTemp >= m_uiMovePoint)
+ if (iTemp >= MovePoint)
++iTemp;
- m_uiMovePoint = iTemp;
+ MovePoint = iTemp;
}
- void UpdateAI(const uint32 uiDiff)
+ void UpdateAI(const uint32 Diff)
{
if (!UpdateVictim())
return;
//Common to PHASE_START && PHASE_END
- if (m_uiPhase == PHASE_START || m_uiPhase == PHASE_END)
+ if (Phase == PHASE_START || Phase == PHASE_END)
{
//Specific to PHASE_START || PHASE_END
- if (m_uiPhase == PHASE_START)
+ if (Phase == PHASE_START)
{
if (HealthBelowPct(60))
{
SetCombatMovement(false);
- m_uiPhase = PHASE_BREATH;
+ Phase = PHASE_BREATH;
me->GetMotionMaster()->MovePoint(10, Phase2Location);
return;
}
}
else
{
- if (m_uiBellowingRoarTimer <= uiDiff)
+ if (BellowingRoarTimer <= Diff)
{
DoCastVictim(SPELL_BELLOWING_ROAR);
// Eruption
- GameObject* pFloor = NULL;
+ GameObject* Floor = NULL;
Trinity::GameObjectInRangeCheck check(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 15);
- Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, pFloor, check);
+ Trinity::GameObjectLastSearcher<Trinity::GameObjectInRangeCheck> searcher(me, Floor, check);
me->VisitNearbyGridObject(30, searcher);
- if (instance && pFloor)
- instance->SetData64(DATA_FLOOR_ERUPTION_GUID, pFloor->GetGUID());
- m_uiBellowingRoarTimer = 30000;
+ if (instance && Floor)
+ instance->SetData64(DATA_FLOOR_ERUPTION_GUID, Floor->GetGUID());
+ BellowingRoarTimer = 30000;
}
else
- m_uiBellowingRoarTimer -= uiDiff;
+ BellowingRoarTimer -= Diff;
}
- if (m_uiFlameBreathTimer <= uiDiff)
+ if (FlameBreathTimer <= Diff)
{
DoCastVictim(SPELL_FLAME_BREATH);
- m_uiFlameBreathTimer = urand(10000, 20000);
+ FlameBreathTimer = urand(10000, 20000);
}
else
- m_uiFlameBreathTimer -= uiDiff;
+ FlameBreathTimer -= Diff;
- if (m_uiTailSweepTimer <= uiDiff)
+ if (TailSweepTimer <= Diff)
{
DoCastAOE(SPELL_TAIL_SWEEP);
- m_uiTailSweepTimer = urand(15000, 20000);
+ TailSweepTimer = urand(15000, 20000);
}
else
- m_uiTailSweepTimer -= uiDiff;
+ TailSweepTimer -= Diff;
- if (m_uiCleaveTimer <= uiDiff)
+ if (CleaveTimer <= Diff)
{
DoCastVictim(SPELL_CLEAVE);
- m_uiCleaveTimer = urand(2000, 5000);
+ CleaveTimer = urand(2000, 5000);
}
else
- m_uiCleaveTimer -= uiDiff;
+ CleaveTimer -= Diff;
- if (m_uiWingBuffetTimer <= uiDiff)
+ if (WingBuffetTimer <= Diff)
{
DoCastVictim(SPELL_WING_BUFFET);
- m_uiWingBuffetTimer = urand(15000, 30000);
+ WingBuffetTimer = urand(15000, 30000);
}
else
- m_uiWingBuffetTimer -= uiDiff;
+ WingBuffetTimer -= Diff;
DoMeleeAttackIfReady();
}
@@ -408,86 +413,86 @@ public:
{
if (HealthBelowPct(40))
{
- m_uiPhase = PHASE_END;
+ Phase = PHASE_END;
if (instance)
- instance->SetData(DATA_ONYXIA_PHASE, m_uiPhase);
+ instance->SetData(DATA_ONYXIA_PHASE, Phase);
DoScriptText(SAY_PHASE_3_TRANS, me);
SetCombatMovement(true);
me->SetCanFly(false);
- m_bIsMoving = false;
+ IsMoving = false;
me->GetMotionMaster()->MovePoint(9, me->GetHomePosition());
return;
}
- if (m_uiDeepBreathTimer <= uiDiff)
+ if (DeepBreathTimer <= Diff)
{
- if (!m_bIsMoving)
+ if (!IsMoving)
{
if (me->IsNonMeleeSpellCasted(false))
me->InterruptNonMeleeSpells(false);
DoScriptText(EMOTE_BREATH, me);
- DoCast(me, m_pPointData->uiSpellId);
- m_uiDeepBreathTimer = 70000;
+ DoCast(me, PointData->SpellId);
+ DeepBreathTimer = 70000;
}
}
else
- m_uiDeepBreathTimer -= uiDiff;
+ DeepBreathTimer -= Diff;
- if (m_uiMovementTimer <= uiDiff)
+ if (MovementTimer <= Diff)
{
- if (!m_bIsMoving)
+ if (!IsMoving)
{
SetNextRandomPoint();
- m_pPointData = GetMoveData();
+ PointData = GetMoveData();
- if (!m_pPointData)
+ if (!PointData)
return;
- me->GetMotionMaster()->MovePoint(m_pPointData->uiLocId, m_pPointData->fX, m_pPointData->fY, m_pPointData->fZ);
- m_bIsMoving = true;
- m_uiMovementTimer = 25000;
+ me->GetMotionMaster()->MovePoint(PointData->LocId, PointData->fX, PointData->fY, PointData->fZ);
+ IsMoving = true;
+ MovementTimer = 25000;
}
}
else
- m_uiMovementTimer -= uiDiff;
+ MovementTimer -= Diff;
- if (m_uiFireballTimer <= uiDiff)
+ if (FireballTimer <= Diff)
{
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_FIREBALL);
- m_uiFireballTimer = 8000;
+ FireballTimer = 8000;
}
}
else
- m_uiFireballTimer -= uiDiff;
+ FireballTimer -= Diff;
- if (m_uiLairGuardTimer <= uiDiff)
+ if (LairGuardTimer <= Diff)
{
- me->SummonCreature(NPC_LAIRGUARD, aSpawnLocations[2].GetPositionX(), aSpawnLocations[2].GetPositionY(), aSpawnLocations[2].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
- m_uiLairGuardTimer = 30000;
+ me->SummonCreature(NPC_LAIRGUARD, SpawnLocations[2], TEMPSUMMON_CORPSE_DESPAWN);
+ LairGuardTimer = 30000;
}
else
- m_uiLairGuardTimer -= uiDiff;
+ LairGuardTimer -= Diff;
- if (m_uiWhelpTimer <= uiDiff)
+ if (WhelpTimer <= Diff)
{
- me->SummonCreature(NPC_WHELP, aSpawnLocations[0].GetPositionX(), aSpawnLocations[0].GetPositionY(), aSpawnLocations[0].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
- me->SummonCreature(NPC_WHELP, aSpawnLocations[1].GetPositionX(), aSpawnLocations[1].GetPositionY(), aSpawnLocations[1].GetPositionZ(), 0.0f, TEMPSUMMON_CORPSE_DESPAWN);
- if (m_uiSummonWhelpCount >= RAID_MODE(20, 40))
+ me->SummonCreature(NPC_WHELP, SpawnLocations[0], TEMPSUMMON_CORPSE_DESPAWN);
+ me->SummonCreature(NPC_WHELP, SpawnLocations[1], TEMPSUMMON_CORPSE_DESPAWN);
+ if (SummonWhelpCount >= RAID_MODE(20, 40))
{
- m_uiSummonWhelpCount = 0;
- m_uiWhelpTimer = 90000;
+ SummonWhelpCount = 0;
+ WhelpTimer = 90000;
}
else
- m_uiWhelpTimer = 500;
+ WhelpTimer = 500;
}
else
- m_uiWhelpTimer -= uiDiff;
+ WhelpTimer -= Diff;
}
}
};
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
index 1c599ce7c6f..0689a8872bb 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/instance_onyxias_lair.cpp
@@ -22,7 +22,12 @@ SDComment:
SDCategory: Onyxia's Lair
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "InstanceScript.h"
+#include "Cell.h"
+#include "CellImpl.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
#include "onyxias_lair.h"
class instance_onyxias_lair : public InstanceMapScript
@@ -44,27 +49,27 @@ public:
std::map<uint64, uint32> FloorEruptionGUID[2];
std::queue<uint64> FloorEruptionGUIDQueue;
- uint64 m_uiOnyxiasGUID;
- uint32 m_uiOnyxiaLiftoffTimer;
- uint32 m_uiManyWhelpsCounter;
- uint32 m_uiEruptTimer;
+ uint64 OnyxiasGUID;
+ uint32 OnyxiaLiftoffTimer;
+ uint32 ManyWhelpsCounter;
+ uint32 EruptTimer;
- uint8 m_auiEncounter[MAX_ENCOUNTER];
+ uint8 Encounter[MAX_ENCOUNTER];
- bool m_bAchievManyWhelpsHandleIt;
- bool m_bAchievSheDeepBreathMore;
+ bool AchievManyWhelpsHandleIt;
+ bool AchievSheDeepBreathMore;
void Initialize()
{
- memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
+ memset(&Encounter, 0, sizeof(Encounter));
- m_uiOnyxiasGUID = 0;
- m_uiOnyxiaLiftoffTimer = 0;
- m_uiManyWhelpsCounter = 0;
- m_bAchievManyWhelpsHandleIt = false;
- m_bAchievSheDeepBreathMore = true;
+ OnyxiasGUID = 0;
+ OnyxiaLiftoffTimer = 0;
+ ManyWhelpsCounter = 0;
+ AchievManyWhelpsHandleIt = false;
+ AchievSheDeepBreathMore = true;
- m_uiEruptTimer = 0;
+ EruptTimer = 0;
}
void OnCreatureCreate(Creature* creature)
@@ -72,7 +77,7 @@ public:
switch (creature->GetEntry())
{
case NPC_ONYXIA:
- m_uiOnyxiasGUID = creature->GetGUID();
+ OnyxiasGUID = creature->GetGUID();
break;
}
}
@@ -93,7 +98,7 @@ public:
if (Creature* temp = go->SummonCreature(NPC_WHELP, goPos, TEMPSUMMON_CORPSE_DESPAWN))
{
temp->SetInCombatWithZone();
- ++m_uiManyWhelpsCounter;
+ ++ManyWhelpsCounter;
}
break;
}
@@ -139,88 +144,88 @@ public:
FloorEruptionGUID[1].erase(floorEruptedGUID);
}
- void SetData(uint32 uiType, uint32 uiData)
+ void SetData(uint32 Type, uint32 Data)
{
- switch (uiType)
+ switch (Type)
{
case DATA_ONYXIA:
- m_auiEncounter[0] = uiData;
- if (uiData == IN_PROGRESS)
+ Encounter[0] = Data;
+ if (Data == IN_PROGRESS)
SetData(DATA_SHE_DEEP_BREATH_MORE, IN_PROGRESS);
break;
case DATA_ONYXIA_PHASE:
- if (uiData == PHASE_BREATH) //Used to mark the liftoff phase
+ if (Data == PHASE_BREATH) //Used to mark the liftoff phase
{
- m_bAchievManyWhelpsHandleIt = false;
- m_uiManyWhelpsCounter = 0;
- m_uiOnyxiaLiftoffTimer = 10*IN_MILLISECONDS;
+ AchievManyWhelpsHandleIt = false;
+ ManyWhelpsCounter = 0;
+ OnyxiaLiftoffTimer = 10*IN_MILLISECONDS;
}
break;
case DATA_SHE_DEEP_BREATH_MORE:
- if (uiData == IN_PROGRESS)
+ if (Data == IN_PROGRESS)
{
- m_bAchievSheDeepBreathMore = true;
+ AchievSheDeepBreathMore = true;
}
- else if (uiData == FAIL)
+ else if (Data == FAIL)
{
- m_bAchievSheDeepBreathMore = false;
+ AchievSheDeepBreathMore = false;
}
break;
}
- if (uiType < MAX_ENCOUNTER && uiData == DONE)
+ if (Type < MAX_ENCOUNTER && Data == DONE)
SaveToDB();
}
- void SetData64(uint32 uiType, uint64 uiData)
+ void SetData64(uint32 Type, uint64 Data)
{
- switch (uiType)
+ switch (Type)
{
case DATA_FLOOR_ERUPTION_GUID:
FloorEruptionGUID[1] = FloorEruptionGUID[0];
- FloorEruptionGUIDQueue.push(uiData);
- m_uiEruptTimer = 2500;
+ FloorEruptionGUIDQueue.push(Data);
+ EruptTimer = 2500;
break;
}
}
- uint32 GetData(uint32 uiType)
+ uint32 GetData(uint32 Type)
{
- switch (uiType)
+ switch (Type)
{
case DATA_ONYXIA:
- return m_auiEncounter[0];
+ return Encounter[0];
}
return 0;
}
- uint64 GetData64(uint32 uiData)
+ uint64 GetData64(uint32 Data)
{
- switch (uiData)
+ switch (Data)
{
case DATA_ONYXIA_GUID:
- return m_uiOnyxiasGUID;
+ return OnyxiasGUID;
}
return 0;
}
- void Update(uint32 uiDiff)
+ void Update(uint32 Diff)
{
if (GetData(DATA_ONYXIA) == IN_PROGRESS)
{
- if (m_uiOnyxiaLiftoffTimer && m_uiOnyxiaLiftoffTimer <= uiDiff)
+ if (OnyxiaLiftoffTimer && OnyxiaLiftoffTimer <= Diff)
{
- m_uiOnyxiaLiftoffTimer = 0;
- if (m_uiManyWhelpsCounter >= 50)
- m_bAchievManyWhelpsHandleIt = true;
- } else m_uiOnyxiaLiftoffTimer -= uiDiff;
+ OnyxiaLiftoffTimer = 0;
+ if (ManyWhelpsCounter >= 50)
+ AchievManyWhelpsHandleIt = true;
+ } else OnyxiaLiftoffTimer -= Diff;
}
if (!FloorEruptionGUIDQueue.empty())
{
- if (m_uiEruptTimer <= uiDiff)
+ if (EruptTimer <= Diff)
{
uint32 treeHeight = 0;
do
@@ -229,10 +234,10 @@ public:
FloorEruption(FloorEruptionGUIDQueue.front());
FloorEruptionGUIDQueue.pop();
} while (!FloorEruptionGUIDQueue.empty() && (*FloorEruptionGUID[1].find(FloorEruptionGUIDQueue.front())).second == treeHeight);
- m_uiEruptTimer = 1000;
+ EruptTimer = 1000;
}
else
- m_uiEruptTimer -= uiDiff;
+ EruptTimer -= Diff;
}
}
@@ -242,10 +247,10 @@ public:
{
case ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER: // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
case ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER: // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
- return m_bAchievManyWhelpsHandleIt;
+ return AchievManyWhelpsHandleIt;
case ACHIEV_CRITERIA_DEEP_BREATH_10_PLAYER: // Criteria for achievement 4404: She Deep Breaths More (10 player) Everybody evade Deep Breath
case ACHIEV_CRITERIA_DEEP_BREATH_25_PLAYER: // Criteria for achievement 4407: She Deep Breaths More (25 player) Everybody evade Deep Breath
- return m_bAchievSheDeepBreathMore;
+ return AchievSheDeepBreathMore;
}
return false;
}
diff --git a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h
index eaf6cac43af..26fd9284ea2 100644
--- a/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h
+++ b/src/server/scripts/Kalimdor/OnyxiasLair/onyxias_lair.h
@@ -18,13 +18,13 @@
#ifndef DEF_ONYXIAS_LAIR_H
#define DEF_ONYXIAS_LAIR_H
-enum eData64
+enum Data64
{
DATA_ONYXIA_GUID,
DATA_FLOOR_ERUPTION_GUID
};
-enum eInstanceData
+enum InstanceData
{
DATA_ONYXIA,
MAX_ENCOUNTER,
@@ -34,7 +34,7 @@ enum eInstanceData
DATA_MANY_WHELPS_COUNT
};
-enum eCreatures
+enum Creatures
{
NPC_WHELP = 11262,
NPC_LAIRGUARD = 36561,
@@ -42,20 +42,20 @@ enum eCreatures
NPC_ONYXIA = 10184
};
-enum eOnyxiaPhases
+enum OnyxiaPhases
{
PHASE_START = 1,
PHASE_BREATH = 2,
PHASE_END = 3
};
-enum eGameObjects
+enum GameObjects
{
GO_WHELP_SPAWNER = 176510,
GO_WHELP_EGG = 176511
};
-enum eAchievementData
+enum AchievementData
{
ACHIEV_CRITERIA_MANY_WHELPS_10_PLAYER = 12565, // Criteria for achievement 4403: Many Whelps! Handle It! (10 player) Hatch 50 eggs in 10s
ACHIEV_CRITERIA_MANY_WHELPS_25_PLAYER = 12568, // Criteria for achievement 4406: Many Whelps! Handle It! (25 player) Hatch 50 eggs in 10s
diff --git a/src/server/scripts/Kalimdor/ashenvale.cpp b/src/server/scripts/Kalimdor/ashenvale.cpp
index e28665c038e..9e8cdaa8b92 100644
--- a/src/server/scripts/Kalimdor/ashenvale.cpp
+++ b/src/server/scripts/Kalimdor/ashenvale.cpp
@@ -169,15 +169,15 @@ class npc_torek : public CreatureScript
# npc_ruul_snowhoof
####*/
-enum RuulSnowhoof
-{
+enum RuulSnowhoof
+{
NPC_THISTLEFUR_URSA = 3921,
NPC_THISTLEFUR_TOTEMIC = 3922,
NPC_THISTLEFUR_PATHFINDER = 3926,
QUEST_FREEDOM_TO_RUUL = 6482,
- GO_CAGE = 178147
+ GO_CAGE = 178147
};
Position const RuulSnowhoofSummonsCoord[6] =
diff --git a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
index 45e1c1808c1..5800a6a58a0 100644
--- a/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
+++ b/src/server/scripts/Kalimdor/dustwallow_marsh.cpp
@@ -25,7 +25,6 @@ EndScriptData */
/* ContentData
mobs_risen_husk_spirit
-npc_deserter_agitator
npc_lady_jaina_proudmoore
npc_nat_pagle
npc_private_hendel
@@ -132,93 +131,7 @@ class mobs_risen_husk_spirit : public CreatureScript
};
/*######
-## npc_deserter_agitator
-######*/
-
-enum Deserter
-{
- QUEST_TRAITORS_AMONG_US = 11126,
- NPC_THERAMORE_DESERTER = 23602,
-};
-
-const Position DeserterDisappearPos = {-3609.03f, -4332.91f, 9.39354f, 3.73862f};
-
-#define GOSSIP_ITEM_DESERTER "Your propaganda wont`t work on me. Spout your treasonous filth elsewhere traitor!"
-
-class npc_deserter_agitator : public CreatureScript
-{
-public:
- npc_deserter_agitator() : CreatureScript("npc_deserter_agitator") { }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (player->GetQuestStatus(QUEST_TRAITORS_AMONG_US) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_DESERTER, GOSSIP_SENDER_MAIN, GOSSIP_SENDER_INFO);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
-
- if (action == GOSSIP_SENDER_INFO)
- {
- player->CLOSE_GOSSIP_MENU();
- switch (urand(0, 1))
- {
- case 0:
- creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- creature->setFaction(14);
- creature->AI()->AttackStart(player);
- break;
- case 1:
- player->KilledMonsterCredit(NPC_THERAMORE_DESERTER, 0);
- creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- creature->SetSpeed(MOVE_RUN, creature->GetSpeedRate(MOVE_RUN), true);
- creature->setFaction(35);
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- creature->SetReactState(REACT_PASSIVE);
- creature->GetMotionMaster()->MovePoint(1, DeserterDisappearPos);
- break;
- }
- }
-
- return true;
- }
-
- CreatureAI* GetAI(Creature* creature) const
- {
- return new npc_deserter_agitatorAI(creature);
- }
-
- struct npc_deserter_agitatorAI : public ScriptedAI
- {
- npc_deserter_agitatorAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset()
- {
- me->RestoreFaction();
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- me->SetReactState(REACT_AGGRESSIVE);
- me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- }
-
- void MovementInform(uint32 Type, uint32 Id)
- {
- if (Type != POINT_MOTION_TYPE)
- return;
-
- if (Id == 1)
- me->DisappearAndDie();
- }
- };
-};
-
-/*######
-## npc_deserter_agitator
+## npc_theramor_guard
######*/
enum TheramoreGuard
@@ -794,16 +707,16 @@ class spell_energize_aoe : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();)
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
if ((*itr)->GetTypeId() == TYPEID_PLAYER && (*itr)->ToPlayer()->GetQuestStatus(GetSpellInfo()->Effects[EFFECT_1].CalcValue()) == QUEST_STATUS_INCOMPLETE)
++itr;
else
- unitList.erase(itr++);
+ targets.erase(itr++);
}
- unitList.push_back(GetCaster());
+ targets.push_back(GetCaster());
}
void HandleScript(SpellEffIndex effIndex)
@@ -815,8 +728,8 @@ class spell_energize_aoe : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_energize_aoe_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_energize_aoe_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -865,7 +778,6 @@ void AddSC_dustwallow_marsh()
new npc_zelfrax();
new npc_stinky();
new npc_theramore_guard();
- new npc_deserter_agitator();
new spell_ooze_zap();
new spell_ooze_zap_channel_end();
new spell_energize_aoe();
diff --git a/src/server/scripts/Kalimdor/winterspring.cpp b/src/server/scripts/Kalimdor/winterspring.cpp
index a02156ee110..2c4da0fdf7c 100644
--- a/src/server/scripts/Kalimdor/winterspring.cpp
+++ b/src/server/scripts/Kalimdor/winterspring.cpp
@@ -18,15 +18,13 @@
/* ScriptData
SDName: Winterspring
-SD%Complete: 90
-SDComment: Quest support: 5126 (Loraxs' tale missing proper gossip items text). Vendor Rivern Frostwind. Obtain Cache of Mau'ari
+SD%Complete: Almost Completely Emptied
+SDComment: Vendor Rivern Frostwind.
SDCategory: Winterspring
EndScriptData */
/* ContentData
-npc_lorax
npc_rivern_frostwind
-npc_witch_doctor_mauari
EndContentData */
#include "ScriptMgr.h"
@@ -34,71 +32,6 @@ EndContentData */
#include "ScriptedGossip.h"
/*######
-## npc_lorax
-######*/
-
-#define GOSSIP_HL "Talk to me"
-
-#define GOSSIP_SL1 "What do you do here?"
-#define GOSSIP_SL2 "I can help you"
-#define GOSSIP_SL3 "What deal?"
-#define GOSSIP_SL4 "Then what happened?"
-#define GOSSIP_SL5 "He is not safe, i'll make sure of that."
-
-class npc_lorax : public CreatureScript
-{
-public:
- npc_lorax() : CreatureScript("npc_lorax") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
- player->SEND_GOSSIP_MENU(3759, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+1:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
- player->SEND_GOSSIP_MENU(3760, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
- player->SEND_GOSSIP_MENU(3761, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
- player->SEND_GOSSIP_MENU(3762, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+4:
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_SL5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
- player->SEND_GOSSIP_MENU(3763, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+5:
- player->CLOSE_GOSSIP_MENU();
- player->AreaExploredOrEventHappens(5126);
- break;
- }
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestStatus(5126) == QUEST_STATUS_INCOMPLETE)
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
-
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
-
- return true;
- }
-
-};
-
-/*######
## npc_rivern_frostwind
######*/
@@ -131,49 +64,7 @@ public:
};
-/*######
-## npc_witch_doctor_mauari
-######*/
-
-#define GOSSIP_HWDM "I'd like you to make me a new Cache of Mau'ari please."
-
-class npc_witch_doctor_mauari : public CreatureScript
-{
-public:
- npc_witch_doctor_mauari() : CreatureScript("npc_witch_doctor_mauari") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
- {
- player->PlayerTalkClass->ClearMenus();
- if (action == GOSSIP_ACTION_INFO_DEF+1)
- {
- player->CLOSE_GOSSIP_MENU();
- creature->CastSpell(player, 16351, false);
- }
-
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature)
- {
- if (creature->isQuestGiver())
- player->PrepareQuestMenu(creature->GetGUID());
-
- if (player->GetQuestRewardStatus(975))
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HWDM, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(3377, creature->GetGUID());
- }
- else
- player->SEND_GOSSIP_MENU(3375, creature->GetGUID());
-
- return true;
- }
-};
-
void AddSC_winterspring()
{
- new npc_lorax();
new npc_rivern_frostwind();
- new npc_witch_doctor_mauari();
}
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
index 4e5e01cc745..5a7809dbe70 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp
@@ -186,7 +186,7 @@ class ConflagrationTargetSelector
public:
ConflagrationTargetSelector() { }
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* unit) const
{
return unit->GetTypeId() != TYPEID_PLAYER;
}
@@ -201,12 +201,12 @@ class spell_saviana_conflagration_init : public SpellScriptLoader
{
PrepareSpellScript(spell_saviana_conflagration_init_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove_if (ConflagrationTargetSelector());
+ targets.remove_if(ConflagrationTargetSelector());
uint8 maxSize = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 3);
- if (unitList.size() > maxSize)
- Trinity::Containers::RandomResizeList(unitList, maxSize);
+ if (targets.size() > maxSize)
+ Trinity::Containers::RandomResizeList(targets, maxSize);
}
void HandleDummy(SpellEffIndex effIndex)
@@ -218,7 +218,7 @@ class spell_saviana_conflagration_init : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_saviana_conflagration_init_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_saviana_conflagration_init_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
index 305266ee628..e96408acc09 100644
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheChampion/boss_argent_challenge.cpp
@@ -60,9 +60,9 @@ class OrientationCheck : public std::unary_function<Unit*, bool>
{
public:
explicit OrientationCheck(Unit* _caster) : caster(_caster) { }
- bool operator() (Unit* unit)
+ bool operator()(WorldObject* object)
{
- return !unit->isInFront(caster, 2.5f) || !unit->IsWithinDist(caster, 40.0f);
+ return !object->isInFront(caster, 2.5f) || !object->IsWithinDist(caster, 40.0f);
}
private:
@@ -76,15 +76,16 @@ class spell_eadric_radiance : public SpellScriptLoader
class spell_eadric_radiance_SpellScript : public SpellScript
{
PrepareSpellScript(spell_eadric_radiance_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (OrientationCheck(GetCaster()));
+ unitList.remove_if(OrientationCheck(GetCaster()));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_eadric_radiance_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
index 79bbb470edf..3b0aeb958cb 100755
--- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
+++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_faction_champions.cpp
@@ -27,7 +27,10 @@ EndScriptData */
// All - untested
// Pets aren't being summoned by their masters
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "trial_of_the_crusader.h"
enum eYell
@@ -945,18 +948,18 @@ public:
};
-enum eWarlockSpells
+enum WarlockSpells
{
- SPELL_HELLFIRE = 65816,
- SPELL_CORRUPTION = 65810,
- SPELL_CURSE_OF_AGONY = 65814,
- SPELL_CURSE_OF_EXHAUSTION = 65815,
- SPELL_FEAR = 65809, //8s
- SPELL_SEARING_PAIN = 65819,
- SPELL_SHADOW_BOLT = 65821,
- SPELL_UNSTABLE_AFFLICTION = 65812,
- SPELL_SUMMON_FELHUNTER = 67514,
- H_SPELL_UNSTABLE_AFFLICTION = 68155, //15s
+ SPELL_HELLFIRE = 65816,
+ SPELL_CORRUPTION = 65810,
+ SPELL_CURSE_OF_AGONY = 65814,
+ SPELL_CURSE_OF_EXHAUSTION = 65815,
+ SPELL_FEAR = 65809, // 8s
+ SPELL_SEARING_PAIN = 65819,
+ SPELL_SHADOW_BOLT = 65821,
+ SPELL_UNSTABLE_AFFLICTION = 65812, // 15s
+ SPELL_UNSTABLE_AFFLICTION_DISPEL = 65813,
+ SPELL_SUMMON_FELHUNTER = 67514,
};
class mob_toc_warlock : public CreatureScript
@@ -2030,6 +2033,40 @@ public:
};
};
+class spell_faction_champion_warl_unstable_affliction : public SpellScriptLoader
+{
+ public:
+ spell_faction_champion_warl_unstable_affliction() : SpellScriptLoader("spell_faction_champion_warl_unstable_affliction") { }
+
+ class spell_faction_champion_warl_unstable_affliction_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_faction_champion_warl_unstable_affliction_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_UNSTABLE_AFFLICTION_DISPEL))
+ return false;
+ return true;
+ }
+
+ void HandleDispel(DispelInfo* dispelInfo)
+ {
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(dispelInfo->GetDispeller(), SPELL_UNSTABLE_AFFLICTION_DISPEL, true, NULL, GetEffect(EFFECT_0));
+ }
+
+ void Register()
+ {
+ AfterDispel += AuraDispelFn(spell_faction_champion_warl_unstable_affliction_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_faction_champion_warl_unstable_affliction_AuraScript();
+ }
+};
+
void AddSC_boss_faction_champions()
{
new boss_toc_champion_controller();
@@ -2049,4 +2086,5 @@ void AddSC_boss_faction_champions()
new mob_toc_retro_paladin();
new mob_toc_pet_warlock();
new mob_toc_pet_hunter();
+ new spell_faction_champion_warl_unstable_affliction();
}
diff --git a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
index 4a28ebe6495..5b6bf14c29e 100644
--- a/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
+++ b/src/server/scripts/Northrend/FrozenHalls/ForgeOfSouls/boss_bronjahm.cpp
@@ -359,7 +359,7 @@ class DistanceCheck
public:
explicit DistanceCheck(Unit* _caster) : caster(_caster) { }
- bool operator() (Unit* unit)
+ bool operator() (WorldObject* unit) const
{
if (caster->GetExactDist2d(unit) <= 10.0f)
return true;
@@ -378,25 +378,25 @@ class spell_bronjahm_soulstorm_targeting : public SpellScriptLoader
{
PrepareSpellScript(spell_bronjahm_soulstorm_targeting_SpellScript);
- void FilterTargetsInitial(std::list<Unit*>& unitList)
+ void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
- unitList.remove_if (DistanceCheck(GetCaster()));
- sharedUnitList = unitList;
+ targets.remove_if(DistanceCheck(GetCaster()));
+ sharedTargets = targets;
}
// use the same target for first and second effect
- void FilterTargetsSubsequent(std::list<Unit*>& unitList)
+ void FilterTargetsSubsequent(std::list<WorldObject*>& targets)
{
- unitList = sharedUnitList;
+ targets = sharedTargets;
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsInitial, EFFECT_1, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_bronjahm_soulstorm_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_2, TARGET_UNIT_DEST_AREA_ENEMY);
}
- std::list<Unit*> sharedUnitList;
+ std::list<WorldObject*> sharedTargets;
};
SpellScript* GetSpellScript() const
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
index ee966256e2b..0d092ec86b2 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp
@@ -631,9 +631,9 @@ class BloodboltHitCheck
public:
explicit BloodboltHitCheck(LanaThelAI* ai) : _ai(ai) {}
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- return _ai->WasBloodbolted(unit->GetGUID());
+ return _ai->WasBloodbolted(object->GetGUID());
}
private:
@@ -661,13 +661,13 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader
return GetCaster()->GetEntry() == NPC_BLOOD_QUEEN_LANA_THEL;
}
- void FilterTargets(std::list<Unit*>& targets)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
uint32 targetCount = (targets.size() + 2) / 3;
- targets.remove_if (BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));
+ targets.remove_if(BloodboltHitCheck(static_cast<LanaThelAI*>(GetCaster()->GetAI())));
Trinity::Containers::RandomResizeList(targets, targetCount);
// mark targets now, effect hook has missile travel time delay (might cast next in that time)
- for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
GetCaster()->GetAI()->SetGUID((*itr)->GetGUID(), GUID_BLOODBOLT);
}
@@ -679,7 +679,7 @@ class spell_blood_queen_bloodbolt : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_bloodbolt_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_blood_queen_bloodbolt_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -699,19 +699,19 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader
{
PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove_if (Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN));
+ targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PACT_OF_THE_DARKFALLEN));
bool remove = true;
- std::list<Unit*>::const_iterator itrEnd = unitList.end(), itr, itr2;
+ std::list<WorldObject*>::const_iterator itrEnd = targets.end(), itr, itr2;
// we can do this, unitList is MAX 4 in size
- for (itr = unitList.begin(); itr != itrEnd && remove; ++itr)
+ for (itr = targets.begin(); itr != itrEnd && remove; ++itr)
{
if (!GetCaster()->IsWithinDist(*itr, 5.0f, false))
remove = false;
- for (itr2 = unitList.begin(); itr2 != itrEnd && remove; ++itr2)
+ for (itr2 = targets.begin(); itr2 != itrEnd && remove; ++itr2)
if (itr != itr2 && !(*itr2)->IsWithinDist(*itr, 5.0f, false))
remove = false;
}
@@ -721,14 +721,14 @@ class spell_blood_queen_pact_of_the_darkfallen : public SpellScriptLoader
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
{
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PACT_OF_THE_DARKFALLEN);
- unitList.clear();
+ targets.clear();
}
}
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -785,15 +785,15 @@ class spell_blood_queen_pact_of_the_darkfallen_dmg_target : public SpellScriptLo
{
PrepareSpellScript(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN));
+ unitList.remove_if(Trinity::UnitAuraCheck(true, SPELL_PACT_OF_THE_DARKFALLEN));
unitList.push_back(GetCaster());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_blood_queen_pact_of_the_darkfallen_dmg_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 494be259baa..9017509781f 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -1198,34 +1198,34 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader
return true;
}
- void FilterTargetsInitial(std::list<Unit*>& unitList)
+ void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
- if (unitList.empty())
+ if (targets.empty())
return;
// select one random target, with preference of ranged targets
uint32 targetsAtRange = 0;
uint32 const minTargets = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 10 : 4);
- unitList.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
+ targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster(), false));
// get target count at range
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr, ++targetsAtRange)
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr, ++targetsAtRange)
if ((*itr)->GetDistance(GetCaster()) < 12.0f)
break;
// set the upper cap
if (targetsAtRange < minTargets)
- targetsAtRange = std::min<uint32>(unitList.size() - 1, minTargets);
+ targetsAtRange = std::min<uint32>(targets.size() - 1, minTargets);
- std::list<Unit*>::const_iterator itr = unitList.begin();
+ std::list<WorldObject*>::const_iterator itr = targets.begin();
std::advance(itr, urand(0, targetsAtRange));
target = *itr;
- unitList.clear();
- unitList.push_back(target);
+ targets.clear();
+ targets.push_back(target);
}
// use the same target for first and second effect
- void FilterTargetsSubsequent(std::list<Unit*>& unitList)
+ void FilterTargetsSubsequent(std::list<WorldObject*>& unitList)
{
if (!target)
return;
@@ -1241,12 +1241,13 @@ class spell_deathbringer_blood_nova_targeting : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_blood_nova_targeting_SpellScript::FilterTargetsSubsequent, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
OnEffectHitTarget += SpellEffectFn(spell_deathbringer_blood_nova_targeting_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
- Unit* target;
+ WorldObject* target;
};
SpellScript* GetSpellScript() const
@@ -1269,20 +1270,20 @@ class spell_deathbringer_boiling_blood : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove(GetCaster()->getVictim());
- if (unitList.empty())
+ targets.remove(GetCaster()->getVictim());
+ if (targets.empty())
return;
- Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
- unitList.clear();
- unitList.push_back(target);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_deathbringer_boiling_blood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
index 1672d8b2d87..0c5cb0aba52 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
@@ -416,7 +416,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
{
PrepareSpellScript(spell_marrowgar_coldflame_SpellScript);
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
targets.clear();
// select any unit but not the tank (by owners threatlist)
@@ -438,7 +438,7 @@ class spell_marrowgar_coldflame : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_marrowgar_coldflame_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_marrowgar_coldflame_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
index a0fca522f61..a9ba0baa86f 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_professor_putricide.cpp
@@ -296,6 +296,7 @@ class boss_professor_putricide : public CreatureScript
summon->ModifyAuraState(AURA_STATE_UNKNOWN22, true);
summon->CastSpell(summon, SPELL_GASEOUS_BLOAT_PROC, true);
summon->CastCustomSpell(SPELL_GASEOUS_BLOAT, SPELLVALUE_AURA_STACK, 10, summon, false);
+ summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_VOLATILE_OOZE:
@@ -303,6 +304,7 @@ class boss_professor_putricide : public CreatureScript
summon->ModifyAuraState(AURA_STATE_UNKNOWN19, true);
summon->CastSpell(summon, SPELL_OOZE_ERUPTION_SEARCH_PERIODIC, true);
summon->CastSpell(summon, SPELL_VOLATILE_OOZE_ADHESIVE, false);
+ summon->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
summon->SetReactState(REACT_PASSIVE);
return;
case NPC_CHOKING_GAS_BOMB:
@@ -868,26 +870,26 @@ class spell_putricide_ooze_channel : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
- void SelectTarget(std::list<Unit*>& targetList)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
- if (targetList.empty())
+ if (targets.empty())
{
FinishCast(SPELL_FAILED_NO_VALID_TARGETS);
GetCaster()->ToCreature()->DespawnOrUnsummon(1); // despawn next update
return;
}
- Unit* target = Trinity::Containers::SelectRandomContainerElement(targetList);
- targetList.clear();
- targetList.push_back(target);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
_target = target;
}
- void SetTarget(std::list<Unit*>& targetList)
+ void SetTarget(std::list<WorldObject*>& targets)
{
- targetList.clear();
+ targets.clear();
if (_target)
- targetList.push_back(_target);
+ targets.push_back(_target);
}
void StartAttack()
@@ -910,14 +912,14 @@ class spell_putricide_ooze_channel : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_ooze_channel_SpellScript::SetTarget, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
AfterHit += SpellHitFn(spell_putricide_ooze_channel_SpellScript::StartAttack);
OnCast += SpellCastFn(spell_putricide_ooze_channel_SpellScript::CheckTarget);
}
- Unit* _target;
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -931,7 +933,7 @@ class ExactDistanceCheck
public:
ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {}
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* unit) const
{
return _source->GetExactDist2d(unit) > _dist;
}
@@ -950,15 +952,15 @@ class spell_putricide_slime_puddle : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_slime_puddle_SpellScript);
- void ScaleRange(std::list<Unit*>& targets)
+ void ScaleRange(std::list<WorldObject*>& targets)
{
targets.remove_if(ExactDistanceCheck(GetCaster(), 2.5f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_slime_puddle_SpellScript::ScaleRange, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
}
};
@@ -1176,13 +1178,13 @@ class spell_putricide_eat_ooze : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_eat_ooze_SpellScript);
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
- Unit* target = targets.front();
+ WorldObject* target = targets.front();
targets.clear();
targets.push_back(target);
}
@@ -1209,7 +1211,7 @@ class spell_putricide_eat_ooze : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_putricide_eat_ooze_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_eat_ooze_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
}
};
@@ -1456,15 +1458,15 @@ class spell_putricide_mutated_transformation_dmg : public SpellScriptLoader
{
PrepareSpellScript(spell_putricide_mutated_transformation_dmg_SpellScript);
- void FilterTargetsInitial(std::list<Unit*>& unitList)
+ void FilterTargetsInitial(std::list<WorldObject*>& targets)
{
if (Unit* owner = ObjectAccessor::GetUnit(*GetCaster(), GetCaster()->GetCreatorGUID()))
- unitList.remove(owner);
+ targets.remove(owner);
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_putricide_mutated_transformation_dmg_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
index a4ab13f6ada..5a0560293da 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp
@@ -449,23 +449,23 @@ class spell_rotface_ooze_flood : public SpellScriptLoader
GetHitUnit()->CastSpell(triggers.back(), uint32(GetEffectValue()), false, NULL, NULL, GetOriginalCaster() ? GetOriginalCaster()->GetGUID() : 0);
}
- void FilterTargets(std::list<Unit*>& targetList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
// get 2 targets except 2 nearest
- targetList.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
+ targets.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
// .resize() runs pop_back();
- if (targetList.size() > 4)
- targetList.resize(4);
+ if (targets.size() > 4)
+ targets.resize(4);
- while (targetList.size() > 2)
- targetList.pop_front();
+ while (targets.size() > 2)
+ targets.pop_front();
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_rotface_ooze_flood_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_ooze_flood_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -490,21 +490,21 @@ class spell_rotface_mutated_infection : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& targets)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
// remove targets with this aura already
// tank is not on this list
- targets.remove_if (Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
+ targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
if (targets.empty())
return;
- Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
_target = target;
}
- void ReplaceTargets(std::list<Unit*>& targets)
+ void ReplaceTargets(std::list<WorldObject*>& targets)
{
targets.clear();
if (_target)
@@ -520,13 +520,13 @@ class spell_rotface_mutated_infection : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_rotface_mutated_infection_SpellScript::ReplaceTargets, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
AfterHit += SpellHitFn(spell_rotface_mutated_infection_SpellScript::NotifyTargets);
}
- Unit* _target;
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index 6039ace44ab..e3c0f2260df 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -19,6 +19,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellAuraEffects.h"
+#include "GridNotifiers.h"
#include "icecrown_citadel.h"
enum Texts
@@ -167,7 +168,7 @@ class FrostwyrmLandEvent : public BasicEvent
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
{
- _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest, 8.247422f);
+ _owner.GetMotionMaster()->MoveLand(POINT_FROSTWYRM_LAND, _dest);
return true;
}
@@ -183,7 +184,7 @@ class FrostBombExplosion : public BasicEvent
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
{
- _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, true, NULL, NULL, _sindragosaGUID);
+ _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, false, NULL, NULL, _sindragosaGUID);
_owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
return true;
}
@@ -200,7 +201,7 @@ class boss_sindragosa : public CreatureScript
struct boss_sindragosaAI : public BossAI
{
- boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA)
+ boss_sindragosaAI(Creature* creature) : BossAI(creature, DATA_SINDRAGOSA), _summoned(false)
{
}
@@ -220,7 +221,7 @@ class boss_sindragosa : public CreatureScript
_isInAirPhase = false;
_isThirdPhase = false;
- if (instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) != 255)
+ if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -266,10 +267,13 @@ class boss_sindragosa : public CreatureScript
{
if (action == ACTION_START_FROSTWYRM)
{
+ if (_summoned)
+ return;
+
+ _summoned = true;
if (TempSummon* summon = me->ToTempSummon())
summon->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
- instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 255);
if (me->isDead())
return;
@@ -481,7 +485,7 @@ class boss_sindragosa : public CreatureScript
Position pos;
pos.Relocate(me);
pos.m_positionZ += 17.0f;
- me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos, 8.30078125f);
+ me->GetMotionMaster()->MoveTakeoff(POINT_TAKEOFF, pos);
events.CancelEventGroup(EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_AIR_PHASE, 110000);
break;
@@ -523,7 +527,7 @@ class boss_sindragosa : public CreatureScript
events.ScheduleEvent(EVENT_FROST_BREATH, urand(10000, 15000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_UNCHAINED_MAGIC, urand(12000, 17000), EVENT_GROUP_LAND_PHASE);
events.ScheduleEvent(EVENT_ICY_GRIP, urand(35000, 40000), EVENT_GROUP_LAND_PHASE);
- me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos, 0.0f);
+ me->GetMotionMaster()->MoveLand(POINT_LAND_GROUND, SindragosaLandPos);
break;
case EVENT_THIRD_PHASE_CHECK:
{
@@ -550,6 +554,7 @@ class boss_sindragosa : public CreatureScript
uint8 _mysticBuffetStack;
bool _isInAirPhase;
bool _isThirdPhase;
+ bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -642,7 +647,7 @@ class npc_spinestalker : public CreatureScript
struct npc_spinestalkerAI : public ScriptedAI
{
- npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
+ npc_spinestalkerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)
{
}
@@ -651,7 +656,7 @@ class npc_spinestalker : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -664,7 +669,7 @@ class npc_spinestalker : public CreatureScript
_events.ScheduleEvent(EVENT_TAIL_SWEEP, urand(8000, 12000));
me->SetReactState(REACT_DEFENSIVE);
- if (_instance->GetData(DATA_SPINESTALKER) != 255)
+ if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -674,20 +679,22 @@ class npc_spinestalker : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
{
if (action == ACTION_START_FROSTWYRM)
{
- _instance->SetData(DATA_SPINESTALKER, 255);
+ if (_summoned)
+ return;
+
+ _summoned = true;
if (me->isDead())
return;
@@ -754,6 +761,7 @@ class npc_spinestalker : public CreatureScript
private:
EventMap _events;
InstanceScript* _instance;
+ bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -769,7 +777,7 @@ class npc_rimefang : public CreatureScript
struct npc_rimefangAI : public ScriptedAI
{
- npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript())
+ npc_rimefangAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()), _summoned(false)
{
}
@@ -778,7 +786,7 @@ class npc_rimefang : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -791,7 +799,7 @@ class npc_rimefang : public CreatureScript
me->SetReactState(REACT_DEFENSIVE);
_icyBlastCounter = 0;
- if (_instance->GetData(DATA_RIMEFANG) != 255)
+ if (!_summoned)
{
me->SetCanFly(true);
me->SetDisableGravity(true);
@@ -801,20 +809,22 @@ class npc_rimefang : public CreatureScript
void JustRespawned()
{
ScriptedAI::JustRespawned();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade
+ _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void JustDied(Unit* /*killer*/)
{
_events.Reset();
- _instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
}
void DoAction(int32 const action)
{
if (action == ACTION_START_FROSTWYRM)
{
- _instance->SetData(DATA_RIMEFANG, 255);
+ if (_summoned)
+ return;
+
+ _summoned = true;
if (me->isDead())
return;
@@ -908,6 +918,7 @@ class npc_rimefang : public CreatureScript
EventMap _events;
InstanceScript* _instance;
uint8 _icyBlastCounter;
+ bool _summoned;
};
CreatureAI* GetAI(Creature* creature) const
@@ -934,7 +945,8 @@ class npc_sindragosa_trash : public CreatureScript
// Increase add count
if (!me->isDead())
{
- _instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
+ if (me->GetEntry() == NPC_FROSTWING_WHELP)
+ _instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
Reset();
}
}
@@ -956,13 +968,8 @@ class npc_sindragosa_trash : public CreatureScript
ScriptedAI::JustRespawned();
// Increase add count
- _instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade
- }
-
- void JustDied(Unit* /*killer*/)
- {
- // Decrease add count
- _instance->SetData(_frostwyrmId, 0);
+ if (me->GetEntry() == NPC_FROSTWING_WHELP)
+ _instance->SetData(_frostwyrmId, me->GetDBTableGUIDLow()); // this cannot be in Reset because reset also happens on evade
}
void SetData(uint32 type, uint32 data)
@@ -1035,12 +1042,31 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
bool Load()
{
_targetCount = 0;
- return true;
+
+ // This script should execute only in Icecrown Citadel
+ if (InstanceMap* instance = GetCaster()->GetMap()->ToInstanceMap())
+ if (instance->GetInstanceScript())
+ if (instance->GetScriptId() == sObjectMgr->GetScriptId(ICCScriptName))
+ return true;
+
+ return false;
+ }
+
+ void SelectDest()
+ {
+ if (Position* dest = const_cast<WorldLocation*>(GetExplTargetDest()))
+ {
+ float destX = float(rand_norm()) * 75.0f + 4350.0f;
+ float destY = float(rand_norm()) * 75.0f + 2450.0f;
+ float destZ = 205.0f; // random number close to ground, get exact in next call
+ GetCaster()->UpdateGroundPositionZ(destX, destY, destZ);
+ dest->Relocate(destX, destY, destZ);
+ }
}
- void CountTargets(std::list<Unit*>& unitList)
+ void CountTargets(std::list<WorldObject*>& targets)
{
- _targetCount = unitList.size();
+ _targetCount = targets.size();
}
void HandleDummy(SpellEffIndex effIndex)
@@ -1051,10 +1077,10 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
return;
float resistance = float(GetHitUnit()->GetResistance(SpellSchoolMask(GetSpellInfo()->SchoolMask)));
- uint32 minResistFactor = uint32((resistance / (resistance + 510.0f))* 10.0f) * 2;
- uint32 randomResist = urand(0, (9 - minResistFactor) * 100)/100 + minResistFactor;
+ uint32 minResistFactor = uint32((resistance / (resistance + 510.0f)) * 10.0f) * 2;
+ uint32 randomResist = urand(0, (9 - minResistFactor) * 100) / 100 + minResistFactor;
- uint32 damage = (uint32(GetEffectValue()/_targetCount) * randomResist) / 10;
+ uint32 damage = (uint32(GetEffectValue() / _targetCount) * randomResist) / 10;
SpellNonMeleeDamage damageInfo(GetCaster(), GetHitUnit(), GetSpellInfo()->Id, GetSpellInfo()->SchoolMask);
damageInfo.damage = damage;
@@ -1064,8 +1090,9 @@ class spell_sindragosa_s_fury : public SpellScriptLoader
void Register()
{
+ BeforeCast += SpellCastFn(spell_sindragosa_s_fury_SpellScript::SelectDest);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_sindragosa_s_fury_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_s_fury_SpellScript::CountTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ENTRY);
}
uint32 _targetCount;
@@ -1082,9 +1109,11 @@ class UnchainedMagicTargetSelector
public:
UnchainedMagicTargetSelector() { }
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- return unit->getPowerType() != POWER_MANA;
+ if (Unit* unit = object->ToUnit())
+ return unit->getPowerType() != POWER_MANA;
+ return true;
}
};
@@ -1097,7 +1126,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
{
PrepareSpellScript(spell_sindragosa_unchained_magic_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(UnchainedMagicTargetSelector());
uint32 maxSize = uint32(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 6 : 2);
@@ -1107,7 +1136,7 @@ class spell_sindragosa_unchained_magic : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_unchained_magic_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1290,7 +1319,7 @@ class MysticBuffetTargetFilter
public:
explicit MysticBuffetTargetFilter(Unit* caster) : _caster(caster) { }
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* unit) const
{
return !unit->IsWithinLOSInMap(_caster);
}
@@ -1308,14 +1337,14 @@ class spell_sindragosa_mystic_buffet : public SpellScriptLoader
{
PrepareSpellScript(spell_sindragosa_mystic_buffet_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove_if(MysticBuffetTargetFilter(GetCaster()));
+ targets.remove_if(MysticBuffetTargetFilter(GetCaster()));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sindragosa_mystic_buffet_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1393,22 +1422,15 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end();)
- {
- if ((*itr)->GetTypeId() != TYPEID_PLAYER)
- unitList.erase(itr++);
- else
- ++itr;
- }
-
- if (unitList.empty())
+ targets.remove_if(Trinity::ObjectTypeIdCheck(TYPEID_PLAYER, false));
+ if (targets.empty())
return;
- Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
- unitList.clear();
- unitList.push_back(target);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
}
void HandleForcedCast(SpellEffIndex effIndex)
@@ -1429,7 +1451,7 @@ class spell_frostwarden_handler_order_whelp : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_frostwarden_handler_order_whelp_SpellScript::HandleForcedCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frostwarden_handler_order_whelp_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -1509,7 +1531,7 @@ class at_sindragosa_lair : public AreaTriggerScript
if (Creature* rimefang = ObjectAccessor::GetCreature(*player, instance->GetData64(DATA_RIMEFANG)))
rimefang->AI()->DoAction(ACTION_START_FROSTWYRM);
- if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)
+ if (!instance->GetData(DATA_SINDRAGOSA_FROSTWYRMS) && !instance->GetData64(DATA_SINDRAGOSA) && instance->GetBossState(DATA_SINDRAGOSA) != DONE)
{
if (player->GetMap()->IsHeroic() && !instance->GetData(DATA_HEROIC_ATTEMPTS))
return true;
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 4dab215d1da..a8657925131 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -138,7 +138,7 @@ enum Spells
SPELL_IN_FROSTMOURNE_ROOM = 74276,
SPELL_KILL_FROSTMOURNE_PLAYERS = 75127,
SPELL_HARVESTED_SOUL = 72679,
- SPELL_TRIGGER_VILE_SPIRIT_HEROIC = 73582,
+ SPELL_TRIGGER_VILE_SPIRIT_HEROIC = 73582, // TODO: Cast every 3 seconds during Frostmourne phase, targets a Wicked Spirit amd activates it
// Frostmourne
SPELL_LIGHTS_FAVOR = 69382,
@@ -152,6 +152,7 @@ enum Spells
SPELL_SUMMON_SPIRIT_BOMB_1 = 73581, // (Heroic)
SPELL_SUMMON_SPIRIT_BOMB_2 = 74299, // (Heroic)
SPELL_EXPLOSION = 73576, // Spirit Bomb (Heroic)
+ SPELL_HARVEST_SOUL_DAMAGE_AURA = 73655,
// Outro
SPELL_FURY_OF_FROSTMOURNE = 72350,
@@ -221,7 +222,7 @@ enum Events
EVENT_QUAKE_2 = 27,
EVENT_VILE_SPIRITS = 28,
EVENT_HARVEST_SOULS = 29, // heroic only
- EVENT_WICKED_SPIRITS = 30,
+ EVENT_BERSERK = 30,
EVENT_SOUL_RIP = 31,
EVENT_DESTROY_SOUL = 32,
EVENT_FROSTMOURNE_TALK_1 = 33,
@@ -249,19 +250,18 @@ enum Events
EVENT_OUTRO_TERENAS_TALK_2 = 55,
EVENT_OUTRO_TALK_7 = 56,
EVENT_OUTRO_TALK_8 = 57,
- EVENT_BERSERK = 58,
// Shambling Horror
- EVENT_SHOCKWAVE = 59,
- EVENT_ENRAGE = 60,
+ EVENT_SHOCKWAVE = 58,
+ EVENT_ENRAGE = 59,
// Raging Spirit
- EVENT_SOUL_SHRIEK = 61,
+ EVENT_SOUL_SHRIEK = 60,
// Strangulate Vehicle (Harvest Soul)
- EVENT_TELEPORT = 62,
- EVENT_MOVE_TO_LICH_KING = 63,
- EVENT_DESPAWN_SELF = 64,
+ EVENT_TELEPORT = 61,
+ EVENT_MOVE_TO_LICH_KING = 62,
+ EVENT_DESPAWN_SELF = 63,
};
enum EventGroups
@@ -391,7 +391,7 @@ class HeightDifferenceCheck
{
}
- bool operator()(Unit* unit) const
+ bool operator()(WorldObject* unit) const
{
return (unit->GetPositionZ() - _baseObject->GetPositionZ() > _difference) != _reverse;
}
@@ -475,6 +475,32 @@ class VileSpiritActivateEvent : public BasicEvent
Creature* _owner;
};
+class TriggerWickedSpirit : public BasicEvent
+{
+ public:
+ explicit TriggerWickedSpirit(Creature* owner)
+ : _owner(owner), _counter(13)
+ {
+ }
+
+ bool Execute(uint64 /*time*/, uint32 /*diff*/)
+ {
+ _owner->CastCustomSpell(SPELL_TRIGGER_VILE_SPIRIT_HEROIC, SPELLVALUE_MAX_TARGETS, 1, NULL, true);
+
+ if (--_counter)
+ {
+ _owner->m_Events.AddEvent(this, _owner->m_Events.CalculateTime(3000));
+ return false;
+ }
+
+ return true;
+ }
+
+ private:
+ Creature* _owner;
+ uint32 _counter;
+};
+
class boss_the_lich_king : public CreatureScript
{
public:
@@ -503,6 +529,8 @@ class boss_the_lich_king : public CreatureScript
me->SetDisableGravity(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
me->GetMotionMaster()->MoveFall();
+ if (Creature* frostmourne = me->FindNearestCreature(NPC_FROSTMOURNE_TRIGGER, 50.0f))
+ frostmourne->DespawnOrUnsummon();
}
void EnterCombat(Unit* target)
@@ -601,8 +629,6 @@ class boss_the_lich_king : public CreatureScript
summons.DoAction(ACTION_TELEPORT_BACK, pred);
if (!IsHeroic())
Talk(SAY_LK_FROSTMOURNE_ESCAPE);
- else
- DoCastAOE(SPELL_TRIGGER_VILE_SPIRIT_HEROIC);
break;
}
default:
@@ -645,6 +671,8 @@ class boss_the_lich_king : public CreatureScript
if (events.GetPhaseMask() & PHASE_MASK_ONE && !HealthAbovePct(70))
{
events.SetPhase(PHASE_TRANSITION);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
me->GetMotionMaster()->MovePoint(POINT_CENTER_1, CenterPosition);
return;
}
@@ -652,6 +680,8 @@ class boss_the_lich_king : public CreatureScript
if (events.GetPhaseMask() & PHASE_MASK_TWO && !HealthAbovePct(40))
{
events.SetPhase(PHASE_TRANSITION);
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
me->GetMotionMaster()->MovePoint(POINT_CENTER_2, CenterPosition);
return;
}
@@ -664,7 +694,8 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_OUTRO);
summons.DespawnAll();
SendMusicToPlayers(MUSIC_FURY_OF_FROSTMOURNE);
- DoCastAOE(SPELL_FURY_OF_FROSTMOURNE);
+ me->InterruptNonMeleeSpells(true);
+ me->CastSpell((Unit*)NULL, SPELL_FURY_OF_FROSTMOURNE, TRIGGERED_NONE);
me->SetWalk(true);
events.ScheduleEvent(EVENT_OUTRO_TALK_1, 2600, 0, PHASE_OUTRO);
events.ScheduleEvent(EVENT_OUTRO_EMOTE_TALK, 6600, 0, PHASE_OUTRO);
@@ -712,7 +743,6 @@ class boss_the_lich_king : public CreatureScript
break;
case NPC_FROSTMOURNE_TRIGGER:
{
- summons.Summon(summon);
summon->CastSpell((Unit*)NULL, SPELL_BROKEN_FROSTMOURNE, true);
SendLightOverride(LIGHT_SOULSTORM, 10000);
@@ -724,16 +754,11 @@ class boss_the_lich_king : public CreatureScript
case NPC_VILE_SPIRIT:
{
summons.Summon(summon);
- if (events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE)
- {
- TeleportSpirit(summon);
- return;
- }
-
summon->SetReactState(REACT_PASSIVE);
summon->SetSpeed(MOVE_FLIGHT, 0.5f);
summon->GetMotionMaster()->MoveRandom(10.0f);
- summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
+ if (!(events.GetPhaseMask() & PHASE_MASK_FROSTMOURNE))
+ summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(15000));
return;
}
case NPC_STRANGULATE_VEHICLE:
@@ -756,7 +781,6 @@ class boss_the_lich_king : public CreatureScript
case NPC_VALKYR_SHADOWGUARD:
case NPC_RAGING_SPIRIT:
case NPC_VILE_SPIRIT:
- case NPC_WICKED_SPIRIT:
summon->ToTempSummon()->SetTempSummonType(TEMPSUMMON_CORPSE_DESPAWN);
break;
default:
@@ -802,8 +826,6 @@ class boss_the_lich_king : public CreatureScript
me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
DoCast(me, SPELL_REMORSELESS_WINTER_1);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
events.ScheduleEvent(EVENT_QUAKE, 62500, 0, PHASE_TRANSITION);
@@ -819,8 +841,6 @@ class boss_the_lich_king : public CreatureScript
me->SetFacingTo(0.0f);
Talk(SAY_LK_REMORSELESS_WINTER);
SendMusicToPlayers(MUSIC_SPECIAL);
- me->SetReactState(REACT_PASSIVE);
- me->AttackStop();
DoCast(me, SPELL_REMORSELESS_WINTER_2);
summons.DespawnEntry(NPC_VALKYR_SHADOWGUARD);
events.DelayEvents(62500, EVENT_GROUP_BERSERK); // delay berserk timer, its not ticking during phase transitions
@@ -992,10 +1012,6 @@ class boss_the_lich_king : public CreatureScript
DoCastAOE(SPELL_VILE_SPIRITS);
events.ScheduleEvent(EVENT_VILE_SPIRITS, urand(35000, 40000), EVENT_GROUP_VILE_SPIRITS, PHASE_THREE);
break;
- case EVENT_WICKED_SPIRITS:
- DoCastAOE(SPELL_VILE_SPIRITS);
- events.ScheduleEvent(EVENT_WICKED_SPIRITS, urand(35000, 40000), 0, PHASE_FROSTMOURNE);
- break;
case EVENT_HARVEST_SOULS:
Talk(SAY_LK_HARVEST_SOUL);
DoCastAOE(SPELL_HARVEST_SOULS);
@@ -1003,7 +1019,6 @@ class boss_the_lich_king : public CreatureScript
events.SetPhase(PHASE_FROSTMOURNE); // will stop running UpdateVictim (no evading)
me->SetReactState(REACT_PASSIVE);
me->AttackStop();
- events.ScheduleEvent(EVENT_WICKED_SPIRITS, events.GetNextEventTime(EVENT_VILE_SPIRITS) - events.GetTimer(), 0, PHASE_FROSTMOURNE);
events.DelayEvents(50000, EVENT_GROUP_VILE_SPIRITS);
events.RescheduleEvent(EVENT_DEFILE, 50000, 0, PHASE_THREE);
events.RescheduleEvent(EVENT_SOUL_REAPER, urand(57000, 62000), 0, PHASE_THREE);
@@ -1019,16 +1034,22 @@ class boss_the_lich_king : public CreatureScript
if (!triggers.empty())
{
triggers.sort(Trinity::ObjectDistanceOrderPred(terenas, true));
- Unit* spawner = triggers.front();
+ Creature* spawner = triggers.front();
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_1, true); // summons bombs randomly
spawner->CastSpell(spawner, SPELL_SUMMON_SPIRIT_BOMB_2, true); // summons bombs on players
+ spawner->m_Events.AddEvent(new TriggerWickedSpirit(spawner), spawner->m_Events.CalculateTime(3000));
}
for (SummonList::iterator i = summons.begin(); i != summons.end(); ++i)
{
Creature* summon = ObjectAccessor::GetCreature(*me, *i);
if (summon && summon->GetEntry() == NPC_VILE_SPIRIT)
- TeleportSpirit(summon);
+ {
+ summon->m_Events.KillAllEvents(true);
+ summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(50000));
+ summon->GetMotionMaster()->MoveRandom(10.0f);
+ summon->SetReactState(REACT_PASSIVE);
+ }
}
}
break;
@@ -1099,22 +1120,6 @@ class boss_the_lich_king : public CreatureScript
}
private:
-
- void TeleportSpirit(Creature* summon)
- {
- float dist = me->GetObjectSize() + (15.0f - me->GetObjectSize()) * float(rand_norm());
- float angle = float(rand_norm()) * float(2.0f * M_PI);
- Position dest = TerenasSpawnHeroic;
- me->MovePosition(dest, dist, angle);
- dest.m_positionZ += 15.0f;
- summon->UpdateEntry(NPC_WICKED_SPIRIT);
- summon->SetReactState(REACT_PASSIVE);
- summon->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
- summon->SetSpeed(MOVE_FLIGHT, 0.5f);
- summon->m_Events.KillAllEvents(true);
- summon->m_Events.AddEvent(new VileSpiritActivateEvent(summon), summon->m_Events.CalculateTime(1000));
- }
-
void SendMusicToPlayers(uint32 musicId) const
{
WorldPacket data(SMSG_PLAY_MUSIC, 4);
@@ -1635,8 +1640,13 @@ class npc_strangulate_vehicle : public CreatureScript
return;
if (TempSummon* summ = me->ToTempSummon())
+ {
if (Unit* summoner = summ->GetSummoner())
+ {
DoCast(summoner, SPELL_HARVEST_SOUL_TELEPORT_BACK);
+ summoner->RemoveAurasDueToSpell(SPELL_HARVEST_SOUL_DAMAGE_AURA);
+ }
+ }
if (Creature* lichKing = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_THE_LICH_KING)))
lichKing->AI()->SummonedCreatureDespawn(me);
@@ -1993,6 +2003,10 @@ class npc_broken_frostmourne : public CreatureScript
_events.ScheduleEvent(EVENT_OUTRO_SUMMON_TERENAS, 6000, 0, PHASE_OUTRO);
}
+ void EnterEvadeMode()
+ {
+ }
+
void UpdateAI(uint32 const diff)
{
UpdateVictim();
@@ -2274,7 +2288,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_shadow_trap_periodic_SpellScript);
- void CheckTargetCount(std::list<Unit*>& targets)
+ void CheckTargetCount(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2284,7 +2298,7 @@ class spell_the_lich_king_shadow_trap_periodic : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_shadow_trap_periodic_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -2308,10 +2322,10 @@ class spell_the_lich_king_quake : public SpellScriptLoader
return GetCaster()->GetInstanceScript() != NULL;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
if (GameObject* platform = ObjectAccessor::GetGameObject(*GetCaster(), GetCaster()->GetInstanceScript()->GetData64(DATA_ARTHAS_PLATFORM)))
- unitList.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
+ targets.remove_if(HeightDifferenceCheck(platform, 5.0f, false));
}
void HandleSendEvent(SpellEffIndex /*effIndex*/)
@@ -2322,7 +2336,7 @@ class spell_the_lich_king_quake : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_quake_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHit += SpellEffectFn(spell_the_lich_king_quake_SpellScript::HandleSendEvent, EFFECT_1, SPELL_EFFECT_SEND_EVENT);
}
};
@@ -2349,7 +2363,7 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
return true;
}
- void CheckTargetCount(std::list<Unit*>& unitList)
+ void CheckTargetCount(std::list<WorldObject*>& unitList)
{
if (unitList.empty())
return;
@@ -2357,12 +2371,16 @@ class spell_the_lich_king_ice_burst_target_search : public SpellScriptLoader
// if there is at least one affected target cast the explosion
GetCaster()->CastSpell(GetCaster(), SPELL_ICE_BURST, true);
if (GetCaster()->GetTypeId() == TYPEID_UNIT)
+ {
+ GetCaster()->ToCreature()->SetReactState(REACT_PASSIVE);
+ GetCaster()->AttackStop();
GetCaster()->ToCreature()->DespawnOrUnsummon(500);
+ }
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_ice_burst_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -2411,7 +2429,7 @@ class ExactDistanceCheck
public:
ExactDistanceCheck(Unit* source, float dist) : _source(source), _dist(dist) {}
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* unit)
{
return _source->GetExactDist2d(unit) > _dist;
}
@@ -2430,7 +2448,7 @@ class spell_the_lich_king_defile : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_defile_SpellScript);
- void CorrectRange(std::list<Unit*>& targets)
+ void CorrectRange(std::list<WorldObject*>& targets)
{
targets.remove_if(ExactDistanceCheck(GetCaster(), 10.0f * GetCaster()->GetFloatValue(OBJECT_FIELD_SCALE_X)));
}
@@ -2446,8 +2464,8 @@ class spell_the_lich_king_defile : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_defile_SpellScript::CorrectRange, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnHit += SpellHitFn(spell_the_lich_king_defile_SpellScript::ChangeDamageAndGrow);
}
};
@@ -2472,14 +2490,18 @@ class spell_the_lich_king_summon_into_air : public SpellScriptLoader
static Position const offset = {0.0f, 0.0f, 15.0f, 0.0f};
WorldLocation* dest = const_cast<WorldLocation*>(GetExplTargetDest());
dest->RelocateOffset(offset);
+ GetHitDest()->RelocateOffset(offset);
// spirit bombs get higher
if (GetSpellInfo()->Effects[effIndex].MiscValue == NPC_SPIRIT_BOMB)
+ {
dest->RelocateOffset(offset);
+ GetHitDest()->RelocateOffset(offset);
+ }
}
void Register()
{
- OnEffectLaunch += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
+ OnEffectHit += SpellEffectFn(spell_the_lich_king_summon_into_air_SpellScript::ModDestHeight, EFFECT_0, SPELL_EFFECT_SUMMON);
}
};
@@ -2545,26 +2567,26 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
return true;
}
- void SelectTarget(std::list<Unit*>& unitList)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
- if (unitList.empty())
+ if (targets.empty())
return;
- unitList.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
- if (unitList.empty())
+ targets.remove_if(Trinity::UnitAuraCheck(true, GetSpellInfo()->Id));
+ if (targets.empty())
return;
- _target = Trinity::Containers::SelectRandomContainerElement(unitList);
- unitList.clear();
- unitList.push_back(_target);
+ _target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(_target);
GetCaster()->GetAI()->SetGUID(_target->GetGUID());
}
- void ReplaceTarget(std::list<Unit*>& unitList)
+ void ReplaceTarget(std::list<WorldObject*>& targets)
{
- unitList.clear();
+ targets.clear();
if (_target)
- unitList.push_back(_target);
+ targets.push_back(_target);
}
void HandleScript(SpellEffIndex effIndex)
@@ -2575,12 +2597,12 @@ class spell_the_lich_king_valkyr_target_search : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_valkyr_target_search_SpellScript::ReplaceTarget, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_valkyr_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
- Unit* _target;
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -2757,7 +2779,7 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2778,11 +2800,11 @@ class spell_the_lich_king_vile_spirit_move_target_search : public SpellScriptLoa
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_the_lich_king_vile_spirit_move_target_search_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
- Unit* _target;
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const
@@ -2805,7 +2827,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
- void CheckTargetCount(std::list<Unit*>& targets)
+ void CheckTargetCount(std::list<WorldObject*>& targets)
{
if (targets.empty())
return;
@@ -2822,7 +2844,7 @@ class spell_the_lich_king_vile_spirit_damage_target_search : public SpellScriptL
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_the_lich_king_vile_spirit_damage_target_search_SpellScript::CheckTargetCount, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
Unit* _target;
@@ -2954,6 +2976,15 @@ class spell_the_lich_king_restore_soul : public SpellScriptLoader
lichKing->AI()->DoAction(ACTION_TELEPORT_BACK);
if (Creature* spawner = GetCaster()->FindNearestCreature(NPC_WORLD_TRIGGER_INFINITE_AOI, 50.0f))
spawner->RemoveAllAuras();
+
+ std::list<Creature*> spirits;
+ GetCaster()->GetCreatureListWithEntryInGrid(spirits, NPC_WICKED_SPIRIT, 200.0f);
+ for (std::list<Creature*>::iterator itr = spirits.begin(); itr != spirits.end(); ++itr)
+ {
+ (*itr)->m_Events.KillAllEvents(true);
+ (*itr)->SetReactState(REACT_PASSIVE);
+ (*itr)->AI()->EnterEvadeMode();
+ }
}
void RemoveAura()
@@ -3046,23 +3077,18 @@ class spell_the_lich_king_trigger_vile_spirit : public SpellScriptLoader
{
PrepareSpellScript(spell_the_lich_king_trigger_vile_spirit_SpellScript);
- void TeleportOutside()
+ void ActivateSpirit()
{
Creature* target = GetHitCreature();
if (!target)
return;
- Position dest;
- Position offset;
- TerenasSpawnHeroic.GetPositionOffsetTo(*target, offset);
- GetCaster()->GetPosition(&dest);
- dest.RelocateOffset(offset);
- target->NearTeleportTo(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ(), dest.GetOrientation());
+ VileSpiritActivateEvent(target).Execute(0, 0);
}
void Register()
{
- OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::TeleportOutside);
+ OnHit += SpellHitFn(spell_the_lich_king_trigger_vile_spirit_SpellScript::ActivateSpirit);
}
};
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index c40a521c794..826c62a4390 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -1013,11 +1013,8 @@ class npc_dream_portal : public CreatureScript
{
}
- void DoAction(int32 const action)
+ void OnSpellClick(Unit* /*clicker*/)
{
- if (action != EVENT_SPELLCLICK)
- return;
-
_used = true;
me->DespawnOrUnsummon();
}
@@ -1190,13 +1187,13 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& targets)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- targets.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
if (targets.empty())
return;
- Unit* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
targets.clear();
targets.push_back(target);
}
@@ -1212,7 +1209,7 @@ class spell_dreamwalker_summoner : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dreamwalker_summoner_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
OnEffectHitTarget += SpellEffectFn(spell_dreamwalker_summoner_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST);
}
};
@@ -1241,7 +1238,7 @@ class spell_dreamwalker_summon_suppresser : public SpellScriptLoader
std::list<Creature*> summoners;
GetCreatureListWithEntryInGrid(summoners, caster, NPC_WORLD_TRIGGER, 100.0f);
- summoners.remove_if (Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
+ summoners.remove_if(Trinity::UnitAuraCheck(true, SPELL_RECENTLY_SPAWNED));
Trinity::Containers::RandomResizeList(summoners, 2);
if (summoners.empty())
return;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index fab9a5f0740..17e33912a86 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -19,6 +19,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
+#include "PassiveAI.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
@@ -158,6 +159,9 @@ enum Spells
SPELL_FEL_IRON_BOMB_UNDEAD = 71787,
SPELL_MACHINE_GUN_UNDEAD = 71788,
SPELL_ROCKET_LAUNCH_UNDEAD = 71786,
+
+ // Invisible Stalker (Float, Uninteractible, LargeAOI)
+ SPELL_SOUL_MISSILE = 72585,
};
// Helper defines
@@ -248,6 +252,9 @@ enum EventTypes
EVENT_RUPERT_FEL_IRON_BOMB = 52,
EVENT_RUPERT_MACHINE_GUN = 53,
EVENT_RUPERT_ROCKET_LAUNCH = 54,
+
+ // Invisible Stalker (Float, Uninteractible, LargeAOI)
+ EVENT_SOUL_MISSILE = 55,
};
enum DataTypesICC
@@ -1668,6 +1675,56 @@ class npc_impaling_spear : public CreatureScript
}
};
+class npc_arthas_teleport_visual : public CreatureScript
+{
+ public:
+ npc_arthas_teleport_visual() : CreatureScript("npc_arthas_teleport_visual") { }
+
+ struct npc_arthas_teleport_visualAI : public NullCreatureAI
+ {
+ npc_arthas_teleport_visualAI(Creature* creature) : NullCreatureAI(creature), _instance(creature->GetInstanceScript())
+ {
+ }
+
+ void Reset()
+ {
+ _events.Reset();
+ if (_instance->GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE &&
+ _instance->GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE &&
+ _instance->GetBossState(DATA_SINDRAGOSA) == DONE)
+ _events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(1000, 6000));
+ }
+
+ void UpdateAI(uint32 const diff)
+ {
+ if (_events.Empty())
+ return;
+
+ _events.Update(diff);
+
+ if (_events.ExecuteEvent() == EVENT_SOUL_MISSILE)
+ {
+ DoCastAOE(SPELL_SOUL_MISSILE);
+ _events.ScheduleEvent(EVENT_SOUL_MISSILE, urand(5000, 7000));
+ }
+ }
+
+ private:
+ InstanceScript* _instance;
+ EventMap _events;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ // Distance from the center of the spire
+ if (creature->GetExactDist2d(4357.052f, 2769.421f) < 100.0f && creature->GetHomePosition().GetPositionZ() < 315.0f)
+ return GetIcecrownCitadelAI<npc_arthas_teleport_visualAI>(creature);
+
+ // Default to no script
+ return NULL;
+ }
+};
+
class spell_icc_stoneform : public SpellScriptLoader
{
public:
@@ -1777,15 +1834,15 @@ class DeathPlagueTargetSelector
public:
explicit DeathPlagueTargetSelector(Unit* caster) : _caster(caster) {}
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- if (unit == _caster)
+ if (object == _caster)
return true;
- if (unit->GetTypeId() != TYPEID_PLAYER)
+ if (object->GetTypeId() != TYPEID_PLAYER)
return true;
- if (unit->HasAura(SPELL_RECENTLY_INFECTED) || unit->HasAura(SPELL_DEATH_PLAGUE_AURA))
+ if (object->ToUnit()->HasAura(SPELL_RECENTLY_INFECTED) || object->ToUnit()->HasAura(SPELL_DEATH_PLAGUE_AURA))
return true;
return false;
@@ -1811,25 +1868,25 @@ class spell_frost_giant_death_plague : public SpellScriptLoader
}
// First effect
- void CountTargets(std::list<Unit*>& unitList)
+ void CountTargets(std::list<WorldObject*>& targets)
{
- unitList.remove(GetCaster());
- _failed = unitList.empty();
+ targets.remove(GetCaster());
+ _failed = targets.empty();
}
// Second effect
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
// Select valid targets for jump
- unitList.remove_if (DeathPlagueTargetSelector(GetCaster()));
- if (!unitList.empty())
+ targets.remove_if(DeathPlagueTargetSelector(GetCaster()));
+ if (!targets.empty())
{
- Unit* target = Trinity::Containers::SelectRandomContainerElement(unitList);
- unitList.clear();
- unitList.push_back(target);
+ WorldObject* target = Trinity::Containers::SelectRandomContainerElement(targets);
+ targets.clear();
+ targets.push_back(target);
}
- unitList.push_back(GetCaster());
+ targets.push_back(GetCaster());
}
void HandleScript(SpellEffIndex effIndex)
@@ -1843,8 +1900,8 @@ class spell_frost_giant_death_plague : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_frost_giant_death_plague_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY);
OnEffectHitTarget += SpellEffectFn(spell_frost_giant_death_plague_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
@@ -1893,9 +1950,11 @@ class spell_icc_harvest_blight_specimen : public SpellScriptLoader
class AliveCheck
{
public:
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- return unit->isAlive();
+ if (Unit* unit = object->ToUnit())
+ return unit->isAlive();
+ return true;
}
};
@@ -1908,10 +1967,10 @@ class spell_svalna_revive_champion : public SpellScriptLoader
{
PrepareSpellScript(spell_svalna_revive_champion_SpellScript);
- void RemoveAliveTarget(std::list<Unit*>& unitList)
+ void RemoveAliveTarget(std::list<WorldObject*>& targets)
{
- unitList.remove_if(AliveCheck());
- Trinity::Containers::RandomResizeList(unitList, 2);
+ targets.remove_if(AliveCheck());
+ Trinity::Containers::RandomResizeList(targets, 2);
}
void Land(SpellEffIndex /*effIndex*/)
@@ -1926,12 +1985,12 @@ class spell_svalna_revive_champion : public SpellScriptLoader
//pos.m_positionZ = caster->GetBaseMap()->GetHeight(caster->GetPhaseMask(), pos.GetPositionX(), pos.GetPositionY(), caster->GetPositionZ(), true, 50.0f);
//pos.m_positionZ += 0.05f;
caster->SetHomePosition(pos);
- caster->GetMotionMaster()->MoveLand(POINT_LAND, pos, caster->GetSpeed(MOVE_FLIGHT));
+ caster->GetMotionMaster()->MoveLand(POINT_LAND, pos);
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_svalna_revive_champion_SpellScript::RemoveAliveTarget, EFFECT_0, TARGET_UNIT_DEST_AREA_ENTRY);
OnEffectHit += SpellEffectFn(spell_svalna_revive_champion_SpellScript::Land, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
@@ -1974,6 +2033,33 @@ class spell_svalna_remove_spear : public SpellScriptLoader
}
};
+class spell_icc_soul_missile : public SpellScriptLoader
+{
+ public:
+ spell_icc_soul_missile() : SpellScriptLoader("spell_icc_soul_missile") { }
+
+ class spell_icc_soul_missile_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_icc_soul_missile_SpellScript);
+
+ void RelocateDest()
+ {
+ static Position const offset = {0.0f, 0.0f, 200.0f, 0.0f};
+ const_cast<WorldLocation*>(GetExplTargetDest())->RelocateOffset(offset);
+ }
+
+ void Register()
+ {
+ OnCast += SpellCastFn(spell_icc_soul_missile_SpellScript::RelocateDest);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_icc_soul_missile_SpellScript();
+ }
+};
+
class at_icc_saurfang_portal : public AreaTriggerScript
{
public:
@@ -2063,6 +2149,7 @@ void AddSC_icecrown_citadel()
new npc_captain_rupert();
new npc_frostwing_vrykul();
new npc_impaling_spear();
+ new npc_arthas_teleport_visual();
new spell_icc_stoneform();
new spell_icc_sprit_alarm();
new spell_frost_giant_death_plague();
@@ -2070,6 +2157,7 @@ void AddSC_icecrown_citadel()
new spell_trigger_spell_from_caster("spell_svalna_caress_of_death", SPELL_IMPALING_SPEAR_KILL);
new spell_svalna_revive_champion();
new spell_svalna_remove_spear();
+ new spell_icc_soul_missile();
new at_icc_saurfang_portal();
new at_icc_shutdown_traps();
new at_icc_start_blood_quickening();
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 224777c3db7..31639a698ef 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -51,6 +51,7 @@ enum SharedSpells
SPELL_GREEN_BLIGHT_RESIDUE = 72145,
// The Lich King
+ SPELL_ARTHAS_TELEPORTER_CEREMONY = 72915,
SPELL_FROSTMOURNE_TELEPORT_VISUAL = 73078,
};
@@ -275,6 +276,9 @@ enum CreaturesIds
NPC_WORLD_TRIGGER_INFINITE_AOI = 36171,
NPC_SPIRIT_BOMB = 39189,
NPC_FROSTMOURNE_TRIGGER = 38584,
+
+ // Generic
+ NPC_INVISIBLE_STALKER = 30298,
};
enum GameObjectsIds
@@ -345,6 +349,7 @@ enum GameObjectsIds
GO_SIGIL_OF_THE_FROSTWING = 202181,
// The Lich King
+ GO_SCOURGE_TRANSPORTER_LK = 202223,
GO_ARTHAS_PLATFORM = 202161,
GO_ARTHAS_PRECIPICE = 202078,
GO_DOODAD_ICECROWN_THRONEFROSTYWIND01 = 202188,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index cb83efc748f..650f426d29c 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -130,6 +130,7 @@ class instance_icecrown_citadel : public InstanceMapScript
SindragosaGUID = 0;
SpinestalkerGUID = 0;
RimefangGUID = 0;
+ TheLichKingTeleportGUID = 0;
TheLichKingGUID = 0;
HighlordTirionFordringGUID = 0;
TerenasMenethilGUID = 0;
@@ -138,9 +139,6 @@ class instance_icecrown_citadel : public InstanceMapScript
FrozenThroneEdgeGUID = 0;
FrozenThroneWindGUID = 0;
FrozenThroneWarningGUID = 0;
- FrostwyrmCount = 0;
- SpinestalkerTrashCount = 0;
- RimefangTrashCount = 0;
IsBonedEligible = true;
IsOozeDanceEligible = true;
IsNauseaEligible = true;
@@ -283,6 +281,11 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_RIMEFANG:
RimefangGUID = creature->GetGUID();
break;
+ case NPC_INVISIBLE_STALKER:
+ // Teleporter visual at center
+ if (creature->GetExactDist2d(4357.052f, 2769.421f) < 10.0f)
+ creature->CastSpell(creature, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
+ break;
case NPC_THE_LICH_KING:
TheLichKingGUID = creature->GetGUID();
break;
@@ -293,11 +296,22 @@ class instance_icecrown_citadel : public InstanceMapScript
case NPC_TERENAS_MENETHIL_FROSTMOURNE_H:
TerenasMenethilGUID = creature->GetGUID();
break;
+ case NPC_WICKED_SPIRIT:
+ // Remove corpse as soon as it dies (and respawn 10 seconds later)
+ creature->SetCorpseDelay(0);
+ creature->SetReactState(REACT_PASSIVE);
+ break;
default:
break;
}
}
+ void OnCreatureRemove(Creature* creature)
+ {
+ if (creature->GetEntry() == NPC_SINDRAGOSA)
+ SindragosaGUID = 0;
+ }
+
// Weekly quest spawn prevention
uint32 GetCreatureEntry(uint32 /*guidLow*/, CreatureData const* data)
{
@@ -347,6 +361,43 @@ class instance_icecrown_citadel : public InstanceMapScript
if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
break;
+ case NPC_FROSTWING_WHELP:
+ if (FrostwyrmGUIDs.empty())
+ return;
+
+ if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER)
+ {
+ SpinestalkerTrash.erase(creature->GetDBTableGUIDLow());
+ if (SpinestalkerTrash.empty())
+ if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
+ spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ else
+ {
+ RimefangTrash.erase(creature->GetDBTableGUIDLow());
+ if (RimefangTrash.empty())
+ if (Creature* spinestalk = instance->GetCreature(RimefangGUID))
+ spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ break;
+ case NPC_RIMEFANG:
+ case NPC_SPINESTALKER:
+ {
+ if (instance->IsHeroic() && !HeroicAttempts)
+ return;
+
+ if (GetBossState(DATA_SINDRAGOSA) == DONE)
+ return;
+
+ FrostwyrmGUIDs.erase(creature->GetDBTableGUIDLow());
+ if (FrostwyrmGUIDs.empty())
+ {
+ instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
+ if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
+ boss->AI()->DoAction(ACTION_START_FROSTWYRM);
+ }
+ break;
+ }
default:
break;
}
@@ -460,6 +511,11 @@ class instance_icecrown_citadel : public InstanceMapScript
go->SetLootRecipient(valithria->GetLootRecipient());
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED | GO_FLAG_NOT_SELECTABLE | GO_FLAG_NODESPAWN);
break;
+ case GO_SCOURGE_TRANSPORTER_LK:
+ TheLichKingTeleportGUID = go->GetGUID();
+ if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE)
+ go->SetGoState(GO_STATE_ACTIVE);
+ break;
case GO_ARTHAS_PLATFORM:
// this enables movement at The Frozen Throne, when printed this value is 0.000000f
// however, when represented as integer client will accept only this value
@@ -538,11 +594,11 @@ class instance_icecrown_citadel : public InstanceMapScript
switch (type)
{
case DATA_SINDRAGOSA_FROSTWYRMS:
- return FrostwyrmCount;
+ return FrostwyrmGUIDs.size();
case DATA_SPINESTALKER:
- return SpinestalkerTrashCount;
+ return SpinestalkerTrash.size();
case DATA_RIMEFANG:
- return RimefangTrashCount;
+ return RimefangTrash.size();
case DATA_COLDFLAME_JETS:
return ColdflameJetsState;
case DATA_TEAM_IN_INSTANCE:
@@ -698,6 +754,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_PROFESSOR_PUTRICIDE:
HandleGameObject(PlagueSigilGUID, state != DONE);
+ if (state == DONE)
+ CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -712,6 +770,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_BLOOD_QUEEN_LANA_THEL:
HandleGameObject(BloodwingSigilGUID, state != DONE);
+ if (state == DONE)
+ CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -730,6 +790,8 @@ class instance_icecrown_citadel : public InstanceMapScript
break;
case DATA_SINDRAGOSA:
HandleGameObject(FrostwingSigilGUID, state != DONE);
+ if (state == DONE)
+ CheckLichKingAvailability();
if (instance->IsHeroic())
{
if (state == FAIL && HeroicAttempts)
@@ -798,89 +860,14 @@ class instance_icecrown_citadel : public InstanceMapScript
IsOrbWhispererEligible = data ? true : false;
break;
case DATA_SINDRAGOSA_FROSTWYRMS:
- {
- if (FrostwyrmCount == 255)
- return;
-
- if (instance->IsHeroic() && !HeroicAttempts)
- return;
-
- if (GetBossState(DATA_SINDRAGOSA) == DONE)
- return;
-
- switch (data)
- {
- case 0:
- if (FrostwyrmCount)
- {
- --FrostwyrmCount;
- if (!FrostwyrmCount)
- {
- instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
- if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
- boss->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- }
- break;
- case 1:
- ++FrostwyrmCount;
- break;
- default:
- FrostwyrmCount = data;
- break;
- }
+ FrostwyrmGUIDs.insert(data);
break;
- }
case DATA_SPINESTALKER:
- {
- if (SpinestalkerTrashCount == 255)
- return;
-
- switch (data)
- {
- case 0:
- if (SpinestalkerTrashCount)
- {
- --SpinestalkerTrashCount;
- if (!SpinestalkerTrashCount)
- if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
- spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- break;
- case 1:
- ++SpinestalkerTrashCount;
- break;
- default:
- SpinestalkerTrashCount = data;
- break;
- }
+ SpinestalkerTrash.insert(data);
break;
- }
case DATA_RIMEFANG:
- {
- if (RimefangTrashCount == 255)
- return;
-
- switch (data)
- {
- case 0:
- if (RimefangTrashCount)
- {
- --RimefangTrashCount;
- if (!RimefangTrashCount)
- if (Creature* rime = instance->GetCreature(RimefangGUID))
- rime->AI()->DoAction(ACTION_START_FROSTWYRM);
- }
- break;
- case 1:
- ++RimefangTrashCount;
- break;
- default:
- RimefangTrashCount = data;
- break;
- }
+ RimefangTrash.insert(data);
break;
- }
case DATA_COLDFLAME_JETS:
ColdflameJetsState = data;
if (ColdflameJetsState == DONE)
@@ -1095,6 +1082,28 @@ class instance_icecrown_citadel : public InstanceMapScript
return true;
}
+ void CheckLichKingAvailability()
+ {
+ if (GetBossState(DATA_PROFESSOR_PUTRICIDE) == DONE && GetBossState(DATA_BLOOD_QUEEN_LANA_THEL) == DONE && GetBossState(DATA_SINDRAGOSA) == DONE)
+ {
+ if (GameObject* teleporter = instance->GetGameObject(TheLichKingTeleportGUID))
+ {
+ teleporter->SetGoState(GO_STATE_ACTIVE);
+
+ std::list<Creature*> stalkers;
+ GetCreatureListWithEntryInGrid(stalkers, teleporter, NPC_INVISIBLE_STALKER, 100.0f);
+ if (stalkers.empty())
+ return;
+
+ stalkers.sort(Trinity::ObjectDistanceOrderPred(teleporter));
+ stalkers.front()->CastSpell((Unit*)NULL, SPELL_ARTHAS_TELEPORTER_CEREMONY, false);
+ stalkers.pop_front();
+ for (std::list<Creature*>::iterator itr = stalkers.begin(); itr != stalkers.end(); ++itr)
+ (*itr)->AI()->Reset();
+ }
+ }
+ }
+
std::string GetSaveData()
{
OUT_SAVE_INST_DATA;
@@ -1276,6 +1285,7 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 SindragosaGUID;
uint64 SpinestalkerGUID;
uint64 RimefangGUID;
+ uint64 TheLichKingTeleportGUID;
uint64 TheLichKingGUID;
uint64 HighlordTirionFordringGUID;
uint64 TerenasMenethilGUID;
@@ -1289,9 +1299,9 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 PillarsUnchainedGUID;
uint32 TeamInInstance;
uint32 ColdflameJetsState;
- uint32 FrostwyrmCount;
- uint32 SpinestalkerTrashCount;
- uint32 RimefangTrashCount;
+ std::set<uint32> FrostwyrmGUIDs;
+ std::set<uint32> SpinestalkerTrash;
+ std::set<uint32> RimefangTrash;
uint32 BloodQuickeningState;
uint32 HeroicAttempts;
uint16 BloodQuickeningMinutes;
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
index 17ed6a79c76..f81ddbf6bf8 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_four_horsemen.cpp
@@ -15,7 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "naxxramas.h"
enum Horsemen
@@ -26,6 +29,11 @@ enum Horsemen
HORSEMEN_SIR,
};
+enum Spells
+{
+ SPELL_MARK_DAMAGE = 28836
+};
+
enum Events
{
EVENT_NONE,
@@ -395,7 +403,63 @@ public:
};
+class spell_four_horsemen_mark : public SpellScriptLoader
+{
+ public:
+ spell_four_horsemen_mark() : SpellScriptLoader("spell_four_horsemen_mark") { }
+
+ class spell_four_horsemen_mark_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_four_horsemen_mark_AuraScript);
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ int32 damage;
+ switch (GetStackAmount())
+ {
+ case 1:
+ damage = 0;
+ break;
+ case 2:
+ damage = 500;
+ break;
+ case 3:
+ damage = 1000;
+ break;
+ case 4:
+ damage = 1500;
+ break;
+ case 5:
+ damage = 4000;
+ break;
+ case 6:
+ damage = 12000;
+ break;
+ default:
+ damage = 20000 + 1000 * (GetStackAmount() - 7);
+ break;
+ }
+ if (damage)
+ caster->CastCustomSpell(SPELL_MARK_DAMAGE, SPELLVALUE_BASE_POINT0, damage, GetTarget());
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_four_horsemen_mark_AuraScript::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_four_horsemen_mark_AuraScript();
+ }
+};
+
void AddSC_boss_four_horsemen()
{
new boss_four_horsemen();
+ new spell_four_horsemen_mark();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
index 8d23de5427c..faaea9c4cae 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_gothik.cpp
@@ -15,7 +15,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
+#include "GridNotifiers.h"
+#include "CombatAI.h"
#include "naxxramas.h"
enum Yells
@@ -25,6 +29,7 @@ enum Yells
SAY_DEATH = -1533042,
SAY_TELEPORT = -1533043
};
+
//Gothik
enum Spells
{
@@ -36,8 +41,11 @@ enum Spells
SPELL_INFORM_LIVE_RIDER = 27935,
SPELL_INFORM_DEAD_TRAINEE = 27915,
SPELL_INFORM_DEAD_KNIGHT = 27931,
- SPELL_INFORM_DEAD_RIDER = 27937
+ SPELL_INFORM_DEAD_RIDER = 27937,
+
+ SPELL_SHADOW_MARK = 27825
};
+
enum Creatures
{
MOB_LIVE_TRAINEE = 16124,
@@ -585,8 +593,35 @@ class mob_gothik_minion : public CreatureScript
}
};
+class spell_gothik_shadow_bolt_volley : public SpellScriptLoader
+{
+ public:
+ spell_gothik_shadow_bolt_volley() : SpellScriptLoader("spell_gothik_shadow_bolt_volley") { }
+
+ class spell_gothik_shadow_bolt_volley_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gothik_shadow_bolt_volley_SpellScript);
+
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_SHADOW_MARK));
+ }
+
+ void Register()
+ {
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_gothik_shadow_bolt_volley_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gothik_shadow_bolt_volley_SpellScript();
+ }
+};
+
void AddSC_boss_gothik()
{
new boss_gothik();
new mob_gothik_minion();
+ new spell_gothik_shadow_bolt_volley();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
index 0a4fdec7222..38c22a93ac4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp
@@ -86,6 +86,7 @@ enum Spells
SPELL_SHADOW_FISURE = 27810,
SPELL_VOID_BLAST = 27812,
SPELL_MANA_DETONATION = 27819,
+ SPELL_MANA_DETONATION_DAMAGE = 27820,
SPELL_FROST_BLAST = 27808,
SPELL_CHAINS_OF_KELTHUZAD = 28410, //28408 script effect
SPELL_KELTHUZAD_CHANNEL = 29423,
@@ -773,6 +774,46 @@ class npc_kelthuzad_abomination : public CreatureScript
}
};
+class spell_kelthuzad_detonate_mana : public SpellScriptLoader
+{
+ public:
+ spell_kelthuzad_detonate_mana() : SpellScriptLoader("spell_kelthuzad_detonate_mana") { }
+
+ class spell_kelthuzad_detonate_mana_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_kelthuzad_detonate_mana_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MANA_DETONATION_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void HandleScript(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+
+ Unit* target = GetTarget();
+ if (int32 mana = int32(target->GetMaxPower(POWER_MANA) / 10))
+ {
+ mana = target->ModifyPower(POWER_MANA, -mana);
+ target->CastCustomSpell(SPELL_MANA_DETONATION_DAMAGE, SPELLVALUE_BASE_POINT0, -mana * 10, target, true, NULL, aurEff);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_kelthuzad_detonate_mana_AuraScript::HandleScript, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_kelthuzad_detonate_mana_AuraScript();
+ }
+};
+
class achievement_just_cant_get_enough : public AchievementCriteriaScript
{
public:
@@ -796,5 +837,6 @@ void AddSC_boss_kelthuzad()
new boss_kelthuzad();
new at_kelthuzad_center();
new npc_kelthuzad_abomination();
+ new spell_kelthuzad_detonate_mana();
new achievement_just_cant_get_enough();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
index ccc8e9a5663..e45700ebd72 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_thaddius.cpp
@@ -456,10 +456,10 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_UNIT;
}
- void HandleTargets(std::list<Unit*>& targetList)
+ void HandleTargets(std::list<WorldObject*>& targets)
{
uint8 count = 0;
- for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
+ for (std::list<WorldObject*>::iterator ihit = targets.begin(); ihit != targets.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
@@ -498,7 +498,7 @@ class spell_thaddius_pos_neg_charge : public SpellScriptLoader
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);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_thaddius_pos_neg_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
index 19a84fdae84..d200e8bf4bf 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/boss_varos.cpp
@@ -297,7 +297,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
{
PrepareSpellScript(spell_varos_energize_core_area_enemySpellScript)
- void FilterTargets(std::list<Unit*>& targetList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
Creature* varos = GetCaster()->ToCreature();
if (!varos)
@@ -308,7 +308,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation();
- for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
Position pos;
(*itr)->GetPosition(&pos);
@@ -317,7 +317,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
float diff = fabs(orientation - angle);
if (diff > 1.0f)
- itr = targetList.erase(itr);
+ itr = targets.erase(itr);
else
++itr;
}
@@ -325,7 +325,7 @@ class spell_varos_energize_core_area_enemy : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_enemySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -344,7 +344,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
{
PrepareSpellScript(spell_varos_energize_core_area_entrySpellScript)
- void FilterTargets(std::list<Unit*>& targetList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
Creature* varos = GetCaster()->ToCreature();
if (!varos)
@@ -355,7 +355,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
float orientation = CAST_AI(boss_varos::boss_varosAI, varos->AI())->GetCoreEnergizeOrientation();
- for (std::list<Unit*>::iterator itr = targetList.begin(); itr != targetList.end();)
+ for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end();)
{
Position pos;
(*itr)->GetPosition(&pos);
@@ -364,7 +364,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
float diff = fabs(orientation - angle);
if (diff > 1.0f)
- itr = targetList.erase(itr);
+ itr = targets.erase(itr);
else
++itr;
}
@@ -372,7 +372,7 @@ class spell_varos_energize_core_area_entry : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_varos_energize_core_area_entrySpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
diff --git a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
index 23f55a3033b..0eafd7a7fea 100644
--- a/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
+++ b/src/server/scripts/Northrend/Nexus/Oculus/oculus.cpp
@@ -47,7 +47,9 @@ enum Drakes
NPC_VERDISA = 27657,
NPC_BELGARISTRASZ = 27658,
- NPC_ETERNOS = 27659
+ NPC_ETERNOS = 27659,
+
+ SPELL_SHOCK_CHARGE = 49836,
};
enum Says
@@ -210,8 +212,40 @@ public:
}
};
+class spell_gen_stop_time : public SpellScriptLoader
+{
+public:
+ spell_gen_stop_time() : SpellScriptLoader("spell_gen_stop_time") { }
+
+ class spell_gen_stop_time_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_stop_time_AuraScript);
+
+ void Apply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* caster = GetCaster();
+ if (!caster)
+ return;
+ Unit* target = GetTarget();
+ for (uint32 i = 0; i < 5; ++i)
+ caster->CastSpell(target, SPELL_SHOCK_CHARGE, false);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_stop_time_AuraScript::Apply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_stop_time_AuraScript();
+ }
+};
+
void AddSC_oculus()
{
new npc_oculus_drake();
new npc_image_belgaristrasz();
+ new spell_gen_stop_time();
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
index 2e2744baa3c..f42fd87c643 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfLightning/boss_loken.cpp
@@ -19,11 +19,13 @@
/* ScriptData
SDName: Boss Loken
SD%Complete: 60%
-SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414)
+SDComment: Missing intro.
SDCategory: Halls of Lightning
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "halls_of_lightning.h"
enum eEnums
@@ -73,23 +75,17 @@ public:
InstanceScript* instance;
- bool m_bIsAura;
-
uint32 m_uiArcLightning_Timer;
uint32 m_uiLightningNova_Timer;
- uint32 m_uiPulsingShockwave_Timer;
uint32 m_uiResumePulsingShockwave_Timer;
uint32 m_uiHealthAmountModifier;
void Reset()
{
- m_bIsAura = false;
-
m_uiArcLightning_Timer = 15000;
m_uiLightningNova_Timer = 20000;
- m_uiPulsingShockwave_Timer = 2000;
- m_uiResumePulsingShockwave_Timer = 15000;
+ m_uiResumePulsingShockwave_Timer = 1000;
m_uiHealthAmountModifier = 1;
@@ -116,7 +112,10 @@ public:
Talk(SAY_DEATH);
if (instance)
+ {
instance->SetData(TYPE_LOKEN, DONE);
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_PULSING_SHOCKWAVE_AURA);
+ }
}
void KilledUnit(Unit* /*victim*/)
@@ -130,44 +129,13 @@ public:
if (!UpdateVictim())
return;
- if (m_bIsAura)
- {
- // workaround for PULSING_SHOCKWAVE
- if (m_uiPulsingShockwave_Timer <= uiDiff)
- {
- Map* map = me->GetMap();
- if (map->IsDungeon())
- {
- Map::PlayerList const &PlayerList = map->GetPlayers();
-
- if (PlayerList.isEmpty())
- return;
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack())
- {
- int32 dmg;
- float m_fDist = me->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ());
-
- dmg = DUNGEON_MODE(100, 150); // need to correct damage
- if (m_fDist > 1.0f) // Further from 1 yard
- dmg = int32(dmg*m_fDist);
-
- me->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false);
- }
- }
- m_uiPulsingShockwave_Timer = 2000;
- } else m_uiPulsingShockwave_Timer -= uiDiff;
- }
- else
+ if (m_uiResumePulsingShockwave_Timer)
{
if (m_uiResumePulsingShockwave_Timer <= uiDiff)
{
- //breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?
DoCast(me, SPELL_PULSING_SHOCKWAVE_AURA, true);
- DoCast(me, SPELL_PULSING_SHOCKWAVE_N); // need core support
- m_bIsAura = true;
+ DoCast(me, SPELL_PULSING_SHOCKWAVE_N, true);
m_uiResumePulsingShockwave_Timer = 0;
}
else
@@ -190,7 +158,7 @@ public:
Talk(EMOTE_NOVA);
DoCast(me, SPELL_LIGHTNING_NOVA_N);
- m_bIsAura = false;
+ me->RemoveAurasDueToSpell(DUNGEON_MODE<uint32>(SPELL_PULSING_SHOCKWAVE_N, SPELL_PULSING_SHOCKWAVE_H));
m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
m_uiLightningNova_Timer = urand(20000, 21000);
}
@@ -216,7 +184,39 @@ public:
};
+class spell_loken_pulsing_shockwave : public SpellScriptLoader
+{
+ public:
+ spell_loken_pulsing_shockwave() : SpellScriptLoader("spell_loken_pulsing_shockwave") { }
+
+ class spell_loken_pulsing_shockwave_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_loken_pulsing_shockwave_SpellScript);
+
+ void CalculateDamage(SpellEffIndex /*effIndex*/)
+ {
+ if (!GetHitUnit())
+ return;
+
+ float distance = GetCaster()->GetDistance2d(GetHitUnit());
+ if (distance > 1.0f)
+ SetHitDamage(int32(GetHitDamage() * distance));
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_loken_pulsing_shockwave_SpellScript::CalculateDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_loken_pulsing_shockwave_SpellScript();
+ }
+};
+
void AddSC_boss_loken()
{
new boss_loken();
+ new spell_loken_pulsing_shockwave();
}
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
index bc57ce21a4d..93bea92503c 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/boss_krystallus.cpp
@@ -23,7 +23,9 @@ SDComment:
SDCategory:
Script Data End */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "halls_of_stone.h"
enum Spells
@@ -157,17 +159,12 @@ public:
DoScriptText(SAY_KILL, me);
}
- void SpellHitTarget(Unit* target, const SpellInfo* pSpell)
+ void SpellHitTarget(Unit* /*target*/, const SpellInfo* pSpell)
{
//this part should be in the core
if (pSpell->Id == SPELL_SHATTER || pSpell->Id == H_SPELL_SHATTER)
{
- //this spell must have custom handling in the core, dealing damage based on distance
- target->CastSpell(target, DUNGEON_MODE(SPELL_SHATTER_EFFECT, H_SPELL_SHATTER_EFFECT), true);
-
- if (target->HasAura(SPELL_STONED))
- target->RemoveAurasDueToSpell(SPELL_STONED);
-
+ // todo: we need eventmap to kill this stuff
//clear this, if we are still performing
if (bIsSlam)
{
@@ -186,7 +183,74 @@ public:
};
+class spell_krystallus_shatter : public SpellScriptLoader
+{
+ public:
+ spell_krystallus_shatter() : SpellScriptLoader("spell_krystallus_shatter") { }
+
+ class spell_krystallus_shatter_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_krystallus_shatter_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->RemoveAurasDueToSpell(SPELL_STONED);
+ target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_krystallus_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_krystallus_shatter_SpellScript();
+ }
+};
+
+class spell_krystallus_shatter_effect : public SpellScriptLoader
+{
+ public:
+ spell_krystallus_shatter_effect() : SpellScriptLoader("spell_krystallus_shatter_effect") { }
+
+ class spell_krystallus_shatter_effect_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_krystallus_shatter_effect_SpellScript);
+
+ void CalculateDamage()
+ {
+ if (!GetHitUnit())
+ return;
+
+ float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ if (!radius)
+ return;
+
+ float distance = GetCaster()->GetDistance2d(GetHitUnit());
+ if (distance > 1.0f)
+ SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
+ }
+
+ void Register()
+ {
+ OnHit += SpellHitFn(spell_krystallus_shatter_effect_SpellScript::CalculateDamage);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_krystallus_shatter_effect_SpellScript();
+ }
+};
+
void AddSC_boss_krystallus()
{
new boss_krystallus();
+ new spell_krystallus_shatter();
+ new spell_krystallus_shatter_effect();
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
index 2af73389ecb..7ee67060f97 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_algalon_the_observer.cpp
@@ -1080,7 +1080,7 @@ class NotVictimFilter
{
}
- bool operator()(Unit* target)
+ bool operator()(WorldObject* target)
{
return target != _victim;
}
@@ -1098,14 +1098,14 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader
{
PrepareSpellScript(spell_algalon_arcane_barrage_SpellScript);
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
targets.remove_if(NotVictimFilter(GetCaster()));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_arcane_barrage_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
@@ -1118,9 +1118,9 @@ class spell_algalon_arcane_barrage : public SpellScriptLoader
class ActiveConstellationFilter
{
public:
- bool operator()(Unit* target) const
+ bool operator()(WorldObject* target) const
{
- return target->GetAI()->GetData(0);
+ return target->ToUnit() && target->ToUnit()->GetAI() && target->ToUnit()->GetAI()->GetData(0);
}
};
@@ -1133,7 +1133,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader
{
PrepareSpellScript(spell_algalon_trigger_3_adds_SpellScript);
- void SelectTarget(std::list<Unit*>& targets)
+ void SelectTarget(std::list<WorldObject*>& targets)
{
targets.remove_if(ActiveConstellationFilter());
}
@@ -1150,7 +1150,7 @@ class spell_algalon_trigger_3_adds : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_trigger_3_adds_SpellScript::SelectTarget, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
}
};
@@ -1202,7 +1202,7 @@ class spell_algalon_big_bang : public SpellScriptLoader
return true;
}
- void CountTargets(std::list<Unit*>& targets)
+ void CountTargets(std::list<WorldObject*>& targets)
{
_targetCount = targets.size();
}
@@ -1215,7 +1215,7 @@ class spell_algalon_big_bang : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_algalon_big_bang_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
AfterCast += SpellCastFn(spell_algalon_big_bang_SpellScript::CheckTargets);
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
index 472ff153d73..ec3125f7c0a 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_auriaya.cpp
@@ -472,9 +472,9 @@ class npc_feral_defender : public CreatureScript
class SanctumSentryCheck
{
public:
- bool operator() (Unit* unit)
+ bool operator()(WorldObject* object) const
{
- if (unit->GetEntry() == NPC_SANCTUM_SENTRY)
+ if (object->GetEntry() == NPC_SANCTUM_SENTRY)
return false;
return true;
@@ -490,14 +490,14 @@ class spell_auriaya_strenght_of_the_pack : public SpellScriptLoader
{
PrepareSpellScript(spell_auriaya_strenght_of_the_pack_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (SanctumSentryCheck());
+ unitList.remove_if(SanctumSentryCheck());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_strenght_of_the_pack_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -516,15 +516,15 @@ class spell_auriaya_sentinel_blast : public SpellScriptLoader
{
PrepareSpellScript(spell_auriaya_sentinel_blast_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (PlayerOrPetCheck());
+ unitList.remove_if(PlayerOrPetCheck());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_auriaya_sentinel_blast_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
index 0e453eceaa1..9d5adf39817 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -720,20 +720,18 @@ class boss_flame_leviathan_overload_device : public CreatureScript
{
}
- void DoAction(const int32 param)
+ void OnSpellClick(Unit* /*clicker*/)
{
- if (param == EVENT_SPELLCLICK)
+ if (me->GetVehicle())
{
- if (me->GetVehicle())
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
{
- me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- if (Unit* player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
- {
- me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
- player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30);
- player->ExitVehicle();
- }
+ me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
+ player->GetMotionMaster()->MoveKnockbackFrom(me->GetVehicleBase()->GetPositionX(), me->GetVehicleBase()->GetPositionY(), 30, 30);
+ player->ExitVehicle();
}
}
}
@@ -1232,7 +1230,7 @@ public:
//bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
//{
// player->PlayerTalkClass->ClearMenus();
- // switch(action)
+ // switch (action)
// {
// case GOSSIP_ACTION_INFO_DEF+1:
// if (player)
@@ -1619,7 +1617,7 @@ class FlameLeviathanPursuedTargetSelector
public:
explicit FlameLeviathanPursuedTargetSelector(Unit* unit) : _me(unit) {};
- bool operator()(Unit* target) const
+ bool operator()(WorldObject* target) const
{
//! No players, only vehicles (todo: check if blizzlike)
Creature* creatureTarget = target->ToCreature();
@@ -1667,7 +1665,7 @@ class spell_pursue : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& targets)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(FlameLeviathanPursuedTargetSelector(GetCaster()));
if (targets.empty())
@@ -1683,7 +1681,7 @@ class spell_pursue : public SpellScriptLoader
}
}
- void FilterTargetsSubsequently(std::list<Unit*>& targets)
+ void FilterTargetsSubsequently(std::list<WorldObject*>& targets)
{
targets.clear();
if (_target)
@@ -1710,12 +1708,12 @@ class spell_pursue : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pursue_SpellScript::FilterTargetsSubsequently, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_pursue_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
- Unit* _target;
+ WorldObject* _target;
};
SpellScript* GetSpellScript() const
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
index 3556bf188de..8090b9e8a3e 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_general_vezax.cpp
@@ -51,6 +51,8 @@ enum VezaxSpells
SPELL_SHADOW_CRASH_HIT = 62659,
SPELL_SURGE_OF_DARKNESS = 62662,
SPELL_SARONITE_VAPORS = 63323,
+ SPELL_SARONITE_VAPORS_ENERGIZE = 63337,
+ SPELL_SARONITE_VAPORS_DAMAGE = 63338,
SPELL_SUMMON_SARONITE_VAPORS = 63081,
SPELL_BERSERK = 26662,
@@ -463,6 +465,45 @@ class spell_mark_of_the_faceless : public SpellScriptLoader
}
};
+class spell_general_vezax_saronite_vapors : public SpellScriptLoader
+{
+ public:
+ spell_general_vezax_saronite_vapors() : SpellScriptLoader("spell_general_vezax_saronite_vapors") { }
+
+ class spell_general_vezax_saronite_vapors_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_general_vezax_saronite_vapors_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_ENERGIZE) || !sSpellMgr->GetSpellInfo(SPELL_SARONITE_VAPORS_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void HandleEffectApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ int32 mana = int32(aurEff->GetAmount() * pow(2.0f, GetStackAmount())); // mana restore - bp * 2^stackamount
+ int32 damage = mana * 2;
+ caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_ENERGIZE, &mana, NULL, NULL, true);
+ caster->CastCustomSpell(GetTarget(), SPELL_SARONITE_VAPORS_DAMAGE, &damage, NULL, NULL, true);
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_general_vezax_saronite_vapors_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_general_vezax_saronite_vapors_AuraScript();
+ }
+};
+
class achievement_shadowdodger : public AchievementCriteriaScript
{
public:
@@ -509,6 +550,7 @@ void AddSC_boss_general_vezax()
new boss_saronite_animus();
new npc_saronite_vapors();
new spell_mark_of_the_faceless();
+ new spell_general_vezax_saronite_vapors();
new achievement_shadowdodger();
new achievement_smell_saronite();
}
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
index d89d640b083..24a9171e29f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_kologarn.cpp
@@ -354,7 +354,7 @@ class StoneGripTargetSelector : public std::unary_function<Unit*, bool>
public:
StoneGripTargetSelector(Creature* me, Unit const* victim) : _me(me), _victim(victim) {}
- bool operator() (Unit* target)
+ bool operator()(WorldObject* target)
{
if (target == _victim && _me->getThreatManager().getThreatList().size() > 1)
return true;
@@ -385,10 +385,10 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
return true;
}
- void FilterTargetsInitial(std::list<Unit*>& unitList)
+ void FilterTargetsInitial(std::list<WorldObject*>& unitList)
{
// Remove "main tank" and non-player targets
- unitList.remove_if (StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim()));
+ unitList.remove_if(StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim()));
// Maximum affected targets per difficulty mode
uint32 maxTargets = 1;
if (GetSpellInfo()->Id == 63981)
@@ -397,7 +397,7 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
// Return a random amount of targets based on maxTargets
while (maxTargets < unitList.size())
{
- std::list<Unit*>::iterator itr = unitList.begin();
+ std::list<WorldObject*>::iterator itr = unitList.begin();
advance(itr, urand(0, unitList.size()-1));
unitList.erase(itr);
}
@@ -406,20 +406,20 @@ class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader
m_unitList = unitList;
}
- void FillTargetsSubsequential(std::list<Unit*>& unitList)
+ void FillTargetsSubsequential(std::list<WorldObject*>& unitList)
{
unitList = m_unitList;
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_SRC_AREA_ENEMY);
}
// Shared between effects
- std::list<Unit*> m_unitList;
+ std::list<WorldObject*> m_unitList;
};
SpellScript* GetSpellScript() const
@@ -598,14 +598,14 @@ class spell_kologarn_stone_shout : public SpellScriptLoader
{
PrepareSpellScript(spell_kologarn_stone_shout_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (PlayerOrPetCheck());
+ unitList.remove_if(PlayerOrPetCheck());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_kologarn_stone_shout_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
index c7091b42c5a..79e4684f3a6 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_xt002.cpp
@@ -170,7 +170,11 @@ enum AchievementCredits
ACHIEV_MUST_DECONSTRUCT_FASTER = 21027,
};
-#define HEART_VEHICLE_SEAT 0
+enum VehicleSeats
+{
+ HEART_VEHICLE_SEAT_NORMAL = 0,
+ HEART_VEHICLE_SEAT_EXPOSED = 1,
+};
/*-------------------------------------------------------
*
@@ -198,6 +202,8 @@ class boss_xt002 : public CreatureScript
_Reset();
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoCast(me, SPELL_STAND);
_healthRecovered = false;
_gravityBombCasualty = false;
@@ -356,15 +362,16 @@ class boss_xt002 : public CreatureScript
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
- Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
+ Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_NORMAL) : NULL;
if (heart)
{
heart->CastSpell(heart, SPELL_HEART_OVERLOAD, false);
heart->CastSpell(me, SPELL_HEART_LIGHTNING_TETHER, false);
heart->CastSpell(heart, SPELL_HEART_HEAL_TO_FULL, true);
heart->CastSpell(heart, SPELL_EXPOSED_HEART, false); // Channeled
-
- heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ heart->ChangeSeat(HEART_VEHICLE_SEAT_EXPOSED, true);
+ heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
}
events.CancelEvent(EVENT_SEARING_LIGHT);
@@ -392,11 +399,13 @@ class boss_xt002 : public CreatureScript
events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));
- Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
+ Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_EXPOSED) : NULL;
if (!heart)
return;
- heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
+ heart->ChangeSeat(HEART_VEHICLE_SEAT_NORMAL, false);
+ heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);
if (!_hardMode)
@@ -425,43 +434,39 @@ class boss_xt002 : public CreatureScript
* XT-002 HEART
*
*///----------------------------------------------------
+
class mob_xt002_heart : public CreatureScript
{
public:
mob_xt002_heart() : CreatureScript("mob_xt002_heart") { }
- CreatureAI* GetAI(Creature* creature) const
+ struct mob_xt002_heartAI : public Scripted_NoMovementAI
{
- return new mob_xt002_heartAI(creature);
- }
-
- struct mob_xt002_heartAI : public ScriptedAI
- {
- mob_xt002_heartAI(Creature* creature) : ScriptedAI(creature)
+ mob_xt002_heartAI(Creature* creature) : Scripted_NoMovementAI(creature),
+ _instance(creature->GetInstanceScript())
{
- _instance = creature->GetInstanceScript();
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_STUNNED | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->SetReactState(REACT_PASSIVE);
}
- void DamageTaken(Unit* /*pDone*/, uint32 &damage)
+ void UpdateAI(uint32 const /*diff*/) { }
+
+ void JustDied(Unit* /*killer*/)
{
- Creature* xt002 = me->GetCreature(*me, _instance->GetData64(BOSS_XT002));
+ Creature* xt002 = _instance ? me->GetCreature(*me, _instance->GetData64(BOSS_XT002)) : NULL;
if (!xt002 || !xt002->AI())
return;
- if (damage >= me->GetHealth())
- {
- xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetMaxHealth());
- xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
- damage = 0;
- }
+ xt002->AI()->SetData(DATA_TRANSFERED_HEALTH, me->GetHealth());
+ xt002->AI()->DoAction(ACTION_ENTER_HARD_MODE);
}
- private:
- InstanceScript* _instance;
- uint32 _damageTaken;
+ private:
+ InstanceScript* _instance;
};
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new mob_xt002_heartAI(creature);
+ }
};
/*-------------------------------------------------------
@@ -915,7 +920,7 @@ class spell_xt002_heart_overload_periodic : public SpellScriptLoader
{
uint8 a = urand(0, 4);
uint32 spellId = spells[a];
- toyPile->CastSpell(toyPile, spellId, true);
+ toyPile->CastSpell(toyPile, spellId, true, NULL, NULL, instance->GetData64(BOSS_XT002));
}
}
}
@@ -945,9 +950,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader
{
PrepareSpellScript(spell_xt002_tympanic_tantrum_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove_if(PlayerOrPetCheck());
+ targets.remove_if(PlayerOrPetCheck());
}
void RecalculateDamage()
@@ -957,8 +962,9 @@ class spell_xt002_tympanic_tantrum : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_xt002_tympanic_tantrum_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
OnHit += SpellHitFn(spell_xt002_tympanic_tantrum_SpellScript::RecalculateDamage);
}
};
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index d35f0559080..858a82bbe57 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -268,10 +268,10 @@ GameObjectAI* GetUlduarAI(GameObject* go)
class PlayerOrPetCheck
{
public:
- bool operator() (Unit* unit)
+ bool operator()(WorldObject* object) const
{
- if (unit->GetTypeId() != TYPEID_PLAYER)
- if (!unit->ToCreature()->isPet())
+ if (object->GetTypeId() != TYPEID_PLAYER)
+ if (!object->ToCreature()->isPet())
return true;
return false;
diff --git a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
index 29b8f2e7f48..41a25ce5f76 100644
--- a/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
+++ b/src/server/scripts/Northrend/UtgardeKeep/UtgardePinnacle/boss_svala.cpp
@@ -276,7 +276,7 @@ public:
arthas->CastSpell(me, SPELL_TRANSFORMING_CHANNEL, false);
pos.Relocate(me);
pos.m_positionZ += 8.0f;
- me->GetMotionMaster()->MoveTakeoff(0, pos, 3.30078125f);
+ me->GetMotionMaster()->MoveTakeoff(0, pos);
// spectators flee event
if (instance)
{
@@ -333,7 +333,9 @@ public:
pos.m_positionX = me->GetHomePosition().GetPositionX();
pos.m_positionY = me->GetHomePosition().GetPositionY();
pos.m_positionZ = 90.6065f;
- me->GetMotionMaster()->MoveLand(0, pos, 6.247422f);
+ me->GetMotionMaster()->MoveLand(0, pos);
+ me->SetDisableGravity(false, true);
+ me->SetHover(true);
me->SetDisableGravity(false, true);
me->SetHover(true);
++introPhase;
@@ -522,12 +524,12 @@ public:
};
};
-class checkRitualTarget
+class RitualTargetCheck
{
public:
- explicit checkRitualTarget(Unit* _caster) : caster(_caster) { }
+ explicit RitualTargetCheck(Unit* _caster) : caster(_caster) { }
- bool operator() (Unit* unit)
+ bool operator() (WorldObject* unit) const
{
if (InstanceScript* instance = caster->GetInstanceScript())
if (instance->GetData64(DATA_SACRIFICED_PLAYER) == unit->GetGUID())
@@ -549,14 +551,14 @@ class spell_paralyze_pinnacle : public SpellScriptLoader
{
PrepareSpellScript(spell_paralyze_pinnacle_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if(checkRitualTarget(GetCaster()));
+ unitList.remove_if(RitualTargetCheck(GetCaster()));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_paralyze_pinnacle_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
diff --git a/src/server/scripts/Northrend/dragonblight.cpp b/src/server/scripts/Northrend/dragonblight.cpp
index 4cbe280a9f2..1b339b24549 100644
--- a/src/server/scripts/Northrend/dragonblight.cpp
+++ b/src/server/scripts/Northrend/dragonblight.cpp
@@ -69,7 +69,106 @@ public:
}
};
+/*######
+## Quest Strengthen the Ancients (12096|12092)
+######*/
+
+enum StrengthenAncientsMisc
+{
+ SAY_WALKER_FRIENDLY = 0,
+ SAY_WALKER_ENEMY = 1,
+ SAY_LOTHALOR = 0,
+
+ SPELL_CREATE_ITEM_BARK = 47550,
+ SPELL_CONFUSED = 47044,
+
+ NPC_LOTHALOR = 26321,
+
+ FACTION_WALKER_ENEMY = 14,
+};
+
+class spell_q12096_q12092_dummy : public SpellScriptLoader // Strengthen the Ancients: On Interact Dummy to Woodlands Walker
+{
+public:
+ spell_q12096_q12092_dummy() : SpellScriptLoader("spell_q12096_q12092_dummy") { }
+
+ class spell_q12096_q12092_dummy_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_dummy_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint32 roll = rand() % 2;
+
+ Creature* tree = GetHitCreature();
+ Player* player = GetCaster()->ToPlayer();
+
+ if (!tree || !player)
+ return;
+
+ tree->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
+
+ if (roll == 1) // friendly version
+ {
+ tree->CastSpell(player, SPELL_CREATE_ITEM_BARK);
+ tree->AI()->Talk(SAY_WALKER_FRIENDLY, player->GetGUID());
+ tree->DespawnOrUnsummon(1000);
+ }
+ else if (roll == 0) // enemy version
+ {
+ tree->AI()->Talk(SAY_WALKER_ENEMY, player->GetGUID());
+ tree->setFaction(FACTION_WALKER_ENEMY);
+ tree->Attack(player, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_dummy_SpellScript();
+ }
+};
+
+class spell_q12096_q12092_bark : public SpellScriptLoader // Bark of the Walkers
+{
+public:
+ spell_q12096_q12092_bark() : SpellScriptLoader("spell_q12096_q12092_bark") { }
+
+ class spell_q12096_q12092_bark_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12096_q12092_bark_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ Creature* lothalor = GetHitCreature();
+ if (!lothalor || lothalor->GetEntry() != NPC_LOTHALOR)
+ return;
+
+ lothalor->AI()->Talk(SAY_LOTHALOR);
+ lothalor->RemoveAura(SPELL_CONFUSED);
+ lothalor->DespawnOrUnsummon(4000);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12096_q12092_bark_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12096_q12092_bark_SpellScript();
+ }
+};
+
void AddSC_dragonblight()
{
new npc_alexstrasza_wr_gate;
+ new spell_q12096_q12092_dummy;
+ new spell_q12096_q12092_bark;
}
diff --git a/src/server/scripts/Northrend/sholazar_basin.cpp b/src/server/scripts/Northrend/sholazar_basin.cpp
index 93d0182ea08..afab9b90a4a 100644
--- a/src/server/scripts/Northrend/sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/sholazar_basin.cpp
@@ -746,6 +746,130 @@ public:
}
};
+/*######
+## Quest Kick, What Kick? (12589)
+######*/
+
+enum KickWhatKick
+{
+ NPC_LUCKY_WILHELM = 28054,
+ NPC_APPLE = 28053,
+ NPC_DROSTAN = 28328,
+ NPC_CRUNCHY = 28346,
+ NPC_THICKBIRD = 28093,
+
+ SPELL_HIT_APPLE = 51331,
+ SPELL_MISS_APPLE = 51332,
+ SPELL_MISS_BIRD_APPLE = 51366,
+ SPELL_APPLE_FALL = 51371,
+ SPELL_BIRD_FALL = 51369,
+
+ EVENT_MISS = 0,
+ EVENT_HIT = 1,
+ EVENT_MISS_BIRD = 2,
+
+ SAY_WILHELM_MISS = 0,
+ SAY_WILHELM_HIT = 1,
+ SAY_DROSTAN_REPLY_MISS = 0,
+};
+
+class spell_q12589_shoot_rjr : public SpellScriptLoader
+{
+public:
+ spell_q12589_shoot_rjr() : SpellScriptLoader("spell_q12589_shoot_rjr") { }
+
+ class spell_q12589_shoot_rjr_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12589_shoot_rjr_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ if (Unit* target = GetExplTargetUnit())
+ if (target->GetEntry() == NPC_LUCKY_WILHELM)
+ return SPELL_CAST_OK;
+
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_TARGET_WILHELM);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ uint32 roll = urand(1, 100);
+
+ uint8 ev;
+ if (roll <= 50)
+ ev = EVENT_MISS;
+ else if (roll <= 83)
+ ev = EVENT_HIT;
+ else
+ ev = EVENT_MISS_BIRD;
+
+ Unit* shooter = GetCaster();
+ Creature* wilhelm = GetHitUnit()->ToCreature();
+ Creature* apple = shooter->FindNearestCreature(NPC_APPLE, 30);
+ Creature* drostan = shooter->FindNearestCreature(NPC_DROSTAN, 30);
+
+ if (!wilhelm || !apple || !drostan)
+ return;
+
+ switch (ev)
+ {
+ case EVENT_MISS_BIRD:
+ {
+ Creature* crunchy = shooter->FindNearestCreature(NPC_CRUNCHY, 30);
+ Creature* bird = shooter->FindNearestCreature(NPC_THICKBIRD, 30);
+
+ if (!bird || !crunchy)
+ ; // fall to EVENT_MISS
+ else
+ {
+ shooter->CastSpell(bird, SPELL_MISS_BIRD_APPLE);
+ bird->CastSpell(bird, SPELL_BIRD_FALL);
+ wilhelm->AI()->Talk(SAY_WILHELM_MISS);
+ drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
+
+ bird->Kill(bird);
+ crunchy->GetMotionMaster()->MovePoint(0, bird->GetPositionX(), bird->GetPositionY(),
+ bird->GetMap()->GetWaterOrGroundLevel(bird->GetPositionX(), bird->GetPositionY(), bird->GetPositionZ()));
+ // TODO: Make crunchy perform emote eat when he reaches the bird
+
+ break;
+ }
+ }
+ case EVENT_MISS:
+ {
+ shooter->CastSpell(wilhelm, SPELL_MISS_APPLE);
+ wilhelm->AI()->Talk(SAY_WILHELM_MISS);
+ drostan->AI()->Talk(SAY_DROSTAN_REPLY_MISS);
+ break;
+ }
+ case EVENT_HIT:
+ {
+ shooter->CastSpell(apple, SPELL_HIT_APPLE);
+ apple->CastSpell(apple, SPELL_APPLE_FALL);
+ wilhelm->AI()->Talk(SAY_WILHELM_HIT);
+ if (Player* player = shooter->ToPlayer())
+ player->KilledMonsterCredit(NPC_APPLE, 0);
+ apple->DespawnOrUnsummon();
+
+ break;
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_q12589_shoot_rjr_SpellScript::CheckCast);
+ OnEffectHitTarget += SpellEffectFn(spell_q12589_shoot_rjr_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12589_shoot_rjr_SpellScript();
+ }
+};
+
void AddSC_sholazar_basin()
{
new npc_injured_rainspeaker_oracle();
@@ -756,4 +880,5 @@ void AddSC_sholazar_basin()
new npc_adventurous_dwarf();
new npc_jungle_punch_target();
new spell_q12620_the_lifewarden_wrath();
+ new spell_q12589_shoot_rjr();
}
diff --git a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
index 0e654ade995..3443103fa70 100644
--- a/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
+++ b/src/server/scripts/Outland/GruulsLair/boss_gruul.cpp
@@ -19,11 +19,13 @@
/* ScriptData
SDName: Boss_Gruul
SD%Complete: 60
-SDComment: Ground Slam need further development (knock back effect and shatter effect must be added to the core)
+SDComment: Ground Slam need further development (knock back effect must be added to the core)
SDCategory: Gruul's Lair
EndScriptData */
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellScript.h"
#include "gruuls_lair.h"
enum eEnums
@@ -144,12 +146,7 @@ public:
//this part should be in the core
if (pSpell->Id == SPELL_SHATTER)
{
- //this spell must have custom handling in the core, dealing damage based on distance
- target->CastSpell(target, SPELL_SHATTER_EFFECT, true);
-
- if (target->HasAura(SPELL_STONED))
- target->RemoveAurasDueToSpell(SPELL_STONED);
-
+ // todo: use eventmap to kill this stuff
//clear this, if we are still performing
if (m_bPerformingGroundSlam)
{
@@ -258,7 +255,83 @@ public:
};
+class spell_gruul_shatter : public SpellScriptLoader
+{
+ public:
+ spell_gruul_shatter() : SpellScriptLoader("spell_gruul_shatter") { }
+
+ class spell_gruul_shatter_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gruul_shatter_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_STONED))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHATTER_EFFECT))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ {
+ target->RemoveAurasDueToSpell(SPELL_STONED);
+ target->CastSpell((Unit*)NULL, SPELL_SHATTER_EFFECT, true);
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gruul_shatter_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gruul_shatter_SpellScript();
+ }
+};
+
+class spell_gruul_shatter_effect : public SpellScriptLoader
+{
+ public:
+ spell_gruul_shatter_effect() : SpellScriptLoader("spell_gruul_shatter_effect") { }
+
+ class spell_gruul_shatter_effect_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gruul_shatter_effect_SpellScript);
+
+ void CalculateDamage()
+ {
+ if (!GetHitUnit())
+ return;
+
+ float radius = GetSpellInfo()->Effects[EFFECT_0].CalcRadius(GetCaster());
+ if (!radius)
+ return;
+
+ float distance = GetCaster()->GetDistance2d(GetHitUnit());
+ if (distance > 1.0f)
+ SetHitDamage(int32(GetHitDamage() * ((radius - distance) / radius)));
+ }
+
+ void Register()
+ {
+ OnHit += SpellHitFn(spell_gruul_shatter_effect_SpellScript::CalculateDamage);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gruul_shatter_effect_SpellScript();
+ }
+};
+
void AddSC_boss_gruul()
{
new boss_gruul();
+ new spell_gruul_shatter();
+ new spell_gruul_shatter_effect();
}
diff --git a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
index d202fdd2f44..0454274401c 100644
--- a/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Eye/boss_astromancer.cpp
@@ -518,7 +518,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
return true;
}
- void CountTargets(std::list<Unit*>& targetList)
+ void CountTargets(std::list<WorldObject*>& targetList)
{
_targetCount = targetList.size();
}
@@ -549,7 +549,7 @@ class spell_astromancer_wrath_of_the_astromancer : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_astromancer_wrath_of_the_astromancer_SpellScript::CountTargets, EFFECT_0, TARGET_DEST_CASTER_RADIUS);
}
};
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
index 3579a7d697b..1cd67065af1 100644
--- a/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
+++ b/src/server/scripts/Outland/TempestKeep/Mechanar/boss_mechano_lord_capacitus.cpp
@@ -52,10 +52,10 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader
return true;
}
- void HandleTargets(std::list<Unit*>& targetList)
+ void HandleTargets(std::list<WorldObject*>& targetList)
{
uint8 count = 0;
- for (std::list<Unit*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
+ for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
@@ -88,7 +88,7 @@ class spell_capacitus_polarity_charge : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
diff --git a/src/server/scripts/Outland/blades_edge_mountains.cpp b/src/server/scripts/Outland/blades_edge_mountains.cpp
index 4ec1d04b6ad..c46757a3956 100644
--- a/src/server/scripts/Outland/blades_edge_mountains.cpp
+++ b/src/server/scripts/Outland/blades_edge_mountains.cpp
@@ -651,7 +651,7 @@ class npc_simon_bunny : public CreatureScript
{
_events.Update(diff);
- switch(_events.ExecuteEvent())
+ switch (_events.ExecuteEvent())
{
case EVENT_SIMON_PERIODIC_PLAYER_CHECK:
if (!CheckPlayer())
diff --git a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp
index a213713ae1a..96897ae3033 100644
--- a/src/server/scripts/Outland/boss_doomlord_kazzak.cpp
+++ b/src/server/scripts/Outland/boss_doomlord_kazzak.cpp
@@ -16,7 +16,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptPCH.h"
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
+#include "SpellScript.h"
enum Texts
{
@@ -36,6 +39,7 @@ enum Spells
SPELL_THUNDERCLAP = 36706,
SPELL_VOID_BOLT = 39329,
SPELL_MARK_OF_KAZZAK = 32960,
+ SPELL_MARK_OF_KAZZAK_DAMAGE = 32961,
SPELL_ENRAGE = 32964,
SPELL_CAPTURE_SOUL = 32966,
SPELL_TWISTED_REFLECTION = 21063,
@@ -171,7 +175,55 @@ class boss_doomlord_kazzak : public CreatureScript
}
};
+class spell_mark_of_kazzak : public SpellScriptLoader
+{
+ public:
+ spell_mark_of_kazzak() : SpellScriptLoader("spell_mark_of_kazzak") { }
+
+ class spell_mark_of_kazzak_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mark_of_kazzak_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_MARK_OF_KAZZAK_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* owner = GetUnitOwner())
+ amount = CalculatePctU(owner->GetPower(POWER_MANA), 5);
+ }
+
+ void OnPeriodic(AuraEffect const* aurEff)
+ {
+ Unit* target = GetTarget();
+
+ if (target->GetPower(POWER_MANA) == 0)
+ {
+ target->CastSpell(target, SPELL_MARK_OF_KAZZAK_DAMAGE, true, NULL, aurEff);
+ // Remove aura
+ SetDuration(0);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_mark_of_kazzak_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazzak_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_mark_of_kazzak_AuraScript();
+ }
+};
+
void AddSC_boss_doomlordkazzak()
{
new boss_doomlord_kazzak();
+ new spell_mark_of_kazzak();
}
diff --git a/src/server/scripts/Outland/netherstorm.cpp b/src/server/scripts/Outland/netherstorm.cpp
index afc18c71b92..16dac13d1a9 100644
--- a/src/server/scripts/Outland/netherstorm.cpp
+++ b/src/server/scripts/Outland/netherstorm.cpp
@@ -777,10 +777,10 @@ public:
PlayerGUID = who->GetGUID();
}
- void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
- {
- DoCast(me, SPELL_DE_MATERIALIZE);
- }
+ //void SpellHit(Unit* /*caster*/, const SpellInfo* /*spell*/)
+ //{
+ // DoCast(me, SPELL_DE_MATERIALIZE);
+ //}
void UpdateAI(const uint32 diff)
{
diff --git a/src/server/scripts/Spells/CMakeLists.txt b/src/server/scripts/Spells/CMakeLists.txt
index 04dcee9287c..2bb695bd8a9 100644
--- a/src/server/scripts/Spells/CMakeLists.txt
+++ b/src/server/scripts/Spells/CMakeLists.txt
@@ -24,6 +24,7 @@ set(scripts_STAT_SRCS
Spells/spell_paladin.cpp
Spells/spell_item.cpp
Spells/spell_holiday.cpp
+ Spells/spell_pet.cpp
)
message(" -> Prepared: Spells")
diff --git a/src/server/scripts/Spells/spell_dk.cpp b/src/server/scripts/Spells/spell_dk.cpp
index 36dcb53ad00..5095092927e 100644
--- a/src/server/scripts/Spells/spell_dk.cpp
+++ b/src/server/scripts/Spells/spell_dk.cpp
@@ -40,6 +40,8 @@ enum DeathKnightSpells
DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED = 63611,
DK_SPELL_UNHOLY_PRESENCE = 48265,
DK_SPELL_IMPROVED_UNHOLY_PRESENCE_TRIGGERED = 63622,
+ SPELL_DK_ITEM_T8_MALEE_4P_BONUS = 64736,
+ DK_SPELL_BLACK_ICE_R1 = 49140,
};
// 50462 - Anti-Magic Shell (on raid member)
@@ -111,8 +113,7 @@ class spell_dk_anti_magic_shell_self : public SpellScriptLoader
void CalculateAmount(AuraEffect const* /*aurEff*/, int32 & amount, bool & /*canBeRecalculated*/)
{
- // Set absorbtion amount to unlimited
- amount = -1;
+ amount = GetCaster()->CountPctFromMaxHealth(hpPct);
}
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
@@ -334,16 +335,30 @@ class spell_dk_death_pact : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_death_pact_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ SpellCastResult CheckCast()
+ {
+ // Check if we have valid targets, otherwise skip spell casting here
+ if (Player* player = GetCaster()->ToPlayer())
+ for (Unit::ControlList::const_iterator itr = player->m_Controlled.begin(); itr != player->m_Controlled.end(); ++itr)
+ if (Creature* undeadPet = (*itr)->ToCreature())
+ if (undeadPet->isAlive() &&
+ undeadPet->GetOwnerGUID() == player->GetGUID() &&
+ undeadPet->GetCreatureType() == CREATURE_TYPE_UNDEAD &&
+ undeadPet->IsWithinDist(player, 100.0f, false))
+ return SPELL_CAST_OK;
+
+ return SPELL_FAILED_NO_PET;
+ }
+
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
Unit* unit_to_add = NULL;
- for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
+ for (std::list<WorldObject*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
{
- if ((*itr)->GetTypeId() == TYPEID_UNIT
- && (*itr)->GetOwnerGUID() == GetCaster()->GetGUID()
- && (*itr)->ToCreature()->GetCreatureTemplate()->type == CREATURE_TYPE_UNDEAD)
+ if (Unit* unit = (*itr)->ToUnit())
+ if (unit->GetOwnerGUID() == GetCaster()->GetGUID() && unit->GetCreatureType() == CREATURE_TYPE_UNDEAD)
{
- unit_to_add = (*itr);
+ unit_to_add = unit;
break;
}
}
@@ -351,18 +366,12 @@ class spell_dk_death_pact : public SpellScriptLoader
unitList.clear();
if (unit_to_add)
unitList.push_back(unit_to_add);
- else
- {
- // Pet not found - remove cooldown
- if (Player* modOwner = GetCaster()->GetSpellModOwner())
- modOwner->RemoveSpellCooldown(GetSpellInfo()->Id, true);
- FinishCast(SPELL_FAILED_NO_PET);
- }
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
+ OnCheckCast += SpellCheckCastFn(spell_dk_death_pact_SpellScript::CheckCast);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dk_death_pact_SpellScript::FilterTargets, EFFECT_1, TARGET_UNIT_DEST_AREA_ALLY);
}
};
@@ -381,6 +390,13 @@ class spell_dk_scourge_strike : public SpellScriptLoader
class spell_dk_scourge_strike_SpellScript : public SpellScript
{
PrepareSpellScript(spell_dk_scourge_strike_SpellScript);
+ float multiplier;
+
+ bool Load()
+ {
+ multiplier = 1.0f;
+ return true;
+ }
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -394,7 +410,23 @@ class spell_dk_scourge_strike : public SpellScriptLoader
Unit* caster = GetCaster();
if (Unit* unitTarget = GetHitUnit())
{
- int32 bp = CalculatePctN(GetHitDamage(), GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()));
+ multiplier = (GetEffectValue() * unitTarget->GetDiseasesByCaster(caster->GetGUID()) / 100.f);
+ // Death Knight T8 Melee 4P Bonus
+ if (AuraEffect const* aurEff = caster->GetAuraEffect(SPELL_DK_ITEM_T8_MALEE_4P_BONUS, EFFECT_0))
+ AddPctF(multiplier, aurEff->GetAmount());
+ }
+ }
+
+ void HandleAfterHit()
+ {
+ Unit* caster = GetCaster();
+ if (Unit* unitTarget = GetHitUnit())
+ {
+ int32 bp = GetHitDamage() * multiplier;
+
+ if (AuraEffect* aurEff = caster->GetAuraEffectOfRankedSpell(DK_SPELL_BLACK_ICE_R1, EFFECT_0))
+ AddPctN(bp, aurEff->GetAmount());
+
caster->CastCustomSpell(unitTarget, DK_SPELL_SCOURGE_STRIKE_TRIGGERED, &bp, NULL, NULL, true);
}
}
@@ -402,6 +434,7 @@ class spell_dk_scourge_strike : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_dk_scourge_strike_SpellScript::HandleDummy, EFFECT_2, SPELL_EFFECT_DUMMY);
+ AfterHit += SpellHitFn(spell_dk_scourge_strike_SpellScript::HandleAfterHit);
}
};
@@ -588,7 +621,7 @@ public:
if (!target->HasAura(DK_SPELL_BLOOD_PRESENCE) && !target->HasAura(DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED))
{
int32 basePoints1 = aurEff->GetAmount();
- target->CastCustomSpell(target, 63611, NULL, &basePoints1, NULL, true, 0, aurEff);
+ target->CastCustomSpell(target, DK_SPELL_IMPROVED_BLOOD_PRESENCE_TRIGGERED, NULL, &basePoints1, NULL, true, 0, aurEff);
}
}
@@ -723,14 +756,14 @@ class spell_dk_death_coil : public SpellScriptLoader
{
PrepareSpellScript(spell_dk_death_coil_SpellScript);
- bool Validate(SpellInfo const* /*SpellEntry*/)
+ bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_DAMAGE) || !sSpellMgr->GetSpellInfo(SPELL_DEATH_COIL_HEAL))
return false;
return true;
}
- void HandleDummy(SpellEffIndex /* effIndex */)
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
Unit* caster = GetCaster();
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 286bec6abab..f34e9e772f3 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -28,7 +28,11 @@
enum DruidSpells
{
DRUID_INCREASED_MOONFIRE_DURATION = 38414,
- DRUID_NATURES_SPLENDOR = 57865
+ DRUID_NATURES_SPLENDOR = 57865,
+ DRUID_LIFEBLOOM_FINAL_HEAL = 33778,
+ DRUID_LIFEBLOOM_ENERGIZE = 64372,
+ DRUID_SURVIVAL_INSTINCTS = 50322,
+ DRUID_SAVAGE_ROAR = 62071
};
// 54846 Glyph of Starfire
@@ -154,7 +158,7 @@ class spell_dru_primal_tenacity : public SpellScriptLoader
void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
{
// reduces all damage taken while Stunned in Cat Form
- if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->GetUInt32Value(UNIT_FIELD_FLAGS) & (UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
+ if (GetTarget()->GetShapeshiftForm() == FORM_CAT && GetTarget()->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED) && GetTarget()->HasAuraWithMechanic(1<<MECHANIC_STUN))
absorbAmount = CalculatePctN(dmgInfo.GetDamage(), absorbPct);
}
@@ -228,37 +232,37 @@ class spell_dru_t10_restoration_4p_bonus : public SpellScriptLoader
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
if (!GetCaster()->ToPlayer()->GetGroup())
{
- unitList.clear();
- unitList.push_back(GetCaster());
+ targets.clear();
+ targets.push_back(GetCaster());
}
else
{
- unitList.remove(GetExplTargetUnit());
+ targets.remove(GetExplTargetUnit());
std::list<Unit*> tempTargets;
- for (std::list<Unit*>::const_iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
- if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith(*itr))
- tempTargets.push_back(*itr);
+ for (std::list<WorldObject*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
+ if ((*itr)->GetTypeId() == TYPEID_PLAYER && GetCaster()->IsInRaidWith((*itr)->ToUnit()))
+ tempTargets.push_back((*itr)->ToUnit());
if (tempTargets.empty())
{
- unitList.clear();
+ targets.clear();
FinishCast(SPELL_FAILED_DONT_REPORT);
return;
}
Unit* target = Trinity::Containers::SelectRandomContainerElement(tempTargets);
- unitList.clear();
- unitList.push_back(target);
+ targets.clear();
+ targets.push_back(target);
}
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_t10_restoration_4p_bonus_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ALLY);
}
};
@@ -277,14 +281,14 @@ class spell_dru_starfall_aoe : public SpellScriptLoader
{
PrepareSpellScript(spell_dru_starfall_aoe_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove(GetExplTargetUnit());
+ targets.remove(GetExplTargetUnit());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_aoe_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -337,7 +341,12 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
{
PrepareSpellScript(spell_dru_starfall_dummy_SpellScript);
- void HandleDummy(SpellEffIndex /* effIndex */)
+ void FilterTargets(std::list<WorldObject*>& targets)
+ {
+ Trinity::Containers::RandomResizeList(targets, 2);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
// Shapeshifting into an animal form or mounting cancels the effect
@@ -348,15 +357,16 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
return;
}
- //Any effect which causes you to lose control of your character will supress the starfall effect.
+ // Any effect which causes you to lose control of your character will supress the starfall effect.
if (caster->HasUnitState(UNIT_STATE_CONTROLLED))
return;
- caster->CastSpell(GetHitUnit(), GetEffectValue(), true);
+ caster->CastSpell(GetHitUnit(), uint32(GetEffectValue()), true);
}
void Register()
{
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dru_starfall_dummy_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_dru_starfall_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
@@ -367,6 +377,244 @@ class spell_dru_starfall_dummy : public SpellScriptLoader
}
};
+class spell_dru_lifebloom : public SpellScriptLoader
+{
+ public:
+ spell_dru_lifebloom() : SpellScriptLoader("spell_dru_lifebloom") { }
+
+ class spell_dru_lifebloom_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_lifebloom_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_FINAL_HEAL))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(DRUID_LIFEBLOOM_ENERGIZE))
+ return false;
+ return true;
+ }
+
+ void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ // Final heal only on duration end
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
+ return;
+
+ // final heal
+ int32 stack = GetStackAmount();
+ int32 healAmount = aurEff->GetAmount();
+ if (Unit* caster = GetCaster())
+ {
+ healAmount = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), healAmount, HEAL, stack);
+ healAmount = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, stack);
+
+ GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
+
+ // restore mana
+ int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * stack / 2;
+ caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
+ return;
+ }
+
+ GetTarget()->CastCustomSpell(GetTarget(), DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
+ }
+
+ void HandleDispel(DispelInfo* dispelInfo)
+ {
+ if (Unit* target = GetUnitOwner())
+ {
+ if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
+ {
+ // final heal
+ int32 healAmount = aurEff->GetAmount();
+ if (Unit* caster = GetCaster())
+ {
+ healAmount = caster->SpellHealingBonusDone(target, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
+ healAmount = target->SpellHealingBonusTaken(caster, GetSpellInfo(), healAmount, HEAL, dispelInfo->GetRemovedCharges());
+ target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID());
+
+ // restore mana
+ int32 returnMana = CalculatePctU(caster->GetCreateMana(), GetSpellInfo()->ManaCostPercentage) * dispelInfo->GetRemovedCharges() / 2;
+ caster->CastCustomSpell(caster, DRUID_LIFEBLOOM_ENERGIZE, &returnMana, NULL, NULL, true, NULL, NULL, GetCasterGUID());
+ return;
+ }
+
+ target->CastCustomSpell(target, DRUID_LIFEBLOOM_FINAL_HEAL, &healAmount, NULL, NULL, true, NULL, NULL, GetCasterGUID());
+ }
+ }
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dru_lifebloom_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterDispel += AuraDispelFn(spell_dru_lifebloom_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dru_lifebloom_AuraScript();
+ }
+};
+
+class spell_dru_predatory_strikes : public SpellScriptLoader
+{
+ public:
+ spell_dru_predatory_strikes() : SpellScriptLoader("spell_dru_predatory_strikes") { }
+
+ class spell_dru_predatory_strikes_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_predatory_strikes_AuraScript);
+
+ void UpdateAmount(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Player* target = GetTarget()->ToPlayer())
+ target->UpdateAttackPowerAndDamage();
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dru_predatory_strikes_AuraScript::UpdateAmount, EFFECT_ALL, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dru_predatory_strikes_AuraScript();
+ }
+};
+
+class spell_dru_savage_roar : public SpellScriptLoader
+{
+ public:
+ spell_dru_savage_roar() : SpellScriptLoader("spell_dru_savage_roar") { }
+
+ class spell_dru_savage_roar_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dru_savage_roar_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (caster->GetShapeshiftForm() != FORM_CAT)
+ return SPELL_FAILED_ONLY_SHAPESHIFT;
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_dru_savage_roar_SpellScript::CheckCast);
+ }
+ };
+
+ class spell_dru_savage_roar_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_savage_roar_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(DRUID_SAVAGE_ROAR))
+ return false;
+ return true;
+ }
+
+ void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ target->CastSpell(target, DRUID_SAVAGE_ROAR, true, NULL, aurEff, GetCasterGUID());
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(DRUID_SAVAGE_ROAR);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_dru_savage_roar_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dru_savage_roar_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_dru_savage_roar_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dru_savage_roar_AuraScript();
+ }
+};
+
+class spell_dru_survival_instincts : public SpellScriptLoader
+{
+ public:
+ spell_dru_survival_instincts() : SpellScriptLoader("spell_dru_survival_instincts") { }
+
+ class spell_dru_survival_instincts_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_dru_survival_instincts_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (!caster->IsInFeralForm())
+ return SPELL_FAILED_ONLY_SHAPESHIFT;
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_dru_survival_instincts_SpellScript::CheckCast);
+ }
+ };
+
+ class spell_dru_survival_instincts_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dru_survival_instincts_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(DRUID_SURVIVAL_INSTINCTS))
+ return false;
+ return true;
+ }
+
+ void AfterApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ Unit* target = GetTarget();
+ int32 bp0 = target->CountPctFromMaxHealth(aurEff->GetAmount());
+ target->CastCustomSpell(target, DRUID_SURVIVAL_INSTINCTS, &bp0, NULL, NULL, true);
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(DRUID_SURVIVAL_INSTINCTS);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_dru_survival_instincts_AuraScript::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_dru_survival_instincts_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_dru_survival_instincts_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dru_survival_instincts_AuraScript();
+ }
+};
+
void AddSC_druid_spell_scripts()
{
new spell_dru_glyph_of_starfire();
@@ -377,4 +625,8 @@ void AddSC_druid_spell_scripts()
new spell_dru_starfall_aoe();
new spell_dru_swift_flight_passive();
new spell_dru_starfall_dummy();
+ new spell_dru_lifebloom();
+ new spell_dru_predatory_strikes();
+ new spell_dru_savage_roar();
+ new spell_dru_survival_instincts();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 0c879cfb029..a35d243593e 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -239,7 +239,7 @@ class spell_gen_parachute : public SpellScriptLoader
{
PrepareAuraScript(spell_gen_parachute_AuraScript);
- bool Validate(SpellInfo const* /*spellEntry*/)
+ bool Validate(SpellInfo const* /*spell*/)
{
if (!sSpellMgr->GetSpellInfo(SPELL_PARACHUTE) || !sSpellMgr->GetSpellInfo(SPELL_PARACHUTE_BUFF))
return false;
@@ -660,22 +660,16 @@ class spell_pvp_trinket_wotf_shared_cd : public SpellScriptLoader
return true;
}
- void HandleScript(SpellEffIndex /*effIndex*/)
+ void HandleScript()
{
- Player* caster = GetCaster()->ToPlayer();
- SpellInfo const* spellInfo = GetSpellInfo();
- caster->AddSpellCooldown(spellInfo->Id, 0, time(NULL) + sSpellMgr->GetSpellInfo(SPELL_WILL_OF_THE_FORSAKEN_COOLDOWN_TRIGGER)->GetRecoveryTime() / IN_MILLISECONDS);
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4);
- data << uint64(caster->GetGUID());
- data << uint8(0);
- data << uint32(spellInfo->Id);
- data << uint32(0);
- caster->GetSession()->SendPacket(&data);
+ // This is only needed because spells cast from spell_linked_spell are triggered by default
+ // Spell::SendSpellCooldown() skips all spells with TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
+ GetCaster()->ToPlayer()->AddSpellAndCategoryCooldowns(GetSpellInfo(), GetCastItem() ? GetCastItem()->GetEntry() : 0, GetSpell());
}
void Register()
{
- OnEffectHit += SpellEffectFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ AfterCast += SpellCastFn(spell_pvp_trinket_wotf_shared_cd_SpellScript::HandleScript);
}
};
@@ -2052,9 +2046,9 @@ class spell_gen_defend : public SpellScriptLoader
public:
spell_gen_defend() : SpellScriptLoader("spell_gen_defend") { }
- class spell_gen_defendAuraScript : public AuraScript
+ class spell_gen_defend_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_defendAuraScript);
+ PrepareAuraScript(spell_gen_defend_AuraScript);
bool Validate(SpellInfo const* /*spellEntry*/)
{
@@ -2103,26 +2097,26 @@ class spell_gen_defend : public SpellScriptLoader
// 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_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
// 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);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::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_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_defend_AuraScript::RefreshVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_defend_AuraScript::RemoveVisualShields, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
}
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_defendAuraScript();
+ return new spell_gen_defend_AuraScript();
}
};
@@ -2326,9 +2320,9 @@ 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
+ class spell_gen_on_tournament_mount_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_on_tournament_mountAuraScript);
+ PrepareAuraScript(spell_gen_on_tournament_mount_AuraScript);
uint32 _pennantSpellId;
@@ -2468,14 +2462,14 @@ class spell_gen_on_tournament_mount : public SpellScriptLoader
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);
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_on_tournament_mount_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectRemove += AuraEffectRemoveFn(spell_gen_on_tournament_mount_AuraScript::HandleRemoveEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_on_tournament_mountAuraScript();
+ return new spell_gen_on_tournament_mount_AuraScript();
}
};
@@ -2484,9 +2478,9 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
public:
spell_gen_tournament_pennant() : SpellScriptLoader("spell_gen_tournament_pennant") { }
- class spell_gen_tournament_pennantAuraScript : public AuraScript
+ class spell_gen_tournament_pennant_AuraScript : public AuraScript
{
- PrepareAuraScript(spell_gen_tournament_pennantAuraScript);
+ PrepareAuraScript(spell_gen_tournament_pennant_AuraScript);
bool Load()
{
@@ -2502,13 +2496,13 @@ class spell_gen_tournament_pennant : public SpellScriptLoader
void Register()
{
- OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennantAuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ OnEffectApply += AuraEffectApplyFn(spell_gen_tournament_pennant_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
}
};
AuraScript* GetAuraScript() const
{
- return new spell_gen_tournament_pennantAuraScript();
+ return new spell_gen_tournament_pennant_AuraScript();
}
};
@@ -2688,6 +2682,401 @@ public:
}
};
+class spell_gen_touch_the_nightmare : public SpellScriptLoader
+{
+public:
+ spell_gen_touch_the_nightmare() : SpellScriptLoader("spell_gen_touch_the_nightmare") { }
+
+ class spell_gen_touch_the_nightmare_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_touch_the_nightmare_SpellScript);
+
+ void HandleDamageCalc(SpellEffIndex /*effIndex*/)
+ {
+ uint32 bp = GetCaster()->GetMaxHealth() * 0.3f;
+ SetHitDamage(bp);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_touch_the_nightmare_SpellScript::HandleDamageCalc, EFFECT_2, SPELL_EFFECT_SCHOOL_DAMAGE);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_touch_the_nightmare_SpellScript();
+ }
+};
+
+class spell_gen_dream_funnel: public SpellScriptLoader
+{
+public:
+ spell_gen_dream_funnel() : SpellScriptLoader("spell_gen_dream_funnel") { }
+
+ class spell_gen_dream_funnel_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_dream_funnel_AuraScript);
+
+ void HandleEffectCalcAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated)
+ {
+ if (GetCaster())
+ amount = GetCaster()->GetMaxHealth() * 0.05f;
+
+ canBeRecalculated = false;
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_0, SPELL_AURA_PERIODIC_HEAL);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_dream_funnel_AuraScript::HandleEffectCalcAmount, EFFECT_2, SPELL_AURA_PERIODIC_DAMAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_dream_funnel_AuraScript();
+ }
+};
+
+enum GenericBandage
+{
+ SPELL_RECENTLY_BANDAGED = 11196,
+};
+
+class spell_gen_bandage : public SpellScriptLoader
+{
+ public:
+ spell_gen_bandage() : SpellScriptLoader("spell_gen_bandage") { }
+
+ class spell_gen_bandage_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_bandage_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_RECENTLY_BANDAGED))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ if (Unit* target = GetExplTargetUnit())
+ {
+ if (target->HasAura(SPELL_RECENTLY_BANDAGED))
+ return SPELL_FAILED_TARGET_AURASTATE;
+ }
+ return SPELL_CAST_OK;
+ }
+
+ void HandleScript()
+ {
+ if (Unit* target = GetHitUnit())
+ GetCaster()->CastSpell(target, SPELL_RECENTLY_BANDAGED, true);
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_gen_bandage_SpellScript::CheckCast);
+ AfterHit += SpellHitFn(spell_gen_bandage_SpellScript::HandleScript);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_bandage_SpellScript();
+ }
+};
+
+enum GenericLifebloom
+{
+ SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL = 43422,
+ SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL = 52552,
+ SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL = 53692,
+ SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL = 57763,
+ SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL = 66094,
+};
+
+class spell_gen_lifebloom : public SpellScriptLoader
+{
+ public:
+ spell_gen_lifebloom(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
+
+ class spell_gen_lifebloom_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_lifebloom_AuraScript);
+
+ public:
+ spell_gen_lifebloom_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { }
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(_spellId))
+ return false;
+ return true;
+ }
+
+ void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ // Final heal only on duration end
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ // final heal
+ GetTarget()->CastSpell(GetTarget(), _spellId, true, NULL, aurEff, GetCasterGUID());
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gen_lifebloom_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ private:
+ uint32 _spellId;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_lifebloom_AuraScript(_spellId);
+ }
+
+ private:
+ uint32 _spellId;
+};
+
+enum SummonElemental
+{
+ SPELL_SUMMON_FIRE_ELEMENTAL = 8985,
+ SPELL_SUMMON_EARTH_ELEMENTAL = 19704
+};
+
+class spell_gen_summon_elemental : public SpellScriptLoader
+{
+ public:
+ spell_gen_summon_elemental(const char* name, uint32 spellId) : SpellScriptLoader(name), _spellId(spellId) { }
+
+ class spell_gen_summon_elemental_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_summon_elemental_AuraScript);
+
+ public:
+ spell_gen_summon_elemental_AuraScript(uint32 spellId) : AuraScript(), _spellId(spellId) { }
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(_spellId))
+ return false;
+ return true;
+ }
+
+ void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetCaster())
+ if (Unit* owner = GetCaster()->GetOwner())
+ owner->CastSpell(owner, _spellId, true);
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetCaster())
+ if (Unit* owner = GetCaster()->GetOwner())
+ if (owner->GetTypeId() == TYPEID_PLAYER) // todo: this check is maybe wrong
+ owner->ToPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_summon_elemental_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gen_summon_elemental_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+
+ private:
+ uint32 _spellId;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_summon_elemental_AuraScript(_spellId);
+ }
+
+ private:
+ uint32 _spellId;
+};
+
+enum Mounts
+{
+ SPELL_COLD_WEATHER_FLYING = 54197,
+
+ // Magic Broom
+ SPELL_MAGIC_BROOM_60 = 42680,
+ SPELL_MAGIC_BROOM_100 = 42683,
+ SPELL_MAGIC_BROOM_150 = 42667,
+ SPELL_MAGIC_BROOM_280 = 42668,
+
+ // Headless Horseman's Mount
+ SPELL_HEADLESS_HORSEMAN_MOUNT_60 = 51621,
+ SPELL_HEADLESS_HORSEMAN_MOUNT_100 = 48024,
+ SPELL_HEADLESS_HORSEMAN_MOUNT_150 = 51617,
+ SPELL_HEADLESS_HORSEMAN_MOUNT_280 = 48023,
+
+ // Winged Steed of the Ebon Blade
+ SPELL_WINGED_STEED_150 = 54726,
+ SPELL_WINGED_STEED_280 = 54727,
+
+ // Big Love Rocket
+ SPELL_BIG_LOVE_ROCKET_0 = 71343,
+ SPELL_BIG_LOVE_ROCKET_60 = 71344,
+ SPELL_BIG_LOVE_ROCKET_100 = 71345,
+ SPELL_BIG_LOVE_ROCKET_150 = 71346,
+ SPELL_BIG_LOVE_ROCKET_310 = 71347,
+
+ // Invincible
+ SPELL_INVINCIBLE_60 = 72281,
+ SPELL_INVINCIBLE_100 = 72282,
+ SPELL_INVINCIBLE_150 = 72283,
+ SPELL_INVINCIBLE_310 = 72284,
+
+ // Blazing Hippogryph
+ SPELL_BLAZING_HIPPOGRYPH_150 = 74854,
+ SPELL_BLAZING_HIPPOGRYPH_280 = 74855,
+
+ // Celestial Steed
+ SPELL_CELESTIAL_STEED_60 = 75619,
+ SPELL_CELESTIAL_STEED_100 = 75620,
+ SPELL_CELESTIAL_STEED_150 = 75617,
+ SPELL_CELESTIAL_STEED_280 = 75618,
+ SPELL_CELESTIAL_STEED_310 = 76153,
+
+ // X-53 Touring Rocket
+ SPELL_X53_TOURING_ROCKET_150 = 75957,
+ SPELL_X53_TOURING_ROCKET_280 = 75972,
+ SPELL_X53_TOURING_ROCKET_310 = 76154,
+};
+
+class spell_gen_mount : public SpellScriptLoader
+{
+ public:
+ spell_gen_mount(const char* name, uint32 mount0 = 0, uint32 mount60 = 0, uint32 mount100 = 0, uint32 mount150 = 0, uint32 mount280 = 0, uint32 mount310 = 0) : SpellScriptLoader(name),
+ _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
+
+ class spell_gen_mount_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_gen_mount_SpellScript);
+
+ public:
+ spell_gen_mount_SpellScript(uint32 mount0, uint32 mount60, uint32 mount100, uint32 mount150, uint32 mount280, uint32 mount310) : SpellScript(),
+ _mount0(mount0), _mount60(mount60), _mount100(mount100), _mount150(mount150), _mount280(mount280), _mount310(mount310) { }
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (_mount0 && !sSpellMgr->GetSpellInfo(_mount0))
+ return false;
+ if (_mount60 && !sSpellMgr->GetSpellInfo(_mount60))
+ return false;
+ if (_mount100 && !sSpellMgr->GetSpellInfo(_mount100))
+ return false;
+ if (_mount150 && !sSpellMgr->GetSpellInfo(_mount150))
+ return false;
+ if (_mount280 && !sSpellMgr->GetSpellInfo(_mount280))
+ return false;
+ if (_mount310 && !sSpellMgr->GetSpellInfo(_mount310))
+ return false;
+ return true;
+ }
+
+ void HandleMount(SpellEffIndex effIndex)
+ {
+ PreventHitDefaultEffect(effIndex);
+
+ if (Player* target = GetHitPlayer())
+ {
+ // Prevent stacking of mounts and client crashes upon dismounting
+ target->RemoveAurasByType(SPELL_AURA_MOUNTED, 0, GetHitAura());
+
+ // Triggered spell id dependent on riding skill and zone
+ bool canFly = false;
+ uint32 map = GetVirtualMapForMapAndZone(target->GetMapId(), target->GetZoneId());
+ if (map == 530 || (map == 571 && target->HasSpell(SPELL_COLD_WEATHER_FLYING)))
+ canFly = true;
+
+ float x, y, z;
+ target->GetPosition(x, y, z);
+ uint32 areaFlag = target->GetBaseMap()->GetAreaFlag(x, y, z);
+ AreaTableEntry const* area = sAreaStore.LookupEntry(areaFlag);
+ if (!area || (canFly && (area->flags & AREA_FLAG_NO_FLY_ZONE)))
+ canFly = false;
+
+ uint32 mount = 0;
+ switch (target->GetBaseSkillValue(SKILL_RIDING))
+ {
+ case 0:
+ mount = _mount0;
+ break;
+ case 75:
+ mount = _mount60;
+ break;
+ case 150:
+ mount = _mount100;
+ break;
+ case 225:
+ if (canFly)
+ mount = _mount150;
+ else
+ mount = _mount100;
+ break;
+ case 300:
+ if (canFly)
+ mount = _mount280;
+ else
+ mount = _mount100;
+ break;
+ case 375:
+ if (canFly)
+ mount = _mount310;
+ else
+ mount = _mount100;
+ break;
+ default:
+ break;
+ }
+
+ if (mount)
+ {
+ PreventHitAura();
+ target->CastSpell(target, mount, true);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_mount_SpellScript::HandleMount, EFFECT_2, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+
+ private:
+ uint32 _mount0;
+ uint32 _mount60;
+ uint32 _mount100;
+ uint32 _mount150;
+ uint32 _mount280;
+ uint32 _mount310;
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_gen_mount_SpellScript(_mount0, _mount60, _mount100, _mount150, _mount280, _mount310);
+ }
+
+ private:
+ uint32 _mount0;
+ uint32 _mount60;
+ uint32 _mount100;
+ uint32 _mount150;
+ uint32 _mount280;
+ uint32 _mount310;
+};
+
void AddSC_generic_spell_scripts()
{
new spell_gen_absorb0_hitlimit1();
@@ -2742,4 +3131,22 @@ void AddSC_generic_spell_scripts()
new spell_gen_count_pct_from_max_hp("spell_gen_default_count_pct_from_max_hp");
new spell_gen_count_pct_from_max_hp("spell_gen_50pct_count_pct_from_max_hp", 50);
new spell_gen_despawn_self();
+ new spell_gen_touch_the_nightmare();
+ new spell_gen_dream_funnel();
+ new spell_gen_bandage();
+ new spell_gen_lifebloom("spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL);
+ new spell_gen_lifebloom("spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL);
+ new spell_gen_lifebloom("spell_cenarion_scout_lifebloom", SPELL_CENARION_SCOUT_LIFEBLOOM_FINAL_HEAL);
+ new spell_gen_lifebloom("spell_twisted_visage_lifebloom", SPELL_TWISTED_VISAGE_LIFEBLOOM_FINAL_HEAL);
+ new spell_gen_lifebloom("spell_faction_champion_dru_lifebloom", SPELL_FACTION_CHAMPIONS_DRU_LIFEBLOOM_FINAL_HEAL);
+ new spell_gen_summon_elemental("spell_gen_summon_fire_elemental", SPELL_SUMMON_FIRE_ELEMENTAL);
+ new spell_gen_summon_elemental("spell_gen_summon_earth_elemental", SPELL_SUMMON_EARTH_ELEMENTAL);
+ new spell_gen_mount("spell_magic_broom", 0, SPELL_MAGIC_BROOM_60, SPELL_MAGIC_BROOM_100, SPELL_MAGIC_BROOM_150, SPELL_MAGIC_BROOM_280);
+ new spell_gen_mount("spell_headless_horseman_mount", 0, SPELL_HEADLESS_HORSEMAN_MOUNT_60, SPELL_HEADLESS_HORSEMAN_MOUNT_100, SPELL_HEADLESS_HORSEMAN_MOUNT_150, SPELL_HEADLESS_HORSEMAN_MOUNT_280);
+ new spell_gen_mount("spell_winged_steed_of_the_ebon_blade", 0, 0, 0, SPELL_WINGED_STEED_150, SPELL_WINGED_STEED_280);
+ new spell_gen_mount("spell_big_love_rocket", SPELL_BIG_LOVE_ROCKET_0, SPELL_BIG_LOVE_ROCKET_60, SPELL_BIG_LOVE_ROCKET_100, SPELL_BIG_LOVE_ROCKET_150, SPELL_BIG_LOVE_ROCKET_310);
+ new spell_gen_mount("spell_invincible", 0, SPELL_INVINCIBLE_60, SPELL_INVINCIBLE_100, SPELL_INVINCIBLE_150, SPELL_INVINCIBLE_310);
+ new spell_gen_mount("spell_blazing_hippogryph", 0, 0, 0, SPELL_BLAZING_HIPPOGRYPH_150, SPELL_BLAZING_HIPPOGRYPH_280);
+ new spell_gen_mount("spell_celestial_steed", 0, SPELL_CELESTIAL_STEED_60, SPELL_CELESTIAL_STEED_100, SPELL_CELESTIAL_STEED_150, SPELL_CELESTIAL_STEED_280, SPELL_CELESTIAL_STEED_310);
+ new spell_gen_mount("spell_x53_touring_rocket", 0, 0, 0, SPELL_X53_TOURING_ROCKET_150, SPELL_X53_TOURING_ROCKET_280, SPELL_X53_TOURING_ROCKET_310);
}
diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp
index 896ed331bde..a2ee6c1c3a3 100644
--- a/src/server/scripts/Spells/spell_hunter.cpp
+++ b/src/server/scripts/Spells/spell_hunter.cpp
@@ -618,6 +618,86 @@ class spell_hun_misdirection_proc : public SpellScriptLoader
}
};
+class spell_hun_disengage : public SpellScriptLoader
+{
+ public:
+ spell_hun_disengage() : SpellScriptLoader("spell_hun_disengage") { }
+
+ class spell_hun_disengage_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_hun_disengage_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (caster->GetTypeId() == TYPEID_PLAYER && !caster->isInCombat())
+ return SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW;
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_hun_disengage_SpellScript::CheckCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_hun_disengage_SpellScript();
+ }
+};
+
+class spell_hun_tame_beast : public SpellScriptLoader
+{
+ public:
+ spell_hun_tame_beast() : SpellScriptLoader("spell_hun_tame_beast") { }
+
+ class spell_hun_tame_beast_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_hun_tame_beast_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_DONT_REPORT;
+
+ if (!GetExplTargetUnit())
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+
+ if (Creature* target = GetExplTargetUnit()->ToCreature())
+ {
+ if (target->getLevel() > caster->getLevel())
+ return SPELL_FAILED_HIGHLEVEL;
+
+ // use SMSG_PET_TAME_FAILURE?
+ if (!target->GetCreatureTemplate()->isTameable(caster->ToPlayer()->CanTameExoticPets()))
+ return SPELL_FAILED_BAD_TARGETS;
+
+ if (caster->GetPetGUID())
+ return SPELL_FAILED_ALREADY_HAVE_SUMMON;
+
+ if (caster->GetCharmGUID())
+ return SPELL_FAILED_ALREADY_HAVE_CHARM;
+ }
+ else
+ return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_hun_tame_beast_SpellScript::CheckCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_hun_tame_beast_SpellScript();
+ }
+};
void AddSC_hunter_spell_scripts()
{
@@ -633,4 +713,6 @@ void AddSC_hunter_spell_scripts()
new spell_hun_pet_carrion_feeder();
new spell_hun_misdirection();
new spell_hun_misdirection_proc();
+ new spell_hun_disengage();
+ new spell_hun_tame_beast();
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 4e2eb633662..3c89cb7005a 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -1848,60 +1848,6 @@ class spell_item_unusual_compass : public SpellScriptLoader
}
};
-enum UDED
-{
- NPC_IRONWOOL_MAMMOTH = 53806,
- SPELL_MAMMOTH_CARCASS = 57444,
- SPELL_MAMMOTH_MEAT = 54625,
-};
-
-class spell_item_uded : public SpellScriptLoader
-{
- public:
- spell_item_uded() : SpellScriptLoader("spell_item_uded") { }
-
- class spell_item_uded_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_item_uded_SpellScript);
-
- bool Load()
- {
- if (GetHitCreature() && GetHitCreature()->GetEntry() == NPC_IRONWOOL_MAMMOTH)
- return true;
- return false;
- }
-
- bool Validate(SpellInfo const* /*spell*/)
- {
- if (!sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_CARCASS) || !sSpellMgr->GetSpellInfo(SPELL_MAMMOTH_MEAT))
- return false;
- return true;
- }
-
- void HandleDummy(SpellEffIndex /* effIndex */)
- {
- Unit* caster = GetCaster();
- Creature* creature = GetHitCreature();
- caster->CastSpell(caster,SPELL_MAMMOTH_CARCASS,true);
-
- for (uint8 i = 0; i < 4; ++i)
- caster->CastSpell(caster,SPELL_MAMMOTH_MEAT,true);
-
- creature->Kill(creature);
- }
-
- void Register()
- {
- OnEffectHitTarget += SpellEffectFn(spell_item_uded_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const
- {
- return new spell_item_uded_SpellScript();
- }
-};
-
enum ChickenCover
{
SPELL_CHICKEN_NET = 51959,
@@ -2109,7 +2055,6 @@ void AddSC_item_spell_scripts()
new spell_item_rocket_boots();
new spell_item_pygmy_oil();
new spell_item_unusual_compass();
- new spell_item_uded();
new spell_item_chicken_cover();
new spell_item_muisek_vessel();
new spell_item_greatmothers_soulcatcher();
diff --git a/src/server/scripts/Spells/spell_mage.cpp b/src/server/scripts/Spells/spell_mage.cpp
index 050741ffaba..0edfbaee437 100644
--- a/src/server/scripts/Spells/spell_mage.cpp
+++ b/src/server/scripts/Spells/spell_mage.cpp
@@ -342,13 +342,52 @@ public:
}
};
+class spell_mage_living_bomb : public SpellScriptLoader
+{
+ public:
+ spell_mage_living_bomb() : SpellScriptLoader("spell_mage_living_bomb") { }
+
+ class spell_mage_living_bomb_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_mage_living_bomb_AuraScript);
+
+ bool Validate(SpellInfo const* spell)
+ {
+ if (!sSpellMgr->GetSpellInfo(uint32(spell->Effects[EFFECT_1].CalcValue())))
+ return false;
+ return true;
+ }
+
+ void AfterRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ AuraRemoveMode removeMode = GetTargetApplication()->GetRemoveMode();
+ if (removeMode != AURA_REMOVE_BY_ENEMY_SPELL && removeMode != AURA_REMOVE_BY_EXPIRE)
+ return;
+
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(GetTarget(), uint32(aurEff->GetAmount()), true, NULL, aurEff);
+ }
+
+ void Register()
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_mage_living_bomb_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_mage_living_bomb_AuraScript();
+ }
+};
+
void AddSC_mage_spell_scripts()
{
- new spell_mage_blast_wave;
- new spell_mage_cold_snap;
+ new spell_mage_blast_wave();
+ new spell_mage_cold_snap();
new spell_mage_frost_warding_trigger();
new spell_mage_incanters_absorbtion_absorb();
new spell_mage_incanters_absorbtion_manashield();
- new spell_mage_polymorph_cast_visual;
- new spell_mage_summon_water_elemental;
+ new spell_mage_polymorph_cast_visual();
+ new spell_mage_summon_water_elemental();
+ new spell_mage_living_bomb();
}
diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp
index 4baa1eb3735..7d248b35853 100644
--- a/src/server/scripts/Spells/spell_paladin.cpp
+++ b/src/server/scripts/Spells/spell_paladin.cpp
@@ -43,6 +43,10 @@ enum PaladinSpells
SPELL_DIVINE_STORM = 53385,
SPELL_DIVINE_STORM_DUMMY = 54171,
SPELL_DIVINE_STORM_HEAL = 54172,
+
+ SPELL_FORBEARANCE = 25771,
+ SPELL_AVENGING_WRATH_MARKER = 61987,
+ SPELL_IMMUNE_SHIELD_MARKER = 61988,
};
// 31850 - Ardent Defender
@@ -255,17 +259,18 @@ class spell_pal_holy_shock : public SpellScriptLoader
class spell_pal_holy_shock_SpellScript : public SpellScript
{
- PrepareSpellScript(spell_pal_holy_shock_SpellScript)
- bool Validate(SpellInfo const* spellEntry)
+ PrepareSpellScript(spell_pal_holy_shock_SpellScript);
+
+ bool Validate(SpellInfo const* spell)
{
if (!sSpellMgr->GetSpellInfo(PALADIN_SPELL_HOLY_SHOCK_R1))
return false;
// can't use other spell than holy shock due to spell_ranks dependency
- if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spellEntry->Id))
+ if (sSpellMgr->GetFirstSpellInChain(PALADIN_SPELL_HOLY_SHOCK_R1) != sSpellMgr->GetFirstSpellInChain(spell->Id))
return false;
- uint8 rank = sSpellMgr->GetSpellRank(spellEntry->Id);
+ uint8 rank = sSpellMgr->GetSpellRank(spell->Id);
if (!sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_DAMAGE, rank, true) || !sSpellMgr->GetSpellWithRank(PALADIN_SPELL_HOLY_SHOCK_R1_HEALING, rank, true))
return false;
@@ -287,7 +292,7 @@ class spell_pal_holy_shock : public SpellScriptLoader
SpellCastResult CheckCast()
{
- Player* caster = GetCaster()->ToPlayer();
+ Unit* caster = GetCaster();
if (Unit* target = GetExplTargetUnit())
{
if (!caster->IsFriendlyTo(target))
@@ -404,7 +409,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
return true;
}
- void CountTargets(std::list<Unit*>& targetList)
+ void CountTargets(std::list<WorldObject*>& targetList)
{
_targetCount = targetList.size();
}
@@ -423,7 +428,7 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_pal_divine_storm_dummy_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pal_divine_storm_dummy_SpellScript::CountTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
}
};
@@ -433,6 +438,99 @@ class spell_pal_divine_storm_dummy : public SpellScriptLoader
}
};
+class spell_pal_lay_on_hands : public SpellScriptLoader
+{
+ public:
+ spell_pal_lay_on_hands() : SpellScriptLoader("spell_pal_lay_on_hands") { }
+
+ class spell_pal_lay_on_hands_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pal_lay_on_hands_SpellScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_FORBEARANCE))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_AVENGING_WRATH_MARKER))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SPELL_IMMUNE_SHIELD_MARKER))
+ return false;
+ return true;
+ }
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (Unit* target = GetExplTargetUnit())
+ if (caster == target)
+ if (target->HasAura(SPELL_FORBEARANCE) || target->HasAura(SPELL_AVENGING_WRATH_MARKER) || target->HasAura(SPELL_IMMUNE_SHIELD_MARKER))
+ return SPELL_FAILED_TARGET_AURASTATE;
+
+ return SPELL_CAST_OK;
+ }
+
+ void HandleScript()
+ {
+ Unit* caster = GetCaster();
+ if (caster == GetHitUnit())
+ {
+ caster->CastSpell(caster, SPELL_FORBEARANCE, true);
+ caster->CastSpell(caster, SPELL_AVENGING_WRATH_MARKER, true);
+ caster->CastSpell(caster, SPELL_IMMUNE_SHIELD_MARKER, true);
+ }
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_pal_lay_on_hands_SpellScript::CheckCast);
+ AfterHit += SpellHitFn(spell_pal_lay_on_hands_SpellScript::HandleScript);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_pal_lay_on_hands_SpellScript();
+ }
+};
+
+class spell_pal_righteous_defense : public SpellScriptLoader
+{
+ public:
+ spell_pal_righteous_defense() : SpellScriptLoader("spell_pal_righteous_defense") { }
+
+ class spell_pal_righteous_defense_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_pal_righteous_defense_SpellScript);
+
+ SpellCastResult CheckCast()
+ {
+ Unit* caster = GetCaster();
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ return SPELL_FAILED_DONT_REPORT;
+
+ if (Unit* target = GetExplTargetUnit())
+ {
+ if (!target->IsFriendlyTo(caster) || target->getAttackers().empty())
+ return SPELL_FAILED_BAD_TARGETS;
+ }
+ else
+ return SPELL_FAILED_BAD_TARGETS;
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_pal_righteous_defense_SpellScript::CheckCast);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_pal_righteous_defense_SpellScript();
+ }
+};
+
void AddSC_paladin_spell_scripts()
{
new spell_pal_ardent_defender();
@@ -443,4 +541,6 @@ void AddSC_paladin_spell_scripts()
new spell_pal_judgement_of_command();
new spell_pal_divine_storm();
new spell_pal_divine_storm_dummy();
+ new spell_pal_lay_on_hands();
+ new spell_pal_righteous_defense();
}
diff --git a/src/server/scripts/Spells/spell_pet.cpp b/src/server/scripts/Spells/spell_pet.cpp
new file mode 100644
index 00000000000..4928ec40abd
--- /dev/null
+++ b/src/server/scripts/Spells/spell_pet.cpp
@@ -0,0 +1,1726 @@
+/*
+ * 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/>.
+ */
+
+/*
+ * Scripts for spells with SPELLFAMILY_DEATHKNIGHT and SPELLFAMILY_GENERIC spells used by deathknight players.
+ * Ordered alphabetically using scriptname.
+ * Scriptnames of files in this file should be prefixed with "spell_dk_".
+ */
+
+#include "ScriptMgr.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
+#include "Unit.h"
+#include "Player.h"
+#include "Pet.h"
+
+enum HunterPetCalculate
+{
+ SPELL_TAMED_PET_PASSIVE_06 = 19591,
+ SPELL_TAMED_PET_PASSIVE_07 = 20784,
+ SPELL_TAMED_PET_PASSIVE_08 = 34666,
+ SPELL_TAMED_PET_PASSIVE_09 = 34667,
+ SPELL_TAMED_PET_PASSIVE_10 = 34675,
+ SPELL_HUNTER_PET_SCALING_01 = 34902,
+ SPELL_HUNTER_PET_SCALING_02 = 34903,
+ SPELL_HUNTER_PET_SCALING_03 = 34904,
+ SPELL_HUNTER_PET_SCALING_04 = 61017,
+ SPELL_HUNTER_ANIMAL_HANDLER = 34453,
+};
+
+enum WarlockPetCalculate
+{
+ SPELL_PET_PASSIVE_CRIT = 35695,
+ SPELL_PET_PASSIVE_DAMAGE_TAKEN = 35697,
+ SPELL_WARLOCK_PET_SCALING_01 = 34947,
+ SPELL_WARLOCK_PET_SCALING_02 = 34956,
+ SPELL_WARLOCK_PET_SCALING_03 = 34957,
+ SPELL_WARLOCK_PET_SCALING_04 = 34958,
+ SPELL_WARLOCK_PET_SCALING_05 = 61013,
+ ENTRY_FELGUARD = 17252,
+ ENTRY_VOIDWALKER = 1860,
+ ENTRY_FELHUNTER = 417,
+ ENTRY_SUCCUBUS = 1863,
+ ENTRY_IMP = 416,
+ SPELL_WARLOCK_GLYPH_OF_VOIDWALKER = 56247,
+};
+
+enum DKPetCalculate
+{
+ SPELL_DEATH_KNIGHT_RUNE_WEAPON_02 = 51906,
+ SPELL_DEATH_KNIGHT_PET_SCALING_01 = 54566,
+ SPELL_DEATH_KNIGHT_PET_SCALING_02 = 51996,
+ SPELL_DEATH_KNIGHT_PET_SCALING_03 = 61697,
+ SPELL_NIGHT_OF_THE_DEAD = 55620,
+ ENTRY_ARMY_OF_THE_DEAD_GHOUL = 24207,
+ SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL = 58686,
+};
+
+enum ShamanPetCalculate
+{
+ SPELL_FERAL_SPIRIT_PET_UNK_01 = 35674,
+ SPELL_FERAL_SPIRIT_PET_UNK_02 = 35675,
+ SPELL_FERAL_SPIRIT_PET_UNK_03 = 35676,
+ SPELL_FERAL_SPIRIT_PET_SCALING_04 = 61783,
+};
+
+enum MiscPetCalculate
+{
+ SPELL_MAGE_PET_PASSIVE_ELEMENTAL = 44559,
+ SPELL_PET_HEALTH_SCALING = 61679,
+ SPELL_PET_UNK_01 = 67561,
+ SPELL_PET_UNK_02 = 67557,
+};
+
+class spell_gen_pet_calculate : public SpellScriptLoader
+{
+ public:
+ spell_gen_pet_calculate() : SpellScriptLoader("spell_gen_pet_calculate") { }
+
+ class spell_gen_pet_calculate_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_pet_calculate_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ amount += int32(CritSpell);
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ amount += int32(CritMelee);
+ }
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_EXPERTISE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE);
+ // Increase Expertise from Expertise ratings
+ Expertise += owner->GetRatingBonusValue(CR_EXPERTISE);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ switch (m_scriptSpellId)
+ {
+ case SPELL_TAMED_PET_PASSIVE_06:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ break;
+ case SPELL_PET_PASSIVE_CRIT:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ break;
+ case SPELL_WARLOCK_PET_SCALING_05:
+ case SPELL_HUNTER_PET_SCALING_04:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ break;
+ case SPELL_DEATH_KNIGHT_PET_SCALING_03:
+// case SPELL_SHAMAN_PET_HIT:
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_gen_pet_calculate_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_gen_pet_calculate_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_01() : SpellScriptLoader("spell_warl_pet_scaling_01") { }
+
+ class spell_warl_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_01_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempBonus = 0;
+ return true;
+ }
+
+ void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = CalculatePctN(owner->GetStat(STAT_STAMINA), 75);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempBonus)
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ uint32 healthMod = 0;
+ uint32 baseHealth = pInfo->health;
+ switch (pet->GetEntry())
+ {
+ case ENTRY_IMP:
+ healthMod = uint32(_tempBonus * 8.4f);
+ break;
+ case ENTRY_FELGUARD:
+ case ENTRY_VOIDWALKER:
+ healthMod = _tempBonus * 11;
+ break;
+ case ENTRY_SUCCUBUS:
+ healthMod = uint32(_tempBonus * 9.1f);
+ break;
+ case ENTRY_FELHUNTER:
+ healthMod = uint32(_tempBonus * 9.5f);
+ break;
+ default:
+ healthMod = 0;
+ break;
+ }
+ if (healthMod)
+ pet->ToPet()->SetCreateHealth(baseHealth + healthMod);
+ }
+ }
+
+ void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ pet->ToPet()->SetCreateHealth(pInfo->health);
+ }
+ }
+
+ void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
+ int32 maximum = (fire > shadow) ? fire : shadow;
+ if (maximum < 0)
+ maximum = 0;
+ float bonusAP = maximum * 0.57f;
+
+ amount += bonusAP;
+
+ // Glyph of felguard
+ if (pet->GetEntry() == ENTRY_FELGUARD)
+ {
+ if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(56246, EFFECT_0))
+ {
+ float base_attPower = pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE) * pet->GetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_PCT);
+ amount += CalculatePctN(amount+base_attPower, /* aurEff */ect->GetAmount());
+ }
+ }
+ }
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ //the damage bonus used for pets is either fire or shadow damage, whatever is higher
+ int32 fire = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_FIRE)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_FIRE);
+ int32 shadow = int32(owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS + SPELL_SCHOOL_SHADOW)) - owner->GetUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG + SPELL_SCHOOL_SHADOW);
+ int32 maximum = (fire > shadow) ? fire : shadow;
+ float bonusDamage = 0.0f;
+
+ if (maximum > 0)
+ bonusDamage = maximum * 0.15f;
+
+ amount += bonusDamage;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE);
+ }
+
+ private:
+ uint32 _tempBonus;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_02() : SpellScriptLoader("spell_warl_pet_scaling_02") { }
+
+ class spell_warl_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempBonus = 0;
+ return true;
+ }
+
+ void CalculateIntellectAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetStat(STAT_INTELLECT), 30);
+
+ amount += ownerBonus;
+ _tempBonus = ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempBonus)
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ uint32 manaMod = 0;
+ uint32 baseMana = pInfo->mana;
+ switch (pet->GetEntry())
+ {
+ case ENTRY_IMP:
+ manaMod = uint32(_tempBonus * 4.9f);
+ break;
+ case ENTRY_VOIDWALKER:
+ case ENTRY_SUCCUBUS:
+ case ENTRY_FELHUNTER:
+ case ENTRY_FELGUARD:
+ manaMod = uint32(_tempBonus * 11.5f);
+ break;
+ default:
+ manaMod = 0;
+ break;
+ }
+ if (manaMod)
+ pet->ToPet()->SetCreateMana(baseMana + manaMod);
+ }
+ }
+
+ void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ {
+ PetLevelInfo const* pInfo = sObjectMgr->GetPetLevelInfo(pet->GetEntry(), pet->getLevel());
+ pet->ToPet()->SetCreateMana(pInfo->mana);
+ }
+ }
+
+ void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetArmor(), 35);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_warl_pet_scaling_02_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_warl_pet_scaling_02_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateIntellectAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateArmorAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+
+ private:
+ uint32 _tempBonus;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_03() : SpellScriptLoader("spell_warl_pet_scaling_03") { }
+
+ class spell_warl_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateFrostResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_03_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_03_AuraScript();
+ }
+};
+
+
+class spell_warl_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_04() : SpellScriptLoader("spell_warl_pet_scaling_04") { }
+
+ class spell_warl_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float ownerBonus = 0.0f;
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40);
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_04_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_warl_pet_scaling_05 : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_scaling_05() : SpellScriptLoader("spell_warl_pet_scaling_05") { }
+
+ class spell_warl_pet_scaling_05_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_scaling_05_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ Expertise += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_scaling_05_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_scaling_05_AuraScript();
+ }
+};
+
+class spell_warl_pet_passive : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive() : SpellScriptLoader("spell_warl_pet_passive") { }
+
+ class spell_warl_pet_passive_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347))
+ if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase())
+ if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0))
+ amount += CalculatePctN(CritSpell, improvedDemonicTacticsEffect->GetAmount());
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ if (AuraApplication* improvedDemonicTacticsApp = owner->GetAuraApplicationOfRankedSpell(54347))
+ if (Aura* improvedDemonicTactics = improvedDemonicTacticsApp->GetBase())
+ if (AuraEffect* improvedDemonicTacticsEffect = improvedDemonicTactics->GetEffect(EFFECT_0))
+ amount += CalculatePctN(CritMelee, improvedDemonicTacticsEffect->GetAmount());
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritSpell, EFFECT_0, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_AuraScript::CalculateAmountCritMelee, EFFECT_1, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_AuraScript();
+ }
+};
+// this doesnt actually fit in here
+class spell_warl_pet_passive_damage_done : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive_damage_done() : SpellScriptLoader("spell_warl_pet_passive_damage_done") { }
+
+ class spell_warl_pet_passive_damage_done_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_damage_done_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (GetCaster()->GetOwner()->ToPlayer())
+ {
+ switch (GetCaster()->GetEntry())
+ {
+ case ENTRY_VOIDWALKER:
+ amount += -16;
+ break;
+ case ENTRY_FELHUNTER:
+ amount += -20;
+ break;
+ case ENTRY_SUCCUBUS:
+ case ENTRY_FELGUARD:
+ amount += 5;
+ break;
+ }
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_1, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_damage_done_AuraScript();
+ }
+};
+
+class spell_warl_pet_passive_voidwalker : public SpellScriptLoader
+{
+public:
+ spell_warl_pet_passive_voidwalker() : SpellScriptLoader("spell_warl_pet_passive_voidwalker") { }
+
+ class spell_warl_pet_passive_voidwalker_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_pet_passive_voidwalker_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ if (AuraEffect* /* aurEff */ect = owner->GetAuraEffect(SPELL_WARLOCK_GLYPH_OF_VOIDWALKER, EFFECT_0))
+ amount += /* aurEff */ect->GetAmount();
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_warl_pet_passive_voidwalker_AuraScript::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_pet_passive_voidwalker_AuraScript();
+ }
+};
+
+
+class spell_sha_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_sha_pet_scaling_04() : SpellScriptLoader("spell_sha_pet_scaling_04") { }
+
+ class spell_sha_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_sha_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_sha_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_01() : SpellScriptLoader("spell_hun_pet_scaling_01") { }
+
+ class spell_hun_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_01_AuraScript);
+
+ void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (pet->isPet())
+ if (Unit* owner = pet->ToPet()->GetOwner())
+ {
+ float mod = 0.45f;
+ float ownerBonus = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ AddPctN(mod, spellInfo->Effects[EFFECT_0].CalcValue());
+ }
+
+ ownerBonus = owner->GetStat(STAT_STAMINA)*mod;
+
+ amount += ownerBonus;
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempHealth)
+ pet->SetHealth(_tempHealth);
+ }
+
+ void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ _tempHealth = pet->GetHealth();
+ }
+
+ void CalculateAttackPowerAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 1.0f; //Hunter contribution modifier
+ float bonusAP = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ }
+
+ bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f * mod;
+
+ amount += bonusAP;
+ }
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 1.0f; //Hunter contribution modifier
+ float bonusDamage = 0.0f;
+
+ PetSpellMap::const_iterator itr = (pet->ToPet()->m_spells.find(62758)); // Wild Hunt rank 1
+ if (itr == pet->ToPet()->m_spells.end())
+ itr = pet->ToPet()->m_spells.find(62762); // Wild Hunt rank 2
+
+ if (itr != pet->ToPet()->m_spells.end()) // If pet has Wild Hunt
+ {
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first); // Then get the SpellProto and add the dummy effect value
+ mod += CalculatePctN(1.0f, spellInfo->Effects[EFFECT_1].CalcValue());
+ }
+
+ bonusDamage = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f * mod;
+
+ amount += bonusDamage;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_hun_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_hun_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateAttackPowerAmount, EFFECT_1, SPELL_AURA_MOD_ATTACK_POWER);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_01_AuraScript::CalculateDamageDoneAmount, EFFECT_2, SPELL_AURA_MOD_DAMAGE_DONE);
+ }
+
+ private:
+ uint32 _tempHealth;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_02() : SpellScriptLoader("spell_hun_pet_scaling_02") { }
+
+ class spell_hun_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateFrostResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FROST), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateFireResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_FIRE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateNatureResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_NATURE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFrostResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateFireResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_02_AuraScript::CalculateNatureResistanceAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_03() : SpellScriptLoader("spell_hun_pet_scaling_03") { }
+
+ class spell_hun_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateShadowResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_SHADOW), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArcaneResistanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetResistance(SPELL_SCHOOL_ARCANE), 40);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void CalculateArmorAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isPet())
+ return;
+
+ Unit* owner = pet->ToPet()->GetOwner();
+ if (!owner)
+ return;
+
+ float ownerBonus = 0.0f;
+
+ ownerBonus = CalculatePctN(owner->GetArmor(), 35);
+
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateShadowResistanceAmount, EFFECT_0, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArcaneResistanceAmount, EFFECT_1, SPELL_AURA_MOD_RESISTANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_03_AuraScript::CalculateArmorAmount, EFFECT_2, SPELL_AURA_MOD_RESISTANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_03_AuraScript();
+ }
+};
+
+class spell_hun_pet_scaling_04 : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_scaling_04() : SpellScriptLoader("spell_hun_pet_scaling_04") { }
+
+ class spell_hun_pet_scaling_04_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_scaling_04_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void CalculateAmountExpertise(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float Expertise = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_EXPERTISE
+ Expertise += owner->GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE);
+ // Increase Expertise from Expertise ratings
+ Expertise += owner->GetRatingBonusValue(CR_EXPERTISE);
+
+ amount += int32(Expertise);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_scaling_04_AuraScript::CalculateAmountExpertise, EFFECT_2, SPELL_AURA_MOD_EXPERTISE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_scaling_04_AuraScript();
+ }
+};
+
+class spell_hun_pet_passive_crit : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_passive_crit() : SpellScriptLoader("spell_hun_pet_passive_crit") { }
+
+ class spell_hun_pet_passive_crit_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_passive_crit_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountCritSpell(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritSpell = 0.0f;
+ // Crit from Intellect
+ // CritSpell += owner->GetSpellCritFromIntellect();
+ // Increase crit from SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ // CritSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit spell from spell crit ratings
+ // CritSpell += owner->GetRatingBonusValue(CR_CRIT_SPELL);
+
+ amount += (CritSpell*0.8f);
+ }
+ }
+
+ void CalculateAmountCritMelee(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float CritMelee = 0.0f;
+ // Crit from Agility
+ // CritMelee += owner->GetMeleeCritFromAgility();
+ // Increase crit from SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ // Increase crit from SPELL_AURA_MOD_CRIT_PCT
+ // CritMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_PCT);
+ // Increase crit melee from melee crit ratings
+ // CritMelee += owner->GetRatingBonusValue(CR_CRIT_MELEE);
+
+ amount += (CritMelee*0.8f);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritSpell, EFFECT_1, SPELL_AURA_MOD_SPELL_CRIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_crit_AuraScript::CalculateAmountCritMelee, EFFECT_0, SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_passive_crit_AuraScript();
+ }
+};
+
+class spell_hun_pet_passive_damage_done : public SpellScriptLoader
+{
+public:
+ spell_hun_pet_passive_damage_done() : SpellScriptLoader("spell_hun_pet_passive_damage_done") { }
+
+ class spell_hun_pet_passive_damage_done_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_pet_passive_damage_done_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (GetCaster()->GetOwner()->ToPlayer())
+ {
+ // Cobra Reflexes
+ if (AuraEffect* cobraReflexes = GetCaster()->GetAuraEffectOfRankedSpell(61682, EFFECT_0))
+ amount -= cobraReflexes->GetAmount();
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_pet_passive_damage_done_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_pet_passive_damage_done_AuraScript();
+ }
+};
+
+class spell_hun_animal_handler : public SpellScriptLoader
+{
+public:
+ spell_hun_animal_handler() : SpellScriptLoader("spell_hun_animal_handler") { }
+
+ class spell_hun_animal_handler_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_hun_animal_handler_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountDamageDone(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ if (AuraEffect* /* aurEff */ect = owner->GetAuraEffectOfRankedSpell(SPELL_HUNTER_ANIMAL_HANDLER, EFFECT_1))
+ amount = /* aurEff */ect->GetAmount();
+ else
+ amount = 0;
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_hun_animal_handler_AuraScript::CalculateAmountDamageDone, EFFECT_0, SPELL_AURA_MOD_ATTACK_POWER_PCT);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_hun_animal_handler_AuraScript();
+ }
+};
+
+
+class spell_dk_avoidance_passive : public SpellScriptLoader
+{
+public:
+ spell_dk_avoidance_passive() : SpellScriptLoader("spell_dk_avoidance_passive") { }
+
+ class spell_dk_avoidance_passive_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_avoidance_passive_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAvoidanceAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (Unit* owner = pet->GetOwner())
+ {
+ // Army of the dead ghoul
+ if (pet->GetEntry() == ENTRY_ARMY_OF_THE_DEAD_GHOUL)
+ amount = -90;
+ // Night of the dead
+ else if ( Aura * aur = owner->GetAuraOfRankedSpell(SPELL_NIGHT_OF_THE_DEAD))
+ amount = aur->GetSpellInfo()->Effects[EFFECT_2].CalcValue();
+ }
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_avoidance_passive_AuraScript::CalculateAvoidanceAmount, EFFECT_0, SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_avoidance_passive_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_01 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_01() : SpellScriptLoader("spell_dk_pet_scaling_01") { }
+
+ class spell_dk_pet_scaling_01_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_01_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ _tempHealth = 0;
+ return true;
+ }
+
+ void CalculateStaminaAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (pet->isGuardian())
+ {
+ if (Unit* owner = pet->GetOwner())
+ {
+ float mod = 0.3f;
+
+ // Ravenous Dead. Check just if owner has Ravenous Dead since it's effect is not an aura
+ if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0))
+ {
+ mod += aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()/100; // Ravenous Dead edits the original scale
+ }
+ // Glyph of the Ghoul
+ if (AuraEffect const* aurEff = owner->GetAuraEffect(SPELL_DEATH_KNIGHT_GLYPH_OF_GHOUL, 0))
+ mod += aurEff->GetAmount()/100;
+
+ float ownerBonus = float(owner->GetStat(STAT_STAMINA)) * mod;
+ amount += ownerBonus;
+ }
+ }
+ }
+ }
+
+ void ApplyEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ if (_tempHealth)
+ pet->SetHealth(_tempHealth);
+ }
+
+ void RemoveEffect(AuraEffect const* /* aurEff */, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ _tempHealth = pet->GetHealth();
+ }
+
+ void CalculateStrengthAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ if (!pet->isGuardian())
+ return;
+
+ Unit* owner = pet->GetOwner();
+ if (!owner)
+ return;
+
+ float mod = 0.7f;
+
+ // Ravenous Dead
+ AuraEffect const* aurEff = NULL;
+ // Check just if owner has Ravenous Dead since it's effect is not an aura
+ aurEff = owner->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DEATHKNIGHT, 3010, 0);
+ if (aurEff)
+ {
+ mod += CalculatePctN(mod, aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()); // Ravenous Dead edits the original scale
+ }
+ // Glyph of the Ghoul
+ aurEff = owner->GetAuraEffect(58686, 0);
+ if (aurEff)
+ mod += CalculatePctN(1.0f, aurEff->GetAmount()); // Glyph of the Ghoul adds a flat value to the scale mod
+ float ownerBonus = float(owner->GetStat(STAT_STRENGTH)) * mod;
+ amount += ownerBonus;
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectRemoveFn(spell_dk_pet_scaling_01_AuraScript::RemoveEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ AfterEffectApply += AuraEffectApplyFn(spell_dk_pet_scaling_01_AuraScript::ApplyEffect, EFFECT_0, SPELL_AURA_MOD_STAT, AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStaminaAmount, EFFECT_0, SPELL_AURA_MOD_STAT);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_01_AuraScript::CalculateStrengthAmount, EFFECT_1, SPELL_AURA_MOD_STAT);
+ }
+
+ private:
+ uint32 _tempHealth;
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_01_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_02() : SpellScriptLoader("spell_dk_pet_scaling_02") { }
+
+ class spell_dk_pet_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HasteMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100;
+
+ amount += int32(HasteMelee);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_02_AuraScript();
+ }
+};
+
+class spell_dk_pet_scaling_03 : public SpellScriptLoader
+{
+public:
+ spell_dk_pet_scaling_03() : SpellScriptLoader("spell_dk_pet_scaling_03") { }
+
+ class spell_dk_pet_scaling_03_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_pet_scaling_03_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateAmountMeleeHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HitMelee += owner->GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ // Increase hit melee from meele hit ratings
+ HitMelee += owner->GetRatingBonusValue(CR_HIT_MELEE);
+
+ amount += int32(HitMelee);
+ }
+ }
+
+ void CalculateAmountSpellHit(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HitSpell = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ HitSpell += owner->GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ // Increase hit spell from spell hit ratings
+ HitSpell += owner->GetRatingBonusValue(CR_HIT_SPELL);
+
+ amount += int32(HitSpell);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountMeleeHit, EFFECT_0, SPELL_AURA_MOD_HIT_CHANCE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_pet_scaling_03_AuraScript::CalculateAmountSpellHit, EFFECT_1, SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_pet_scaling_03_AuraScript();
+ }
+};
+
+class spell_dk_rune_weapon_scaling_02 : public SpellScriptLoader
+{
+public:
+ spell_dk_rune_weapon_scaling_02() : SpellScriptLoader("spell_dk_rune_weapon_scaling_02") { }
+
+ class spell_dk_rune_weapon_scaling_02_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_dk_rune_weapon_scaling_02_AuraScript);
+
+ bool Load()
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner() || GetCaster()->GetOwner()->GetTypeId() != TYPEID_PLAYER)
+ return false;
+ return true;
+ }
+
+ void CalculateDamageDoneAmount(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (Unit* pet = GetUnitOwner())
+ {
+ Unit* owner = pet->GetOwner();
+ if (!owner)
+ return;
+
+ if (pet->isGuardian())
+ ((Guardian*)pet)->SetBonusDamage(owner->GetTotalAttackPowerValue(BASE_ATTACK));
+
+ amount += owner->CalculateDamage(BASE_ATTACK, true, true);;
+ }
+ }
+
+ void CalculateAmountMeleeHaste(AuraEffect const* /* aurEff */, int32& amount, bool& /*canBeRecalculated*/)
+ {
+ if (!GetCaster() || !GetCaster()->GetOwner())
+ return;
+ if (Player* owner = GetCaster()->GetOwner()->ToPlayer())
+ {
+ // For others recalculate it from:
+ float HasteMelee = 0.0f;
+ // Increase hit from SPELL_AURA_MOD_HIT_CHANCE
+ HasteMelee += (1-owner->m_modAttackSpeedPct[BASE_ATTACK])*100;
+
+ amount += int32(HasteMelee);
+ }
+ }
+
+ void Register()
+ {
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateDamageDoneAmount, EFFECT_0, SPELL_AURA_MOD_DAMAGE_DONE);
+ DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dk_rune_weapon_scaling_02_AuraScript::CalculateAmountMeleeHaste, EFFECT_1, SPELL_AURA_MELEE_SLOW);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_dk_rune_weapon_scaling_02_AuraScript();
+ }
+};
+
+void AddSC_pet_spell_scripts()
+{
+ new spell_gen_pet_calculate();
+}
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 8088004c9d1..aab1e974e53 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -34,6 +34,9 @@ enum PriestSpells
PRIEST_SPELL_PENANCE_R1_HEAL = 47757,
PRIEST_SPELL_REFLECTIVE_SHIELD_TRIGGERED = 33619,
PRIEST_SPELL_REFLECTIVE_SHIELD_R1 = 33201,
+ PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL = 64085,
+ PRIEST_SPELL_EMPOWERED_RENEW = 63544,
+ PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT = 3021,
};
// Guardian Spirit
@@ -129,14 +132,14 @@ class spell_pri_mind_sear : public SpellScriptLoader
{
PrepareSpellScript(spell_pri_mind_sear_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)));
+ unitList.remove_if(Trinity::ObjectGUIDCheck(GetCaster()->GetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT)));
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_pri_mind_sear_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -330,6 +333,88 @@ public:
}
};
+class spell_pri_vampiric_touch : public SpellScriptLoader
+{
+ public:
+ spell_pri_vampiric_touch() : SpellScriptLoader("spell_pri_vampiric_touch") { }
+
+ class spell_pri_vampiric_touch_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_pri_vampiric_touch_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL))
+ return false;
+ return true;
+ }
+
+ void HandleDispel(DispelInfo* /*dispelInfo*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Unit* target = GetUnitOwner())
+ if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
+ {
+ int32 damage = aurEff->GetAmount() * 8;
+ // backfire damage
+ caster->CastCustomSpell(target, PRIEST_SPELL_VAMPIRIC_TOUCH_DISPEL, &damage, NULL, NULL, true, NULL, aurEff);
+ }
+ }
+
+ void Register()
+ {
+ AfterDispel += AuraDispelFn(spell_pri_vampiric_touch_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_pri_vampiric_touch_AuraScript();
+ }
+};
+
+class spell_priest_renew : public SpellScriptLoader
+{
+ public:
+ spell_priest_renew() : SpellScriptLoader("spell_priest_renew") { }
+
+ class spell_priest_renew_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_priest_renew_AuraScript);
+
+ bool Load()
+ {
+ return GetCaster() && GetCaster()->GetTypeId() == TYPEID_PLAYER;
+ }
+
+ void HandleApplyEffect(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ {
+ // Empowered Renew
+ if (AuraEffect const* empoweredRenewAurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_EMPOWERED_RENEW_TALENT, EFFECT_1))
+ {
+ uint32 heal = caster->SpellHealingBonusDone(GetTarget(), GetSpellInfo(), GetEffect(EFFECT_0)->GetAmount(), DOT);
+ heal = GetTarget()->SpellHealingBonusTaken(caster, GetSpellInfo(), heal, DOT);
+
+ int32 basepoints0 = empoweredRenewAurEff->GetAmount() * GetEffect(EFFECT_0)->GetTotalTicks() * int32(heal) / 100;
+ caster->CastCustomSpell(GetTarget(), PRIEST_SPELL_EMPOWERED_RENEW, &basepoints0, NULL, NULL, true, NULL, aurEff);
+ }
+ }
+ }
+
+ void Register()
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_priest_renew_AuraScript::HandleApplyEffect, EFFECT_0, SPELL_AURA_PERIODIC_HEAL, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_priest_renew_AuraScript();
+ }
+};
+
void AddSC_priest_spell_scripts()
{
new spell_pri_guardian_spirit();
@@ -339,4 +424,6 @@ void AddSC_priest_spell_scripts()
new spell_pri_reflective_shield_trigger();
new spell_pri_mind_sear();
new spell_pri_prayer_of_mending_heal();
+ new spell_pri_vampiric_touch();
+ new spell_priest_renew();
}
diff --git a/src/server/scripts/Spells/spell_quest.cpp b/src/server/scripts/Spells/spell_quest.cpp
index 810cc20e04b..e3714a22304 100644
--- a/src/server/scripts/Spells/spell_quest.cpp
+++ b/src/server/scripts/Spells/spell_quest.cpp
@@ -639,7 +639,7 @@ class spell_q12851_going_bearback : public SpellScriptLoader
// Already in fire
if (target->HasAura(SPELL_ABLAZE))
return;
-
+
if (Player* player = caster->GetCharmerOrOwnerPlayerOrPlayerItself())
{
switch (target->GetEntry())
@@ -1162,6 +1162,84 @@ class spell_q12277_wintergarde_mine_explosion : public SpellScriptLoader
}
};
+enum FocusOnTheBeach
+{
+ SPELL_BUNNY_CREDIT_BEAM = 47390,
+};
+
+class spell_q12066_bunny_kill_credit : public SpellScriptLoader
+{
+public:
+ spell_q12066_bunny_kill_credit() : SpellScriptLoader("spell_q12066_bunny_kill_credit") { }
+
+ class spell_q12066_bunny_kill_credit_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12066_bunny_kill_credit_SpellScript);
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* target = GetHitCreature())
+ target->CastSpell(GetCaster(), SPELL_BUNNY_CREDIT_BEAM, false);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12066_bunny_kill_credit_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12066_bunny_kill_credit_SpellScript();
+ }
+};
+
+enum ACleansingSong
+{
+ SPELL_SUMMON_SPIRIT_ATAH = 52954,
+ SPELL_SUMMON_SPIRIT_HAKHALAN = 52958,
+ SPELL_SUMMON_SPIRIT_KOOSU = 52959,
+
+ AREA_BITTERTIDELAKE = 4385,
+ AREA_RIVERSHEART = 4290,
+ AREA_WINTERGRASPRIVER = 4388,
+};
+
+class spell_q12735_song_of_cleansing : public SpellScriptLoader
+{
+ public:
+ spell_q12735_song_of_cleansing() : SpellScriptLoader("spell_q12735_song_of_cleansing") { }
+
+ class spell_q12735_song_of_cleansing_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12735_song_of_cleansing_SpellScript);
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+
+ if (caster && caster->GetAreaId() == AREA_BITTERTIDELAKE)
+ caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_ATAH);
+
+ else if (caster && caster->GetAreaId() == AREA_RIVERSHEART)
+ caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_HAKHALAN);
+
+ else if (caster && caster->GetAreaId() == AREA_WINTERGRASPRIVER)
+ caster->CastSpell(caster, SPELL_SUMMON_SPIRIT_KOOSU);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12735_song_of_cleansing_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12735_song_of_cleansing_SpellScript();
+ }
+};
+
void AddSC_quest_spell_scripts()
{
new spell_q55_sacred_cleansing();
@@ -1189,4 +1267,6 @@ void AddSC_quest_spell_scripts()
new spell_q9452_cast_net();
new spell_q12987_read_pronouncement();
new spell_q12277_wintergarde_mine_explosion();
+ new spell_q12066_bunny_kill_credit();
+ new spell_q12735_song_of_cleansing();
}
diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp
index c9c036d5329..c863c2363af 100644
--- a/src/server/scripts/Spells/spell_shaman.cpp
+++ b/src/server/scripts/Spells/spell_shaman.cpp
@@ -35,13 +35,19 @@ enum ShamanSpells
SHAMAN_SPELL_FIRE_NOVA_TRIGGERED_R1 = 8349,
SHAMAN_SPELL_SATED = 57724,
SHAMAN_SPELL_EXHAUSTION = 57723,
-
+
SHAMAN_SPELL_STORM_EARTH_AND_FIRE = 51483,
EARTHBIND_TOTEM_SPELL_EARTHGRAB = 64695,
// For Earthen Power
SHAMAN_TOTEM_SPELL_EARTHBIND_TOTEM = 6474,
SHAMAN_TOTEM_SPELL_EARTHEN_POWER = 59566,
+
+ SHAMAN_BIND_SIGHT = 6277,
+
+ ICON_ID_SHAMAN_LAVA_FLOW = 3087,
+ SHAMAN_LAVA_FLOWS_R1 = 51480,
+ SHAMAN_LAVA_FLOWS_TRIGGERED_R1 = 64694,
};
// 51474 - Astral shift
@@ -255,10 +261,13 @@ class EarthenPowerTargetSelector
{
public:
EarthenPowerTargetSelector() { }
-
- bool operator() (Unit* target)
+
+ bool operator() (WorldObject* target)
{
- if (!target->HasAuraWithMechanic(1 << MECHANIC_SNARE))
+ if (!target->ToUnit())
+ return true;
+
+ if (!target->ToUnit()->HasAuraWithMechanic(1 << MECHANIC_SNARE))
return true;
return false;
@@ -274,14 +283,14 @@ class spell_sha_earthen_power : public SpellScriptLoader
{
PrepareSpellScript(spell_sha_earthen_power_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
unitList.remove_if(EarthenPowerTargetSelector());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_earthen_power_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
@@ -307,7 +316,7 @@ class spell_sha_bloodlust : public SpellScriptLoader
return true;
}
- void RemoveInvalidTargets(std::list<Unit*>& targets)
+ void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_SATED));
}
@@ -320,9 +329,9 @@ class spell_sha_bloodlust : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_bloodlust_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
AfterHit += SpellHitFn(spell_sha_bloodlust_SpellScript::ApplyDebuff);
}
};
@@ -349,9 +358,9 @@ class spell_sha_heroism : public SpellScriptLoader
return true;
}
- void RemoveInvalidTargets(std::list<Unit*>& targets)
+ void RemoveInvalidTargets(std::list<WorldObject*>& targets)
{
- targets.remove_if (Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION));
+ targets.remove_if(Trinity::UnitAuraCheck(true, SHAMAN_SPELL_EXHAUSTION));
}
void ApplyDebuff()
@@ -362,9 +371,9 @@ class spell_sha_heroism : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
- OnUnitTargetSelect += SpellUnitTargetFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_1, TARGET_UNIT_CASTER_AREA_RAID);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_sha_heroism_SpellScript::RemoveInvalidTargets, EFFECT_2, TARGET_UNIT_CASTER_AREA_RAID);
AfterHit += SpellHitFn(spell_sha_heroism_SpellScript::ApplyDebuff);
}
};
@@ -652,6 +661,94 @@ class spell_sha_chain_heal : public SpellScriptLoader
}
};
+class spell_sha_flame_shock : public SpellScriptLoader
+{
+ public:
+ spell_sha_flame_shock() : SpellScriptLoader("spell_sha_flame_shock") { }
+
+ class spell_sha_flame_shock_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_flame_shock_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_R1))
+ return false;
+ if (!sSpellMgr->GetSpellInfo(SHAMAN_LAVA_FLOWS_TRIGGERED_R1))
+ return false;
+ return true;
+ }
+
+ void HandleDispel(DispelInfo* /*dispelInfo*/)
+ {
+ if (Unit* caster = GetCaster())
+ // Lava Flows
+ if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, ICON_ID_SHAMAN_LAVA_FLOW, EFFECT_0))
+ {
+ if (sSpellMgr->GetFirstSpellInChain(SHAMAN_LAVA_FLOWS_R1) != sSpellMgr->GetFirstSpellInChain(aurEff->GetId()))
+ return;
+
+ uint8 rank = sSpellMgr->GetSpellRank(aurEff->GetId());
+ caster->CastSpell(caster, sSpellMgr->GetSpellWithRank(SHAMAN_LAVA_FLOWS_TRIGGERED_R1, rank), true);
+ }
+ }
+
+ void Register()
+ {
+ AfterDispel += AuraDispelFn(spell_sha_flame_shock_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_sha_flame_shock_AuraScript();
+ }
+};
+
+class spell_sha_sentry_totem : public SpellScriptLoader
+{
+ public:
+ spell_sha_sentry_totem() : SpellScriptLoader("spell_sha_sentry_totem") { }
+
+ class spell_sha_sentry_totem_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_sha_sentry_totem_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(SHAMAN_BIND_SIGHT))
+ return false;
+ return true;
+ }
+
+ void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (Creature* totem = caster->GetMap()->GetCreature(caster->m_SummonSlot[4]))
+ if (totem->isTotem())
+ caster->CastSpell(totem, SHAMAN_BIND_SIGHT, true);
+ }
+
+ void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ if (caster->GetTypeId() == TYPEID_PLAYER)
+ caster->ToPlayer()->StopCastingBindSight();
+ }
+
+ void Register()
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_sha_sentry_totem_AuraScript::AfterApply, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_sha_sentry_totem_AuraScript::AfterRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_sha_sentry_totem_AuraScript();
+ }
+};
+
void AddSC_shaman_spell_scripts()
{
new spell_sha_astral_shift();
@@ -667,4 +764,6 @@ void AddSC_shaman_spell_scripts()
new spell_sha_mana_spring_totem();
new spell_sha_lava_lash();
new spell_sha_chain_heal();
+ new spell_sha_flame_shock();
+ new spell_sha_sentry_totem();
}
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 838b9e4f932..74118599b9f 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -37,6 +37,9 @@ enum WarlockSpells
WARLOCK_DEMONIC_CIRCLE_SUMMON = 48018,
WARLOCK_DEMONIC_CIRCLE_TELEPORT = 48020,
WARLOCK_DEMONIC_CIRCLE_ALLOW_CAST = 62388,
+ WARLOCK_HAUNT = 48181,
+ WARLOCK_HAUNT_HEAL = 48210,
+ WARLOCK_UNSTABLE_AFFLICTION_DISPEL = 31117,
};
class spell_warl_banish : public SpellScriptLoader
@@ -299,15 +302,15 @@ class spell_warl_seed_of_corruption : public SpellScriptLoader
{
PrepareSpellScript(spell_warl_seed_of_corruption_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
if (GetExplTargetUnit())
- unitList.remove(GetExplTargetUnit());
+ targets.remove(GetExplTargetUnit());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warl_seed_of_corruption_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -523,6 +526,107 @@ class spell_warl_demonic_circle_teleport : public SpellScriptLoader
}
};
+class spell_warl_haunt : public SpellScriptLoader
+{
+ public:
+ spell_warl_haunt() : SpellScriptLoader("spell_warl_haunt") { }
+
+ class spell_warl_haunt_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warl_haunt_SpellScript);
+
+ void HandleOnHit()
+ {
+ if (Aura* aura = GetHitAura())
+ if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1))
+ aurEff->SetAmount(CalculatePctN(aurEff->GetAmount(), GetHitDamage()));
+ }
+
+ void Register()
+ {
+ OnHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleOnHit);
+ }
+ };
+
+ class spell_warl_haunt_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_haunt_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(WARLOCK_HAUNT_HEAL))
+ return false;
+ return true;
+ }
+
+ void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
+ return;
+
+ if (Unit* caster = GetCaster())
+ {
+ int32 amount = aurEff->GetAmount();
+ GetTarget()->CastCustomSpell(caster, WARLOCK_HAUNT_HEAL, &amount, NULL, NULL, true, NULL, aurEff, GetCasterGUID());
+ }
+ }
+
+ void Register()
+ {
+ OnEffectRemove += AuraEffectApplyFn(spell_warl_haunt_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_warl_haunt_SpellScript();
+ }
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_haunt_AuraScript();
+ }
+};
+
+class spell_warl_unstable_affliction : public SpellScriptLoader
+{
+ public:
+ spell_warl_unstable_affliction() : SpellScriptLoader("spell_warl_unstable_affliction") { }
+
+ class spell_warl_unstable_affliction_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_warl_unstable_affliction_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/)
+ {
+ if (!sSpellMgr->GetSpellInfo(WARLOCK_UNSTABLE_AFFLICTION_DISPEL))
+ return false;
+ return true;
+ }
+
+ void HandleDispel(DispelInfo* dispelInfo)
+ {
+ if (Unit* caster = GetCaster())
+ if (AuraEffect const* aurEff = GetEffect(EFFECT_0))
+ {
+ int32 damage = aurEff->GetAmount() * 9;
+ // backfire damage and silence
+ caster->CastCustomSpell(dispelInfo->GetDispeller(), WARLOCK_UNSTABLE_AFFLICTION_DISPEL, &damage, NULL, NULL, true, NULL, aurEff);
+ }
+ }
+
+ void Register()
+ {
+ AfterDispel += AuraDispelFn(spell_warl_unstable_affliction_AuraScript::HandleDispel);
+ }
+ };
+
+ AuraScript* GetAuraScript() const
+ {
+ return new spell_warl_unstable_affliction_AuraScript();
+ }
+};
+
void AddSC_warlock_spell_scripts()
{
new spell_warl_banish();
@@ -535,4 +639,6 @@ void AddSC_warlock_spell_scripts()
new spell_warl_life_tap();
new spell_warl_demonic_circle_summon();
new spell_warl_demonic_circle_teleport();
+ new spell_warl_haunt();
+ new spell_warl_unstable_affliction();
}
diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp
index 0ba5c866d63..c64101e11ea 100644
--- a/src/server/scripts/Spells/spell_warrior.cpp
+++ b/src/server/scripts/Spells/spell_warrior.cpp
@@ -77,7 +77,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_improved_spell_reflection_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
if (GetCaster())
unitList.remove(GetCaster());
@@ -85,7 +85,7 @@ class spell_warr_improved_spell_reflection : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_warr_improved_spell_reflection_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_CASTER_AREA_PARTY);
}
};
@@ -184,9 +184,9 @@ class spell_warr_deep_wounds : public SpellScriptLoader
damage = caster->SpellDamageBonusDone(target, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
ApplyPctN(damage, 16 * sSpellMgr->GetSpellRank(GetSpellInfo()->Id));
-
+
damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, SPELL_DIRECT_DAMAGE);
-
+
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_DEEP_WOUNDS_RANK_PERIODIC);
uint32 ticks = spellInfo->GetDuration() / spellInfo->Effects[EFFECT_0].Amplitude;
@@ -397,7 +397,20 @@ class spell_warr_bloodthirst : public SpellScriptLoader
{
PrepareSpellScript(spell_warr_bloodthirst_SpellScript);
- void HandleDummy(SpellEffIndex /* effIndex */)
+ void HandleDamage(SpellEffIndex /*effIndex*/)
+ {
+ int32 damage = GetEffectValue();
+ ApplyPctF(damage, GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK));
+
+ if (Unit* target = GetHitUnit())
+ {
+ damage = GetCaster()->SpellDamageBonusDone(target, GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
+ damage = target->SpellDamageBonusTaken(GetCaster(), GetSpellInfo(), uint32(damage), SPELL_DIRECT_DAMAGE);
+ }
+ SetHitDamage(damage);
+ }
+
+ void HandleDummy(SpellEffIndex /*effIndex*/)
{
int32 damage = GetEffectValue();
GetCaster()->CastCustomSpell(GetCaster(), SPELL_BLOODTHIRST, &damage, NULL, NULL, true, NULL);
@@ -405,7 +418,8 @@ class spell_warr_bloodthirst : public SpellScriptLoader
void Register()
{
- OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
+ OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
+ OnEffectHit += SpellEffectFn(spell_warr_bloodthirst_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
}
};
@@ -415,6 +429,38 @@ class spell_warr_bloodthirst : public SpellScriptLoader
}
};
+enum BloodthirstHeal
+{
+ SPELL_BLOODTHIRST_DAMAGE = 23881,
+};
+
+class spell_warr_bloodthirst_heal : public SpellScriptLoader
+{
+ public:
+ spell_warr_bloodthirst_heal() : SpellScriptLoader("spell_warr_bloodthirst_heal") { }
+
+ class spell_warr_bloodthirst_heal_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_warr_bloodthirst_heal_SpellScript);
+
+ void HandleHeal(SpellEffIndex /*effIndex*/)
+ {
+ if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_BLOODTHIRST_DAMAGE))
+ SetHitHeal(GetCaster()->CountPctFromMaxHealth(spellInfo->Effects[EFFECT_1].CalcValue(GetCaster())));
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_warr_bloodthirst_heal_SpellScript::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_warr_bloodthirst_heal_SpellScript();
+ }
+};
+
enum Overpower
{
SPELL_UNRELENTING_ASSAULT_RANK_1 = 46859,
@@ -471,5 +517,6 @@ void AddSC_warrior_spell_scripts()
new spell_warr_execute();
new spell_warr_concussion_blow();
new spell_warr_bloodthirst();
+ new spell_warr_bloodthirst_heal();
new spell_warr_overpower();
}
diff --git a/src/server/scripts/World/achievement_scripts.cpp b/src/server/scripts/World/achievement_scripts.cpp
index 9bcf450b3aa..3dc737f0c95 100755
--- a/src/server/scripts/World/achievement_scripts.cpp
+++ b/src/server/scripts/World/achievement_scripts.cpp
@@ -313,6 +313,27 @@ class achievement_tilted : public AchievementCriteriaScript
}
};
+class achievement_not_even_a_scratch : public AchievementCriteriaScript
+{
+ public:
+ achievement_not_even_a_scratch() : AchievementCriteriaScript("achievement_not_even_a_scratch") { }
+
+ bool OnCheck(Player* source, Unit* /*target*/)
+ {
+ if (!source)
+ return false;
+
+ Battleground* battleground = source->GetBattleground();
+ if (!battleground)
+ return false;
+
+ if (static_cast<BattlegroundSA*>(battleground)->notEvenAScratch(source->GetTeam()))
+ return true;
+
+ return false;
+ }
+};
+
void AddSC_achievement_scripts()
{
new achievement_resilient_victory();
@@ -331,4 +352,5 @@ void AddSC_achievement_scripts()
new achievement_arena_kills("achievement_arena_5v5_kills", ARENA_TYPE_5v5);
new achievement_bg_sa_defense_of_ancients();
new achievement_tilted();
+ new achievement_not_even_a_scratch();
}
diff --git a/src/server/scripts/World/boss_emerald_dragons.cpp b/src/server/scripts/World/boss_emerald_dragons.cpp
index 045dea9c9a9..abb20130ef8 100644
--- a/src/server/scripts/World/boss_emerald_dragons.cpp
+++ b/src/server/scripts/World/boss_emerald_dragons.cpp
@@ -224,9 +224,9 @@ class DreamFogTargetSelector
public:
DreamFogTargetSelector() { }
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- return unit->HasAura(SPELL_SLEEP);
+ return object->ToUnit() && object->ToUnit()->HasAura(SPELL_SLEEP);
}
};
@@ -239,14 +239,14 @@ class spell_dream_fog_sleep : public SpellScriptLoader
{
PrepareSpellScript(spell_dream_fog_sleep_SpellScript);
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& unitList)
{
- unitList.remove_if (DreamFogTargetSelector());
+ unitList.remove_if(DreamFogTargetSelector());
}
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_dream_fog_sleep_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_DEST_AREA_ENEMY);
}
};
@@ -265,10 +265,12 @@ class MarkOfNatureTargetSelector
public:
MarkOfNatureTargetSelector() { }
- bool operator()(Unit* unit)
+ bool operator()(WorldObject* object) const
{
- // return anyone that isn't tagged or already under the influence of Aura of Nature
- return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
+ if (Unit* unit = object->ToUnit())
+ // return anyone that isn't tagged or already under the influence of Aura of Nature
+ return !(unit->HasAura(SPELL_MARK_OF_NATURE) && !unit->HasAura(SPELL_AURA_OF_NATURE));
+ return true;
}
};
@@ -290,9 +292,9 @@ class spell_mark_of_nature : public SpellScriptLoader
return true;
}
- void FilterTargets(std::list<Unit*>& unitList)
+ void FilterTargets(std::list<WorldObject*>& targets)
{
- unitList.remove_if (MarkOfNatureTargetSelector());
+ targets.remove_if(MarkOfNatureTargetSelector());
}
void HandleEffect(SpellEffIndex effIndex)
@@ -305,7 +307,7 @@ class spell_mark_of_nature : public SpellScriptLoader
void Register()
{
- OnUnitTargetSelect += SpellUnitTargetFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
+ OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_nature_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
OnEffectHitTarget += SpellEffectFn(spell_mark_of_nature_SpellScript::HandleEffect, EFFECT_0, SPELL_EFFECT_APPLY_AURA);
}
};
diff --git a/src/server/scripts/World/go_scripts.cpp b/src/server/scripts/World/go_scripts.cpp
index 790a9d0f814..21a852ae9ed 100644
--- a/src/server/scripts/World/go_scripts.cpp
+++ b/src/server/scripts/World/go_scripts.cpp
@@ -1245,6 +1245,58 @@ class go_veil_skith_cage : public GameObjectScript
}
};
+/*######
+## go_frostblade_shrine
+######*/
+
+enum TheCleansing
+{
+ QUEST_THE_CLEANSING_HORDE = 11317,
+ QUEST_THE_CLEANSING_ALLIANCE = 11322,
+ SPELL_CLEANSING_SOUL = 43351,
+ SPELL_RECENT_MEDITATION = 61720,
+};
+
+class go_frostblade_shrine : public GameObjectScript
+{
+public:
+ go_frostblade_shrine() : GameObjectScript("go_frostblade_shrine") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (!player->HasAura(SPELL_RECENT_MEDITATION))
+ if (player->GetQuestStatus(QUEST_THE_CLEANSING_HORDE) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_THE_CLEANSING_ALLIANCE) == QUEST_STATUS_INCOMPLETE)
+ {
+ go->UseDoorOrButton(10);
+ player->CastSpell(player, SPELL_CLEANSING_SOUL);
+ player->SetStandState(UNIT_STAND_STATE_SIT);
+ }
+ return true;
+ }
+};
+
+/*######
+## go_midsummer_bonfire
+######*/
+
+enum eMidsummerBonfire
+{
+ STAMP_OUT_BONFIRE_QUEST_COMPLETE = 45458,
+};
+
+class go_midsummer_bonfire : public GameObjectScript
+{
+public:
+ go_midsummer_bonfire() : GameObjectScript("go_midsummer_bonfire") { }
+
+ bool OnGossipSelect(Player* player, GameObject* /*go*/, uint32 /*sender*/, uint32 /*action*/)
+ {
+ player->CastSpell(player, STAMP_OUT_BONFIRE_QUEST_COMPLETE, true);
+ player->CLOSE_GOSSIP_MENU();
+ return false;
+ }
+};
+
void AddSC_go_scripts()
{
new go_cat_figurine;
@@ -1285,4 +1337,6 @@ void AddSC_go_scripts()
new go_gjalerbron_cage;
new go_large_gjalerbron_cage;
new go_veil_skith_cage;
+ new go_frostblade_shrine;
+ new go_midsummer_bonfire;
}
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index ecd1a439a58..57a65423b6f 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -47,6 +47,7 @@ EndContentData */
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "World.h"
+#include "PetAI.h"
/*########
# npc_air_force_bots
@@ -2100,16 +2101,18 @@ class npc_shadowfiend : public CreatureScript
public:
npc_shadowfiend() : CreatureScript("npc_shadowfiend") { }
- struct npc_shadowfiendAI : public ScriptedAI
+ struct npc_shadowfiendAI : public PetAI
{
- npc_shadowfiendAI(Creature* creature) : ScriptedAI(creature) {}
+ npc_shadowfiendAI(Creature* creature) : PetAI(creature) {}
- void DamageTaken(Unit* /*killer*/, uint32& damage)
+ void JustDied(Unit* killer)
{
if (me->isSummon())
if (Unit* owner = me->ToTempSummon()->GetSummoner())
- if (owner->HasAura(GLYPH_OF_SHADOWFIEND) && damage >= me->GetHealth())
+ if (owner->HasAura(GLYPH_OF_SHADOWFIEND))
owner->CastSpell(owner, GLYPH_OF_SHADOWFIEND_MANA, true);
+
+ PetAI::JustDied(killer);
}
};
@@ -2988,6 +2991,31 @@ public:
};
};
+/*######
+## npc_generic_harpoon_cannon
+######*/
+
+class npc_generic_harpoon_cannon : public CreatureScript
+{
+public:
+ npc_generic_harpoon_cannon() : CreatureScript("npc_generic_harpoon_cannon") { }
+
+ struct npc_generic_harpoon_cannonAI : public ScriptedAI
+ {
+ npc_generic_harpoon_cannonAI(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset()
+ {
+ me->SetUnitMovementFlags(MOVEMENTFLAG_ROOT);
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_generic_harpoon_cannonAI(creature);
+ }
+};
+
void AddSC_npcs_special()
{
new npc_air_force_bots();
@@ -3020,4 +3048,5 @@ void AddSC_npcs_special()
new npc_earth_elemental();
new npc_firework();
new npc_spring_rabbit();
+ new npc_generic_harpoon_cannon();
}
diff --git a/src/server/shared/Cryptography/WardenKeyGeneration.h b/src/server/shared/Cryptography/WardenKeyGeneration.h
index 9b44ab1832e..f0a9905b6fe 100644
--- a/src/server/shared/Cryptography/WardenKeyGeneration.h
+++ b/src/server/shared/Cryptography/WardenKeyGeneration.h
@@ -21,50 +21,56 @@
#ifndef _WARDEN_KEY_GENERATION_H
#define _WARDEN_KEY_GENERATION_H
-class SHA1Randx {
+class SHA1Randx
+{
public:
- SHA1Randx(uint8 *buff, uint32 size) {
+ SHA1Randx(uint8* buff, uint32 size)
+ {
uint32 taken = size/2;
sh.Initialize();
- sh.UpdateData(buff,taken);
+ sh.UpdateData(buff, taken);
sh.Finalize();
- memcpy(o1,sh.GetDigest(),20);
+ memcpy(o1, sh.GetDigest(), 20);
sh.Initialize();
- sh.UpdateData(buff+taken,size-taken);
+ sh.UpdateData(buff + taken, size - taken);
sh.Finalize();
- memcpy(o2,sh.GetDigest(),20);
+ memcpy(o2, sh.GetDigest(), 20);
- memset(o0,0x00,20);
+ memset(o0, 0x00, 20);
- fillUp();
+ FillUp();
}
- void generate(uint8 *buf, uint32 sz) {
- for(uint32 i=0;i<sz;i++) {
- if(taken == 20) {
- fillUp();
- }
+ void Generate(uint8* buf, uint32 sz)
+ {
+ for (uint32 i = 0; i < sz; ++i)
+ {
+ if (taken == 20)
+ FillUp();
buf[i] = o0[taken];
taken++;
}
}
+
private:
- void fillUp() {
+ void FillUp()
+ {
sh.Initialize();
- sh.UpdateData(o1,20);
- sh.UpdateData(o0,20);
- sh.UpdateData(o2,20);
+ sh.UpdateData(o1, 20);
+ sh.UpdateData(o0, 20);
+ sh.UpdateData(o2, 20);
sh.Finalize();
- memcpy(o0,sh.GetDigest(),20);
+ memcpy(o0, sh.GetDigest(), 20);
taken = 0;
}
+
SHA1Hash sh;
uint32 taken;
uint8 o0[20],o1[20],o2[20];
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.cpp b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
index ea9165f86ec..27bf92ad846 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp
@@ -317,18 +317,17 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PREPARE_STATEMENT(CHAR_DEL_OLD_CORPSES, "DELETE FROM corpse WHERE corpseType = 0 OR time < (UNIX_TIMESTAMP(NOW()) - ?)", CONNECTION_ASYNC)
// Creature respawn
- PREPARE_STATEMENT(CHAR_SEL_CREATURE_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM creature_respawn", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC)
- PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND instanceId = ?", CONNECTION_ASYNC)
- 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_CREATURE_RESPAWNS, "SELECT guid, respawnTime FROM creature_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_REP_CREATURE_RESPAWN, "REPLACE INTO creature_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN, "DELETE FROM creature_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE, "DELETE FROM creature_respawn WHERE mapId = ? AND 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)
// Gameobject respawn
- PREPARE_STATEMENT(CHAR_SEL_GO_RESPAWNS, "SELECT guid, respawnTime, instanceId FROM gameobject_respawn", CONNECTION_SYNCH)
- PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, instanceId) VALUES (?, ?, ?)", CONNECTION_ASYNC)
- 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_SEL_GO_RESPAWNS, "SELECT guid, respawnTime FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_SYNCH)
+ PREPARE_STATEMENT(CHAR_REP_GO_RESPAWN, "REPLACE INTO gameobject_respawn (guid, respawnTime, mapId, instanceId) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN, "DELETE FROM gameobject_respawn WHERE guid = ? AND mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
+ PREPARE_STATEMENT(CHAR_DEL_GO_RESPAWN_BY_INSTANCE, "DELETE FROM gameobject_respawn WHERE mapId = ? AND instanceId = ?", CONNECTION_ASYNC)
// 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)
diff --git a/src/server/shared/Database/Implementation/CharacterDatabase.h b/src/server/shared/Database/Implementation/CharacterDatabase.h
index 51ab97fe021..08265c455d6 100755
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h
@@ -298,7 +298,6 @@ enum CharacterDatabaseStatements
CHAR_SEL_CREATURE_RESPAWNS,
CHAR_REP_CREATURE_RESPAWN,
CHAR_DEL_CREATURE_RESPAWN,
- CHAR_DEL_CREATURE_RESPAWN_BY_GUID,
CHAR_DEL_CREATURE_RESPAWN_BY_INSTANCE,
CHAR_SEL_MAX_CREATURE_RESPAWNS,
diff --git a/src/server/shared/Database/PreparedStatement.cpp b/src/server/shared/Database/PreparedStatement.cpp
index db26dabaee7..58aa2bd3aa0 100755
--- a/src/server/shared/Database/PreparedStatement.cpp
+++ b/src/server/shared/Database/PreparedStatement.cpp
@@ -209,7 +209,7 @@ m_bind(NULL)
MySQLPreparedStatement::~MySQLPreparedStatement()
{
ClearParameters();
- if(m_Mstmt->bind_result_done)
+ if (m_Mstmt->bind_result_done)
{
delete[] m_Mstmt->bind->length;
delete[] m_Mstmt->bind->is_null;
diff --git a/src/server/shared/Packets/ByteBuffer.h b/src/server/shared/Packets/ByteBuffer.h
index bc87950da16..27d5e78bac5 100755
--- a/src/server/shared/Packets/ByteBuffer.h
+++ b/src/server/shared/Packets/ByteBuffer.h
@@ -326,8 +326,7 @@ class ByteBuffer
ByteBuffer &operator<<(const char *str)
{
- size_t len = 0;
- if (str && (len = strlen(str)))
+ if (size_t len = (str ? strlen(str) : 0))
append((uint8 const*)str, len);
append((uint8)0);
return *this;
diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp
index e85a3e1870d..699e7cad97c 100755
--- a/src/server/worldserver/CommandLine/CliRunnable.cpp
+++ b/src/server/worldserver/CommandLine/CliRunnable.cpp
@@ -116,458 +116,6 @@ void commandFinished(void*, bool /*success*/)
fflush(stdout);
}
-/**
- * Collects all GUIDs (and related info) from deleted characters which are still in the database.
- *
- * @param foundList a reference to an std::list which will be filled with info data
- * @param searchString the search string which either contains a player GUID or a part fo the character-name
- * @return returns false if there was a problem while selecting the characters (e.g. player name not normalizeable)
- */
-bool ChatHandler::GetDeletedCharacterInfoList(DeletedInfoList& foundList, std::string searchString)
-{
- PreparedQueryResult result;
- PreparedStatement* stmt;
- if (!searchString.empty())
- {
- // search by GUID
- if (isNumeric(searchString.c_str()))
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_GUID);
-
- stmt->setUInt32(0, uint32(atoi(searchString.c_str())));
-
- result = CharacterDatabase.Query(stmt);
- }
- // search by name
- else
- {
- if (!normalizePlayerName(searchString))
- return false;
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO_BY_NAME);
-
- stmt->setString(0, searchString);
-
- result = CharacterDatabase.Query(stmt);
- }
- }
- else
- {
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_DEL_INFO);
-
- result = CharacterDatabase.Query(stmt);
- }
-
- if (result)
- {
- do
- {
- Field* fields = result->Fetch();
-
- DeletedInfo info;
-
- info.lowguid = fields[0].GetUInt32();
- info.name = fields[1].GetString();
- info.accountId = fields[2].GetUInt32();
-
- // account name will be empty for not existed account
- AccountMgr::GetName(info.accountId, info.accountName);
-
- info.deleteDate = time_t(fields[3].GetUInt32());
-
- foundList.push_back(info);
- } while (result->NextRow());
- }
-
- return true;
-}
-
-/**
- * Generate WHERE guids list by deleted info in way preventing return too long where list for existed query string length limit.
- *
- * @param itr a reference to an deleted info list iterator, it updated in function for possible next function call if list to long
- * @param itr_end a reference to an deleted info list iterator end()
- * @return returns generated where list string in form: 'guid IN (gui1, guid2, ...)'
- */
-std::string ChatHandler::GenerateDeletedCharacterGUIDsWhereStr(DeletedInfoList::const_iterator& itr, DeletedInfoList::const_iterator const& itr_end)
-{
- std::ostringstream wherestr;
- wherestr << "guid IN ('";
- for (; itr != itr_end; ++itr)
- {
- wherestr << itr->lowguid;
-
- if (wherestr.str().size() > MAX_QUERY_LEN - 50) // near to max query
- {
- ++itr;
- break;
- }
-
- DeletedInfoList::const_iterator itr2 = itr;
- if (++itr2 != itr_end)
- wherestr << "', '";
- }
- wherestr << "')";
- return wherestr.str();
-}
-
-/**
- * Shows all deleted characters which matches the given search string, expected non empty list
- *
- * @see ChatHandler::HandleCharacterDeletedListCommand
- * @see ChatHandler::HandleCharacterDeletedRestoreCommand
- * @see ChatHandler::HandleCharacterDeletedDeleteCommand
- * @see ChatHandler::DeletedInfoList
- *
- * @param foundList contains a list with all found deleted characters
- */
-void ChatHandler::HandleCharacterDeletedListHelper(DeletedInfoList const& foundList)
-{
- if (!m_session)
- {
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_HEADER);
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
- }
-
- for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
- {
- std::string dateStr = TimeToTimestampStr(itr->deleteDate);
-
- if (!m_session)
- PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CONSOLE,
- itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
- itr->accountId, dateStr.c_str());
- else
- PSendSysMessage(LANG_CHARACTER_DELETED_LIST_LINE_CHAT,
- itr->lowguid, itr->name.c_str(), itr->accountName.empty() ? "<Not existed>" : itr->accountName.c_str(),
- itr->accountId, dateStr.c_str());
- }
-
- if (!m_session)
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_BAR);
-}
-
-/**
- * Handles the '.character deleted list' command, which shows all deleted characters which matches the given search string
- *
- * @see ChatHandler::HandleCharacterDeletedListHelper
- * @see ChatHandler::HandleCharacterDeletedRestoreCommand
- * @see ChatHandler::HandleCharacterDeletedDeleteCommand
- * @see ChatHandler::DeletedInfoList
- *
- * @param args the search string which either contains a player GUID or a part fo the character-name
- */
-bool ChatHandler::HandleCharacterDeletedListCommand(const char* args)
-{
- DeletedInfoList foundList;
- if (!GetDeletedCharacterInfoList(foundList, args))
- return false;
-
- // if no characters have been found, output a warning
- if (foundList.empty())
- {
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
- return false;
- }
-
- HandleCharacterDeletedListHelper(foundList);
- return true;
-}
-
-/**
- * Restore a previously deleted character
- *
- * @see ChatHandler::HandleCharacterDeletedListHelper
- * @see ChatHandler::HandleCharacterDeletedRestoreCommand
- * @see ChatHandler::HandleCharacterDeletedDeleteCommand
- * @see ChatHandler::DeletedInfoList
- *
- * @param delInfo the informations about the character which will be restored
- */
-void ChatHandler::HandleCharacterDeletedRestoreHelper(DeletedInfo const& delInfo)
-{
- if (delInfo.accountName.empty()) // account not exist
- {
- PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_ACCOUNT, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
- return;
- }
-
- // check character count
- uint32 charcount = AccountMgr::GetCharactersCount(delInfo.accountId);
- if (charcount >= 10)
- {
- PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_FULL, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
- return;
- }
-
- if (sObjectMgr->GetPlayerGUIDByName(delInfo.name))
- {
- PSendSysMessage(LANG_CHARACTER_DELETED_SKIP_NAME, delInfo.name.c_str(), delInfo.lowguid, delInfo.accountId);
- return;
- }
-
- PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UDP_RESTORE_DELETE_INFO);
-
- stmt->setString(0, delInfo.name);
- stmt->setUInt32(1, delInfo.accountId);
- stmt->setUInt32(2, delInfo.lowguid);
-
- CharacterDatabase.Execute(stmt);
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_NAME_DATA);
- stmt->setUInt32(0, delInfo.lowguid);
- if (PreparedQueryResult result = CharacterDatabase.Query(stmt))
- sWorld->AddCharacterNameData(delInfo.lowguid, delInfo.name, (*result)[2].GetUInt8(), (*result)[0].GetUInt8(), (*result)[1].GetUInt8());
-}
-
-/**
- * Handles the '.character deleted restore' command, which restores all deleted characters which matches the given search string
- *
- * The command automatically calls '.character deleted list' command with the search string to show all restored characters.
- *
- * @see ChatHandler::HandleCharacterDeletedRestoreHelper
- * @see ChatHandler::HandleCharacterDeletedListCommand
- * @see ChatHandler::HandleCharacterDeletedDeleteCommand
- *
- * @param args the search string which either contains a player GUID or a part of the character-name
- */
-bool ChatHandler::HandleCharacterDeletedRestoreCommand(const char* args)
-{
- // It is required to submit at least one argument
- if (!*args)
- return false;
-
- std::string searchString;
- std::string newCharName;
- uint32 newAccount = 0;
-
- // GCC by some strange reason fail build code without temporary variable
- std::istringstream params(args);
- params >> searchString >> newCharName >> newAccount;
-
- DeletedInfoList foundList;
- if (!GetDeletedCharacterInfoList(foundList, searchString))
- return false;
-
- if (foundList.empty())
- {
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
- return false;
- }
-
- SendSysMessage(LANG_CHARACTER_DELETED_RESTORE);
- HandleCharacterDeletedListHelper(foundList);
-
- if (newCharName.empty())
- {
- // Drop not existed account cases
- for (DeletedInfoList::iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
- HandleCharacterDeletedRestoreHelper(*itr);
- }
- else if (foundList.size() == 1 && normalizePlayerName(newCharName))
- {
- DeletedInfo delInfo = foundList.front();
-
- // update name
- delInfo.name = newCharName;
-
- // if new account provided update deleted info
- if (newAccount && newAccount != delInfo.accountId)
- {
- delInfo.accountId = newAccount;
- AccountMgr::GetName(newAccount, delInfo.accountName);
- }
-
- HandleCharacterDeletedRestoreHelper(delInfo);
- }
- else
- SendSysMessage(LANG_CHARACTER_DELETED_ERR_RENAME);
-
- return true;
-}
-
-/**
- * Handles the '.character deleted delete' command, which completely deletes all deleted characters which matches the given search string
- *
- * @see Player::GetDeletedCharacterGUIDs
- * @see Player::DeleteFromDB
- * @see ChatHandler::HandleCharacterDeletedListCommand
- * @see ChatHandler::HandleCharacterDeletedRestoreCommand
- *
- * @param args the search string which either contains a player GUID or a part fo the character-name
- */
-bool ChatHandler::HandleCharacterDeletedDeleteCommand(const char* args)
-{
- // It is required to submit at least one argument
- if (!*args)
- return false;
-
- DeletedInfoList foundList;
- if (!GetDeletedCharacterInfoList(foundList, args))
- return false;
-
- if (foundList.empty())
- {
- SendSysMessage(LANG_CHARACTER_DELETED_LIST_EMPTY);
- return false;
- }
-
- SendSysMessage(LANG_CHARACTER_DELETED_DELETE);
- HandleCharacterDeletedListHelper(foundList);
-
- // Call the appropriate function to delete them (current account for deleted characters is 0)
- for (DeletedInfoList::const_iterator itr = foundList.begin(); itr != foundList.end(); ++itr)
- Player::DeleteFromDB(itr->lowguid, 0, false, true);
-
- return true;
-}
-
-/**
- * Handles the '.character deleted old' command, which completely deletes all deleted characters deleted with some days ago
- *
- * @see Player::DeleteOldCharacters
- * @see Player::DeleteFromDB
- * @see ChatHandler::HandleCharacterDeletedDeleteCommand
- * @see ChatHandler::HandleCharacterDeletedListCommand
- * @see ChatHandler::HandleCharacterDeletedRestoreCommand
- *
- * @param args the search string which either contains a player GUID or a part fo the character-name
- */
-bool ChatHandler::HandleCharacterDeletedOldCommand(const char* args)
-{
- int32 keepDays = sWorld->getIntConfig(CONFIG_CHARDELETE_KEEP_DAYS);
-
- char* px = strtok((char*)args, " ");
- if (px)
- {
- if (!isNumeric(px))
- return false;
-
- keepDays = atoi(px);
- if (keepDays < 0)
- return false;
- }
- // config option value 0 -> disabled and can't be used
- else if (keepDays <= 0)
- return false;
-
- Player::DeleteOldCharacters((uint32)keepDays);
- return true;
-}
-
-bool ChatHandler::HandleCharacterEraseCommand(const char* args){
- if (!*args)
- return false;
-
- char *character_name_str = strtok((char*)args, " ");
- if (!character_name_str)
- return false;
-
- std::string character_name = character_name_str;
- if (!normalizePlayerName(character_name))
- return false;
-
- uint64 character_guid;
- uint32 account_id;
-
- Player* player = sObjectAccessor->FindPlayerByName(character_name.c_str());
- if (player)
- {
- character_guid = player->GetGUID();
- account_id = player->GetSession()->GetAccountId();
- player->GetSession()->KickPlayer();
- }
- else
- {
- character_guid = sObjectMgr->GetPlayerGUIDByName(character_name);
- if (!character_guid)
- {
- PSendSysMessage(LANG_NO_PLAYER, character_name.c_str());
- SetSentErrorMessage(true);
- return false;
- }
-
- account_id = sObjectMgr->GetPlayerAccountIdByGUID(character_guid);
- }
-
- std::string account_name;
- AccountMgr::GetName (account_id, account_name);
-
- Player::DeleteFromDB(character_guid, account_id, true, true);
- PSendSysMessage(LANG_CHARACTER_DELETED, character_name.c_str(), GUID_LOPART(character_guid), account_name.c_str(), account_id);
- return true;
-}
-
-/// Exit the realm
-bool ChatHandler::HandleServerExitCommand(const char* /*args*/)
-{
- SendSysMessage(LANG_COMMAND_EXIT);
- World::StopNow(SHUTDOWN_EXIT_CODE);
- return true;
-}
-
-/// Set the level of logging
-bool ChatHandler::HandleServerSetLogFileLevelCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char *NewLevel = strtok((char*)args, " ");
- if (!NewLevel)
- return false;
-
- sLog->SetLogFileLevel(NewLevel);
- return true;
-}
-
-/// Set the level of logging
-bool ChatHandler::HandleServerSetLogLevelCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char *NewLevel = strtok((char*)args, " ");
- if (!NewLevel)
- return false;
-
- sLog->SetLogLevel(NewLevel);
- return true;
-}
-
-/// set diff time record interval
-bool ChatHandler::HandleServerSetDiffTimeCommand(const char *args)
-{
- if (!*args)
- return false;
-
- char *NewTimeStr = strtok((char*)args, " ");
- if (!NewTimeStr)
- return false;
-
- int32 NewTime =atoi(NewTimeStr);
- if (NewTime < 0)
- return false;
-
- sWorld->SetRecordDiffInterval(NewTime);
- printf( "Record diff every %u ms\n", NewTime);
- return true;
-}
-
-/// toggle sql driver query logging
-bool ChatHandler::HandleServerToggleQueryLogging(const char* /* args */)
-{
- sLog->SetSQLDriverQueryLogging(!sLog->GetSQLDriverQueryLogging());
- if (sLog->GetSQLDriverQueryLogging())
- PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_ENABLED);
- else
- PSendSysMessage(LANG_SQLDRIVER_QUERY_LOGGING_DISABLED);
-
- return true;
-}
-
-/// @}
-
#ifdef linux
// Non-blocking keypress detector, when return pressed, return 1, else always return 0
int kb_hit_return()
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 6c598667a1f..110b7744b94 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -484,12 +484,13 @@ LogFileLevel = 0
DebugLogMask = 0
#
-# WorldLogFile
-# Description: Packet logging file for the world server.
-# Example: "World.log" - (Enabled)
+# PacketLogFile
+# Description: Binary packet logging file for the world server.
+# Filename extension must be .bin to be parsable with WowPacketParser.
+# Example: "World.bin" - (Enabled)
# Default: "" - (Disabled)
-WorldLogFile = ""
+PacketLogFile = ""
#
# DBErrorLogFile
@@ -2025,17 +2026,17 @@ Visibility.GroupMode = 1
# Visibility.Distance.Instances
# Visibility.Distance.BGArenas
# Description: Visibility distance to see other players or gameobjects.
-# Visibility on continents on retail ~90 yards. In BG/Arenas ~180.
-# For instances default ~120.
-# Max limited by active player zone: ~ 333
+# Visibility on continents on retail ~90 yards. In BG/Arenas ~533.
+# For instances default ~170.
+# Max limited by grid size: 533.33333
# Min limit is max aggro radius (45) * Rate.Creature.Aggro
# Default: 90 - (Visibility.Distance.Continents)
-# 120 - (Visibility.Distance.Instances)
-# 180 - (Visibility.Distance.BGArenas)
+# 170 - (Visibility.Distance.Instances)
+# 533 - (Visibility.Distance.BGArenas)
Visibility.Distance.Continents = 90
-Visibility.Distance.Instances = 120
-Visibility.Distance.BGArenas = 180
+Visibility.Distance.Instances = 170
+Visibility.Distance.BGArenas = 533
#
# Visibility.Notify.Period.OnContinents
@@ -2515,6 +2516,13 @@ Arena.MaxRatingDifference = 150
Arena.RatingDiscardTimer = 600000
#
+# Arena.RatedUpdateTimer
+# Description: Time (in milliseconds) between checks for matchups in rated arena
+# Default: 5000 - (5 seconds)
+
+Arena.RatedUpdateTimer = 5000
+
+#
# Arena.AutoDistributePoints
# Description: Automatically distribute arena points.
# Default: 0 - (Disabled)
diff --git a/src/tools/map_extractor/CMakeLists.txt b/src/tools/map_extractor/CMakeLists.txt
index af66b73827e..99bdc1feb5f 100644
--- a/src/tools/map_extractor/CMakeLists.txt
+++ b/src/tools/map_extractor/CMakeLists.txt
@@ -23,6 +23,7 @@ add_executable(mapextractor
)
target_link_libraries(mapextractor
+ mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
storm
diff --git a/src/tools/map_extractor/System.cpp b/src/tools/map_extractor/System.cpp
index 41941795b20..9785f89b199 100644
--- a/src/tools/map_extractor/System.cpp
+++ b/src/tools/map_extractor/System.cpp
@@ -50,9 +50,9 @@ char output_path[128] = ".";
char input_path[128] = ".";
uint32 maxAreaId = 0;
-//**************************************************
+// **************************************************
// Extractor options
-//**************************************************
+// **************************************************
enum Extract
{
EXTRACT_MAP = 1,
@@ -79,13 +79,14 @@ uint32 CONF_TargetBuild = 14545; // 4.2.2.14545
char const* CONF_mpq_list[]=
{
"world.MPQ",
+ "art.MPQ",
"world2.MPQ",
"expansion1.MPQ",
"expansion2.MPQ",
"expansion3.MPQ",
};
-uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 0};
+uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0};
#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder
char* const Locales[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU"};
@@ -293,7 +294,7 @@ void ReadAreaTableDBC()
areas[dbc.getRecord(x).getUInt(0)] = dbc.getRecord(x).getUInt(3);
SFileCloseFile(dbcFile);
- printf("Done! (%u areas loaded)\n", area_count);
+ printf("Done! (%zu areas loaded)\n", area_count);
}
void ReadLiquidTypeTableDBC()
@@ -419,7 +420,7 @@ uint8 liquid_flags[ADT_CELLS_PER_GRID][ADT_CELLS_PER_GRID];
bool liquid_show[ADT_GRID_SIZE][ADT_GRID_SIZE];
float liquid_height[ADT_GRID_SIZE+1][ADT_GRID_SIZE+1];
-bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32 build)
+bool ConvertADT(char *filename, char *filename2, int /*cell_y*/, int /*cell_x*/, uint32 build)
{
ADT_file adt;
@@ -623,7 +624,7 @@ bool ConvertADT(char *filename, char *filename2, int cell_y, int cell_x, uint32
// Try store as packed in uint16 or uint8 values
if (!(heightHeader.flags & MAP_HEIGHT_NO_HEIGHT))
{
- float step;
+ float step = 0;
// Try Store as uint values
if (CONF_allow_float_to_int)
{
@@ -1018,7 +1019,9 @@ void ExtractDBCFiles(int l, bool basicLocale)
uint32 count = 0;
if (listFile)
{
- std::string outputPath = "./dbc/";
+ std::string outputPath = output_path;
+ outputPath += "/dbc/";
+
CreateDir(outputPath);
if (!basicLocale)
{
@@ -1062,7 +1065,8 @@ void ExtractDB2Files(int l, bool basicLocale)
uint32 count = 0;
if (listFile)
{
- std::string outputPath = "./dbc/";
+ std::string outputPath = output_path;
+ outputPath += "/dbc/";
if (!basicLocale)
{
outputPath += Locales[l];
@@ -1150,8 +1154,15 @@ void LoadCommonMPQFiles(uint32 build)
_stprintf(filename, _T("%s/Data/%s"), input_path, CONF_mpq_list[i]);
if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0))
+ {
if (GetLastError() != ERROR_PATH_NOT_FOUND)
_tprintf(_T("Cannot open archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ }
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
+
}
char const* prefix = NULL;
@@ -1173,8 +1184,12 @@ void LoadCommonMPQFiles(uint32 build)
{
if (GetLastError() != ERROR_PATH_NOT_FOUND)
_tprintf(_T("Cannot open patch archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
continue;
}
+ else
+ _tprintf(_T("Loaded %s\n"), filename);
}
}
@@ -1191,9 +1206,6 @@ int main(int argc, char * arg[])
for (int i = 0; i < LOCALES_COUNT; ++i)
{
- TCHAR tmp1[512];
- _stprintf(tmp1, _T("%s/Data/%s/locale-%s.MPQ"), input_path, Locales[i], Locales[i]);
-
//Open MPQs
if (!LoadLocaleMPQFile(i))
{
diff --git a/src/tools/vmap4_extractor/CMakeLists.txt b/src/tools/vmap4_extractor/CMakeLists.txt
index c1ef3125a20..8066b18423a 100644
--- a/src/tools/vmap4_extractor/CMakeLists.txt
+++ b/src/tools/vmap4_extractor/CMakeLists.txt
@@ -15,9 +15,11 @@ file(GLOB_RECURSE sources *.cpp *.h)
add_definitions("-DIOMAP_DEBUG")
# build setup currently only supports libmpq 0.4.x
-add_definitions("-Wall")
-add_definitions("-ggdb")
-add_definitions("-O3")
+if( NOT WIN32 )
+ add_definitions("-Wall")
+ add_definitions("-ggdb")
+ add_definitions("-O3")
+endif()
include_directories(
${CMAKE_SOURCE_DIR}/dep/StormLib/src
@@ -26,6 +28,7 @@ include_directories(
add_executable(vmap4extractor ${sources})
target_link_libraries(vmap4extractor
+ mpq
${BZIP2_LIBRARIES}
${ZLIB_LIBRARIES}
storm
diff --git a/src/tools/vmap4_extractor/adtfile.cpp b/src/tools/vmap4_extractor/adtfile.cpp
index a966172a3be..c53b63ffa5e 100644
--- a/src/tools/vmap4_extractor/adtfile.cpp
+++ b/src/tools/vmap4_extractor/adtfile.cpp
@@ -78,7 +78,9 @@ char * GetExtension(char * FileName)
return NULL;
}
-ADTFile::ADTFile(char* filename): ADT(filename)
+extern HANDLE WorldMpq;
+
+ADTFile::ADTFile(char* filename): ADT(WorldMpq, filename)
{
Adtfilename.append(filename);
}
diff --git a/src/tools/vmap4_extractor/adtfile.h b/src/tools/vmap4_extractor/adtfile.h
index 08814996f68..795eebc892f 100644
--- a/src/tools/vmap4_extractor/adtfile.h
+++ b/src/tools/vmap4_extractor/adtfile.h
@@ -19,7 +19,7 @@
#ifndef ADT_H
#define ADT_H
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "wmo.h"
#include "model.h"
diff --git a/src/tools/vmap4_extractor/dbcfile.cpp b/src/tools/vmap4_extractor/dbcfile.cpp
index 5b5fe314799..efc8aeabe8c 100644
--- a/src/tools/vmap4_extractor/dbcfile.cpp
+++ b/src/tools/vmap4_extractor/dbcfile.cpp
@@ -20,13 +20,16 @@
#include "dbcfile.h"
-DBCFile::DBCFile(HANDLE file) :
- _file(file), _data(NULL), _stringTable(NULL)
+DBCFile::DBCFile(HANDLE mpq, const char* filename) :
+ _mpq(mpq), _filename(filename), _file(NULL), _data(NULL), _stringTable(NULL)
{
}
bool DBCFile::open()
{
+ if (!SFileOpenFileEx(_mpq, _filename, SFILE_OPEN_PATCHED_FILE, &_file))
+ return false;
+
char header[4];
unsigned int na, nb, es, ss;
@@ -38,18 +41,22 @@ bool DBCFile::open()
if (header[0] != 'W' || header[1] != 'D' || header[2] != 'B' || header[3] != 'C')
return false;
+ readBytes = 0;
SFileReadFile(_file, &na, 4, &readBytes, NULL);
if (readBytes != 4) // Number of records
return false;
+ readBytes = 0;
SFileReadFile(_file, &nb, 4, &readBytes, NULL);
if (readBytes != 4) // Number of fields
return false;
+ readBytes = 0;
SFileReadFile(_file, &es, 4, &readBytes, NULL);
if (readBytes != 4) // Size of a record
return false;
+ readBytes = 0;
SFileReadFile(_file, &ss, 4, &readBytes, NULL);
if (readBytes != 4) // String size
return false;
@@ -65,6 +72,7 @@ bool DBCFile::open()
_stringTable = _data + _recordSize*_recordCount;
size_t data_size = _recordSize * _recordCount + _stringSize;
+ readBytes = 0;
SFileReadFile(_file, _data, data_size, &readBytes, NULL);
if (readBytes != data_size)
return false;
@@ -75,6 +83,8 @@ bool DBCFile::open()
DBCFile::~DBCFile()
{
delete [] _data;
+ if (_file != NULL)
+ SFileCloseFile(_file);
}
DBCFile::Record DBCFile::getRecord(size_t id)
diff --git a/src/tools/vmap4_extractor/dbcfile.h b/src/tools/vmap4_extractor/dbcfile.h
index 9fdb7a9e268..007ccb6cdcb 100644
--- a/src/tools/vmap4_extractor/dbcfile.h
+++ b/src/tools/vmap4_extractor/dbcfile.h
@@ -25,7 +25,7 @@
class DBCFile
{
public:
- DBCFile(HANDLE file);
+ DBCFile(HANDLE mpq, const char* filename);
~DBCFile();
// Open database. It must be openened before it can be used.
@@ -131,6 +131,8 @@ class DBCFile
size_t getMaxId();
private:
+ HANDLE _mpq;
+ const char* _filename;
HANDLE _file;
size_t _recordSize;
size_t _recordCount;
diff --git a/src/tools/vmap4_extractor/gameobject_extract.cpp b/src/tools/vmap4_extractor/gameobject_extract.cpp
index 8a1f67cd2c2..4c8e423bfc4 100644
--- a/src/tools/vmap4_extractor/gameobject_extract.cpp
+++ b/src/tools/vmap4_extractor/gameobject_extract.cpp
@@ -35,10 +35,12 @@ bool ExtractSingleModel(std::string& fname)
return mdl.ConvertToVMAPModel(output.c_str());
}
+extern HANDLE LocaleMpq;
+
void ExtractGameobjectModels()
{
printf("Extracting GameObject models...");
- DBCFile dbc("DBFilesClient\\GameObjectDisplayInfo.dbc");
+ DBCFile dbc(LocaleMpq, "DBFilesClient\\GameObjectDisplayInfo.dbc");
if(!dbc.open())
{
printf("Fatal error: Invalid GameObjectDisplayInfo.dbc file format!\n");
diff --git a/src/tools/vmap4_extractor/model.cpp b/src/tools/vmap4_extractor/model.cpp
index e81972f521f..d98dca9001b 100644
--- a/src/tools/vmap4_extractor/model.cpp
+++ b/src/tools/vmap4_extractor/model.cpp
@@ -19,18 +19,20 @@
#include "vmapexport.h"
#include "model.h"
#include "wmo.h"
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include <cassert>
#include <algorithm>
#include <cstdio>
+extern HANDLE WorldMpq;
+
Model::Model(std::string &filename) : filename(filename), vertices(0), indices(0)
{
}
bool Model::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
ok = !f.isEof();
diff --git a/src/tools/vmap4_extractor/modelheaders.h b/src/tools/vmap4_extractor/modelheaders.h
index d859fd3511e..7fd908d7442 100644
--- a/src/tools/vmap4_extractor/modelheaders.h
+++ b/src/tools/vmap4_extractor/modelheaders.h
@@ -19,12 +19,7 @@
#ifndef MODELHEADERS_H
#define MODELHEADERS_H
-/* typedef unsigned char uint8;
-typedef char int8;
-typedef unsigned short uint16;
-typedef short int16;
-typedef unsigned int uint32;
-typedef int int32; */
+#include "mpqfile.h" // integer typedefs
#pragma pack(push,1)
diff --git a/src/tools/vmap4_extractor/mpq_libmpq.cpp b/src/tools/vmap4_extractor/mpq_libmpq.cpp
deleted file mode 100644
index 528b9679a58..00000000000
--- a/src/tools/vmap4_extractor/mpq_libmpq.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-#include "mpq_libmpq04.h"
-#include <deque>
-#include <cstdio>
-
-ArchiveSet gOpenArchives;
-
-MPQArchive::MPQArchive(const char* filename)
-{
- int result = libmpq__archive_open(&mpq_a, filename, -1);
- printf("Opening %s\n", filename);
- if(result) {
- switch(result) {
- case LIBMPQ_ERROR_OPEN :
- printf("Error opening archive '%s': Does file really exist?\n", filename);
- break;
- case LIBMPQ_ERROR_FORMAT : /* bad file format */
- printf("Error opening archive '%s': Bad file format\n", filename);
- break;
- case LIBMPQ_ERROR_SEEK : /* seeking in file failed */
- printf("Error opening archive '%s': Seeking in file failed\n", filename);
- break;
- case LIBMPQ_ERROR_READ : /* Read error in archive */
- printf("Error opening archive '%s': Read error in archive\n", filename);
- break;
- case LIBMPQ_ERROR_MALLOC : /* maybe not enough memory? :) */
- printf("Error opening archive '%s': Maybe not enough memory\n", filename);
- break;
- default:
- printf("Error opening archive '%s': Unknown error\n", filename);
- break;
- }
- return;
- }
- gOpenArchives.push_front(this);
-}
-
-void MPQArchive::close()
-{
- //gOpenArchives.erase(erase(&mpq_a);
- libmpq__archive_close(mpq_a);
-}
-
-MPQFile::MPQFile(const char* filename):
- eof(false),
- buffer(0),
- pointer(0),
- size(0)
-{
- for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
- {
- mpq_archive *mpq_a = (*i)->mpq_a;
-
- uint32 filenum;
- if(libmpq__file_number(mpq_a, filename, &filenum)) continue;
- libmpq__off_t transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- // HACK: in patch.mpq some files don't want to open and give 1 for filesize
- if (size<=1) {
- // printf("info: file %s has size %d; considered dummy file.\n", filename, size);
- eof = true;
- buffer = 0;
- return;
- }
- buffer = new char[size];
-
- //libmpq_file_getdata
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
- /*libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);*/
- return;
-
- }
- eof = true;
- buffer = 0;
-}
-
-size_t MPQFile::read(void* dest, size_t bytes)
-{
- if (eof) return 0;
-
- size_t rpos = pointer + bytes;
- if (rpos > size) {
- bytes = size - pointer;
- eof = true;
- }
-
- memcpy(dest, &(buffer[pointer]), bytes);
-
- pointer = rpos;
-
- return bytes;
-}
-
-void MPQFile::seek(int offset)
-{
- pointer = offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::seekRelative(int offset)
-{
- pointer += offset;
- eof = (pointer >= size);
-}
-
-void MPQFile::close()
-{
- if (buffer) delete[] buffer;
- buffer = 0;
- eof = true;
-}
diff --git a/src/tools/vmap4_extractor/mpq_libmpq04.h b/src/tools/vmap4_extractor/mpq_libmpq04.h
deleted file mode 100644
index 5101309002e..00000000000
--- a/src/tools/vmap4_extractor/mpq_libmpq04.h
+++ /dev/null
@@ -1,90 +0,0 @@
-#define _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_WARNINGS
-
-#ifndef MPQ_H
-#define MPQ_H
-
-#include "libmpq/mpq.h"
-#include <string.h>
-#include <ctype.h>
-#include <vector>
-#include <iostream>
-#include <deque>
-
-using namespace std;
-
-class MPQArchive
-{
-
-public:
- mpq_archive_s *mpq_a;
-
- MPQArchive(const char* filename);
- void close();
-
- void GetFileListTo(vector<string>& filelist) {
- uint32 filenum;
- if(libmpq__file_number(mpq_a, "(listfile)", &filenum)) return;
- libmpq__off_t size, transferred;
- libmpq__file_unpacked_size(mpq_a, filenum, &size);
-
- char *buffer = new char[size];
-
- libmpq__file_read(mpq_a, filenum, (unsigned char*)buffer, size, &transferred);
-
- char seps[] = "\n";
- char *token;
-
- token = strtok( buffer, seps );
- uint32 counter = 0;
- while ((token != NULL) && (counter < size)) {
- //cout << token << endl;
- token[strlen(token) - 1] = 0;
- string s = token;
- filelist.push_back(s);
- counter += strlen(token) + 2;
- token = strtok(NULL, seps);
- }
-
- delete[] buffer;
- }
-};
-typedef std::deque<MPQArchive*> ArchiveSet;
-
-class MPQFile
-{
- //MPQHANDLE handle;
- bool eof;
- char *buffer;
- libmpq__off_t pointer,size;
-
- // disable copying
- MPQFile(const MPQFile &f) {}
- void operator=(const MPQFile &f) {}
-
-public:
- MPQFile(const char* filename); // filenames are not case sensitive
- ~MPQFile() { close(); }
- size_t read(void* dest, size_t bytes);
- size_t getSize() { return size; }
- size_t getPos() { return pointer; }
- char* getBuffer() { return buffer; }
- char* getPointer() { return buffer + pointer; }
- bool isEof() { return eof; }
- void seek(int offset);
- void seekRelative(int offset);
- void close();
-};
-
-inline void flipcc(char *fcc)
-{
- char t;
- t=fcc[0];
- fcc[0]=fcc[3];
- fcc[3]=t;
- t=fcc[1];
- fcc[1]=fcc[2];
- fcc[2]=t;
-}
-
-#endif
diff --git a/src/tools/vmap4_extractor/mpqfile.cpp b/src/tools/vmap4_extractor/mpqfile.cpp
new file mode 100644
index 00000000000..9f019f99f38
--- /dev/null
+++ b/src/tools/vmap4_extractor/mpqfile.cpp
@@ -0,0 +1,86 @@
+#include "mpqfile.h"
+#include <deque>
+#include <cstdio>
+#include "StormLib.h"
+
+MPQFile::MPQFile(HANDLE mpq, const char* filename):
+ eof(false),
+ buffer(0),
+ pointer(0),
+ size(0)
+{
+ HANDLE file;
+ if (!SFileOpenFileEx(mpq, filename, SFILE_OPEN_PATCHED_FILE, &file))
+ {
+ fprintf(stderr, "Can't open %s, err=%u!\n", filename, GetLastError());
+ eof = true;
+ return;
+ }
+
+ DWORD hi = 0;
+ size = SFileGetFileSize(file, &hi);
+
+ if (hi)
+ {
+ fprintf(stderr, "Can't open %s, size[hi] = %u!\n", filename, (uint32)hi);
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ if (size <= 1)
+ {
+ fprintf(stderr, "Can't open %s, size = %u!\n", filename, size);
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ DWORD read = 0;
+ buffer = new char[size];
+ if (!SFileReadFile(file, buffer, size, &read) || size != read)
+ {
+ fprintf(stderr, "Can't read %s, size=%u read=%u!\n", filename, size, read);
+ SFileCloseFile(file);
+ eof = true;
+ return;
+ }
+
+ SFileCloseFile(file);
+}
+
+size_t MPQFile::read(void* dest, size_t bytes)
+{
+ if (eof) return 0;
+
+ size_t rpos = pointer + bytes;
+ if (rpos > size) {
+ bytes = size - pointer;
+ eof = true;
+ }
+
+ memcpy(dest, &(buffer[pointer]), bytes);
+
+ pointer = rpos;
+
+ return bytes;
+}
+
+void MPQFile::seek(int offset)
+{
+ pointer = offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::seekRelative(int offset)
+{
+ pointer += offset;
+ eof = (pointer >= size);
+}
+
+void MPQFile::close()
+{
+ if (buffer) delete[] buffer;
+ buffer = 0;
+ eof = true;
+}
diff --git a/src/tools/vmap4_extractor/mpqfile.h b/src/tools/vmap4_extractor/mpqfile.h
new file mode 100644
index 00000000000..115d096a215
--- /dev/null
+++ b/src/tools/vmap4_extractor/mpqfile.h
@@ -0,0 +1,80 @@
+#define _CRT_SECURE_NO_DEPRECATE
+#ifndef _CRT_SECURE_NO_WARNINGS // fuck the police^Wwarnings
+#define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#ifndef MPQ_H
+#define MPQ_H
+
+#include <string.h>
+#include <ctype.h>
+#include <vector>
+#include <iostream>
+#include <deque>
+
+#ifdef _WIN32
+#include <Windows.h> // mainly only HANDLE definition is required
+typedef __int64 int64;
+typedef __int32 int32;
+typedef __int16 int16;
+typedef __int8 int8;
+typedef unsigned __int64 uint64;
+typedef unsigned __int32 uint32;
+typedef unsigned __int16 uint16;
+typedef unsigned __int8 uint8;
+#else
+#include <stdint.h>
+#ifndef uint64_t
+#ifdef __linux__
+#include <linux/types.h>
+#endif
+#endif
+typedef int64_t int64;
+typedef int32_t int32;
+typedef int16_t int16;
+typedef int8_t int8;
+typedef uint64_t uint64;
+typedef uint32_t uint32;
+typedef uint16_t uint16;
+typedef uint8_t uint8;
+#endif
+
+using namespace std;
+
+class MPQFile
+{
+ //MPQHANDLE handle;
+ bool eof;
+ char *buffer;
+ size_t pointer,size;
+
+ // disable copying
+ MPQFile(const MPQFile &f);
+ void operator=(const MPQFile &f);
+
+public:
+ MPQFile(HANDLE mpq, const char* filename); // filenames are not case sensitive
+ ~MPQFile() { close(); }
+ size_t read(void* dest, size_t bytes);
+ size_t getSize() { return size; }
+ size_t getPos() { return pointer; }
+ char* getBuffer() { return buffer; }
+ char* getPointer() { return buffer + pointer; }
+ bool isEof() { return eof; }
+ void seek(int offset);
+ void seekRelative(int offset);
+ void close();
+};
+
+inline void flipcc(char *fcc)
+{
+ char t;
+ t=fcc[0];
+ fcc[0]=fcc[3];
+ fcc[3]=t;
+ t=fcc[1];
+ fcc[1]=fcc[2];
+ fcc[2]=t;
+}
+
+#endif
diff --git a/src/tools/vmap4_extractor/vmapexport.cpp b/src/tools/vmap4_extractor/vmapexport.cpp
index e60a773c6de..1582f9d0b25 100644
--- a/src/tools/vmap4_extractor/vmapexport.cpp
+++ b/src/tools/vmap4_extractor/vmapexport.cpp
@@ -45,7 +45,7 @@
#include "wdtfile.h"
#include "dbcfile.h"
#include "wmo.h"
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "vmapexport.h"
@@ -56,7 +56,37 @@
//-----------------------------------------------------------------------------
-extern ArchiveSet gOpenArchives;
+HANDLE WorldMpq = NULL;
+HANDLE LocaleMpq = NULL;
+
+uint32 CONF_TargetBuild = 14545; // 4.2.2.14545
+
+// List MPQ for extract maps from
+char const* CONF_mpq_list[]=
+{
+ "world.MPQ",
+ "art.MPQ",
+ "expansion1.MPQ",
+ "expansion2.MPQ",
+ "expansion3.MPQ",
+ "world2.MPQ",
+};
+
+uint32 const Builds[] = {13164, 13205, 13287, 13329, 13596, 13623, 13914, 14007, 14333, 14480, 14545, 15005, 15050, 15211, 15354, 15595, 0};
+#define LAST_DBC_IN_DATA_BUILD 13623 // after this build mpqs with dbc are back to locale folder
+
+char* const Locales[] = {"enGB", "enUS", "deDE", "esES", "frFR", "koKR", "zhCN", "zhTW", "enCN", "enTW", "esMX", "ruRU"};
+TCHAR* const LocalesT[] =
+{
+ _T("enGB"), _T("enUS"),
+ _T("deDE"), _T("esES"),
+ _T("frFR"), _T("koKR"),
+ _T("zhCN"), _T("zhTW"),
+ _T("enCN"), _T("enTW"),
+ _T("esMX"), _T("ruRU"),
+};
+
+#define LOCALES_COUNT 12
typedef struct
{
@@ -69,7 +99,6 @@ uint16 *LiqType = 0;
uint32 map_count;
char output_path[128]=".";
char input_path[1024]=".";
-bool hasInputPathParam = false;
bool preciseVectorData = false;
// Constants
@@ -78,6 +107,148 @@ bool preciseVectorData = false;
const char* szWorkDirWmo = "./Buildings";
const char* szRawVMAPMagic = "VMAP041";
+bool LoadLocaleMPQFile(int locale)
+{
+ TCHAR buff[512];
+ memset(buff, 0, sizeof(buff));
+ _stprintf(buff, _T("%s%s/locale-%s.MPQ"), input_path, LocalesT[locale], LocalesT[locale]);
+ if (!SFileOpenArchive(buff, 0, MPQ_OPEN_READ_ONLY, &LocaleMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), buff);
+ return false;
+ }
+
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
+ {
+ memset(buff, 0, sizeof(buff));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(buff, _T("%s%s/wow-update-%s-%u.MPQ"), input_path, LocalesT[locale], LocalesT[locale], Builds[i]);
+ }
+ else
+ {
+ prefix = Locales[locale];
+ _stprintf(buff, _T("%swow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(LocaleMpq, buff, prefix, 0))
+ {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), buff);
+ continue;
+ }
+ }
+
+ return true;
+}
+
+void LoadCommonMPQFiles(uint32 build)
+{
+ TCHAR filename[512];
+ _stprintf(filename, _T("%sworld.MPQ"), input_path);
+ if (!SFileOpenArchive(filename, 0, MPQ_OPEN_READ_ONLY, &WorldMpq))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ return;
+ }
+
+ int count = sizeof(CONF_mpq_list) / sizeof(char*);
+ for (int i = 1; i < count; ++i)
+ {
+ if (build < 15211 && !strcmp("world2.MPQ", CONF_mpq_list[i])) // 4.3.2 and higher MPQ
+ continue;
+
+ _stprintf(filename, _T("%s%s"), input_path, CONF_mpq_list[i]);
+ if (!SFileOpenPatchArchive(WorldMpq, filename, "", 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ }
+ else
+ {
+ _tprintf(_T("Loaded %s\n"), filename);
+
+ bool found = false;
+ int count = 0;
+ SFILE_FIND_DATA data;
+ HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL);
+ if (find != NULL)
+ {
+ do
+ {
+ ++count;
+ if (data.dwFileFlags & MPQ_FILE_PATCH_FILE)
+ {
+ found = true;
+ break;
+ }
+ }
+ while (SFileFindNextFile(find, &data));
+ }
+ SFileFindClose(find);
+ printf("Scanned %d files, found patch = %d\n", count, found);
+ }
+ }
+
+ char const* prefix = NULL;
+ for (int i = 0; Builds[i] && Builds[i] <= CONF_TargetBuild; ++i)
+ {
+ memset(filename, 0, sizeof(filename));
+ if (Builds[i] > LAST_DBC_IN_DATA_BUILD)
+ {
+ prefix = "";
+ _stprintf(filename, _T("%swow-update-base-%u.MPQ"), input_path, Builds[i]);
+ }
+ else
+ {
+ prefix = "base";
+ _stprintf(filename, _T("%swow-update-%u.MPQ"), input_path, Builds[i]);
+ }
+
+ if (!SFileOpenPatchArchive(WorldMpq, filename, prefix, 0))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ _tprintf(_T("Cannot open patch archive %s\n"), filename);
+ else
+ _tprintf(_T("Not found %s\n"), filename);
+ continue;
+ }
+ else
+ {
+ _tprintf(_T("Loaded %s\n"), filename);
+
+
+ bool found = false;
+ int count = 0;
+ SFILE_FIND_DATA data;
+ HANDLE find = SFileFindFirstFile(WorldMpq, "*.*", &data, NULL);
+ if (find != NULL)
+ {
+ do
+ {
+ ++count;
+ if (data.dwFileFlags & MPQ_FILE_PATCH_FILE)
+ {
+ found = true;
+ break;
+ }
+ }
+ while (SFileFindNextFile(find, &data));
+ }
+ SFileFindClose(find);
+ printf("Scanned %d files, found patch = %d\n", count, found);
+ }
+ }
+
+}
+
+
// Local testing functions
bool FileExists(const char* file)
@@ -103,7 +274,8 @@ void strToLower(char* str)
void ReadLiquidTypeTableDBC()
{
printf("Read LiquidType.dbc file...");
- DBCFile dbc("DBFilesClient\\LiquidType.dbc");
+
+ DBCFile dbc(LocaleMpq, "DBFilesClient\\LiquidType.dbc");
if(!dbc.open())
{
printf("Fatal error: Invalid LiquidType.dbc file format!\n");
@@ -123,21 +295,23 @@ void ReadLiquidTypeTableDBC()
bool ExtractWmo()
{
- bool success = true;
+ bool success = false;
//const char* ParsArchiveNames[] = {"patch-2.MPQ", "patch.MPQ", "common.MPQ", "expansion.MPQ"};
- for (ArchiveSet::const_iterator ar_itr = gOpenArchives.begin(); ar_itr != gOpenArchives.end() && success; ++ar_itr)
+ SFILE_FIND_DATA data;
+ HANDLE find = SFileFindFirstFile(WorldMpq, "*.wmo", &data, NULL);
+ if (find != NULL)
{
- vector<string> filelist;
-
- (*ar_itr)->GetFileListTo(filelist);
- for (vector<string>::iterator fname = filelist.begin(); fname != filelist.end() && success; ++fname)
+ do
{
- if (fname->find(".wmo") != string::npos)
- success = ExtractSingleWmo(*fname);
+ std::string str = data.cFileName;
+ //printf("Extracting wmo %s\n", str.c_str());
+ success |= ExtractSingleWmo(str);
}
+ while (SFileFindNextFile(find, &data));
}
+ SFileFindClose(find);
if (success)
printf("\nExtract wmo complete (No (fatal) errors)\n");
@@ -297,91 +471,10 @@ bool scan_patches(char* scanmatch, std::vector<std::string>& pArchiveNames)
return(true);
}
-bool fillArchiveNameVector(std::vector<std::string>& pArchiveNames)
-{
- if(!hasInputPathParam)
- getGamePath();
-
- printf("\nGame path: %s\n", input_path);
-
- char path[512];
- string in_path(input_path);
- std::vector<std::string> locales, searchLocales;
-
- searchLocales.push_back("enGB");
- searchLocales.push_back("enUS");
- searchLocales.push_back("deDE");
- searchLocales.push_back("esES");
- searchLocales.push_back("frFR");
- searchLocales.push_back("koKR");
- searchLocales.push_back("zhCN");
- searchLocales.push_back("zhTW");
- searchLocales.push_back("enCN");
- searchLocales.push_back("enTW");
- searchLocales.push_back("esMX");
- searchLocales.push_back("ruRU");
-
- for (std::vector<std::string>::iterator i = searchLocales.begin(); i != searchLocales.end(); ++i)
- {
- std::string localePath = in_path + *i;
- // check if locale exists:
- struct stat status;
- if (stat(localePath.c_str(), &status))
- continue;
- if ((status.st_mode & S_IFDIR) == 0)
- continue;
- printf("Found locale '%s'\n", i->c_str());
- locales.push_back(*i);
- }
- printf("\n");
-
- // open locale expansion and common files
- printf("Adding data files from locale directories.\n");
- for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
- {
- pArchiveNames.push_back(in_path + *i + "/locale-" + *i + ".MPQ");
- pArchiveNames.push_back(in_path + *i + "/expansion-locale-" + *i + ".MPQ");
- pArchiveNames.push_back(in_path + *i + "/lichking-locale-" + *i + ".MPQ");
- }
-
- // open expansion and common files
- pArchiveNames.push_back(input_path + string("common.MPQ"));
- pArchiveNames.push_back(input_path + string("common-2.MPQ"));
- pArchiveNames.push_back(input_path + string("expansion.MPQ"));
- pArchiveNames.push_back(input_path + string("lichking.MPQ"));
-
- // now, scan for the patch levels in the core dir
- printf("Scanning patch levels from data directory.\n");
- sprintf(path, "%spatch", input_path);
- if (!scan_patches(path, pArchiveNames))
- return(false);
-
- // now, scan for the patch levels in locale dirs
- printf("Scanning patch levels from locale directories.\n");
- bool foundOne = false;
- for (std::vector<std::string>::iterator i = locales.begin(); i != locales.end(); ++i)
- {
- printf("Locale: %s\n", i->c_str());
- sprintf(path, "%s%s/patch-%s", input_path, i->c_str(), i->c_str());
- if(scan_patches(path, pArchiveNames))
- foundOne = true;
- }
-
- printf("\n");
-
- if(!foundOne)
- {
- printf("no locale found\n");
- return false;
- }
-
- return true;
-}
-
bool processArgv(int argc, char ** argv, const char *versionString)
{
bool result = true;
- hasInputPathParam = false;
+ bool hasInputPathParam = false;
bool preciseVectorData = false;
for(int i=1; i< argc; ++i)
@@ -413,12 +506,18 @@ bool processArgv(int argc, char ** argv, const char *versionString)
{
preciseVectorData = true;
}
+ else if(strcmp("-b",argv[i]) == 0)
+ {
+ if (i + 1 < argc) // all ok
+ CONF_TargetBuild = atoi(argv[i++ + 1]);
+ }
else
{
result = false;
break;
}
}
+
if(!result)
{
printf("Extract %s.\n",versionString);
@@ -426,8 +525,13 @@ bool processArgv(int argc, char ** argv, const char *versionString)
printf(" -s : (default) small size (data size optimization), ~500MB less vmap data.\n");
printf(" -l : large size, ~500MB more vmap data. (might contain more details)\n");
printf(" -d <path>: Path to the vector data source folder.\n");
+ printf(" -b : target build (default 14545)");
printf(" -? : This message.\n");
}
+
+ if(!hasInputPathParam)
+ getGamePath();
+
return result;
}
@@ -476,21 +580,24 @@ int main(int argc, char ** argv)
))
success = (errno == EEXIST);
- // prepare archive name list
- std::vector<std::string> archiveNames;
- fillArchiveNameVector(archiveNames);
- for (size_t i=0; i < archiveNames.size(); ++i)
- {
- MPQArchive *archive = new MPQArchive(archiveNames[i].c_str());
- if(!gOpenArchives.size() || gOpenArchives.front() != archive)
- delete archive;
- }
+ LoadCommonMPQFiles(CONF_TargetBuild);
+
+ int FirstLocale = -1;
- if(gOpenArchives.empty())
+ for (int i = 0; i < LOCALES_COUNT; ++i)
{
- printf("FATAL ERROR: None MPQ archive found by path '%s'. Use -d option with proper path.\n",input_path);
- return 1;
+ //Open MPQs
+ if (!LoadLocaleMPQFile(i))
+ {
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
+ printf("Unable to load %s locale archives!\n", Locales[i]);
+ continue;
+ }
+
+ printf("Detected and using locale locale: %s\n", Locales[i]);
+ break;
}
+
ReadLiquidTypeTableDBC();
// extract data
@@ -501,7 +608,7 @@ int main(int argc, char ** argv)
//map.dbc
if(success)
{
- DBCFile * dbc = new DBCFile("DBFilesClient\\Map.dbc");
+ DBCFile * dbc = new DBCFile(LocaleMpq, "DBFilesClient\\Map.dbc");
if(!dbc->open())
{
delete dbc;
@@ -526,6 +633,9 @@ int main(int argc, char ** argv)
ExtractGameobjectModels();
}
+ SFileCloseArchive(LocaleMpq);
+ SFileCloseArchive(WorldMpq);
+
printf("\n");
if(!success)
{
diff --git a/src/tools/vmap4_extractor/wdtfile.cpp b/src/tools/vmap4_extractor/wdtfile.cpp
index e3ee545db19..2dd7396ae7d 100644
--- a/src/tools/vmap4_extractor/wdtfile.cpp
+++ b/src/tools/vmap4_extractor/wdtfile.cpp
@@ -30,7 +30,9 @@ char * wdtGetPlainName(char * FileName)
return FileName;
}
-WDTFile::WDTFile(char* file_name, char* file_name1):WDT(file_name)
+extern HANDLE WorldMpq;
+
+WDTFile::WDTFile(char* file_name, char* file_name1):WDT(WorldMpq, file_name)
{
filename.append(file_name1,strlen(file_name1));
}
@@ -129,6 +131,6 @@ ADTFile* WDTFile::GetMap(int x, int z)
char name[512];
- sprintf(name,"World\\Maps\\%s\\%s_%d_%d.adt", filename.c_str(), filename.c_str(), x, z);
+ sprintf(name,"World\\Maps\\%s\\%s_%d_%d_obj0.adt", filename.c_str(), filename.c_str(), x, z);
return new ADTFile(name);
}
diff --git a/src/tools/vmap4_extractor/wdtfile.h b/src/tools/vmap4_extractor/wdtfile.h
index f3d71c41791..ef3ec6db98c 100644
--- a/src/tools/vmap4_extractor/wdtfile.h
+++ b/src/tools/vmap4_extractor/wdtfile.h
@@ -1,7 +1,7 @@
#ifndef WDTFILE_H
#define WDTFILE_H
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
#include "wmo.h"
#include <string>
#include "stdlib.h"
diff --git a/src/tools/vmap4_extractor/wmo.cpp b/src/tools/vmap4_extractor/wmo.cpp
index 6703872111b..8bba5610c88 100644
--- a/src/tools/vmap4_extractor/wmo.cpp
+++ b/src/tools/vmap4_extractor/wmo.cpp
@@ -26,7 +26,7 @@
#include <fstream>
#undef min
#undef max
-#include "mpq_libmpq04.h"
+#include "mpqfile.h"
using namespace std;
extern uint16 *LiqType;
@@ -35,9 +35,11 @@ WMORoot::WMORoot(std::string &filename) : filename(filename)
{
}
+extern HANDLE WorldMpq;
+
bool WMORoot::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
if(f.isEof ())
{
printf("No such file.\n");
@@ -143,7 +145,7 @@ WMOGroup::WMOGroup(std::string &filename) : filename(filename),
bool WMOGroup::open()
{
- MPQFile f(filename.c_str());
+ MPQFile f(WorldMpq, filename.c_str());
if(f.isEof ())
{
printf("No such file.\n");
diff --git a/src/tools/vmap4_extractor/wmo.h b/src/tools/vmap4_extractor/wmo.h
index 8c5993d91d5..7020bb90f12 100644
--- a/src/tools/vmap4_extractor/wmo.h
+++ b/src/tools/vmap4_extractor/wmo.h
@@ -24,6 +24,7 @@
#include <string>
#include <set>
#include "vec3d.h"
+#include "mpqfile.h"
// MOPY flags
#define WMO_MATERIAL_NOCAMCOLLIDE 0x01