aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Collision/Management/VMapManager2.cpp5
-rw-r--r--src/common/Collision/Management/VMapManager2.h2
-rw-r--r--src/common/Collision/Maps/MapTree.cpp6
-rw-r--r--src/common/Collision/Models/ModelInstance.h3
-rw-r--r--src/common/Collision/Models/WorldModel.cpp19
-rw-r--r--src/common/Collision/Models/WorldModel.h10
-rw-r--r--src/common/Common.h16
-rw-r--r--src/common/Debugging/Errors.cpp11
-rw-r--r--src/common/Debugging/Errors.h6
-rw-r--r--src/server/bnetserver/Server/Session.cpp1
-rw-r--r--src/server/database/Database/DatabaseLoader.cpp2
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h2
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp2
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.cpp10
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.cpp12
-rw-r--r--src/server/game/AI/CoreAI/CombatAI.h2
-rw-r--r--src/server/game/AI/CreatureAIFactory.h5
-rw-r--r--src/server/game/AI/CreatureAIImpl.h290
-rw-r--r--src/server/game/AI/CreatureAISelector.cpp30
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp18
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.h4
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.h4
-rw-r--r--src/server/game/AI/SmartScripts/SmartScript.cpp33
-rw-r--r--src/server/game/Accounts/RBAC.h1
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp2
-rw-r--r--src/server/game/Battlefield/Battlefield.cpp10
-rw-r--r--src/server/game/Battlefield/Battlefield.h17
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.cpp8
-rw-r--r--src/server/game/Battlefield/BattlefieldMgr.h2
-rw-r--r--src/server/game/Battlegrounds/Battleground.cpp79
-rw-r--r--src/server/game/Battlegrounds/BattlegroundMgr.cpp2
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.cpp35
-rw-r--r--src/server/game/Battlegrounds/BattlegroundQueue.h7
-rw-r--r--src/server/game/Chat/Chat.cpp84
-rw-r--r--src/server/game/Chat/Chat.h27
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp394
-rw-r--r--src/server/game/Conditions/ConditionMgr.h89
-rw-r--r--src/server/game/DataStores/DBCEnums.h20
-rw-r--r--src/server/game/DungeonFinding/LFGMgr.cpp8
-rw-r--r--src/server/game/DungeonFinding/LFGScripts.cpp10
-rw-r--r--src/server/game/Entities/Corpse/Corpse.cpp23
-rw-r--r--src/server/game/Entities/Corpse/Corpse.h7
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp9
-rw-r--r--src/server/game/Entities/Creature/Creature.h2
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.cpp3
-rw-r--r--src/server/game/Entities/Creature/CreatureGroups.h4
-rw-r--r--src/server/game/Entities/Item/Item.cpp31
-rw-r--r--src/server/game/Entities/Item/Item.h6
-rw-r--r--src/server/game/Entities/Object/Object.cpp114
-rw-r--r--src/server/game/Entities/Object/ObjectGuid.h7
-rw-r--r--src/server/game/Entities/Player/CollectionMgr.cpp6
-rw-r--r--src/server/game/Entities/Player/KillRewarder.cpp283
-rw-r--r--src/server/game/Entities/Player/KillRewarder.h59
-rw-r--r--src/server/game/Entities/Player/Player.cpp623
-rw-r--r--src/server/game/Entities/Player/Player.h111
-rw-r--r--src/server/game/Entities/Player/TradeData.cpp145
-rw-r--r--src/server/game/Entities/Player/TradeData.h90
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp6
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp280
-rw-r--r--src/server/game/Entities/Unit/Unit.h18
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp68
-rw-r--r--src/server/game/Globals/ObjectMgr.h58
-rw-r--r--src/server/game/Grids/ObjectGridLoader.cpp9
-rw-r--r--src/server/game/Grids/ObjectGridLoader.h1
-rw-r--r--src/server/game/Handlers/BattlefieldHandler.cpp324
-rw-r--r--src/server/game/Handlers/ChatHandler.cpp26
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp3
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp3
-rw-r--r--src/server/game/Handlers/TradeHandler.cpp1
-rw-r--r--src/server/game/Instances/InstanceScript.cpp27
-rw-r--r--src/server/game/Instances/InstanceScript.h3
-rw-r--r--src/server/game/Loot/LootMgr.cpp8
-rw-r--r--src/server/game/Loot/LootMgr.h6
-rw-r--r--src/server/game/Maps/Map.cpp70
-rw-r--r--src/server/game/Maps/Map.h1
-rw-r--r--src/server/game/Miscellaneous/Language.h4
-rw-r--r--src/server/game/Movement/MotionMaster.cpp18
-rw-r--r--src/server/game/Movement/MotionMaster.h1
-rw-r--r--src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp2
-rw-r--r--src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp2
-rw-r--r--src/server/game/Scripting/ScriptLoader.cpp8
-rw-r--r--src/server/game/Scripting/ScriptMgr.cpp177
-rw-r--r--src/server/game/Scripting/ScriptMgr.h40
-rw-r--r--src/server/game/Server/Packets/BattlefieldPackets.cpp88
-rw-r--r--src/server/game/Server/Packets/BattlefieldPackets.h132
-rw-r--r--src/server/game/Server/Packets/ChatPackets.cpp6
-rw-r--r--src/server/game/Server/Packets/ChatPackets.h11
-rw-r--r--src/server/game/Server/Packets/ItemPackets.cpp57
-rw-r--r--src/server/game/Server/Packets/ItemPackets.h54
-rw-r--r--src/server/game/Server/Packets/MovementPackets.cpp11
-rw-r--r--src/server/game/Server/Packets/MovementPackets.h14
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp10
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h13
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp103
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h2
-rw-r--r--src/server/game/Server/WorldSession.cpp1
-rw-r--r--src/server/game/Server/WorldSession.h41
-rw-r--r--src/server/game/Server/WorldSocket.cpp32
-rw-r--r--src/server/game/Skills/SkillExtraItems.cpp111
-rw-r--r--src/server/game/Skills/SkillExtraItems.h4
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp4
-rw-r--r--src/server/game/Spells/Spell.cpp27
-rw-r--r--src/server/game/Spells/Spell.h18
-rw-r--r--src/server/game/Spells/SpellEffects.cpp32
-rw-r--r--src/server/game/Spells/SpellHistory.cpp54
-rw-r--r--src/server/game/Spells/SpellHistory.h5
-rw-r--r--src/server/game/Spells/SpellInfo.cpp5
-rw-r--r--src/server/game/Spells/SpellInfo.h2
-rw-r--r--src/server/game/Spells/SpellMgr.cpp17
-rw-r--r--src/server/game/Weather/WeatherMgr.cpp2
-rw-r--r--src/server/game/World/World.cpp4
-rw-r--r--src/server/game/World/World.h1
-rw-r--r--src/server/scripts/Commands/cs_account.cpp45
-rw-r--r--src/server/scripts/Commands/cs_achievement.cpp10
-rw-r--r--src/server/scripts/Commands/cs_ahbot.cpp44
-rw-r--r--src/server/scripts/Commands/cs_arena.cpp20
-rw-r--r--src/server/scripts/Commands/cs_ban.cpp45
-rw-r--r--src/server/scripts/Commands/cs_battlenet_account.cpp30
-rw-r--r--src/server/scripts/Commands/cs_bf.cpp18
-rw-r--r--src/server/scripts/Commands/cs_cast.cpp26
-rw-r--r--src/server/scripts/Commands/cs_character.cpp44
-rw-r--r--src/server/scripts/Commands/cs_cheat.cpp69
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp122
-rw-r--r--src/server/scripts/Commands/cs_deserter.cpp22
-rw-r--r--src/server/scripts/Commands/cs_disable.cpp46
-rw-r--r--src/server/scripts/Commands/cs_event.cpp16
-rw-r--r--src/server/scripts/Commands/cs_gm.cpp20
-rw-r--r--src/server/scripts/Commands/cs_go.cpp36
-rw-r--r--src/server/scripts/Commands/cs_gobject.cpp36
-rw-r--r--src/server/scripts/Commands/cs_group.cpp20
-rw-r--r--src/server/scripts/Commands/cs_guild.cpp22
-rw-r--r--src/server/scripts/Commands/cs_honor.cpp17
-rw-r--r--src/server/scripts/Commands/cs_instance.cpp26
-rw-r--r--src/server/scripts/Commands/cs_learn.cpp36
-rw-r--r--src/server/scripts/Commands/cs_lfg.cpp72
-rw-r--r--src/server/scripts/Commands/cs_list.cpp18
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp50
-rw-r--r--src/server/scripts/Commands/cs_message.cpp27
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp135
-rw-r--r--src/server/scripts/Commands/cs_mmaps.cpp18
-rw-r--r--src/server/scripts/Commands/cs_modify.cpp113
-rw-r--r--src/server/scripts/Commands/cs_npc.cpp184
-rw-r--r--src/server/scripts/Commands/cs_pet.cpp14
-rw-r--r--src/server/scripts/Commands/cs_quest.cpp16
-rw-r--r--src/server/scripts/Commands/cs_rbac.cpp21
-rw-r--r--src/server/scripts/Commands/cs_reload.cpp218
-rw-r--r--src/server/scripts/Commands/cs_reset.cpp22
-rw-r--r--src/server/scripts/Commands/cs_send.cpp16
-rw-r--r--src/server/scripts/Commands/cs_server.cpp57
-rw-r--r--src/server/scripts/Commands/cs_tele.cpp18
-rw-r--r--src/server/scripts/Commands/cs_ticket.cpp80
-rw-r--r--src/server/scripts/Commands/cs_titles.cpp19
-rw-r--r--src/server/scripts/Commands/cs_wp.cpp22
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp116
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp93
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp110
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h41
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp7
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp7
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp7
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp7
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp6
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp4
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp231
-rw-r--r--src/server/scripts/EasternKingdoms/CMakeLists.txt3
-rw-r--r--src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp2
-rw-r--r--src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp73
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp25
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp29
-rw-r--r--src/server/scripts/Kalimdor/zone_the_barrens.cpp2
-rw-r--r--src/server/scripts/Kalimdor/zone_winterspring.cpp2
-rw-r--r--src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp2
-rw-r--r--src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp3
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_blood_queen_lana_thel.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp65
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp8
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp2
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h1
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp4
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp208
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp130
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp147
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp84
-rw-r--r--src/server/scripts/Northrend/Naxxramas/boss_noth.cpp284
-rw-r--r--src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp38
-rw-r--r--src/server/scripts/Northrend/Naxxramas/naxxramas.h5
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp2
-rw-r--r--src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp3
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp164
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp14
-rw-r--r--src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h23
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp185
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_erekem.cpp479
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp697
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp160
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_moragg.cpp256
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp425
-rw-r--r--src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp269
-rw-r--r--src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp1340
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.cpp1929
-rw-r--r--src/server/scripts/Northrend/VioletHold/violet_hold.h114
-rw-r--r--src/server/scripts/Northrend/zone_borean_tundra.cpp12
-rw-r--r--src/server/scripts/Northrend/zone_howling_fjord.cpp2
-rw-r--r--src/server/scripts/Northrend/zone_sholazar_basin.cpp68
-rw-r--r--src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp2
-rw-r--r--src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp4
-rw-r--r--src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp2
-rw-r--r--src/server/scripts/Outland/zone_hellfire_peninsula.cpp473
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp42
-rw-r--r--src/server/scripts/World/duel_reset.cpp57
-rw-r--r--src/server/scripts/World/npc_professions.cpp146
-rw-r--r--src/server/scripts/World/npcs_special.cpp1
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.cpp6
-rw-r--r--src/server/worldserver/CommandLine/CliRunnable.cpp13
-rw-r--r--src/server/worldserver/worldserver.conf.dist15
-rw-r--r--src/tools/connection_patcher/Patches/Mac.hpp2
-rw-r--r--src/tools/connection_patcher/Patterns/Mac.hpp2
-rw-r--r--src/tools/mmaps_generator/VMapExtensions.cpp70
221 files changed, 8035 insertions, 7434 deletions
diff --git a/src/common/Collision/Management/VMapManager2.cpp b/src/common/Collision/Management/VMapManager2.cpp
index 9a31692593d..ae39fdaa297 100644
--- a/src/common/Collision/Management/VMapManager2.cpp
+++ b/src/common/Collision/Management/VMapManager2.cpp
@@ -326,4 +326,9 @@ namespace VMAP
return StaticMapTree::CanLoadMap(std::string(basePath), mapId, x, y);
}
+ void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree)
+ {
+ instanceMapTree = iInstanceMapTrees;
+ }
+
} // namespace VMAP
diff --git a/src/common/Collision/Management/VMapManager2.h b/src/common/Collision/Management/VMapManager2.h
index 553145cda4b..d425f35d44b 100644
--- a/src/common/Collision/Management/VMapManager2.h
+++ b/src/common/Collision/Management/VMapManager2.h
@@ -128,7 +128,7 @@ namespace VMAP
return getMapFileName(mapId);
}
virtual bool existsMap(const char* basePath, unsigned int mapId, int x, int y) override;
- public:
+
void getInstanceMapTree(InstanceTreeMap &instanceMapTree);
typedef uint32(*GetLiquidFlagsFn)(uint32 liquidType);
diff --git a/src/common/Collision/Maps/MapTree.cpp b/src/common/Collision/Maps/MapTree.cpp
index 862f3e1cefe..d1bcc12f305 100644
--- a/src/common/Collision/Maps/MapTree.cpp
+++ b/src/common/Collision/Maps/MapTree.cpp
@@ -474,4 +474,10 @@ namespace VMAP
}
iLoadedTiles.erase(tile);
}
+
+ void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count)
+ {
+ models = iTreeValues;
+ count = iNTreeValues;
+ }
}
diff --git a/src/common/Collision/Models/ModelInstance.h b/src/common/Collision/Models/ModelInstance.h
index dfdb001db0a..f8bbfa4fa73 100644
--- a/src/common/Collision/Models/ModelInstance.h
+++ b/src/common/Collision/Models/ModelInstance.h
@@ -70,12 +70,11 @@ namespace VMAP
void intersectPoint(const G3D::Vector3& p, AreaInfo &info) const;
bool GetLocationInfo(const G3D::Vector3& p, LocationInfo &info) const;
bool GetLiquidLevel(const G3D::Vector3& p, LocationInfo &info, float &liqHeight) const;
+ WorldModel* getWorldModel() { return iModel; }
protected:
G3D::Matrix3 iInvRot;
float iInvScale;
WorldModel* iModel;
- public:
- WorldModel* getWorldModel();
};
} // namespace VMAP
diff --git a/src/common/Collision/Models/WorldModel.cpp b/src/common/Collision/Models/WorldModel.cpp
index 3af120045cb..d29758b51f4 100644
--- a/src/common/Collision/Models/WorldModel.cpp
+++ b/src/common/Collision/Models/WorldModel.cpp
@@ -250,6 +250,13 @@ namespace VMAP
return result;
}
+ void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const
+ {
+ tilesX = iTilesX;
+ tilesY = iTilesY;
+ corner = iCorner;
+ }
+
// ===================== GroupModel ==================================
GroupModel::GroupModel(const GroupModel &other):
@@ -410,6 +417,13 @@ namespace VMAP
return 0;
}
+ void GroupModel::getMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid)
+ {
+ outVertices = vertices;
+ outTriangles = triangles;
+ liquid = iLiquid;
+ }
+
// ===================== WorldModel ==================================
void WorldModel::setGroupModels(std::vector<GroupModel> &models)
@@ -583,4 +597,9 @@ namespace VMAP
fclose(rf);
return result;
}
+
+ void WorldModel::getGroupModels(std::vector<GroupModel>& outGroupModels)
+ {
+ outGroupModels = groupModels;
+ }
}
diff --git a/src/common/Collision/Models/WorldModel.h b/src/common/Collision/Models/WorldModel.h
index 6a901a59fdf..afa9d15b264 100644
--- a/src/common/Collision/Models/WorldModel.h
+++ b/src/common/Collision/Models/WorldModel.h
@@ -58,6 +58,7 @@ namespace VMAP
uint32 GetFileSize();
bool writeToFile(FILE* wf);
static bool readFromFile(FILE* rf, WmoLiquid* &liquid);
+ void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const;
private:
WmoLiquid() : iTilesX(0), iTilesY(0), iCorner(), iType(0), iHeight(NULL), iFlags(NULL) { }
uint32 iTilesX; //!< number of tiles in x direction, each
@@ -66,8 +67,6 @@ namespace VMAP
uint32 iType; //!< liquid type
float *iHeight; //!< (tilesX + 1)*(tilesY + 1) height values
uint8 *iFlags; //!< info if liquid tile is used
- public:
- void getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const;
};
/*! holding additional info for WMO group files */
@@ -92,6 +91,7 @@ namespace VMAP
const G3D::AABox& GetBound() const { return iBound; }
uint32 GetMogpFlags() const { return iMogpFlags; }
uint32 GetWmoID() const { return iGroupWMOID; }
+ void getMeshData(std::vector<G3D::Vector3>& outVertices, std::vector<MeshTriangle>& outTriangles, WmoLiquid*& liquid);
protected:
G3D::AABox iBound;
uint32 iMogpFlags;// 0x8 outdor; 0x2000 indoor
@@ -100,9 +100,8 @@ namespace VMAP
std::vector<MeshTriangle> triangles;
BIH meshTree;
WmoLiquid* iLiquid;
- public:
- void getMeshData(std::vector<G3D::Vector3> &vertices, std::vector<MeshTriangle> &triangles, WmoLiquid* &liquid);
};
+
/*! Holds a model (converted M2 or WMO) in its original coordinate space */
class WorldModel
{
@@ -117,12 +116,11 @@ namespace VMAP
bool GetLocationInfo(const G3D::Vector3 &p, const G3D::Vector3 &down, float &dist, LocationInfo &info) const;
bool writeFile(const std::string &filename);
bool readFile(const std::string &filename);
+ void getGroupModels(std::vector<GroupModel>& outGroupModels);
protected:
uint32 RootWMOID;
std::vector<GroupModel> groupModels;
BIH groupTree;
- public:
- void getGroupModels(std::vector<GroupModel> &groupModels);
};
} // namespace VMAP
diff --git a/src/common/Common.h b/src/common/Common.h
index 605b6dc4ae8..2a492e0eeee 100644
--- a/src/common/Common.h
+++ b/src/common/Common.h
@@ -45,6 +45,7 @@
#include <boost/optional.hpp>
#include <boost/utility/in_place_factory.hpp>
+#include <boost/functional/hash.hpp>
#include "Debugging/Errors.h"
@@ -178,4 +179,19 @@ namespace Trinity
}
}
+//! Hash implementation for std::pair to allow using pairs in unordered_set or as key for unordered_map
+//! Individual types used in pair must be hashable by boost::hash
+namespace std
+{
+ template<class K, class V>
+ struct hash<std::pair<K, V>>
+ {
+ public:
+ size_t operator()(std::pair<K, V> const& key) const
+ {
+ return boost::hash_value(key);
+ }
+ };
+}
+
#endif
diff --git a/src/common/Debugging/Errors.cpp b/src/common/Debugging/Errors.cpp
index 6c295a993f5..2406493442d 100644
--- a/src/common/Debugging/Errors.cpp
+++ b/src/common/Debugging/Errors.cpp
@@ -59,10 +59,15 @@ void Assert(char const* file, int line, char const* function, char const* messag
exit(1);
}
-void Fatal(char const* file, int line, char const* function, char const* message)
+void Fatal(char const* file, int line, char const* function, char const* message, ...)
{
- fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n %s\n",
- file, line, function, message);
+ va_list args;
+ va_start(args, message);
+
+ fprintf(stderr, "\n%s:%i in %s FATAL ERROR:\n ", file, line, function);
+ vfprintf(stderr, message, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
std::this_thread::sleep_for(std::chrono::seconds(10));
*((volatile int*)NULL) = 0;
diff --git a/src/common/Debugging/Errors.h b/src/common/Debugging/Errors.h
index edf56b29136..9e526933acc 100644
--- a/src/common/Debugging/Errors.h
+++ b/src/common/Debugging/Errors.h
@@ -26,10 +26,10 @@ namespace Trinity
DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
DECLSPEC_NORETURN void Assert(char const* file, int line, char const* function, char const* message, char const* format, ...) ATTR_NORETURN ATTR_PRINTF(5, 6);
- DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
+ DECLSPEC_NORETURN void Fatal(char const* file, int line, char const* function, char const* message, ...) ATTR_NORETURN ATTR_PRINTF(4, 5);
DECLSPEC_NORETURN void Error(char const* file, int line, char const* function, char const* message) ATTR_NORETURN;
-
+
DECLSPEC_NORETURN void Abort(char const* file, int line, char const* function) ATTR_NORETURN;
void Warning(char const* file, int line, char const* function, char const* message);
@@ -45,7 +45,7 @@ namespace Trinity
#endif
#define WPAssert(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Assert(__FILE__, __LINE__, __FUNCTION__, #cond, ##__VA_ARGS__); } while(0) ASSERT_END
-#define WPFatal(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
+#define WPFatal(cond, ...) ASSERT_BEGIN do { if (!(cond)) Trinity::Fatal(__FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__); } while(0) ASSERT_END
#define WPError(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Error(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define WPWarning(cond, msg) ASSERT_BEGIN do { if (!(cond)) Trinity::Warning(__FILE__, __LINE__, __FUNCTION__, (msg)); } while(0) ASSERT_END
#define WPAbort() ASSERT_BEGIN do { Trinity::Abort(__FILE__, __LINE__, __FUNCTION__); } while(0) ASSERT_END
diff --git a/src/server/bnetserver/Server/Session.cpp b/src/server/bnetserver/Server/Session.cpp
index 36137b20b41..062ee535b23 100644
--- a/src/server/bnetserver/Server/Session.cpp
+++ b/src/server/bnetserver/Server/Session.cpp
@@ -672,6 +672,7 @@ bool Battlenet::Session::Update()
if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
auto callback = std::move(_queryCallback);
+ _queryCallback = nullptr;
callback(_queryFuture.get());
}
diff --git a/src/server/database/Database/DatabaseLoader.cpp b/src/server/database/Database/DatabaseLoader.cpp
index 1d704100d93..d3e9e7a7132 100644
--- a/src/server/database/Database/DatabaseLoader.cpp
+++ b/src/server/database/Database/DatabaseLoader.cpp
@@ -66,7 +66,7 @@ DatabaseLoader& DatabaseLoader::AddDatabase(DatabaseWorkerPool<T>& pool, std::st
if (error)
{
TC_LOG_ERROR("sql.driver", "\nDatabasePool %s NOT opened. There were errors opening the MySQL connections. Check your SQLDriverLogFile "
- "for specific errors. Read wiki at http://collab.kpsn.org/display/tc/TrinityCore+Home", name.c_str());
+ "for specific errors. Read wiki at http://www.trinitycore.info/display/tc/TrinityCore+Home", name.c_str());
return false;
}
diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h
index 7cc5dfb63a0..fecf6c055bc 100644
--- a/src/server/database/Database/DatabaseWorkerPool.h
+++ b/src/server/database/Database/DatabaseWorkerPool.h
@@ -67,6 +67,8 @@ class DatabaseWorkerPool
WPFatal(mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
WPFatal(mysql_get_client_version() >= MIN_MYSQL_CLIENT_VERSION, "TrinityCore does not support MySQL versions below 5.1");
+ WPFatal(mysql_get_client_version() == MYSQL_VERSION_ID, "Used MySQL library version (%s) does not match the version used to compile TrinityCore (%s).",
+ mysql_get_client_info(), MYSQL_SERVER_VERSION);
}
~DatabaseWorkerPool()
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 3399e9a8136..3ecc3975611 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -662,7 +662,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// PvPstats
PrepareStatement(CHAR_SEL_PVPSTATS_MAXID, "SELECT MAX(id) FROM pvpstats_battlegrounds", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_PVPSTATS_BATTLEGROUND, "INSERT INTO pvpstats_battlegrounds (id, winner_faction, bracket_id, type, date) VALUES (?, ?, ?, ?, NOW())", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_PVPSTATS_PLAYER, "INSERT INTO pvpstats_players (battleground_id, character_guid, score_killing_blows, score_deaths, score_honorable_kills, score_bonus_honor, score_damage_done, score_healing_done, attr_1, attr_2, attr_3, attr_4, attr_5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_PVPSTATS_PLAYER, "INSERT INTO pvpstats_players (battleground_id, character_guid, winner, score_killing_blows, score_deaths, score_honorable_kills, score_bonus_honor, score_damage_done, score_healing_done, attr_1, attr_2, attr_3, attr_4, attr_5) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_PVPSTATS_FACTIONS_OVERALL, "SELECT winner_faction, COUNT(*) AS count FROM pvpstats_battlegrounds WHERE DATEDIFF(NOW(), date) < 7 GROUP BY winner_faction ORDER BY winner_faction ASC", CONNECTION_SYNCH);
// QuestTracker
diff --git a/src/server/database/Database/Implementation/LoginDatabase.cpp b/src/server/database/Database/Implementation/LoginDatabase.cpp
index 7e199659177..9b2837bfffe 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.cpp
+++ b/src/server/database/Database/Implementation/LoginDatabase.cpp
@@ -39,10 +39,10 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_LOGON_COUNTRY, "SELECT country FROM ip2nation WHERE ip < ? ORDER BY ip DESC LIMIT 0,1", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_ID_BY_NAME, "SELECT id FROM account WHERE username = ?", CONNECTION_SYNCH);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_NAME, "SELECT id, username FROM account WHERE username = ?", CONNECTION_SYNCH);
- PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.sessionkey, ba.last_ip, ba.locked, a.expansion, a.mutetime, ba.locale, a.recruiter, ba.os, ba.id, aa.gmLevel, "
+ PrepareStatement(LOGIN_SEL_ACCOUNT_INFO_BY_NAME, "SELECT a.id, a.sessionkey, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, ba.os, ba.id, aa.gmLevel, "
"bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id "
"FROM account a LEFT JOIN account r ON a.id = r.recruiter LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id "
- "LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id "
+ "LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?) LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 "
"WHERE a.username = ? ORDER BY aa.RealmID DESC LIMIT 1", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_ACCOUNT_LIST_BY_EMAIL, "SELECT id, username FROM account WHERE email = ?", CONNECTION_SYNCH);
@@ -51,7 +51,7 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_INS_IP_BANNED, "INSERT INTO ip_banned (ip, bandate, unbandate, bannedby, banreason) VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_IP_NOT_BANNED, "DELETE FROM ip_banned WHERE ip = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_ACCOUNT_BANNED, "INSERT INTO account_banned VALUES (?, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()+?, ?, ?, 1)", CONNECTION_ASYNC);
- PrepareStatement(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET unbandate = UNIX_TIMESTAMP(), active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC);
+ PrepareStatement(LOGIN_UPD_ACCOUNT_NOT_BANNED, "UPDATE account_banned SET active = 0 WHERE id = ? AND active != 0", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_REALM_CHARACTERS_BY_REALM, "DELETE FROM realmcharacters WHERE acctid = ? AND realmid = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_DEL_REALM_CHARACTERS, "DELETE FROM realmcharacters WHERE acctid = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_INS_REALM_CHARACTERS, "INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (?, ?, ?)", CONNECTION_ASYNC);
@@ -118,12 +118,12 @@ void LoginDatabaseConnection::DoPrepareStatements()
PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_INFO, "SELECT " BnetAccountInfo ", ba.sha_pass_hash, ba.v, ba.s, " BnetGameAccountInfo
" FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account"
- " LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ?", CONNECTION_ASYNC);
+ " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_VS_FIELDS, "UPDATE battlenet_accounts SET v = ?, s = ? WHERE email = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_SESSION_KEY, "UPDATE battlenet_accounts SET sessionKey = ?, online = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_RECONNECT_INFO, "SELECT " BnetAccountInfo ", ba.sessionKey, " BnetGameAccountInfo
" FROM battlenet_accounts ba LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account a ON ba.id = a.battlenet_account"
- " LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? AND a.username = ?", CONNECTION_ASYNC);
+ " LEFT JOIN account_banned ab ON a.id = ab.id AND ab.active = 1 LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID = -1 WHERE ba.email = ? AND a.username = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_FAILED_LOGINS, "UPDATE battlenet_accounts SET failed_logins = failed_logins + 1 WHERE email = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_UPD_BNET_LAST_LOGIN_INFO, "UPDATE battlenet_accounts SET last_ip = ?, last_login = NOW(), locale = ?, failed_logins = 0, os = ? WHERE id = ?", CONNECTION_ASYNC);
PrepareStatement(LOGIN_SEL_BNET_CHARACTER_COUNTS, "SELECT rc.numchars, r.id, r.Region, r.Battlegroup, r.gamebuild FROM realmcharacters rc INNER JOIN realmlist r ON rc.realmid = r.id WHERE rc.acctid = ?", CONNECTION_ASYNC);
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index 7efed2976c4..9d76ee5573d 100644
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -259,7 +259,7 @@ void TurretAI::UpdateAI(uint32 /*diff*/)
// VehicleAI
//////////////
-VehicleAI::VehicleAI(Creature* creature) : CreatureAI(creature), m_ConditionsTimer(VEHICLE_CONDITION_CHECK_TIME)
+VehicleAI::VehicleAI(Creature* creature) : CreatureAI(creature), m_HasConditions(false), m_ConditionsTimer(VEHICLE_CONDITION_CHECK_TIME)
{
LoadConditions();
m_DoDismiss = false;
@@ -285,7 +285,7 @@ void VehicleAI::UpdateAI(uint32 diff)
void VehicleAI::OnCharmed(bool apply)
{
- if (!me->GetVehicleKit()->IsVehicleInUse() && !apply && !conditions.empty()) // was used and has conditions
+ if (!me->GetVehicleKit()->IsVehicleInUse() && !apply && m_HasConditions) // was used and has conditions
{
m_DoDismiss = true; // needs reset
}
@@ -297,16 +297,14 @@ void VehicleAI::OnCharmed(bool apply)
void VehicleAI::LoadConditions()
{
- conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry());
- if (!conditions.empty())
- TC_LOG_DEBUG("condition", "VehicleAI::LoadConditions: loaded %u conditions", uint32(conditions.size()));
+ m_HasConditions = sConditionMgr->HasConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry());
}
void VehicleAI::CheckConditions(uint32 diff)
{
if (m_ConditionsTimer < diff)
{
- if (!conditions.empty())
+ if (m_HasConditions)
{
if (Vehicle* vehicleKit = me->GetVehicleKit())
for (SeatMap::iterator itr = vehicleKit->Seats.begin(); itr != vehicleKit->Seats.end(); ++itr)
@@ -314,7 +312,7 @@ void VehicleAI::CheckConditions(uint32 diff)
{
if (Player* player = passenger->ToPlayer())
{
- if (!sConditionMgr->IsObjectMeetToConditions(player, me, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE, me->GetEntry(), player, me))
{
player->ExitVehicle();
return; // check other pessanger in next tick
diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h
index 97308f22e5d..26b5db3e7c8 100644
--- a/src/server/game/AI/CoreAI/CombatAI.h
+++ b/src/server/game/AI/CoreAI/CombatAI.h
@@ -112,7 +112,7 @@ struct VehicleAI : public CreatureAI
private:
void LoadConditions();
void CheckConditions(uint32 diff);
- ConditionList conditions;
+ bool m_HasConditions;
uint32 m_ConditionsTimer;
bool m_DoDismiss;
uint32 m_DismissTimer;
diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h
index 4473d3e9cd5..4e11630259b 100644
--- a/src/server/game/AI/CreatureAIFactory.h
+++ b/src/server/game/AI/CreatureAIFactory.h
@@ -50,6 +50,8 @@ CreatureAIFactory<REAL_AI>::Create(void* data) const
typedef FactoryHolder<CreatureAI> CreatureAICreator;
typedef FactoryHolder<CreatureAI>::FactoryHolderRegistry CreatureAIRegistry;
+#define sCreatureAIRegistry CreatureAIRegistry::instance()
+
//GO
struct SelectableGameObjectAI : public FactoryHolder<GameObjectAI>, public Permissible<GameObject>
{
@@ -76,4 +78,7 @@ GameObjectAIFactory<REAL_GO_AI>::Create(void* data) const
typedef FactoryHolder<GameObjectAI> GameObjectAICreator;
typedef FactoryHolder<GameObjectAI>::FactoryHolderRegistry GameObjectAIRegistry;
+
+#define sGameObjectAIRegistry GameObjectAIRegistry::instance()
+
#endif
diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h
index a2c5c5db057..529f7420021 100644
--- a/src/server/game/AI/CreatureAIImpl.h
+++ b/src/server/game/AI/CreatureAIImpl.h
@@ -23,292 +23,14 @@
#include "CreatureAI.h"
#include "SpellMgr.h"
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2)
-{
- return (urand(0, 1)) ? v1 : v2;
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3)
-{
- switch (urand(0, 2))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4)
-{
- switch (urand(0, 3))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5)
-{
- switch (urand(0, 4))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6)
-{
- switch (urand(0, 5))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7)
-{
- switch (urand(0, 6))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8)
-{
- switch (urand(0, 7))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9)
-{
- switch (urand(0, 8))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10)
-{
- switch (urand(0, 9))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11)
-{
- switch (urand(0, 10))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11, const T& v12)
-{
- switch (urand(0, 11))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- case 11: return v12;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11, const T& v12, const T& v13)
-{
- switch (urand(0, 12))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- case 11: return v12;
- case 12: return v13;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14)
-{
- switch (urand(0, 13))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- case 11: return v12;
- case 12: return v13;
- case 13: return v14;
- }
-}
-
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15)
-{
- switch (urand(0, 14))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- case 11: return v12;
- case 12: return v13;
- case 13: return v14;
- case 14: return v15;
- }
-}
+#include <functional>
+#include <type_traits>
-template<class T>
-inline
-const T& RAND(const T& v1, const T& v2, const T& v3, const T& v4, const T& v5, const T& v6, const T& v7, const T& v8,
- const T& v9, const T& v10, const T& v11, const T& v12, const T& v13, const T& v14, const T& v15, const T& v16)
+template<typename First, typename Second, typename... Rest>
+static inline First const& RAND(First const& first, Second const& second, Rest const&... rest)
{
- switch (urand(0, 15))
- {
- default:
- case 0: return v1;
- case 1: return v2;
- case 2: return v3;
- case 3: return v4;
- case 4: return v5;
- case 5: return v6;
- case 6: return v7;
- case 7: return v8;
- case 8: return v9;
- case 9: return v10;
- case 10: return v11;
- case 11: return v12;
- case 12: return v13;
- case 13: return v14;
- case 14: return v15;
- case 15: return v16;
- }
+ std::reference_wrapper<typename std::add_const<First>::type> const pack[] = { first, second, rest... };
+ return pack[urand(0, sizeof...(rest) + 1)].get();
}
enum AITarget
diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp
index ddb5ba3508b..495e6dcee31 100644
--- a/src/server/game/AI/CreatureAISelector.cpp
+++ b/src/server/game/AI/CreatureAISelector.cpp
@@ -30,10 +30,9 @@ namespace FactorySelector
CreatureAI* selectAI(Creature* creature)
{
const CreatureAICreator* ai_factory = NULL;
- CreatureAIRegistry& ai_registry(*CreatureAIRegistry::instance());
if (creature->IsPet())
- ai_factory = ai_registry.GetRegistryItem("PetAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
//scriptname in db
if (!ai_factory)
@@ -43,32 +42,32 @@ namespace FactorySelector
// AIname in db
std::string ainame=creature->GetAIName();
if (!ai_factory && !ainame.empty())
- ai_factory = ai_registry.GetRegistryItem(ainame);
+ ai_factory = sCreatureAIRegistry->GetRegistryItem(ainame);
// select by NPC flags
if (!ai_factory)
{
if (creature->IsVehicle())
- ai_factory = ai_registry.GetRegistryItem("VehicleAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("VehicleAI");
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN) && ((Guardian*)creature)->GetOwner()->GetTypeId() == TYPEID_PLAYER)
- ai_factory = ai_registry.GetRegistryItem("PetAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
else if (creature->HasFlag64(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK))
- ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
else if (creature->IsGuard())
- ai_factory = ai_registry.GetRegistryItem("GuardAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("GuardAI");
else if (creature->HasUnitTypeMask(UNIT_MASK_CONTROLABLE_GUARDIAN))
- ai_factory = ai_registry.GetRegistryItem("PetAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("PetAI");
else if (creature->IsTotem())
- ai_factory = ai_registry.GetRegistryItem("TotemAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("TotemAI");
else if (creature->IsTrigger())
{
if (creature->m_spells[0])
- ai_factory = ai_registry.GetRegistryItem("TriggerAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("TriggerAI");
else
- ai_factory = ai_registry.GetRegistryItem("NullCreatureAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("NullCreatureAI");
}
else if (creature->IsCritter() && !creature->HasUnitTypeMask(UNIT_MASK_GUARDIAN))
- ai_factory = ai_registry.GetRegistryItem("CritterAI");
+ ai_factory = sCreatureAIRegistry->GetRegistryItem("CritterAI");
}
// select by permit check
@@ -76,7 +75,7 @@ namespace FactorySelector
{
int best_val = -1;
typedef CreatureAIRegistry::RegistryMapType RMT;
- RMT const& l = ai_registry.GetRegisteredItems();
+ RMT const& l = sCreatureAIRegistry->GetRegisteredItems();
for (RMT::const_iterator iter = l.begin(); iter != l.end(); ++iter)
{
const CreatureAICreator* factory = iter->second;
@@ -128,14 +127,13 @@ namespace FactorySelector
GameObjectAI* SelectGameObjectAI(GameObject* go)
{
- const GameObjectAICreator* ai_factory = NULL;
- GameObjectAIRegistry& ai_registry(*GameObjectAIRegistry::instance());
+ GameObjectAICreator const* ai_factory = NULL;
// scriptname in db
if (GameObjectAI* scriptedAI = sScriptMgr->GetGameObjectAI(go))
return scriptedAI;
- ai_factory = ai_registry.GetRegistryItem(go->GetAIName());
+ ai_factory = sGameObjectAIRegistry->GetRegistryItem(go->GetAIName());
//future goAI types go here
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 512385a67b6..28f9ad591df 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -446,7 +446,13 @@ BossAI::BossAI(Creature* creature, uint32 bossId) : ScriptedAI(creature),
instance(creature->GetInstanceScript()),
summons(creature),
_boundary(instance ? instance->GetBossBoundary(bossId) : NULL),
- _bossId(bossId) { }
+ _bossId(bossId)
+{
+ scheduler.SetValidator([this]
+ {
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ });
+}
void BossAI::_Reset()
{
@@ -457,6 +463,7 @@ void BossAI::_Reset()
me->ResetLootMode();
events.Reset();
summons.DespawnAll();
+ scheduler.CancelAll();
if (instance)
instance->SetBossState(_bossId, NOT_STARTED);
}
@@ -465,15 +472,13 @@ void BossAI::_JustDied()
{
events.Reset();
summons.DespawnAll();
+ scheduler.CancelAll();
if (instance)
instance->SetBossState(_bossId, DONE);
}
void BossAI::_EnterCombat()
{
- me->SetCombatPulseDelay(5);
- me->setActive(true);
- DoZoneInCombat();
if (instance)
{
// bosses do not respawn, check only on enter combat
@@ -484,6 +489,11 @@ void BossAI::_EnterCombat()
}
instance->SetBossState(_bossId, IN_PROGRESS);
}
+
+ me->SetCombatPulseDelay(5);
+ me->setActive(true);
+ DoZoneInCombat();
+ ScheduleTasks();
}
void BossAI::TeleportCheaters()
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
index 74d0654dff2..49e2e0e8518 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h
@@ -23,6 +23,7 @@
#include "CreatureAI.h"
#include "CreatureAIImpl.h"
#include "InstanceScript.h"
+#include "TaskScheduler.h"
#define CAST_AI(a, b) (dynamic_cast<a*>(b))
#define ENSURE_AI(a,b) (EnsureAI<a>(b))
@@ -356,6 +357,8 @@ class BossAI : public ScriptedAI
// is supposed to run more than once
virtual void ExecuteEvent(uint32 /*eventId*/) { }
+ virtual void ScheduleTasks() { }
+
void Reset() override { _Reset(); }
void EnterCombat(Unit* /*who*/) override { _EnterCombat(); }
void JustDied(Unit* /*killer*/) override { _JustDied(); }
@@ -382,6 +385,7 @@ class BossAI : public ScriptedAI
EventMap events;
SummonList summons;
+ TaskScheduler scheduler;
private:
BossBoundaryMap const* const _boundary;
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
index 1d71652c948..deabd1dc484 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h
@@ -68,8 +68,8 @@ struct npc_escortAI : public ScriptedAI
void EnterEvadeMode() override;
- void UpdateAI(uint32 diff) override; //the "internal" update, calls UpdateEscortAI()
- virtual void UpdateEscortAI(uint32 const diff); //used when it's needed to add code in update (abilities, scripted events, etc)
+ void UpdateAI(uint32 diff) override; // the "internal" update, calls UpdateEscortAI()
+ virtual void UpdateEscortAI(uint32 diff); // used when it's needed to add code in update (abilities, scripted events, etc)
void MovementInform(uint32, uint32) override;
diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp
index fa6db60dac2..56dcbfd38fb 100644
--- a/src/server/game/AI/SmartScripts/SmartScript.cpp
+++ b/src/server/game/AI/SmartScripts/SmartScript.cpp
@@ -89,13 +89,8 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3
continue;
if (eventType == e /*&& (!i->event.event_phase_mask || IsInPhase(i->event.event_phase_mask)) && !(i->event.event_flags & SMART_EVENT_FLAG_NOT_REPEATABLE && i->runOnce)*/)
- {
- ConditionList conds = sConditionMgr->GetConditionsForSmartEvent(i->entryOrGuid, i->event_id, i->source_type);
- ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject());
-
- if (sConditionMgr->IsObjectMeetToConditions(info, conds))
+ if (sConditionMgr->IsObjectMeetingSmartEventConditions(i->entryOrGuid, i->event_id, i->source_type, unit, GetBaseObject()))
ProcessEvent(*i, unit, var0, var1, bvar, spell, gob);
- }
}
}
@@ -1053,16 +1048,21 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr)
{
- if (!IsCreature(*itr))
- continue;
-
- if ((*itr)->ToUnit()->IsAlive() && IsSmart((*itr)->ToCreature()))
+ if (Creature* target = (*itr)->ToCreature())
{
- ENSURE_AI(SmartAI, (*itr)->ToCreature()->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick
- ENSURE_AI(SmartAI, (*itr)->ToCreature()->AI())->StartDespawn();
+ if (target->IsAlive() && IsSmart(target))
+ {
+ ENSURE_AI(SmartAI, target->AI())->SetDespawnTime(e.action.forceDespawn.delay + 1); // Next tick
+ ENSURE_AI(SmartAI, target->AI())->StartDespawn();
+ }
+ else
+ target->DespawnOrUnsummon(e.action.forceDespawn.delay);
+ }
+ else if (GameObject* goTarget = (*itr)->ToGameObject())
+ {
+ if (IsSmartGO(goTarget))
+ goTarget->SetRespawnTime(e.action.forceDespawn.delay + 1);
}
- else
- (*itr)->ToCreature()->DespawnOrUnsummon(e.action.forceDespawn.delay);
}
delete targets;
@@ -2354,10 +2354,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob)
{
- ConditionList const conds = sConditionMgr->GetConditionsForSmartEvent(e.entryOrGuid, e.event_id, e.source_type);
- ConditionSourceInfo info = ConditionSourceInfo(unit, GetBaseObject());
-
- if (sConditionMgr->IsObjectMeetToConditions(info, conds))
+ if (sConditionMgr->IsObjectMeetingSmartEventConditions(e.entryOrGuid, e.event_id, e.source_type, unit, GetBaseObject()))
ProcessAction(e, unit, var0, var1, bvar, spell, gob);
RecalcTimer(e, min, max);
diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h
index 9baa4caeea7..4c630d44c48 100644
--- a/src/server/game/Accounts/RBAC.h
+++ b/src/server/game/Accounts/RBAC.h
@@ -726,6 +726,7 @@ enum RBACPermissions
RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT = 832,
RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION = 833,
RBAC_PERM_COMMAND_GO_QUEST = 834,
+ RBAC_PERM_COMMAND_DEBUG_LOADCELLS = 835,
// custom permissions 1000+
RBAC_PERM_MAX
diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp
index 04fbc45e709..4f1bae9eccd 100644
--- a/src/server/game/Achievements/AchievementMgr.cpp
+++ b/src/server/game/Achievements/AchievementMgr.cpp
@@ -3132,7 +3132,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData()
if (dataType != ACHIEVEMENT_CRITERIA_DATA_TYPE_SCRIPT)
TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` has ScriptName set for non-scripted data type (Entry: %u, type %u), useless data.", criteria_id, dataType);
else
- scriptId = sObjectMgr->GetScriptId(scriptName.c_str());
+ scriptId = sObjectMgr->GetScriptId(scriptName);
}
AchievementCriteriaData data(dataType, fields[2].GetUInt32(), fields[3].GetUInt32(), scriptId);
diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp
index dc1ecf7c1c3..bab3c00e224 100644
--- a/src/server/game/Battlefield/Battlefield.cpp
+++ b/src/server/game/Battlefield/Battlefield.cpp
@@ -106,7 +106,7 @@ void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
if (m_PlayersInWar[player->GetTeamId()].find(player->GetGUID()) != m_PlayersInWar[player->GetTeamId()].end())
{
m_PlayersInWar[player->GetTeamId()].erase(player->GetGUID());
- player->GetSession()->SendBfLeaveMessage(m_Guid);
+ player->GetSession()->SendBfLeaveMessage(GetQueueId(), GetState(), player->GetZoneId() == GetZoneId());
if (Group* group = player->GetGroup()) // Remove the player from the raid group
group->RemoveMember(player->GetGUID());
@@ -210,7 +210,7 @@ void Battlefield::InvitePlayerToQueue(Player* player)
return;
if (m_PlayersInQueue[player->GetTeamId()].size() <= m_MinPlayer || m_PlayersInQueue[GetOtherTeam(player->GetTeamId())].size() >= m_MinPlayer)
- player->GetSession()->SendBfInvitePlayerToQueue(m_Guid);
+ player->GetSession()->SendBfInvitePlayerToQueue(GetQueueId(), GetState());
}
void Battlefield::InvitePlayersInQueueToWar()
@@ -279,7 +279,7 @@ void Battlefield::InvitePlayerToWar(Player* player)
m_PlayersWillBeKick[player->GetTeamId()].erase(player->GetGUID());
m_InvitedPlayers[player->GetTeamId()][player->GetGUID()] = time(NULL) + m_TimeForAcceptInvite;
- player->GetSession()->SendBfInvitePlayerToWar(m_Guid, m_ZoneId, m_TimeForAcceptInvite);
+ player->GetSession()->SendBfInvitePlayerToWar(GetQueueId(), m_ZoneId, m_TimeForAcceptInvite);
}
void Battlefield::InitStalker(uint32 entry, Position const& pos)
@@ -361,7 +361,7 @@ void Battlefield::PlayerAcceptInviteToQueue(Player* player)
// Add player in queue
m_PlayersInQueue[player->GetTeamId()].insert(player->GetGUID());
// Send notification
- player->GetSession()->SendBfQueueInviteResponse(m_Guid, m_ZoneId);
+ player->GetSession()->SendBfQueueInviteResponse(GetQueueId(), m_ZoneId, GetState());
}
// Called in WorldSession::HandleBfExitRequest
@@ -379,7 +379,7 @@ void Battlefield::PlayerAcceptInviteToWar(Player* player)
if (AddOrSetPlayerToCorrectBfGroup(player))
{
- player->GetSession()->SendBfEntered(m_Guid);
+ player->GetSession()->SendBfEntered(GetQueueId(), player->GetZoneId() != GetZoneId(), player->GetTeamId() == GetAttackerTeam());
m_PlayersInWar[player->GetTeamId()].insert(player->GetGUID());
m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID());
diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h
index 42d27ed35cf..78c4f7eb77d 100644
--- a/src/server/game/Battlefield/Battlefield.h
+++ b/src/server/game/Battlefield/Battlefield.h
@@ -30,7 +30,16 @@ enum BattlefieldTypes
enum BattlefieldIDs
{
- BATTLEFIELD_BATTLEID_WG = 1 // Wintergrasp battle
+ BATTLEFIELD_BATTLEID_WG = 1, // Wintergrasp battle
+ BATTLEFIELD_BATTLEID_TB = 21, // Tol Barad
+ BATTLEFIELD_BATTLEID_ASHRAN = 24 // Ashran
+};
+
+enum BattlefieldState
+{
+ BATTLEFIELD_INACTIVE = 0,
+ BATTLEFIELD_WARMUP = 1,
+ BATTLEFIELD_IN_PROGRESS = 2
};
enum BattlefieldObjectiveStates
@@ -224,13 +233,15 @@ class Battlefield : public ZoneScript
uint32 GetTypeId() const { return m_TypeId; }
uint32 GetZoneId() const { return m_ZoneId; }
- ObjectGuid GetGUID() const { return m_Guid; }
+ uint64 GetQueueId() const { return MAKE_PAIR64(m_BattleId | 0x20000, 0x1F100000); }
void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0);
/// Return true if battle is start, false if battle is not started
bool IsWarTime() const { return m_isActive; }
+ int8 GetState() const { return m_isActive ? BATTLEFIELD_IN_PROGRESS : (m_Timer <= m_StartGroupingTimer ? BATTLEFIELD_WARMUP : BATTLEFIELD_INACTIVE); }
+
/// Enable or Disable battlefield
void ToggleBattlefield(bool enable) { m_IsEnabled = enable; }
/// Return if battlefield is enable
@@ -344,8 +355,6 @@ class Battlefield : public ZoneScript
void InitStalker(uint32 entry, Position const& pos);
protected:
- ObjectGuid m_Guid;
-
ObjectGuid StalkerGuid;
uint32 m_Timer; // Global timer for event
bool m_IsEnabled;
diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp
index 0ce7d3a685c..dd0260326d4 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.cpp
+++ b/src/server/game/Battlefield/BattlefieldMgr.cpp
@@ -122,11 +122,11 @@ Battlefield* BattlefieldMgr::GetBattlefieldByBattleId(uint32 battleId)
return NULL;
}
-Battlefield* BattlefieldMgr::GetBattlefieldByGUID(ObjectGuid guid)
+Battlefield* BattlefieldMgr::GetBattlefieldByQueueId(uint64 queueId)
{
- for (BattlefieldSet::iterator itr = _battlefieldSet.begin(); itr != _battlefieldSet.end(); ++itr)
- if ((*itr)->GetGUID() == guid)
- return *itr;
+ for (Battlefield* bf : _battlefieldSet)
+ if (bf->GetQueueId() == queueId)
+ return bf;
return NULL;
}
diff --git a/src/server/game/Battlefield/BattlefieldMgr.h b/src/server/game/Battlefield/BattlefieldMgr.h
index 456d18d6c72..d370add82a9 100644
--- a/src/server/game/Battlefield/BattlefieldMgr.h
+++ b/src/server/game/Battlefield/BattlefieldMgr.h
@@ -44,7 +44,7 @@ class BattlefieldMgr
// return assigned battlefield
Battlefield* GetBattlefieldToZoneId(uint32 zoneId);
Battlefield* GetBattlefieldByBattleId(uint32 battleId);
- Battlefield* GetBattlefieldByGUID(ObjectGuid guid);
+ Battlefield* GetBattlefieldByQueueId(uint64 queueId);
ZoneScript* GetZoneScript(uint32 zoneId);
diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 07c88486c50..82e3aafc098 100644
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -835,19 +835,20 @@ void Battleground::EndBattleground(uint32 winner)
stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_PLAYER);
BattlegroundScoreMap::const_iterator score = PlayerScores.find(player->GetGUID());
- stmt->setUInt32(0, battlegroundId);
- stmt->setUInt64(1, player->GetGUID().GetCounter());
- stmt->setUInt32(2, score->second->GetKillingBlows());
- stmt->setUInt32(3, score->second->GetDeaths());
- stmt->setUInt32(4, score->second->GetHonorableKills());
- stmt->setUInt32(5, score->second->GetBonusHonor());
- stmt->setUInt32(6, score->second->GetDamageDone());
- stmt->setUInt32(7, score->second->GetHealingDone());
- stmt->setUInt32(8, score->second->GetAttr1());
- stmt->setUInt32(9, score->second->GetAttr2());
- stmt->setUInt32(10, score->second->GetAttr3());
- stmt->setUInt32(11, score->second->GetAttr4());
- stmt->setUInt32(12, score->second->GetAttr5());
+ stmt->setUInt32(0, battlegroundId);
+ stmt->setUInt64(1, player->GetGUID().GetCounter());
+ stmt->setBool (2, team == winner);
+ stmt->setUInt32(3, score->second->GetKillingBlows());
+ stmt->setUInt32(4, score->second->GetDeaths());
+ stmt->setUInt32(5, score->second->GetHonorableKills());
+ stmt->setUInt32(6, score->second->GetBonusHonor());
+ stmt->setUInt32(7, score->second->GetDamageDone());
+ stmt->setUInt32(8, score->second->GetHealingDone());
+ stmt->setUInt32(9, score->second->GetAttr1());
+ stmt->setUInt32(10, score->second->GetAttr2());
+ stmt->setUInt32(11, score->second->GetAttr3());
+ stmt->setUInt32(12, score->second->GetAttr4());
+ stmt->setUInt32(13, score->second->GetAttr5());
CharacterDatabase.Execute(stmt);
}
@@ -1250,48 +1251,58 @@ void Battleground::RemoveFromBGFreeSlotQueue()
// returns the number how many players can join battleground to MaxPlayersPerTeam
uint32 Battleground::GetFreeSlotsForTeam(uint32 Team) const
{
- // if BG is starting ... invite anyone
- if (GetStatus() == STATUS_WAIT_JOIN)
+ // if BG is starting and CONFIG_BATTLEGROUND_INVITATION_TYPE == BG_QUEUE_INVITATION_TYPE_NO_BALANCE, invite anyone
+ if (GetStatus() == STATUS_WAIT_JOIN && sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_NO_BALANCE)
return (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
- // if BG is already started .. do not allow to join too much players of one faction
- uint32 otherTeam;
- uint32 otherIn;
+
+ // if BG is already started or CONFIG_BATTLEGROUND_INVITATION_TYPE != BG_QUEUE_INVITATION_TYPE_NO_BALANCE, do not allow to join too much players of one faction
+ uint32 otherTeamInvitedCount;
+ uint32 thisTeamInvitedCount;
+ uint32 otherTeamPlayersCount;
+ uint32 thisTeamPlayersCount;
+
if (Team == ALLIANCE)
{
- otherTeam = GetInvitedCount(HORDE);
- otherIn = GetPlayersCountByTeam(HORDE);
+ thisTeamInvitedCount = GetInvitedCount(ALLIANCE);
+ otherTeamInvitedCount = GetInvitedCount(HORDE);
+ thisTeamPlayersCount = GetPlayersCountByTeam(ALLIANCE);
+ otherTeamPlayersCount = GetPlayersCountByTeam(HORDE);
}
else
{
- otherTeam = GetInvitedCount(ALLIANCE);
- otherIn = GetPlayersCountByTeam(ALLIANCE);
+ thisTeamInvitedCount = GetInvitedCount(HORDE);
+ otherTeamInvitedCount = GetInvitedCount(ALLIANCE);
+ thisTeamPlayersCount = GetPlayersCountByTeam(HORDE);
+ otherTeamPlayersCount = GetPlayersCountByTeam(ALLIANCE);
}
- if (GetStatus() == STATUS_IN_PROGRESS)
+ if (GetStatus() == STATUS_IN_PROGRESS || GetStatus() == STATUS_WAIT_JOIN)
{
// difference based on ppl invited (not necessarily entered battle)
// default: allow 0
uint32 diff = 0;
- // allow join one person if the sides are equal (to fill up bg to minplayersperteam)
- if (otherTeam == GetInvitedCount(Team))
+
+ // allow join one person if the sides are equal (to fill up bg to minPlayerPerTeam)
+ if (otherTeamInvitedCount == thisTeamInvitedCount)
diff = 1;
// allow join more ppl if the other side has more players
- else if (otherTeam > GetInvitedCount(Team))
- diff = otherTeam - GetInvitedCount(Team);
+ else if (otherTeamInvitedCount > thisTeamInvitedCount)
+ diff = otherTeamInvitedCount - thisTeamInvitedCount;
// difference based on max players per team (don't allow inviting more)
- uint32 diff2 = (GetInvitedCount(Team) < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - GetInvitedCount(Team) : 0;
+ uint32 diff2 = (thisTeamInvitedCount < GetMaxPlayersPerTeam()) ? GetMaxPlayersPerTeam() - thisTeamInvitedCount : 0;
+
// difference based on players who already entered
// default: allow 0
uint32 diff3 = 0;
- // allow join one person if the sides are equal (to fill up bg minplayersperteam)
- if (otherIn == GetPlayersCountByTeam(Team))
+ // allow join one person if the sides are equal (to fill up bg minPlayerPerTeam)
+ if (otherTeamPlayersCount == thisTeamPlayersCount)
diff3 = 1;
// allow join more ppl if the other side has more players
- else if (otherIn > GetPlayersCountByTeam(Team))
- diff3 = otherIn - GetPlayersCountByTeam(Team);
+ else if (otherTeamPlayersCount > thisTeamPlayersCount)
+ diff3 = otherTeamPlayersCount - thisTeamPlayersCount;
// or other side has less than minPlayersPerTeam
- else if (GetInvitedCount(Team) <= GetMinPlayersPerTeam())
- diff3 = GetMinPlayersPerTeam() - GetInvitedCount(Team) + 1;
+ else if (thisTeamInvitedCount <= GetMinPlayersPerTeam())
+ diff3 = GetMinPlayersPerTeam() - thisTeamInvitedCount + 1;
// return the minimum of the 3 differences
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
index 74a9ac32b1b..afa6403cc22 100644
--- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp
@@ -502,7 +502,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates()
float dist = fields[7].GetFloat();
bgTemplate.MaxStartDistSq = dist * dist;
bgTemplate.Weight = fields[8].GetUInt8();
- bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[9].GetCString());
+ bgTemplate.ScriptId = sObjectMgr->GetScriptId(fields[9].GetString());
bgTemplate.BattlemasterEntry = bl;
if (bgTemplate.MaxPlayersPerTeam == 0 || bgTemplate.MinPlayersPerTeam > bgTemplate.MaxPlayersPerTeam)
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
index 8f459432d01..ab38b89baac 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp
@@ -497,24 +497,51 @@ void BattlegroundQueue::FillPlayersToBG(Battleground* bg, BattlegroundBracketId
{
int32 hordeFree = bg->GetFreeSlotsForTeam(HORDE);
int32 aliFree = bg->GetFreeSlotsForTeam(ALLIANCE);
+ uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
+ uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
+
+ // try to get even teams
+ if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_EVEN)
+ {
+ // check if the teams are even
+ if (hordeFree == 1 && aliFree == 1)
+ {
+ // if we are here, the teams have the same amount of players
+ // then we have to allow to join the same amount of players
+ int32 hordeExtra = hordeCount - aliCount;
+ int32 aliExtra = aliCount - hordeCount;
+
+ hordeExtra = std::max(hordeExtra, 0);
+ aliExtra = std::max(aliExtra, 0);
+
+ if (aliCount != hordeCount)
+ {
+ aliFree -= aliExtra;
+ hordeFree -= hordeExtra;
+
+ aliFree = std::max(aliFree, 0);
+ hordeFree = std::max(hordeFree, 0);
+ }
+ }
+ }
//iterator for iterating through bg queue
GroupsQueueType::const_iterator Ali_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].begin();
//count of groups in queue - used to stop cycles
- uint32 aliCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_ALLIANCE].size();
+
//index to queue which group is current
uint32 aliIndex = 0;
for (; aliIndex < aliCount && m_SelectionPools[TEAM_ALLIANCE].AddGroup((*Ali_itr), aliFree); aliIndex++)
++Ali_itr;
//the same thing for horde
GroupsQueueType::const_iterator Horde_itr = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].begin();
- uint32 hordeCount = m_QueuedGroups[bracket_id][BG_QUEUE_NORMAL_HORDE].size();
+
uint32 hordeIndex = 0;
for (; hordeIndex < hordeCount && m_SelectionPools[TEAM_HORDE].AddGroup((*Horde_itr), hordeFree); hordeIndex++)
++Horde_itr;
//if ofc like BG queue invitation is set in config, then we are happy
- if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == 0)
+ if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) == BG_QUEUE_INVITATION_TYPE_NO_BALANCE)
return;
/*
@@ -649,7 +676,7 @@ bool BattlegroundQueue::CheckNormalMatch(Battleground* /*bg_template*/, Battlegr
uint32 j = TEAM_ALLIANCE;
if (m_SelectionPools[TEAM_HORDE].GetPlayerCount() < m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount())
j = TEAM_HORDE;
- if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) != 0
+ if (sWorld->getIntConfig(CONFIG_BATTLEGROUND_INVITATION_TYPE) != BG_QUEUE_INVITATION_TYPE_NO_BALANCE
&& m_SelectionPools[TEAM_HORDE].GetPlayerCount() >= minPlayers && m_SelectionPools[TEAM_ALLIANCE].GetPlayerCount() >= minPlayers)
{
//we will try to invite more groups to team with less players indexed by j
diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.h b/src/server/game/Battlegrounds/BattlegroundQueue.h
index eb225250a56..2a64e1cb324 100644
--- a/src/server/game/Battlegrounds/BattlegroundQueue.h
+++ b/src/server/game/Battlegrounds/BattlegroundQueue.h
@@ -64,6 +64,13 @@ enum BattlegroundQueueGroupTypes
};
#define BG_QUEUE_GROUP_TYPES_COUNT 4
+enum BattlegroundQueueInvitationType
+{
+ BG_QUEUE_INVITATION_TYPE_NO_BALANCE = 0, // no balance: N+M vs N players
+ BG_QUEUE_INVITATION_TYPE_BALANCED = 1, // teams balanced: N+1 vs N players
+ BG_QUEUE_INVITATION_TYPE_EVEN = 2 // teams even: N vs N players
+};
+
class Battleground;
class BattlegroundQueue
{
diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp
index ff8192e459a..5be39ba60fc 100644
--- a/src/server/game/Chat/Chat.cpp
+++ b/src/server/game/Chat/Chat.cpp
@@ -35,54 +35,16 @@
bool ChatHandler::load_command_table = true;
-// get number of commands in table
-static size_t getCommandTableSize(const ChatCommand* commands)
+std::vector<ChatCommand> const& ChatHandler::getCommandTable()
{
- if (!commands)
- return 0;
- size_t count = 0;
- while (commands[count].Name != NULL)
- count++;
- return count;
-}
-
-// append source command table to target, return number of appended commands
-static size_t appendCommandTable(ChatCommand* target, const ChatCommand* source)
-{
- const size_t count = getCommandTableSize(source);
- if (count)
- memcpy(target, source, count * sizeof(ChatCommand));
- return count;
-}
-
-ChatCommand* ChatHandler::getCommandTable()
-{
- // cache for commands, needed because some commands are loaded dynamically through ScriptMgr
- // cache is never freed and will show as a memory leak in diagnostic tools
- // can't use vector as vector storage is implementation-dependent, eg, there can be alignment gaps between elements
- static ChatCommand* commandTableCache = NULL;
+ static std::vector<ChatCommand> commandTableCache;
if (LoadCommandTable())
{
SetLoadCommandTable(false);
- {
- // count total number of top-level commands
- size_t total = 0;
- std::vector<ChatCommand*> const& dynamic = sScriptMgr->GetChatCommands();
- for (std::vector<ChatCommand*>::const_iterator it = dynamic.begin(); it != dynamic.end(); ++it)
- total += getCommandTableSize(*it);
- total += 1; // ending zero
-
- // cache top-level commands
- size_t added = 0;
- free(commandTableCache);
- commandTableCache = (ChatCommand*)malloc(sizeof(ChatCommand) * total);
- ASSERT(commandTableCache);
- memset(commandTableCache, 0, sizeof(ChatCommand) * total);
- for (std::vector<ChatCommand*>::const_iterator it = dynamic.begin(); it != dynamic.end(); ++it)
- added += appendCommandTable(commandTableCache + added, *it);
- }
+ std::vector<ChatCommand> cmds = sScriptMgr->GetChatCommands();
+ commandTableCache.swap(cmds);
PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_COMMANDS);
PreparedQueryResult result = WorldDatabase.Query(stmt);
@@ -265,7 +227,7 @@ void ChatHandler::SendSysMessage(uint32 entry)
SendSysMessage(GetTrinityString(entry));
}
-bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, std::string const& fullcmd)
+bool ChatHandler::ExecuteCommandInTable(std::vector<ChatCommand> const& table, const char* text, std::string const& fullcmd)
{
char const* oldtext = text;
std::string cmd = "";
@@ -278,7 +240,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
while (*text == ' ') ++text;
- for (uint32 i = 0; table[i].Name != NULL; ++i)
+ for (uint32 i = 0; i < table.size(); ++i)
{
if (!hasStringAbbr(table[i].Name, cmd.c_str()))
continue;
@@ -286,7 +248,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
bool match = false;
if (strlen(table[i].Name) > cmd.length())
{
- for (uint32 j = 0; table[j].Name != NULL; ++j)
+ for (uint32 j = 0; j < table.size(); ++j)
{
if (!hasStringAbbr(table[j].Name, cmd.c_str()))
continue;
@@ -302,7 +264,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
continue;
// select subcommand from child commands list
- if (table[i].ChildCommands != NULL)
+ if (!table[i].ChildCommands.empty())
{
if (!ExecuteCommandInTable(table[i].ChildCommands, text, fullcmd))
{
@@ -367,7 +329,7 @@ bool ChatHandler::ExecuteCommandInTable(ChatCommand* table, const char* text, st
return false;
}
-bool ChatHandler::SetDataForCommandInTable(ChatCommand* table, char const* text, uint32 permission, std::string const& help, std::string const& fullcommand)
+bool ChatHandler::SetDataForCommandInTable(std::vector<ChatCommand>& table, char const* text, uint32 permission, std::string const& help, std::string const& fullcommand)
{
std::string cmd = "";
@@ -379,14 +341,14 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand* table, char const* text,
while (*text == ' ') ++text;
- for (uint32 i = 0; table[i].Name != NULL; i++)
+ for (uint32 i = 0; i < table.size(); i++)
{
// for data fill use full explicit command names
if (table[i].Name != cmd)
continue;
// select subcommand from child commands list (including "")
- if (table[i].ChildCommands != NULL)
+ if (!table[i].ChildCommands.empty())
{
if (SetDataForCommandInTable(table[i].ChildCommands, text, permission, help, fullcommand))
return true;
@@ -413,7 +375,7 @@ bool ChatHandler::SetDataForCommandInTable(ChatCommand* table, char const* text,
// in case "" command let process by caller
if (!cmd.empty())
{
- if (table == getCommandTable())
+ if (&table == &getCommandTable())
TC_LOG_ERROR("sql.sql", "Table `command` have not existed command '%s', skip.", cmd.c_str());
else
TC_LOG_ERROR("sql.sql", "Table `command` have not existed subcommand '%s' in command '%s', skip.", cmd.c_str(), fullcommand.c_str());
@@ -519,10 +481,10 @@ Valid examples:
return LinkExtractor(message).IsValidMessage();
}
-bool ChatHandler::ShowHelpForSubCommands(ChatCommand* table, char const* cmd, char const* subcmd)
+bool ChatHandler::ShowHelpForSubCommands(std::vector<ChatCommand> const& table, char const* cmd, char const* subcmd)
{
std::string list;
- for (uint32 i = 0; table[i].Name != NULL; ++i)
+ for (uint32 i = 0; i < table.size(); ++i)
{
// must be available (ignore handler existence for show command with possible available subcommands)
if (!isAvailable(table[i]))
@@ -539,14 +501,14 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand* table, char const* cmd, ch
list += table[i].Name;
- if (table[i].ChildCommands)
+ if (!table[i].ChildCommands.empty())
list += " ...";
}
if (list.empty())
return false;
- if (table == getCommandTable())
+ if (&table == &getCommandTable())
{
SendSysMessage(LANG_AVIABLE_CMD);
PSendSysMessage("%s", list.c_str());
@@ -557,11 +519,11 @@ bool ChatHandler::ShowHelpForSubCommands(ChatCommand* table, char const* cmd, ch
return true;
}
-bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
+bool ChatHandler::ShowHelpForCommand(std::vector<ChatCommand> const& table, const char* cmd)
{
if (*cmd)
{
- for (uint32 i = 0; table[i].Name != NULL; ++i)
+ for (uint32 i = 0; i < table.size(); ++i)
{
// must be available (ignore handler existence for show command with possible available subcommands)
if (!isAvailable(table[i]))
@@ -573,7 +535,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
// have subcommand
char const* subcmd = (*cmd) ? strtok(NULL, " ") : "";
- if (table[i].ChildCommands && subcmd && *subcmd)
+ if (!table[i].ChildCommands.empty() && subcmd && *subcmd)
{
if (ShowHelpForCommand(table[i].ChildCommands, subcmd))
return true;
@@ -582,7 +544,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
if (!table[i].Help.empty())
SendSysMessage(table[i].Help.c_str());
- if (table[i].ChildCommands)
+ if (!table[i].ChildCommands.empty())
if (ShowHelpForSubCommands(table[i].ChildCommands, table[i].Name, subcmd ? subcmd : ""))
return true;
@@ -591,7 +553,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
}
else
{
- for (uint32 i = 0; table[i].Name != NULL; ++i)
+ for (uint32 i = 0; i < table.size(); ++i)
{
// must be available (ignore handler existence for show command with possible available subcommands)
if (!isAvailable(table[i]))
@@ -603,7 +565,7 @@ bool ChatHandler::ShowHelpForCommand(ChatCommand* table, const char* cmd)
if (!table[i].Help.empty())
SendSysMessage(table[i].Help.c_str());
- if (table[i].ChildCommands)
+ if (!table[i].ChildCommands.empty())
if (ShowHelpForSubCommands(table[i].ChildCommands, "", ""))
return true;
@@ -1053,7 +1015,7 @@ void ChatHandler::extractOptFirstArg(char* args, char** arg1, char** arg2)
char* ChatHandler::extractQuotedArg(char* args)
{
- if (!*args)
+ if (!args || !*args)
return NULL;
if (*args == '"')
diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h
index 34faac68980..9dc232c4010 100644
--- a/src/server/game/Chat/Chat.h
+++ b/src/server/game/Chat/Chat.h
@@ -39,13 +39,18 @@ struct GameTele;
class ChatCommand
{
+ typedef bool(*pHandler)(ChatHandler*, char const*);
+
public:
- const char * Name;
- uint32 Permission; // function pointer required correct align (use uint32)
- bool AllowConsole;
- bool (*Handler)(ChatHandler*, const char* args);
- std::string Help;
- ChatCommand* ChildCommands;
+ ChatCommand(char const* name, uint32 permission, bool allowConsole, pHandler handler, std::string help, std::vector<ChatCommand> childCommands = std::vector<ChatCommand>())
+ : Name(ASSERT_NOTNULL(name)), Permission(permission), AllowConsole(allowConsole), Handler(handler), Help(std::move(help)), ChildCommands(std::move(childCommands)) { }
+
+ char const* Name;
+ uint32 Permission; // function pointer required correct align (use uint32)
+ bool AllowConsole;
+ pHandler Handler;
+ std::string Help;
+ std::vector<ChatCommand> ChildCommands;
};
class ChatHandler
@@ -83,7 +88,7 @@ class ChatHandler
bool ParseCommands(const char* text);
- static ChatCommand* getCommandTable();
+ static std::vector<ChatCommand> const& getCommandTable();
bool isValidChatMessage(const char* msg);
void SendGlobalSysMessage(const char *str);
@@ -134,12 +139,12 @@ class ChatHandler
static bool LoadCommandTable() { return load_command_table; }
static void SetLoadCommandTable(bool val) { load_command_table = val; }
- bool ShowHelpForCommand(ChatCommand* table, const char* cmd);
+ bool ShowHelpForCommand(std::vector<ChatCommand> const& table, const char* cmd);
protected:
explicit ChatHandler() : m_session(NULL), sentErrorMessage(false) { } // for CLI subclass
- static bool SetDataForCommandInTable(ChatCommand* table, const char* text, uint32 permission, std::string const& help, std::string const& fullcommand);
- bool ExecuteCommandInTable(ChatCommand* table, const char* text, std::string const& fullcmd);
- bool ShowHelpForSubCommands(ChatCommand* table, char const* cmd, char const* subcmd);
+ static bool SetDataForCommandInTable(std::vector<ChatCommand>& table, const char* text, uint32 permission, std::string const& help, std::string const& fullcommand);
+ bool ExecuteCommandInTable(std::vector<ChatCommand> const& table, const char* text, std::string const& fullcmd);
+ bool ShowHelpForSubCommands(std::vector<ChatCommand> const& table, char const* cmd, char const* subcmd);
private:
WorldSession* m_session; // != NULL for chat command call and NULL for CLI command
diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp
index dd3f3244f5b..2c31a61f5cd 100644
--- a/src/server/game/Conditions/ConditionMgr.cpp
+++ b/src/server/game/Conditions/ConditionMgr.cpp
@@ -28,7 +28,7 @@
#include "SpellAuras.h"
#include "SpellMgr.h"
-char const* ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
+char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] =
{
"None",
"Creature Loot",
@@ -107,7 +107,7 @@ ConditionMgr::ConditionTypeInfo const ConditionMgr::StaticConditionTypeData[COND
// Checks if object meets the condition
// Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: SmartAI)
-bool Condition::Meets(ConditionSourceInfo& sourceInfo)
+bool Condition::Meets(ConditionSourceInfo& sourceInfo) const
{
ASSERT(ConditionTarget < MAX_CONDITION_TARGETS);
WorldObject* object = sourceInfo.mConditionTargets[ConditionTarget];
@@ -326,7 +326,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
Unit* unit = object->ToUnit();
if (toUnit && unit)
{
- switch (ConditionValue2)
+ switch (static_cast<RelationType>(ConditionValue2))
{
case RELATION_SELF:
condMeets = unit == toUnit;
@@ -346,6 +346,8 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
case RELATION_CREATED_BY:
condMeets = unit->GetCreatorGUID() == toUnit->GetGUID();
break;
+ default:
+ break;
}
}
}
@@ -452,7 +454,7 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo)
return condMeets && script;
}
-uint32 Condition::GetSearcherTypeMaskForCondition()
+uint32 Condition::GetSearcherTypeMaskForCondition() const
{
// build mask of types for which condition can return true
// this is used for speeding up gridsearches
@@ -622,7 +624,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition()
return mask;
}
-uint32 Condition::GetMaxAvailableConditionTargets()
+uint32 Condition::GetMaxAvailableConditionTargets() const
{
// returns number of targets which are available for given source type
switch (SourceType)
@@ -678,114 +680,105 @@ ConditionMgr::~ConditionMgr()
Clean();
}
-ConditionList ConditionMgr::GetConditionReferences(uint32 refId)
-{
- ConditionList conditions;
- ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(refId);
- if (ref != ConditionReferenceStore.end())
- conditions = (*ref).second;
- return conditions;
-}
-
-uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionList const& conditions)
+uint32 ConditionMgr::GetSearcherTypeMaskForConditionList(ConditionContainer const& conditions) const
{
if (conditions.empty())
return GRID_MAP_TYPE_MASK_ALL;
// groupId, typeMask
- std::map<uint32, uint32> ElseGroupStore;
- for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
+ std::map<uint32, uint32> elseGroupSearcherTypeMasks;
+ for (ConditionContainer::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
{
// no point of having not loaded conditions in list
ASSERT((*i)->isLoaded() && "ConditionMgr::GetSearcherTypeMaskForConditionList - not yet loaded condition found in list");
- std::map<uint32, uint32>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
+ std::map<uint32, uint32>::const_iterator itr = elseGroupSearcherTypeMasks.find((*i)->ElseGroup);
// group not filled yet, fill with widest mask possible
- if (itr == ElseGroupStore.end())
- ElseGroupStore[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
+ if (itr == elseGroupSearcherTypeMasks.end())
+ elseGroupSearcherTypeMasks[(*i)->ElseGroup] = GRID_MAP_TYPE_MASK_ALL;
// no point of checking anymore, empty mask
- else if (!(*itr).second)
+ else if (!itr->second)
continue;
if ((*i)->ReferenceId) // handle reference
{
ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
ASSERT(ref != ConditionReferenceStore.end() && "ConditionMgr::GetSearcherTypeMaskForConditionList - incorrect reference");
- ElseGroupStore[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
+ elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= GetSearcherTypeMaskForConditionList((*ref).second);
}
else // handle normal condition
{
// object will match conditions in one ElseGroupStore only when it matches all of them
// so, let's find a smallest possible mask which satisfies all conditions
- ElseGroupStore[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
+ elseGroupSearcherTypeMasks[(*i)->ElseGroup] &= (*i)->GetSearcherTypeMaskForCondition();
}
}
// object will match condition when one of the checks in ElseGroupStore is matching
// so, let's include all possible masks
uint32 mask = 0;
- for (std::map<uint32, uint32>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
+ for (std::map<uint32, uint32>::const_iterator i = elseGroupSearcherTypeMasks.begin(); i != elseGroupSearcherTypeMasks.end(); ++i)
mask |= i->second;
return mask;
}
-bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
+bool ConditionMgr::IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const
{
// groupId, groupCheckPassed
- std::map<uint32, bool> ElseGroupStore;
- for (ConditionList::const_iterator i = conditions.begin(); i != conditions.end(); ++i)
+ std::map<uint32, bool> elseGroupStore;
+ for (Condition const* condition : conditions)
{
- TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", (*i)->ToString().c_str(), (*i)->ConditionValue1);
- if ((*i)->isLoaded())
+ TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s val1: %u", condition->ToString().c_str(), condition->ConditionValue1);
+ if (condition->isLoaded())
{
//! Find ElseGroup in ElseGroupStore
- std::map<uint32, bool>::const_iterator itr = ElseGroupStore.find((*i)->ElseGroup);
+ std::map<uint32, bool>::const_iterator itr = elseGroupStore.find(condition->ElseGroup);
//! If not found, add an entry in the store and set to true (placeholder)
- if (itr == ElseGroupStore.end())
- ElseGroupStore[(*i)->ElseGroup] = true;
+ if (itr == elseGroupStore.end())
+ elseGroupStore[condition->ElseGroup] = true;
else if (!(*itr).second)
continue;
- if ((*i)->ReferenceId)//handle reference
+ if (condition->ReferenceId)//handle reference
{
- ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find((*i)->ReferenceId);
+ ConditionReferenceContainer::const_iterator ref = ConditionReferenceStore.find(condition->ReferenceId);
if (ref != ConditionReferenceStore.end())
{
- if (!IsObjectMeetToConditionList(sourceInfo, (*ref).second))
- ElseGroupStore[(*i)->ElseGroup] = false;
+ if (!IsObjectMeetToConditionList(sourceInfo, ref->second))
+ elseGroupStore[condition->ElseGroup] = false;
}
else
{
TC_LOG_DEBUG("condition", "ConditionMgr::IsPlayerMeetToConditionList %s Reference template -%u not found",
- (*i)->ToString().c_str(), (*i)->ReferenceId); // checked at loading, should never happen
+ condition->ToString().c_str(), condition->ReferenceId); // checked at loading, should never happen
}
}
else //handle normal condition
{
- if (!(*i)->Meets(sourceInfo))
- ElseGroupStore[(*i)->ElseGroup] = false;
+ if (!condition->Meets(sourceInfo))
+ elseGroupStore[condition->ElseGroup] = false;
}
}
}
- for (std::map<uint32, bool>::const_iterator i = ElseGroupStore.begin(); i != ElseGroupStore.end(); ++i)
+ for (std::map<uint32, bool>::const_iterator i = elseGroupStore.begin(); i != elseGroupStore.end(); ++i)
if (i->second)
return true;
return false;
}
-bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions)
+bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object, ConditionContainer const& conditions) const
{
ConditionSourceInfo srcInfo = ConditionSourceInfo(object);
return IsObjectMeetToConditions(srcInfo, conditions);
}
-bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions)
+bool ConditionMgr::IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionContainer const& conditions) const
{
ConditionSourceInfo srcInfo = ConditionSourceInfo(object1, object2);
return IsObjectMeetToConditions(srcInfo, conditions);
}
-bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions)
+bool ConditionMgr::IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const
{
if (conditions.empty())
return true;
@@ -814,7 +807,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType)
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
- sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
+ sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR ||
+ sourceType == CONDITION_SOURCE_TYPE_PHASE);
}
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
@@ -822,87 +816,114 @@ bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType)
return (sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
}
-ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry)
+bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, ConditionSourceInfo& sourceInfo) const
{
- ConditionList spellCond;
if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
{
- ConditionContainer::const_iterator itr = ConditionStore.find(sourceType);
- if (itr != ConditionStore.end())
+ ConditionsByEntryMap::const_iterator i = ConditionStore[sourceType].find(entry);
+ if (i != ConditionStore[sourceType].end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(entry);
- if (i != (*itr).second.end())
- {
- spellCond = (*i).second;
- TC_LOG_DEBUG("condition", "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u", uint32(sourceType), entry);
- }
+ TC_LOG_DEBUG("condition", "GetConditionsForNotGroupedEntry: found conditions for type %u and entry %u", uint32(sourceType), entry);
+ return IsObjectMeetToConditions(sourceInfo, i->second);
}
}
- return spellCond;
+
+ return true;
+}
+
+bool ConditionMgr::IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, WorldObject* target0, WorldObject* target1 /*= nullptr*/, WorldObject* target2 /*= nullptr*/) const
+{
+ ConditionSourceInfo conditionSource(target0, target1, target2);
+ return IsObjectMeetingNotGroupedConditions(sourceType, entry, conditionSource);
}
-ConditionList ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId)
+bool ConditionMgr::HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const
{
- ConditionList cond;
- CreatureSpellConditionContainer::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
+ ConditionContainer spellCond;
+ if (sourceType > CONDITION_SOURCE_TYPE_NONE && sourceType < CONDITION_SOURCE_TYPE_MAX)
+ if (ConditionStore[sourceType].find(entry) != ConditionStore[sourceType].end())
+ return true;
+
+ return false;
+}
+
+bool ConditionMgr::IsObjectMeetingSpellClickConditions(uint32 creatureId, uint32 spellId, WorldObject* clicker, WorldObject* target) const
+{
+ ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
if (itr != SpellClickEventConditionStore.end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
- if (i != (*itr).second.end())
+ ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
+ if (i != itr->second.end())
{
- cond = (*i).second;
TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId);
+ ConditionSourceInfo sourceInfo(clicker, target);
+ return IsObjectMeetToConditions(sourceInfo, i->second);
}
}
- return cond;
+ return true;
}
-ConditionList ConditionMgr::GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId)
+ConditionContainer const* ConditionMgr::GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const
{
- ConditionList cond;
- CreatureSpellConditionContainer::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
+ ConditionEntriesByCreatureIdMap::const_iterator itr = SpellClickEventConditionStore.find(creatureId);
+ if (itr != SpellClickEventConditionStore.end())
+ {
+ ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
+ if (i != itr->second.end())
+ {
+ TC_LOG_DEBUG("condition", "GetConditionsForSpellClickEvent: found conditions for SpellClickEvent entry %u spell %u", creatureId, spellId);
+ return &i->second;
+ }
+ }
+ return nullptr;
+}
+
+bool ConditionMgr::IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player* player, Unit* vehicle) const
+{
+ ConditionEntriesByCreatureIdMap::const_iterator itr = VehicleSpellConditionStore.find(creatureId);
if (itr != VehicleSpellConditionStore.end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(spellId);
- if (i != (*itr).second.end())
+ ConditionsByEntryMap::const_iterator i = itr->second.find(spellId);
+ if (i != itr->second.end())
{
- cond = (*i).second;
TC_LOG_DEBUG("condition", "GetConditionsForVehicleSpell: found conditions for Vehicle entry %u spell %u", creatureId, spellId);
+ ConditionSourceInfo sourceInfo(player, vehicle);
+ return IsObjectMeetToConditions(sourceInfo, i->second);
}
}
- return cond;
+ return true;
}
-ConditionList ConditionMgr::GetConditionsForSmartEvent(int64 entryOrGuid, uint32 eventId, uint32 sourceType)
+bool ConditionMgr::IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const
{
- ConditionList cond;
SmartEventConditionContainer::const_iterator itr = SmartEventConditionStore.find(std::make_pair(entryOrGuid, sourceType));
if (itr != SmartEventConditionStore.end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(eventId + 1);
- if (i != (*itr).second.end())
+ ConditionsByEntryMap::const_iterator i = itr->second.find(eventId + 1);
+ if (i != itr->second.end())
{
- cond = (*i).second;
TC_LOG_DEBUG("condition", "GetConditionsForSmartEvent: found conditions for Smart Event entry or guid " SI64FMTD " eventId %u", entryOrGuid, eventId);
+ ConditionSourceInfo sourceInfo(unit, baseObject);
+ return IsObjectMeetToConditions(sourceInfo, i->second);
}
}
- return cond;
+ return true;
}
-ConditionList ConditionMgr::GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId)
+bool ConditionMgr::IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const
{
- ConditionList cond;
- NpcVendorConditionContainer::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId);
+ ConditionEntriesByCreatureIdMap::const_iterator itr = NpcVendorConditionContainerStore.find(creatureId);
if (itr != NpcVendorConditionContainerStore.end())
{
- ConditionTypeContainer::const_iterator i = (*itr).second.find(itemId);
+ ConditionsByEntryMap::const_iterator i = (*itr).second.find(itemId);
if (i != (*itr).second.end())
{
- cond = (*i).second;
TC_LOG_DEBUG("condition", "GetConditionsForNpcVendorEvent: found conditions for creature entry %u item %u", creatureId, itemId);
+ ConditionSourceInfo sourceInfo(player, vendor);
+ return IsObjectMeetToConditions(sourceInfo, i->second);
}
}
- return cond;
+ return true;
}
void ConditionMgr::LoadConditions(bool isReload)
@@ -934,6 +955,18 @@ void ConditionMgr::LoadConditions(bool isReload)
TC_LOG_INFO("misc", "Re-Loading `gossip_menu_option` Table for Conditions!");
sObjectMgr->LoadGossipMenuItems();
sSpellMgr->UnloadSpellInfoImplicitTargetConditionLists();
+
+ TC_LOG_INFO("misc", "Re-Loading `terrain_phase_info` Table for Conditions!");
+ sObjectMgr->LoadTerrainPhaseInfo();
+
+ TC_LOG_INFO("misc", "Re-Loading `terrain_swap_defaults` Table for Conditions!");
+ sObjectMgr->LoadTerrainSwapDefaults();
+
+ TC_LOG_INFO("misc", "Re-Loading `terrain_worldmap` Table for Conditions!");
+ sObjectMgr->LoadTerrainWorldMaps();
+
+ TC_LOG_INFO("misc", "Re-Loading `phase_area` Table for Conditions!");
+ sObjectMgr->LoadAreaPhases();
}
QueryResult result = WorldDatabase.Query("SELECT SourceTypeOrReferenceId, SourceGroup, SourceEntry, SourceId, ElseGroup, ConditionTypeOrReference, ConditionTarget, "
@@ -965,7 +998,7 @@ void ConditionMgr::LoadConditions(bool isReload)
cond->NegativeCondition = fields[10].GetBool();
cond->ErrorType = fields[11].GetUInt32();
cond->ErrorTextId = fields[12].GetUInt32();
- cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetCString());
+ cond->ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
if (iConditionTypeOrReference >= 0)
cond->ConditionType = ConditionTypes(iConditionTypeOrReference);
@@ -1010,14 +1043,8 @@ void ConditionMgr::LoadConditions(bool isReload)
if (iSourceTypeOrReferenceId < 0)//it is a reference template
{
- uint32 uRefId = abs(iSourceTypeOrReferenceId);
- if (ConditionReferenceStore.find(uRefId) == ConditionReferenceStore.end())//make sure we have a list for our conditions, based on reference id
- {
- ConditionList mCondList;
- ConditionReferenceStore[uRefId] = mCondList;
- }
- ConditionReferenceStore[uRefId].push_back(cond);//add to reference storage
- count++;
+ ConditionReferenceStore[std::abs(iSourceTypeOrReferenceId)].push_back(cond);//add to reference storage
+ ++count;
continue;
}//end of reference templates
@@ -1135,6 +1162,9 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
+ case CONDITION_SOURCE_TYPE_PHASE:
+ valid = addToPhases(cond);
+ break;
default:
break;
}
@@ -1151,22 +1181,19 @@ void ConditionMgr::LoadConditions(bool isReload)
}
continue;
}
-
- //handle not grouped conditions
- //make sure we have a storage list for our SourceType
- if (ConditionStore.find(cond->SourceType) == ConditionStore.end())
+ else if (cond->SourceType == CONDITION_SOURCE_TYPE_TERRAIN_SWAP)
{
- ConditionTypeContainer mTypeMap;
- ConditionStore[cond->SourceType] = mTypeMap;//add new empty list for SourceType
- }
+ if (!addToTerrainSwaps(cond))
+ {
+ delete cond;
+ continue;
+ }
- //make sure we have a condition list for our SourceType's entry
- if (ConditionStore[cond->SourceType].find(cond->SourceEntry) == ConditionStore[cond->SourceType].end())
- {
- ConditionList mCondList;
- ConditionStore[cond->SourceType][cond->SourceEntry] = mCondList;
+ ++count;
+ continue;
}
+ //handle not grouped conditions
//add new Condition to storage based on Type/Entry
ConditionStore[cond->SourceType][cond->SourceEntry].push_back(cond);
++count;
@@ -1176,7 +1203,7 @@ void ConditionMgr::LoadConditions(bool isReload)
TC_LOG_INFO("server.loading", ">> Loaded %u conditions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
-bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot)
+bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot) const
{
if (!loot)
{
@@ -1191,7 +1218,7 @@ bool ConditionMgr::addToLootTemplate(Condition* cond, LootTemplate* loot)
return false;
}
-bool ConditionMgr::addToGossipMenus(Condition* cond)
+bool ConditionMgr::addToGossipMenus(Condition* cond) const
{
GossipMenusMapBoundsNonConst pMenuBounds = sObjectMgr->GetGossipMenusMapBoundsNonConst(cond->SourceGroup);
@@ -1211,7 +1238,7 @@ bool ConditionMgr::addToGossipMenus(Condition* cond)
return false;
}
-bool ConditionMgr::addToGossipMenuItems(Condition* cond)
+bool ConditionMgr::addToGossipMenuItems(Condition* cond) const
{
GossipMenuItemsMapBoundsNonConst pMenuItemBounds = sObjectMgr->GetGossipMenuItemsMapBoundsNonConst(cond->SourceGroup);
if (pMenuItemBounds.first != pMenuItemBounds.second)
@@ -1230,7 +1257,7 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond)
return false;
}
-bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
+bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond) const
{
uint32 conditionEffMask = cond->SourceGroup;
SpellInfo* spellInfo = const_cast<SpellInfo*>(sSpellMgr->AssertSpellInfo(cond->SourceEntry));
@@ -1257,7 +1284,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
// build new shared mask with found effect
uint32 sharedMask = 1 << i;
- ConditionList* cmp = effect->ImplicitTargetConditions;
+ ConditionContainer* cmp = effect->ImplicitTargetConditions;
for (uint8 effIndex = i + 1; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
{
SpellEffectInfo const* inner = spellInfo->GetEffect(DIFFICULTY_NONE, effIndex);
@@ -1289,7 +1316,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
continue;
// get shared data
- ConditionList* sharedList = effect->ImplicitTargetConditions;
+ ConditionContainer* sharedList = effect->ImplicitTargetConditions;
// there's already data entry for that sharedMask
if (sharedList)
@@ -1306,7 +1333,7 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
else
{
// add new list, create new shared mask
- sharedList = new ConditionList();
+ sharedList = new ConditionContainer();
bool assigned = false;
for (uint8 i = firstEffIndex; i < MAX_SPELL_EFFECTS; ++i)
{
@@ -1334,7 +1361,63 @@ bool ConditionMgr::addToSpellImplicitTargetConditions(Condition* cond)
return true;
}
-bool ConditionMgr::isSourceTypeValid(Condition* cond)
+static bool addToTerrainSwapStore(TerrainPhaseInfo& swaps, Condition* cond)
+{
+ bool added = false;
+ for (auto itr = swaps.begin(); itr != swaps.end(); ++itr)
+ for (auto it2 = itr->second.begin(); it2 != itr->second.end(); ++it2)
+ if (it2->Id == uint32(cond->SourceEntry))
+ it2->Conditions.push_back(cond), added = true;
+
+ return added;
+}
+
+bool ConditionMgr::addToTerrainSwaps(Condition* cond) const
+{
+ bool added = false;
+ added = addToTerrainSwapStore(sObjectMgr->GetPhaseTerrainSwapStoreForLoading(), cond);
+ added = addToTerrainSwapStore(sObjectMgr->GetDefaultTerrainSwapStoreForLoading(), cond) || added;
+ if (added)
+ return true;
+
+ TC_LOG_ERROR("sql.sql", "%s No terrain swap with map %u exists.", cond->ToString().c_str(), cond->SourceEntry);
+ return false;
+}
+
+bool ConditionMgr::addToPhases(Condition* cond) const
+{
+ if (!cond->SourceEntry)
+ {
+ PhaseInfo& p = sObjectMgr->GetAreaPhasesForLoading();
+ for (auto phaseItr = p.begin(); phaseItr != p.end(); ++phaseItr)
+ {
+ for (PhaseInfoStruct& phase : phaseItr->second)
+ {
+ if (phase.Id == cond->SourceGroup)
+ {
+ phase.Conditions.push_back(cond);
+ return true;
+ }
+ }
+ }
+ }
+ else if (std::vector<PhaseInfoStruct>* phases = sObjectMgr->GetPhasesForAreaForLoading(cond->SourceEntry))
+ {
+ for (PhaseInfoStruct& phase : *phases)
+ {
+ if (phase.Id == cond->SourceGroup)
+ {
+ phase.Conditions.push_back(cond);
+ return true;
+ }
+ }
+ }
+
+ TC_LOG_ERROR("sql.sql", "%s Area %u does not have phase %u.", cond->ToString().c_str(), cond->SourceGroup, cond->SourceEntry);
+ return false;
+}
+
+bool ConditionMgr::isSourceTypeValid(Condition* cond) const
{
if (cond->SourceType == CONDITION_SOURCE_TYPE_NONE || cond->SourceType >= CONDITION_SOURCE_TYPE_MAX)
{
@@ -1674,12 +1757,28 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
break;
}
+ case CONDITION_SOURCE_TYPE_TERRAIN_SWAP:
+ {
+ if (!sMapStore.LookupEntry(cond->SourceEntry))
+ {
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in Map.dbc, ignoring.", cond->ToString().c_str());
+ return false;
+ }
+ break;
+ }
+ case CONDITION_SOURCE_TYPE_PHASE:
+ {
+ if (cond->SourceEntry && !GetAreaEntryByAreaID(cond->SourceEntry))
+ {
+ TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in AreaTable.dbc, ignoring.", cond->ToString().c_str());
+ return false;
+ }
+ break;
+ }
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
case CONDITION_SOURCE_TYPE_NONE:
- case CONDITION_SOURCE_TYPE_TERRAIN_SWAP:
- case CONDITION_SOURCE_TYPE_PHASE:
default:
break;
}
@@ -1687,7 +1786,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return true;
}
-bool ConditionMgr::isConditionTypeValid(Condition* cond)
+bool ConditionMgr::isConditionTypeValid(Condition* cond) const
{
if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX)
{
@@ -2154,81 +2253,50 @@ void ConditionMgr::LogUselessConditionValue(Condition* cond, uint8 index, uint32
void ConditionMgr::Clean()
{
for (ConditionReferenceContainer::iterator itr = ConditionReferenceStore.begin(); itr != ConditionReferenceStore.end(); ++itr)
- {
- for (ConditionList::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it)
delete *it;
- itr->second.clear();
- }
ConditionReferenceStore.clear();
- for (ConditionContainer::iterator itr = ConditionStore.begin(); itr != ConditionStore.end(); ++itr)
+ for (uint32 i = 0; i < CONDITION_SOURCE_TYPE_MAX; ++i)
{
- for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- {
- for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
- delete *i;
- it->second.clear();
- }
- itr->second.clear();
- }
+ for (ConditionsByEntryMap::iterator it = ConditionStore[i].begin(); it != ConditionStore[i].end(); ++it)
+ for (ConditionContainer::const_iterator itr = it->second.begin(); itr != it->second.end(); ++itr)
+ delete *itr;
- ConditionStore.clear();
+ ConditionStore[i].clear();
+ }
- for (CreatureSpellConditionContainer::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
- {
- for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- {
- for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ for (ConditionEntriesByCreatureIdMap::iterator itr = VehicleSpellConditionStore.begin(); itr != VehicleSpellConditionStore.end(); ++itr)
+ for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
- it->second.clear();
- }
- itr->second.clear();
- }
VehicleSpellConditionStore.clear();
for (SmartEventConditionContainer::iterator itr = SmartEventConditionStore.begin(); itr != SmartEventConditionStore.end(); ++itr)
- {
- for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- {
- for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
- it->second.clear();
- }
- itr->second.clear();
- }
SmartEventConditionStore.clear();
- for (CreatureSpellConditionContainer::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
- {
- for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- {
- for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ for (ConditionEntriesByCreatureIdMap::iterator itr = SpellClickEventConditionStore.begin(); itr != SpellClickEventConditionStore.end(); ++itr)
+ for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
- it->second.clear();
- }
- itr->second.clear();
- }
SpellClickEventConditionStore.clear();
- for (NpcVendorConditionContainer::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
- {
- for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
- {
- for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
+ for (ConditionEntriesByCreatureIdMap::iterator itr = NpcVendorConditionContainerStore.begin(); itr != NpcVendorConditionContainerStore.end(); ++itr)
+ for (ConditionsByEntryMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
+ for (ConditionContainer::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
- it->second.clear();
- }
- itr->second.clear();
- }
NpcVendorConditionContainerStore.clear();
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
- for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
+ for (std::vector<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
delete *itr;
AllocatedMemoryStore.clear();
diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h
index 3549b1f2515..d33b7edffce 100644
--- a/src/server/game/Conditions/ConditionMgr.h
+++ b/src/server/game/Conditions/ConditionMgr.h
@@ -19,12 +19,9 @@
#ifndef TRINITY_CONDITIONMGR_H
#define TRINITY_CONDITIONMGR_H
-#include "Define.h"
-#include "Errors.h"
-#include <list>
-#include <map>
-#include <string>
+#include "Common.h"
+class Creature;
class Player;
class Unit;
class WorldObject;
@@ -183,13 +180,13 @@ enum MaxConditionTargets
struct ConditionSourceInfo
{
WorldObject* mConditionTargets[MAX_CONDITION_TARGETS]; // an array of targets available for conditions
- Condition* mLastFailedCondition;
- ConditionSourceInfo(WorldObject* target0, WorldObject* target1 = NULL, WorldObject* target2 = NULL)
+ Condition const* mLastFailedCondition;
+ ConditionSourceInfo(WorldObject* target0, WorldObject* target1 = nullptr, WorldObject* target2 = nullptr)
{
mConditionTargets[0] = target0;
mConditionTargets[1] = target1;
mConditionTargets[2] = target2;
- mLastFailedCondition = NULL;
+ mLastFailedCondition = nullptr;
}
};
@@ -230,22 +227,20 @@ struct Condition
NegativeCondition = false;
}
- bool Meets(ConditionSourceInfo& sourceInfo);
- uint32 GetSearcherTypeMaskForCondition();
+ bool Meets(ConditionSourceInfo& sourceInfo) const;
+ uint32 GetSearcherTypeMaskForCondition() const;
bool isLoaded() const { return ConditionType > CONDITION_NONE || ReferenceId; }
- uint32 GetMaxAvailableConditionTargets();
+ uint32 GetMaxAvailableConditionTargets() const;
std::string ToString(bool ext = false) const; /// For logging purpose
};
-typedef std::list<Condition*> ConditionList;
-typedef std::map<uint32, ConditionList> ConditionTypeContainer;
-typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer;
-typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer;
-typedef std::map<uint32, ConditionTypeContainer> NpcVendorConditionContainer;
-typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
-
-typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
+typedef std::vector<Condition*> ConditionContainer;
+typedef std::unordered_map<uint32 /*SourceEntry*/, ConditionContainer> ConditionsByEntryMap;
+typedef std::array<ConditionsByEntryMap, CONDITION_SOURCE_TYPE_MAX> ConditionEntriesByTypeArray;
+typedef std::unordered_map<uint32, ConditionsByEntryMap> ConditionEntriesByCreatureIdMap;
+typedef std::unordered_map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionsByEntryMap> SmartEventConditionContainer;
+typedef std::unordered_map<uint32, ConditionContainer> ConditionReferenceContainer;//only used for references
class ConditionMgr
{
@@ -261,20 +256,22 @@ class ConditionMgr
}
void LoadConditions(bool isReload = false);
- bool isConditionTypeValid(Condition* cond);
- ConditionList GetConditionReferences(uint32 refId);
+ bool isConditionTypeValid(Condition* cond) const;
- uint32 GetSearcherTypeMaskForConditionList(ConditionList const& conditions);
- bool IsObjectMeetToConditions(WorldObject* object, ConditionList const& conditions);
- bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionList const& conditions);
- bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
+ uint32 GetSearcherTypeMaskForConditionList(ConditionContainer const& conditions) const;
+ bool IsObjectMeetToConditions(WorldObject* object, ConditionContainer const& conditions) const;
+ bool IsObjectMeetToConditions(WorldObject* object1, WorldObject* object2, ConditionContainer const& conditions) const;
+ bool IsObjectMeetToConditions(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const;
static bool CanHaveSourceGroupSet(ConditionSourceType sourceType);
static bool CanHaveSourceIdSet(ConditionSourceType sourceType);
- ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry);
- ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
- ConditionList GetConditionsForSmartEvent(int64 entryOrGuid, uint32 eventId, uint32 sourceType);
- ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
- ConditionList GetConditionsForNpcVendorEvent(uint32 creatureId, uint32 itemId);
+ bool IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, ConditionSourceInfo& sourceInfo) const;
+ bool IsObjectMeetingNotGroupedConditions(ConditionSourceType sourceType, uint32 entry, WorldObject* target0, WorldObject* target1 = nullptr, WorldObject* target2 = nullptr) const;
+ bool HasConditionsForNotGroupedEntry(ConditionSourceType sourceType, uint32 entry) const;
+ bool IsObjectMeetingSpellClickConditions(uint32 creatureId, uint32 spellId, WorldObject* clicker, WorldObject* target) const;
+ ConditionContainer const* GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId) const;
+ bool IsObjectMeetingVehicleSpellConditions(uint32 creatureId, uint32 spellId, Player* player, Unit* vehicle) const;
+ bool IsObjectMeetingSmartEventConditions(int64 entryOrGuid, uint32 eventId, uint32 sourceType, Unit* unit, WorldObject* baseObject) const;
+ bool IsObjectMeetingVendorItemConditions(uint32 creatureId, uint32 itemId, Player* player, Creature* vendor) const;
struct ConditionTypeInfo
{
@@ -283,28 +280,30 @@ class ConditionMgr
bool HasConditionValue2;
bool HasConditionValue3;
};
- static char const* StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
+ static char const* const StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX];
static ConditionTypeInfo const StaticConditionTypeData[CONDITION_MAX];
private:
- bool isSourceTypeValid(Condition* cond);
- bool addToLootTemplate(Condition* cond, LootTemplate* loot);
- bool addToGossipMenus(Condition* cond);
- bool addToGossipMenuItems(Condition* cond);
- bool addToSpellImplicitTargetConditions(Condition* cond);
- bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionList const& conditions);
+ bool isSourceTypeValid(Condition* cond) const;
+ bool addToLootTemplate(Condition* cond, LootTemplate* loot) const;
+ bool addToGossipMenus(Condition* cond) const;
+ bool addToGossipMenuItems(Condition* cond) const;
+ bool addToSpellImplicitTargetConditions(Condition* cond) const;
+ bool addToTerrainSwaps(Condition* cond) const;
+ bool addToPhases(Condition* cond) const;
+ bool IsObjectMeetToConditionList(ConditionSourceInfo& sourceInfo, ConditionContainer const& conditions) const;
static void LogUselessConditionValue(Condition* cond, uint8 index, uint32 value);
void Clean(); // free up resources
- std::list<Condition*> AllocatedMemoryStore; // some garbage collection :)
-
- ConditionContainer ConditionStore;
- ConditionReferenceContainer ConditionReferenceStore;
- CreatureSpellConditionContainer VehicleSpellConditionStore;
- CreatureSpellConditionContainer SpellClickEventConditionStore;
- NpcVendorConditionContainer NpcVendorConditionContainerStore;
- SmartEventConditionContainer SmartEventConditionStore;
+ std::vector<Condition*> AllocatedMemoryStore; // some garbage collection :)
+
+ ConditionEntriesByTypeArray ConditionStore;
+ ConditionReferenceContainer ConditionReferenceStore;
+ ConditionEntriesByCreatureIdMap VehicleSpellConditionStore;
+ ConditionEntriesByCreatureIdMap SpellClickEventConditionStore;
+ ConditionEntriesByCreatureIdMap NpcVendorConditionContainerStore;
+ SmartEventConditionContainer SmartEventConditionStore;
};
#define sConditionMgr ConditionMgr::instance()
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h
index 6a230bc9d1e..cf1933c5877 100644
--- a/src/server/game/DataStores/DBCEnums.h
+++ b/src/server/game/DataStores/DBCEnums.h
@@ -527,14 +527,18 @@ enum ItemExtendedCostFlags
enum ItemBonusType
{
- ITEM_BONUS_ITEM_LEVEL = 1,
- ITEM_BONUS_STAT = 2,
- ITEM_BONUS_QUALITY = 3,
- ITEM_BONUS_DESCRIPTION = 4,
- ITEM_BONUS_SUFFIX = 5,
- ITEM_BONUS_SOCKET = 6,
- ITEM_BONUS_APPEARANCE = 7,
- ITEM_BONUS_REQUIRED_LEVEL = 8,
+ ITEM_BONUS_ITEM_LEVEL = 1,
+ ITEM_BONUS_STAT = 2,
+ ITEM_BONUS_QUALITY = 3,
+ ITEM_BONUS_DESCRIPTION = 4,
+ ITEM_BONUS_SUFFIX = 5,
+ ITEM_BONUS_SOCKET = 6,
+ ITEM_BONUS_APPEARANCE = 7,
+ ITEM_BONUS_REQUIRED_LEVEL = 8,
+ ITEM_BONUS_DISPLAY_TOAST_METHOD = 9,
+ ITEM_BONUS_REPAIR_COST_MULTIPLIER = 10,
+ ITEM_BONUS_SCALING_STAT_DISTRIBUTION = 11,
+ ITEM_BONUS_UNK_12 = 12
};
enum ItemLimitCategoryMode
diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp
index 68798d43e38..0e835e02dc2 100644
--- a/src/server/game/DungeonFinding/LFGMgr.cpp
+++ b/src/server/game/DungeonFinding/LFGMgr.cpp
@@ -1273,14 +1273,6 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*
if (player->GetMapId() == uint32(dungeon->map))
player->TeleportToBGEntryPoint();
- // in the case were we are the last in lfggroup then we must disband when porting out of the instance
- if (group && group->GetMembersCount() == 1)
- {
- group->Disband();
- TC_LOG_DEBUG("lfg.teleport", "Player %s is last in lfggroup so we disband the group.",
- player->GetName().c_str());
- }
-
return;
}
diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp
index 42e1f4a545f..224cec71d86 100644
--- a/src/server/game/DungeonFinding/LFGScripts.cpp
+++ b/src/server/game/DungeonFinding/LFGScripts.cpp
@@ -101,7 +101,17 @@ void LFGPlayerScript::OnMapChanged(Player* player)
player->CastSpell(player, LFG_SPELL_LUCK_OF_THE_DRAW, true);
}
else
+ {
+ Group* group = player->GetGroup();
+ if (group && group->GetMembersCount() == 1)
+ {
+ sLFGMgr->LeaveLfg(group->GetGUID());
+ group->Disband();
+ TC_LOG_DEBUG("lfg", "LFGPlayerScript::OnMapChanged, Player %s(%s) is last in the lfggroup so we disband the group.",
+ player->GetName().c_str(), player->GetGUID().ToString().c_str());
+ }
player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW);
+ }
}
LFGGroupScript::LFGGroupScript() : GroupScript("LFGGroupScript") { }
diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp
index 4122c3a61c2..3ed66a71cf4 100644
--- a/src/server/game/Entities/Corpse/Corpse.cpp
+++ b/src/server/game/Entities/Corpse/Corpse.cpp
@@ -61,7 +61,6 @@ void Corpse::RemoveFromWorld()
bool Corpse::Create(ObjectGuid::LowType guidlow, Map* map)
{
- SetMap(map);
Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(map->GetId(), 0, guidlow));
return true;
}
@@ -79,17 +78,13 @@ bool Corpse::Create(ObjectGuid::LowType guidlow, Player* owner)
return false;
}
- //we need to assign owner's map for corpse
- //in other way we will get a crash in Corpse::SaveToDB()
- SetMap(owner->GetMap());
-
Object::_Create(ObjectGuid::Create<HighGuid::Corpse>(GetMapId(), 0, guidlow));
SetPhaseMask(owner->GetPhaseMask(), false);
SetObjectScale(1.0f);
SetGuidValue(CORPSE_FIELD_OWNER, owner->GetGUID());
- _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
+ _cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
CopyPhaseFrom(owner);
@@ -133,20 +128,6 @@ void Corpse::SaveToDB()
CharacterDatabase.CommitTransaction(trans);
}
-void Corpse::DeleteBonesFromWorld()
-{
- ASSERT(GetType() == CORPSE_BONES);
- Corpse* corpse = ObjectAccessor::GetCorpse(*this, GetGUID());
-
- if (!corpse)
- {
- TC_LOG_ERROR("entities.player", "Bones %s not found in world.", GetGUID().ToString().c_str());
- return;
- }
-
- AddObjectToRemoveList();
-}
-
void Corpse::DeleteFromDB(SQLTransaction& trans)
{
DeleteFromDB(GetOwnerGUID(), trans);
@@ -201,7 +182,7 @@ bool Corpse::LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields)
return false;
}
- _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY());
+ _cellCoord = Trinity::ComputeCellCoord(GetPositionX(), GetPositionY());
return true;
}
diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h
index be2cb435ac9..c135548bee3 100644
--- a/src/server/game/Entities/Corpse/Corpse.h
+++ b/src/server/game/Entities/Corpse/Corpse.h
@@ -61,7 +61,6 @@ class Corpse : public WorldObject, public GridObject<Corpse>
void SaveToDB();
bool LoadCorpseFromDB(ObjectGuid::LowType guid, Field* fields);
- void DeleteBonesFromWorld();
void DeleteFromDB(SQLTransaction& trans);
static void DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans);
@@ -71,8 +70,8 @@ class Corpse : public WorldObject, public GridObject<Corpse>
void ResetGhostTime() { m_time = time(NULL); }
CorpseType GetType() const { return m_type; }
- GridCoord const& GetGridCoord() const { return _gridCoord; }
- void SetGridCoord(GridCoord const& gridCoord) { _gridCoord = gridCoord; }
+ CellCoord const& GetCellCoord() const { return _cellCoord; }
+ void SetCellCoord(CellCoord const& cellCoord) { _cellCoord = cellCoord; }
Loot loot; // remove insignia ONLY at BG
Player* lootRecipient;
@@ -83,6 +82,6 @@ class Corpse : public WorldObject, public GridObject<Corpse>
private:
CorpseType m_type;
time_t m_time;
- GridCoord _gridCoord; // gride for corpse position for fast search
+ CellCoord _cellCoord;
};
#endif
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index 26ee5329808..ea21bf8af96 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -1580,7 +1580,7 @@ void Creature::setDeathState(DeathState s)
SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool));
Motion_Initialize();
Unit::setDeathState(ALIVE);
- LoadCreaturesAddon(true);
+ LoadCreaturesAddon();
}
}
@@ -2096,7 +2096,7 @@ CreatureAddon const* Creature::GetCreatureAddon() const
}
//creature_addon table
-bool Creature::LoadCreaturesAddon(bool reload)
+bool Creature::LoadCreaturesAddon()
{
CreatureAddon const* cainfo = GetCreatureAddon();
if (!cainfo)
@@ -2162,12 +2162,7 @@ bool Creature::LoadCreaturesAddon(bool reload)
// skip already applied aura
if (HasAura(*itr))
- {
- if (!reload)
- TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD " Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetSpawnId(), GetEntry(), *itr);
-
continue;
- }
AddAura(*itr, this);
TC_LOG_DEBUG("entities.unit", "Spell: %u added to creature (%s)", *itr, GetGUID().ToString().c_str());
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index eb2e7df65b8..1f5984691be 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -475,7 +475,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
void DisappearAndDie();
bool Create(ObjectGuid::LowType guidlow, Map* map, uint32 phaseMask, uint32 entry, float x, float y, float z, float ang, CreatureData const* data = nullptr, uint32 vehId = 0);
- bool LoadCreaturesAddon(bool reload = false);
+ bool LoadCreaturesAddon();
void SelectLevel();
void LoadEquipment(int8 id = 1, bool force = false);
diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp
index 5f8c3a36692..c26da27051e 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.cpp
+++ b/src/server/game/Entities/Creature/CreatureGroups.cpp
@@ -240,7 +240,8 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z)
Trinity::NormalizeMapCoord(dx);
Trinity::NormalizeMapCoord(dy);
- member->UpdateGroundPositionZ(dx, dy, dz);
+ if (!member->IsFlying())
+ member->UpdateGroundPositionZ(dx, dy, dz);
if (member->IsWithinDist(m_leader, dist + MAX_DESYNC))
member->SetUnitMovementFlags(m_leader->GetUnitMovementFlags());
diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h
index edbea16640e..ac3b740ac16 100644
--- a/src/server/game/Entities/Creature/CreatureGroups.h
+++ b/src/server/game/Entities/Creature/CreatureGroups.h
@@ -32,8 +32,8 @@ struct FormationInfo
float follow_dist;
float follow_angle;
uint8 groupAI;
- uint16 point_1;
- uint16 point_2;
+ uint32 point_1;
+ uint32 point_2;
};
typedef std::unordered_map<ObjectGuid::LowType/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType;
diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp
index 6ea703280df..0f80c5385d4 100644
--- a/src/server/game/Entities/Item/Item.cpp
+++ b/src/server/game/Entities/Item/Item.cpp
@@ -30,6 +30,7 @@
#include "Opcodes.h"
#include "WorldSession.h"
#include "ItemPackets.h"
+#include "TradeData.h"
void AddItemsSetItem(Player* player, Item* item)
{
@@ -790,6 +791,22 @@ bool Item::CanBeTraded(bool mail, bool trade) const
return true;
}
+void Item::SetCount(uint32 value)
+{
+ SetUInt32Value(ITEM_FIELD_STACK_COUNT, value);
+
+ if (Player* player = GetOwner())
+ {
+ if (TradeData* tradeData = player->GetTradeData())
+ {
+ TradeSlots slot = tradeData->GetTradeSlotForItem(GetGUID());
+
+ if (slot != TRADE_SLOT_INVALID)
+ tradeData->SetItem(slot, this, true);
+ }
+ }
+}
+
bool Item::HasEnchantRequiredSkill(const Player* player) const
{
// Check all enchants for required skill
@@ -1224,6 +1241,10 @@ void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, SQLTransa
if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE))
return;
+ WorldPackets::Item::ItemExpirePurchaseRefund itemExpirePurchaseRefund;
+ itemExpirePurchaseRefund.ItemGUID = GetGUID();
+ owner->SendDirectMessage(itemExpirePurchaseRefund.Write());
+
RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE);
// Following is not applicable in the trading procedure
if (changestate)
@@ -1755,7 +1776,7 @@ uint32 Item::GetItemLevel(Player const* owner) const
return MIN_ITEM_LEVEL;
uint32 itemLevel = stats->GetBaseItemLevel();
- if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(stats->GetScalingStatDistribution()))
+ if (ScalingStatDistributionEntry const* ssd = sScalingStatDistributionStore.LookupEntry(GetScalingStatDistribution()))
if (uint32 heirloomIlvl = sDB2Manager.GetHeirloomItemLevel(ssd->ItemLevelCurveID, owner->getLevel()))
itemLevel = heirloomIlvl;
@@ -1839,6 +1860,8 @@ void BonusData::Initialize(ItemTemplate const* proto)
SocketColor[i] = proto->GetSocketColor(i);
AppearanceModID = 0;
+ RepairCostMultiplier = 1.0f;
+ ScalingStatDistribution = proto->GetScalingStatDistribution();
}
void BonusData::Initialize(WorldPackets::Item::ItemInstance const& itemInstance)
@@ -1901,5 +1924,11 @@ void BonusData::AddBonus(uint32 type, int32 const (&values)[2])
case ITEM_BONUS_REQUIRED_LEVEL:
RequiredLevel += values[0];
break;
+ case ITEM_BONUS_REPAIR_COST_MULTIPLIER:
+ RepairCostMultiplier *= static_cast<float>(values[0]) * 0.01f;
+ break;
+ case ITEM_BONUS_SCALING_STAT_DISTRIBUTION:
+ ScalingStatDistribution = static_cast<uint32>(values[0]);
+ break;
}
}
diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h
index 37d7e3613f2..77dc93af56c 100644
--- a/src/server/game/Entities/Item/Item.h
+++ b/src/server/game/Entities/Item/Item.h
@@ -248,6 +248,8 @@ struct BonusData
float ItemStatSocketCostMultiplier[MAX_ITEM_PROTO_STATS];
uint32 SocketColor[MAX_ITEM_PROTO_SOCKETS];
uint32 AppearanceModID;
+ float RepairCostMultiplier;
+ uint32 ScalingStatDistribution;
void Initialize(ItemTemplate const* proto);
void Initialize(WorldPackets::Item::ItemInstance const& itemInstance);
@@ -318,7 +320,7 @@ class Item : public Object
bool GemsFitSockets() const;
uint32 GetCount() const { return GetUInt32Value(ITEM_FIELD_STACK_COUNT); }
- void SetCount(uint32 value) { SetUInt32Value(ITEM_FIELD_STACK_COUNT, value); }
+ void SetCount(uint32 value);
uint32 GetMaxStackCount() const { return GetTemplate()->GetMaxStackSize(); }
uint8 GetGemCountWithID(uint32 GemID) const;
uint8 GetGemCountWithLimitCategory(uint32 limitCategory) const;
@@ -393,6 +395,8 @@ class Item : public Object
uint32 GetArmor(Player const* owner) const { return GetTemplate()->GetArmor(GetItemLevel(owner)); }
void GetDamage(Player const* owner, float& minDamage, float& maxDamage) const { GetTemplate()->GetDamage(GetItemLevel(owner), minDamage, maxDamage); }
uint32 GetDisplayId() const;
+ float GetRepairCostMultiplier() const { return _bonusData.RepairCostMultiplier; }
+ uint32 GetScalingStatDistribution() const { return _bonusData.ScalingStatDistribution; }
// Item Refund system
void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = NULL);
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp
index 9a01eacbf7f..6318caf00b4 100644
--- a/src/server/game/Entities/Object/Object.cpp
+++ b/src/server/game/Entities/Object/Object.cpp
@@ -2807,26 +2807,25 @@ bool WorldObject::HasInPhaseList(uint32 phase)
void WorldObject::UpdateAreaPhase()
{
bool updateNeeded = false;
- PhaseInfo phases = sObjectMgr->GetAreaPhases();
+ PhaseInfo const& phases = sObjectMgr->GetAreaPhases();
for (PhaseInfo::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
{
uint32 areaId = itr->first;
- for (uint32 phaseId : itr->second)
+ for (PhaseInfoStruct const& phase : itr->second)
{
if (areaId == GetAreaId())
{
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId);
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
{
// add new phase if condition passed, true if it wasnt added before
- bool up = SetInPhase(phaseId, false, true);
+ bool up = SetInPhase(phase.Id, false, true);
if (!updateNeeded && up)
updateNeeded = true;
}
else
{
// condition failed, remove phase, true if there was something removed
- bool up = SetInPhase(phaseId, false, false);
+ bool up = SetInPhase(phase.Id, false, false);
if (!updateNeeded && up)
updateNeeded = true;
}
@@ -2834,7 +2833,7 @@ void WorldObject::UpdateAreaPhase()
else
{
// not in area, remove phase, true if there was something removed
- bool up = SetInPhase(phaseId, false, false);
+ bool up = SetInPhase(phase.Id, false, false);
if (!updateNeeded && up)
updateNeeded = true;
}
@@ -2866,7 +2865,6 @@ void WorldObject::UpdateAreaPhase()
}
// only update visibility and send packets if there was a change in the phase list
-
if (updateNeeded && GetTypeId() == TYPEID_PLAYER && IsInWorld())
ToPlayer()->GetSession()->SendSetPhaseShift(GetPhases(), GetTerrainSwaps(), GetWorldMapAreaSwaps());
@@ -2883,32 +2881,31 @@ bool WorldObject::SetInPhase(uint32 id, bool update, bool apply)
{
if (HasInPhaseList(id)) // do not run the updates if we are already in this phase
return false;
+
_phases.insert(id);
}
else
{
- for (uint32 phaseId : sObjectMgr->GetPhasesForArea(GetAreaId()))
- {
- if (id == phaseId)
- {
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_PHASE, phaseId);
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
- {
- // if area phase passes the condition we should not remove it (ie: if remove called from aura remove)
- // this however breaks the .mod phase command, you wont be able to remove any area based phases with it
- return false;
- }
- }
- }
+ // if area phase passes the condition we should not remove it (ie: if remove called from aura remove)
+ // this however breaks the .mod phase command, you wont be able to remove any area based phases with it
+ if (std::vector<PhaseInfoStruct> const* phases = sObjectMgr->GetPhasesForArea(GetAreaId()))
+ for (PhaseInfoStruct const& phase : *phases)
+ if (id == phase.Id)
+ if (sConditionMgr->IsObjectMeetToConditions(this, phase.Conditions))
+ return false;
+
if (!HasInPhaseList(id)) // do not run the updates if we are not in this phase
return false;
+
_phases.erase(id);
}
}
+
RebuildTerrainSwaps();
if (update && IsInWorld())
UpdateObjectVisibility();
+
return true;
}
@@ -3111,37 +3108,30 @@ void WorldObject::RebuildTerrainSwaps()
// Clear all terrain swaps, will be rebuilt below
// Reason for this is, multiple phases can have the same terrain swap, we should not remove the swap if another phase still use it
_terrainSwaps.clear();
- ConditionList conditions;
// Check all applied phases for terrain swap and add it only once
for (uint32 phaseId : _phases)
{
- std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId);
-
- for (uint32 swap : swaps)
+ if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
{
- // only add terrain swaps for current map
- MapEntry const* mapEntry = sMapStore.LookupEntry(swap);
- if (!mapEntry || mapEntry->ParentMapID != int32(GetMapId()))
- continue;
-
- conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
+ for (PhaseInfoStruct const& swap : *swaps)
+ {
+ // only add terrain swaps for current map
+ MapEntry const* mapEntry = sMapStore.LookupEntry(swap.Id);
+ if (!mapEntry || mapEntry->ParentMapID != int32(GetMapId()))
+ continue;
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
- _terrainSwaps.insert(swap);
+ if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
+ _terrainSwaps.insert(swap.Id);
+ }
}
}
// get default terrain swaps, only for current map always
- std::list<uint32>& mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId());
-
- for (uint32 swap : mapSwaps)
- {
- conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
-
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
- _terrainSwaps.insert(swap);
- }
+ if (std::vector<PhaseInfoStruct> const* mapSwaps = sObjectMgr->GetDefaultTerrainSwaps(GetMapId()))
+ for (PhaseInfoStruct const& swap : *mapSwaps)
+ if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
+ _terrainSwaps.insert(swap.Id);
// online players have a game client with world map display
if (GetTypeId() == TYPEID_PLAYER)
@@ -3155,36 +3145,20 @@ void WorldObject::RebuildWorldMapAreaSwaps()
// get ALL default terrain swaps, if we are using it (condition is true)
// send the worldmaparea for it, to see swapped worldmaparea in client from other maps too, not just from our current
- TerrainPhaseInfo defaults = sObjectMgr->GetDefaultTerrainSwapStore();
+ TerrainPhaseInfo const& defaults = sObjectMgr->GetDefaultTerrainSwapStore();
for (TerrainPhaseInfo::const_iterator itr = defaults.begin(); itr != defaults.end(); ++itr)
- {
- for (uint32 swap : itr->second)
- {
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
- {
- for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap))
- _worldMapAreaSwaps.insert(map);
- }
- }
- }
+ for (PhaseInfoStruct const& swap : itr->second)
+ if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.Id))
+ if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
+ for (uint32 worldMapAreaId : *uiMapSwaps)
+ _worldMapAreaSwaps.insert(worldMapAreaId);
// Check all applied phases for world map area swaps
for (uint32 phaseId : _phases)
- {
- std::list<uint32>& swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId);
-
- for (uint32 swap : swaps)
- {
- // add world map swaps for ANY map
-
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_TERRAIN_SWAP, swap);
-
- if (sConditionMgr->IsObjectMeetToConditions(this, conditions))
- {
- for (uint32 map : sObjectMgr->GetTerrainWorldMaps(swap))
- _worldMapAreaSwaps.insert(map);
- }
- }
- }
+ if (std::vector<PhaseInfoStruct> const* swaps = sObjectMgr->GetPhaseTerrainSwaps(phaseId))
+ for (PhaseInfoStruct const& swap : *swaps)
+ if (std::vector<uint32> const* uiMapSwaps = sObjectMgr->GetTerrainWorldMaps(swap.Id))
+ if (sConditionMgr->IsObjectMeetToConditions(this, swap.Conditions))
+ for (uint32 worldMapAreaId : *uiMapSwaps)
+ _worldMapAreaSwaps.insert(worldMapAreaId);
}
diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h
index fcfa0b5a810..feb5219b39f 100644
--- a/src/server/game/Entities/Object/ObjectGuid.h
+++ b/src/server/game/Entities/Object/ObjectGuid.h
@@ -21,10 +21,8 @@
#include "Common.h"
#include "ByteBuffer.h"
-#include <boost/functional/hash.hpp>
#include <type_traits>
#include <functional>
-#include <unordered_set>
enum TypeID
{
@@ -204,11 +202,6 @@ class ObjectGuid
static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific, ObjectGuid>::type Create(uint16 mapId, uint32 entry, LowType counter) { return MapSpecific(type, 0, mapId, 0, entry, counter); }
ObjectGuid() : _low(0), _high(0) { }
- ObjectGuid(ObjectGuid const& r) : _low(r._low), _high(r._high) { }
- ObjectGuid(ObjectGuid&& r) : _low(r._low), _high(r._high) { }
-
- ObjectGuid& operator=(ObjectGuid const& r) { _low = r._low; _high = r._high; return *this; }
- ObjectGuid& operator=(ObjectGuid&& r) { _low = r._low; _high = r._high; return *this; }
std::vector<uint8> GetRawValue() const;
void SetRawValue(std::vector<uint8> const& guid);
diff --git a/src/server/game/Entities/Player/CollectionMgr.cpp b/src/server/game/Entities/Player/CollectionMgr.cpp
index 9929c6362ef..44e7b148b22 100644
--- a/src/server/game/Entities/Player/CollectionMgr.cpp
+++ b/src/server/game/Entities/Player/CollectionMgr.cpp
@@ -53,12 +53,12 @@ void CollectionMgr::LoadAccountToys(PreparedQueryResult result)
void CollectionMgr::SaveAccountToys(SQLTransaction& trans)
{
PreparedStatement* stmt = nullptr;
- for (ToyBoxContainer::const_iterator itr = _toys.begin(); itr != _toys.end(); ++itr)
+ for (auto const& toy : _toys)
{
stmt = LoginDatabase.GetPreparedStatement(LOGIN_REP_ACCOUNT_TOYS);
stmt->setUInt32(0, _owner->GetBattlenetAccountId());
- stmt->setUInt32(1, itr->first);
- stmt->setBool(2, itr->second);
+ stmt->setUInt32(1, toy.first);
+ stmt->setBool(2, toy.second);
trans->Append(stmt);
}
}
diff --git a/src/server/game/Entities/Player/KillRewarder.cpp b/src/server/game/Entities/Player/KillRewarder.cpp
new file mode 100644
index 00000000000..55649a6e366
--- /dev/null
+++ b/src/server/game/Entities/Player/KillRewarder.cpp
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2008-2015 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 "KillRewarder.h"
+#include "SpellAuraEffects.h"
+#include "Creature.h"
+#include "Formulas.h"
+#include "Group.h"
+#include "Guild.h"
+#include "GuildMgr.h"
+#include "InstanceScript.h"
+#include "Pet.h"
+#include "Player.h"
+
+ // == KillRewarder ====================================================
+ // KillRewarder encapsulates logic of rewarding player upon kill with:
+ // * XP;
+ // * honor;
+ // * reputation;
+ // * kill credit (for quest objectives).
+ // Rewarding is initiated in two cases: when player kills unit in Unit::Kill()
+ // and on battlegrounds in Battleground::RewardXPAtKill().
+ //
+ // Rewarding algorithm is:
+ // 1. Initialize internal variables to default values.
+ // 2. In case when player is in group, initialize variables necessary for group calculations:
+ // 2.1. _count - number of alive group members within reward distance;
+ // 2.2. _sumLevel - sum of levels of alive group members within reward distance;
+ // 2.3. _maxLevel - maximum level of alive group member within reward distance;
+ // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
+ // for whom victim is not gray;
+ // 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
+ // so 100% XP will be rewarded (50% otherwise).
+ // 3. Reward killer (and group, if necessary).
+ // 3.1. If killer is in group, reward group.
+ // 3.1.1. Initialize initial XP amount based on maximum level of group member,
+ // for whom victim is not gray.
+ // 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
+ // 3.1.3. Reward each group member (even dead) within reward distance (see 4. for more details).
+ // 3.2. Reward single killer (not group case).
+ // 3.2.1. Initialize initial XP amount based on killer's level.
+ // 3.2.2. Reward killer (see 4. for more details).
+ // 4. Reward player.
+ // 4.1. Give honor (player must be alive and not on BG).
+ // 4.2. Give XP.
+ // 4.2.1. If player is in group, adjust XP:
+ // * set to 0 if player's level is more than maximum level of not gray member;
+ // * cut XP in half if _isFullXP is false.
+ // 4.2.2. Apply auras modifying rewarded XP.
+ // 4.2.3. Give XP to player.
+ // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
+ // 4.3. Give reputation (player must not be on BG).
+ // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
+ // 5. Credit instance encounter.
+ // 6. Update guild achievements.
+
+KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) :
+ // 1. Initialize internal variables to default values.
+ _killer(killer), _victim(victim), _group(killer->GetGroup()),
+ _groupRate(1.0f), _maxNotGrayMember(nullptr), _count(0), _sumLevel(0), _xp(0),
+ _isFullXP(false), _maxLevel(0), _isBattleGround(isBattleGround), _isPvP(false)
+{
+ // mark the credit as pvp if victim is player
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ _isPvP = true;
+ // or if its owned by player and its not a vehicle
+ else if (victim->GetCharmerOrOwnerGUID().IsPlayer())
+ _isPvP = !victim->IsVehicle();
+
+ _InitGroupData();
+}
+
+inline void KillRewarder::_InitGroupData()
+{
+ if (_group)
+ {
+ // 2. In case when player is in group, initialize variables necessary for group calculations:
+ for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next())
+ if (Player* member = itr->GetSource())
+ if (member->IsAlive() && member->IsAtGroupRewardDistance(_victim))
+ {
+ const uint8 lvl = member->getLevel();
+ // 2.1. _count - number of alive group members within reward distance;
+ ++_count;
+ // 2.2. _sumLevel - sum of levels of alive group members within reward distance;
+ _sumLevel += lvl;
+ // 2.3. _maxLevel - maximum level of alive group member within reward distance;
+ if (_maxLevel < lvl)
+ _maxLevel = lvl;
+ // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
+ // for whom victim is not gray;
+ uint32 grayLevel = Trinity::XP::GetGrayLevel(lvl);
+ if (_victim->getLevel() > grayLevel && (!_maxNotGrayMember || _maxNotGrayMember->getLevel() < lvl))
+ _maxNotGrayMember = member;
+ }
+ // 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
+ // so 100% XP will be rewarded (50% otherwise).
+ _isFullXP = _maxNotGrayMember && (_maxLevel == _maxNotGrayMember->getLevel());
+ }
+ else
+ _count = 1;
+}
+
+inline void KillRewarder::_InitXP(Player* player)
+{
+ // Get initial value of XP for kill.
+ // XP is given:
+ // * on battlegrounds;
+ // * otherwise, not in PvP;
+ // * not if killer is on vehicle.
+ if (_isBattleGround || (!_isPvP && !_killer->GetVehicle()))
+ _xp = Trinity::XP::Gain(player, _victim, _isBattleGround);
+}
+
+inline void KillRewarder::_RewardHonor(Player* player)
+{
+ // Rewarded player must be alive.
+ if (player->IsAlive())
+ player->RewardHonor(_victim, _count, -1, true);
+}
+
+inline void KillRewarder::_RewardXP(Player* player, float rate)
+{
+ uint32 xp(_xp);
+ if (_group)
+ {
+ // 4.2.1. If player is in group, adjust XP:
+ // * set to 0 if player's level is more than maximum level of not gray member;
+ // * cut XP in half if _isFullXP is false.
+ if (_maxNotGrayMember && player->IsAlive() &&
+ _maxNotGrayMember->getLevel() >= player->getLevel())
+ xp = _isFullXP ?
+ uint32(xp * rate) : // Reward FULL XP if all group members are not gray.
+ uint32(xp * rate / 2) + 1; // Reward only HALF of XP if some of group members are gray.
+ else
+ xp = 0;
+ }
+ if (xp)
+ {
+ // 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT).
+ for (auto const& aura : player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT))
+ AddPct(xp, aura->GetAmount());
+
+ // 4.2.3. Give XP to player.
+ player->GiveXP(xp, _victim, _groupRate);
+ if (Pet* pet = player->GetPet())
+ // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
+ pet->GivePetXP(_group ? xp / 2 : xp);
+ }
+}
+
+inline void KillRewarder::_RewardReputation(Player* player, float rate)
+{
+ // 4.3. Give reputation (player must not be on BG).
+ // Even dead players and corpses are rewarded.
+ player->RewardReputation(_victim, rate);
+}
+
+inline void KillRewarder::_RewardKillCredit(Player* player)
+{
+ // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
+ if (!_group || player->IsAlive() || !player->GetCorpse())
+ if (Creature* target = _victim->ToCreature())
+ {
+ player->KilledMonster(target->GetCreatureTemplate(), target->GetGUID());
+ player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, 0, target);
+ }
+}
+
+void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
+{
+ // 4. Reward player.
+ if (!_isBattleGround)
+ {
+ // 4.1. Give honor (player must be alive and not on BG).
+ _RewardHonor(player);
+ // 4.1.1 Send player killcredit for quests with PlayerSlain
+ if (_victim->GetTypeId() == TYPEID_PLAYER)
+ player->KilledPlayerCredit();
+ }
+ // Give XP only in PvE or in battlegrounds.
+ // Give reputation and kill credit only in PvE.
+ if (!_isPvP || _isBattleGround)
+ {
+ float const rate = _group ?
+ _groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level.
+ 1.0f; // Personal rate is 100%.
+ if (_xp)
+ // 4.2. Give XP.
+ _RewardXP(player, rate);
+ if (!_isBattleGround)
+ {
+ // If killer is in dungeon then all members receive full reputation at kill.
+ _RewardReputation(player, isDungeon ? 1.0f : rate);
+ _RewardKillCredit(player);
+ }
+ }
+}
+
+void KillRewarder::_RewardGroup()
+{
+ if (_maxLevel)
+ {
+ if (_maxNotGrayMember)
+ // 3.1.1. Initialize initial XP amount based on maximum level of group member,
+ // for whom victim is not gray.
+ _InitXP(_maxNotGrayMember);
+ // To avoid unnecessary calculations and calls,
+ // proceed only if XP is not ZERO or player is not on battleground
+ // (battleground rewards only XP, that's why).
+ if (!_isBattleGround || _xp)
+ {
+ bool const isDungeon = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsDungeon();
+ if (!_isBattleGround)
+ {
+ // 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
+ bool const isRaid = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsRaid() && _group->isRaidGroup();
+ _groupRate = Trinity::XP::xp_in_group_rate(_count, isRaid);
+ }
+
+ // 3.1.3. Reward each group member (even dead or corpse) within reward distance.
+ for (GroupReference* itr = _group->GetFirstMember(); itr != nullptr; itr = itr->next())
+ {
+ if (Player* member = itr->GetSource())
+ {
+ if (member->IsAtGroupRewardDistance(_victim))
+ {
+ _RewardPlayer(member, isDungeon);
+ member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, 0, _victim);
+ }
+ }
+ }
+ }
+ }
+}
+
+void KillRewarder::Reward()
+{
+ // 3. Reward killer (and group, if necessary).
+ if (_group)
+ // 3.1. If killer is in group, reward group.
+ _RewardGroup();
+ else
+ {
+ // 3.2. Reward single killer (not group case).
+ // 3.2.1. Initialize initial XP amount based on killer's level.
+ _InitXP(_killer);
+ // To avoid unnecessary calculations and calls,
+ // proceed only if XP is not ZERO or player is not on battleground
+ // (battleground rewards only XP, that's why).
+ if (!_isBattleGround || _xp)
+ // 3.2.2. Reward killer.
+ _RewardPlayer(_killer, false);
+ }
+
+ // 5. Credit instance encounter.
+ // 6. Update guild achievements.
+ if (Creature* victim = _victim->ToCreature())
+ {
+ if (victim->IsDungeonBoss())
+ if (InstanceScript* instance = _victim->GetInstanceScript())
+ instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim);
+
+ if (ObjectGuid::LowType guildId = victim->GetMap()->GetOwnerGuildId())
+ if (Guild* guild = sGuildMgr->GetGuildById(guildId))
+ guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer);
+ }
+
+}
diff --git a/src/server/game/Entities/Player/KillRewarder.h b/src/server/game/Entities/Player/KillRewarder.h
new file mode 100644
index 00000000000..577a8ffea20
--- /dev/null
+++ b/src/server/game/Entities/Player/KillRewarder.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KillRewarder_h__
+#define KillRewarder_h__
+
+#include "Define.h"
+
+class Player;
+class Unit;
+class Group;
+
+class KillRewarder
+{
+public:
+ KillRewarder(Player* killer, Unit* victim, bool isBattleGround);
+
+ void Reward();
+
+private:
+ void _InitXP(Player* player);
+ void _InitGroupData();
+
+ void _RewardHonor(Player* player);
+ void _RewardXP(Player* player, float rate);
+ void _RewardReputation(Player* player, float rate);
+ void _RewardKillCredit(Player* player);
+ void _RewardPlayer(Player* player, bool isDungeon);
+ void _RewardGroup();
+
+ Player* _killer;
+ Unit* _victim;
+ Group* _group;
+ float _groupRate;
+ Player* _maxNotGrayMember;
+ uint32 _count;
+ uint32 _sumLevel;
+ uint32 _xp;
+ bool _isFullXP;
+ uint8 _maxLevel;
+ bool _isBattleGround;
+ bool _isPvP;
+};
+
+#endif // KillRewarder_h__
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 9d9ff325dc1..2a6715b7457 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -59,6 +59,7 @@
#include "InstanceSaveMgr.h"
#include "InstanceScript.h"
#include "ItemPackets.h"
+#include "KillRewarder.h"
#include "LFGMgr.h"
#include "Language.h"
#include "Log.h"
@@ -87,9 +88,7 @@
#include "SpellMgr.h"
#include "SpellPackets.h"
#include "TalentPackets.h"
-#include "TaxiPackets.h"
#include "ToyPackets.h"
-#include "TradePackets.h"
#include "Transport.h"
#include "UpdateData.h"
#include "UpdateFieldFlags.h"
@@ -130,389 +129,6 @@ uint32 const MasterySpells[MAX_CLASSES] =
uint64 const MAX_MONEY_AMOUNT = 9999999999ULL;
-//== TradeData =================================================
-
-TradeData* TradeData::GetTraderData() const
-{
- return m_trader->GetTradeData();
-}
-
-Item* TradeData::GetItem(TradeSlots slot) const
-{
- return !m_items[slot].IsEmpty() ? m_player->GetItemByGuid(m_items[slot]) : NULL;
-}
-
-bool TradeData::HasItem(ObjectGuid itemGuid) const
-{
- for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
- if (m_items[i] == itemGuid)
- return true;
-
- return false;
-}
-
-TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const
-{
- for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
- if (m_items[i] == itemGuid)
- return TradeSlots(i);
-
- return TRADE_SLOT_INVALID;
-}
-
-Item* TradeData::GetSpellCastItem() const
-{
- return !m_spellCastItem.IsEmpty() ? m_player->GetItemByGuid(m_spellCastItem) : NULL;
-}
-
-void TradeData::SetItem(TradeSlots slot, Item* item)
-{
- ObjectGuid itemGuid;
- if (item)
- itemGuid = item->GetGUID();
-
- if (m_items[slot] == itemGuid)
- return;
-
- m_items[slot] = itemGuid;
-
- SetAccepted(false);
- GetTraderData()->SetAccepted(false);
-
- UpdateServerStateIndex();
-
- Update();
-
- // need remove possible trader spell applied to changed item
- if (slot == TRADE_SLOT_NONTRADED)
- GetTraderData()->SetSpell(0);
-
- // need remove possible player spell applied (possible move reagent)
- SetSpell(0);
-}
-
-void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/)
-{
- ObjectGuid itemGuid = castItem ? castItem->GetGUID() : ObjectGuid::Empty;
-
- if (m_spell == spell_id && m_spellCastItem == itemGuid)
- return;
-
- m_spell = spell_id;
- m_spellCastItem = itemGuid;
-
- SetAccepted(false);
- GetTraderData()->SetAccepted(false);
-
- UpdateServerStateIndex();
-
- Update(true); // send spell info to item owner
- Update(false); // send spell info to caster self
-}
-
-void TradeData::SetMoney(uint64 money)
-{
- if (m_money == money)
- return;
-
- if (!m_player->HasEnoughMoney(money))
- {
- WorldPackets::Trade::TradeStatus info;
- info.Status = TRADE_STATUS_FAILED;
- info.BagResult = EQUIP_ERR_NOT_ENOUGH_MONEY;
- m_player->GetSession()->SendTradeStatus(info);
- return;
- }
-
- m_money = money;
-
- SetAccepted(false);
- GetTraderData()->SetAccepted(false);
-
- UpdateServerStateIndex();
-
- Update(true);
-}
-
-void TradeData::Update(bool forTarget /*= true*/)
-{
- if (forTarget)
- m_trader->GetSession()->SendUpdateTrade(true); // player state for trader
- else
- m_player->GetSession()->SendUpdateTrade(false); // player state for player
-}
-
-void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
-{
- m_accepted = state;
-
- if (!state)
- {
- WorldPackets::Trade::TradeStatus info;
- info.Status = TRADE_STATUS_UNACCEPTED;
- if (crosssend)
- m_trader->GetSession()->SendTradeStatus(info);
- else
- m_player->GetSession()->SendTradeStatus(info);
- }
-}
-
-// == KillRewarder ====================================================
-// KillRewarder incapsulates logic of rewarding player upon kill with:
-// * XP;
-// * honor;
-// * reputation;
-// * kill credit (for quest objectives).
-// Rewarding is initiated in two cases: when player kills unit in Unit::Kill()
-// and on battlegrounds in Battleground::RewardXPAtKill().
-//
-// Rewarding algorithm is:
-// 1. Initialize internal variables to default values.
-// 2. In case when player is in group, initialize variables necessary for group calculations:
-// 2.1. _count - number of alive group members within reward distance;
-// 2.2. _sumLevel - sum of levels of alive group members within reward distance;
-// 2.3. _maxLevel - maximum level of alive group member within reward distance;
-// 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
-// for whom victim is not gray;
-// 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
-// so 100% XP will be rewarded (50% otherwise).
-// 3. Reward killer (and group, if necessary).
-// 3.1. If killer is in group, reward group.
-// 3.1.1. Initialize initial XP amount based on maximum level of group member,
-// for whom victim is not gray.
-// 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
-// 3.1.3. Reward each group member (even dead) within reward distance (see 4. for more details).
-// 3.2. Reward single killer (not group case).
-// 3.2.1. Initialize initial XP amount based on killer's level.
-// 3.2.2. Reward killer (see 4. for more details).
-// 4. Reward player.
-// 4.1. Give honor (player must be alive and not on BG).
-// 4.2. Give XP.
-// 4.2.1. If player is in group, adjust XP:
-// * set to 0 if player's level is more than maximum level of not gray member;
-// * cut XP in half if _isFullXP is false.
-// 4.2.2. Apply auras modifying rewarded XP.
-// 4.2.3. Give XP to player.
-// 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
-// 4.3. Give reputation (player must not be on BG).
-// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
-// 5. Credit instance encounter.
-// 6. Update guild achievements.
-KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) :
- // 1. Initialize internal variables to default values.
- _killer(killer), _victim(victim), _group(killer->GetGroup()),
- _groupRate(1.0f), _maxNotGrayMember(NULL), _count(0), _sumLevel(0), _xp(0),
- _isFullXP(false), _maxLevel(0), _isBattleGround(isBattleGround), _isPvP(false)
-{
- // mark the credit as pvp if victim is player
- if (victim->GetTypeId() == TYPEID_PLAYER)
- _isPvP = true;
- // or if its owned by player and its not a vehicle
- else if (victim->GetCharmerOrOwnerGUID().IsPlayer())
- _isPvP = !victim->IsVehicle();
-
- _InitGroupData();
-}
-
-inline void KillRewarder::_InitGroupData()
-{
- if (_group)
- {
- // 2. In case when player is in group, initialize variables necessary for group calculations:
- for (GroupReference* itr = _group->GetFirstMember(); itr != NULL; itr = itr->next())
- if (Player* member = itr->GetSource())
- if (member->IsAlive() && member->IsAtGroupRewardDistance(_victim))
- {
- const uint8 lvl = member->getLevel();
- // 2.1. _count - number of alive group members within reward distance;
- ++_count;
- // 2.2. _sumLevel - sum of levels of alive group members within reward distance;
- _sumLevel += lvl;
- // 2.3. _maxLevel - maximum level of alive group member within reward distance;
- if (_maxLevel < lvl)
- _maxLevel = lvl;
- // 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
- // for whom victim is not gray;
- uint32 grayLevel = Trinity::XP::GetGrayLevel(lvl);
- if (_victim->getLevel() > grayLevel && (!_maxNotGrayMember || _maxNotGrayMember->getLevel() < lvl))
- _maxNotGrayMember = member;
- }
- // 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
- // so 100% XP will be rewarded (50% otherwise).
- _isFullXP = _maxNotGrayMember && (_maxLevel == _maxNotGrayMember->getLevel());
- }
- else
- _count = 1;
-}
-
-inline void KillRewarder::_InitXP(Player* player)
-{
- // Get initial value of XP for kill.
- // XP is given:
- // * on battlegrounds;
- // * otherwise, not in PvP;
- // * not if killer is on vehicle.
- if (_isBattleGround || (!_isPvP && !_killer->GetVehicle()))
- _xp = Trinity::XP::Gain(player, _victim, _isBattleGround);
-}
-
-inline void KillRewarder::_RewardHonor(Player* player)
-{
- // Rewarded player must be alive.
- if (player->IsAlive())
- player->RewardHonor(_victim, _count, -1, true);
-}
-
-inline void KillRewarder::_RewardXP(Player* player, float rate)
-{
- uint32 xp(_xp);
- if (_group)
- {
- // 4.2.1. If player is in group, adjust XP:
- // * set to 0 if player's level is more than maximum level of not gray member;
- // * cut XP in half if _isFullXP is false.
- if (_maxNotGrayMember && player->IsAlive() &&
- _maxNotGrayMember->getLevel() >= player->getLevel())
- xp = _isFullXP ?
- uint32(xp * rate) : // Reward FULL XP if all group members are not gray.
- uint32(xp * rate / 2) + 1; // Reward only HALF of XP if some of group members are gray.
- else
- xp = 0;
- }
- if (xp)
- {
- // 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT).
- Unit::AuraEffectList const& auras = player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
- for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
- AddPct(xp, (*i)->GetAmount());
-
- // 4.2.3. Give XP to player.
- player->GiveXP(xp, _victim, _groupRate);
- if (Pet* pet = player->GetPet())
- // 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
- pet->GivePetXP(_group ? xp / 2 : xp);
- }
-}
-
-inline void KillRewarder::_RewardReputation(Player* player, float rate)
-{
- // 4.3. Give reputation (player must not be on BG).
- // Even dead players and corpses are rewarded.
- player->RewardReputation(_victim, rate);
-}
-
-inline void KillRewarder::_RewardKillCredit(Player* player)
-{
- // 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
- if (!_group || player->IsAlive() || !player->GetCorpse())
- if (Creature* target = _victim->ToCreature())
- {
- player->KilledMonster(target->GetCreatureTemplate(), target->GetGUID());
- player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE, target->GetCreatureType(), 1, 0, target);
- }
-}
-
-void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
-{
- // 4. Reward player.
- if (!_isBattleGround)
- {
- // 4.1. Give honor (player must be alive and not on BG).
- _RewardHonor(player);
- // 4.1.1 Send player killcredit for quests with PlayerSlain
- if (_victim->GetTypeId() == TYPEID_PLAYER)
- player->KilledPlayerCredit();
- }
- // Give XP only in PvE or in battlegrounds.
- // Give reputation and kill credit only in PvE.
- if (!_isPvP || _isBattleGround)
- {
- const float rate = _group ?
- _groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level.
- 1.0f; // Personal rate is 100%.
- if (_xp)
- // 4.2. Give XP.
- _RewardXP(player, rate);
- if (!_isBattleGround)
- {
- // If killer is in dungeon then all members receive full reputation at kill.
- _RewardReputation(player, isDungeon ? 1.0f : rate);
- _RewardKillCredit(player);
- }
- }
-}
-
-void KillRewarder::_RewardGroup()
-{
- if (_maxLevel)
- {
- if (_maxNotGrayMember)
- // 3.1.1. Initialize initial XP amount based on maximum level of group member,
- // for whom victim is not gray.
- _InitXP(_maxNotGrayMember);
- // To avoid unnecessary calculations and calls,
- // proceed only if XP is not ZERO or player is not on battleground
- // (battleground rewards only XP, that's why).
- if (!_isBattleGround || _xp)
- {
- const bool isDungeon = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsDungeon();
- if (!_isBattleGround)
- {
- // 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
- const bool isRaid = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsRaid() && _group->isRaidGroup();
- _groupRate = Trinity::XP::xp_in_group_rate(_count, isRaid);
- }
-
- // 3.1.3. Reward each group member (even dead or corpse) within reward distance.
- for (GroupReference* itr = _group->GetFirstMember(); itr != NULL; itr = itr->next())
- {
- if (Player* member = itr->GetSource())
- {
- if (member->IsAtGroupRewardDistance(_victim))
- {
- _RewardPlayer(member, isDungeon);
- member->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL, 1, 0, 0, _victim);
- }
- }
- }
- }
- }
-}
-
-void KillRewarder::Reward()
-{
- // 3. Reward killer (and group, if necessary).
- if (_group)
- // 3.1. If killer is in group, reward group.
- _RewardGroup();
- else
- {
- // 3.2. Reward single killer (not group case).
- // 3.2.1. Initialize initial XP amount based on killer's level.
- _InitXP(_killer);
- // To avoid unnecessary calculations and calls,
- // proceed only if XP is not ZERO or player is not on battleground
- // (battleground rewards only XP, that's why).
- if (!_isBattleGround || _xp)
- // 3.2.2. Reward killer.
- _RewardPlayer(_killer, false);
- }
-
- // 5. Credit instance encounter.
- // 6. Update guild achievements.
- if (Creature* victim = _victim->ToCreature())
- {
- if (victim->IsDungeonBoss())
- if (InstanceScript* instance = _victim->GetInstanceScript())
- instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim);
-
- if (ObjectGuid::LowType guildId = victim->GetMap()->GetOwnerGuildId())
- if (Guild* guild = sGuildMgr->GetGuildById(guildId))
- guild->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, victim->GetEntry(), 1, 0, victim, _killer);
- }
-
-}
-
Player::Player(WorldSession* session) : Unit(true)
{
m_speakTime = 0;
@@ -4754,12 +4370,13 @@ Corpse* Player::CreateCorpse()
}
}
+ // register for player, but not show
+ GetMap()->AddCorpse(corpse);
+
// we do not need to save corpses for BG/arenas
if (!GetMap()->IsBattlegroundOrArena())
corpse->SaveToDB();
- // register for player, but not show
- GetMap()->AddCorpse(corpse);
return corpse;
}
@@ -4933,7 +4550,7 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
else if (ditemProto->GetClass() == ITEM_CLASS_ARMOR)
dmultiplier = dcost->ArmorSubClassCost[ditemProto->GetSubClass()];
- uint32 costs = uint32(LostDurability * dmultiplier * double(dQualitymodEntry->QualityMod));
+ uint32 costs = uint32(LostDurability * dmultiplier * double(dQualitymodEntry->QualityMod) * item->GetRepairCostMultiplier());
costs = uint32(costs * discountMod * sWorld->getRate(RATE_REPAIRCOST));
@@ -5317,12 +4934,13 @@ float Player::GetRatingBonusValue(CombatRating cr) const
float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const
{
+ float baseExpertise = 7.5f;
switch (attType)
{
case BASE_ATTACK:
- return GetUInt32Value(PLAYER_EXPERTISE) / 4.0f;
+ return baseExpertise + GetUInt32Value(PLAYER_EXPERTISE) / 4.0f;
case OFF_ATTACK:
- return GetUInt32Value(PLAYER_OFFHAND_EXPERTISE) / 4.0f;
+ return baseExpertise + GetUInt32Value(PLAYER_OFFHAND_EXPERTISE) / 4.0f;
default:
break;
}
@@ -6788,7 +6406,7 @@ void Player::SendNewCurrency(uint32 id) const
record.Type = entry->ID;
record.Quantity = itr->second.Quantity;
record.WeeklyQuantity = itr->second.WeeklyQuantity;
- record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry) / ((entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1);
+ record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry);
record.TrackedQuantity = itr->second.TrackedQuantity;
record.Flags = itr->second.Flags;
@@ -6814,7 +6432,7 @@ void Player::SendCurrencies() const
record.Type = entry->ID;
record.Quantity = itr->second.Quantity;
record.WeeklyQuantity = itr->second.WeeklyQuantity;
- record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry) / ((entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1);
+ record.MaxWeeklyQuantity = GetCurrencyWeekCap(entry);
record.TrackedQuantity = itr->second.TrackedQuantity;
record.Flags = itr->second.Flags;
@@ -6827,38 +6445,32 @@ void Player::SendCurrencies() const
void Player::SendPvpRewards() const
{
WorldPacket packet(SMSG_REQUEST_PVP_REWARDS_RESPONSE, 24);
- packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS, true);
- packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_POINTS, true);
- packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA, true);
- packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_RBG, true);
- packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_ARENA, true);
- packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS, true);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_POINTS);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_RBG);
+ packet << GetCurrencyOnWeek(CURRENCY_TYPE_CONQUEST_META_ARENA);
+ packet << GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_POINTS);
GetSession()->SendPacket(&packet);
}
-uint32 Player::GetCurrency(uint32 id, bool usePrecision) const
+uint32 Player::GetCurrency(uint32 id) const
{
PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
if (itr == _currencyStorage.end())
return 0;
- CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
- uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
-
- return itr->second.Quantity / precision;
+ return itr->second.Quantity;
}
-uint32 Player::GetCurrencyOnWeek(uint32 id, bool usePrecision) const
+uint32 Player::GetCurrencyOnWeek(uint32 id) const
{
PlayerCurrenciesMap::const_iterator itr = _currencyStorage.find(id);
if (itr == _currencyStorage.end())
return 0;
- CurrencyTypesEntry const* currency = sCurrencyTypesStore.LookupEntry(id);
- uint32 precision = (usePrecision && currency->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
-
- return itr->second.WeeklyQuantity / precision;
+ return itr->second.WeeklyQuantity;
}
bool Player::HasCurrency(uint32 id, uint32 count) const
@@ -6984,15 +6596,13 @@ void Player::SetCurrency(uint32 id, uint32 count, bool /*printLog*/ /*= true*/)
}
}
-uint32 Player::GetCurrencyWeekCap(uint32 id, bool usePrecision) const
+uint32 Player::GetCurrencyWeekCap(uint32 id) const
{
CurrencyTypesEntry const* entry = sCurrencyTypesStore.LookupEntry(id);
if (!entry)
return 0;
- uint32 precision = (usePrecision && entry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
-
- return GetCurrencyWeekCap(entry) / precision;
+ return GetCurrencyWeekCap(entry);
}
void Player::ResetCurrencyWeekCap()
@@ -7025,7 +6635,7 @@ uint32 Player::GetCurrencyWeekCap(CurrencyTypesEntry const* currency) const
{
//original conquest not have week cap
case CURRENCY_TYPE_CONQUEST_POINTS:
- return std::max(GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA, false), GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG, false));
+ return std::max(GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_ARENA), GetCurrencyWeekCap(CURRENCY_TYPE_CONQUEST_META_RBG));
case CURRENCY_TYPE_CONQUEST_META_ARENA:
// should add precision mod = 100
return Trinity::Currency::ConquestRatingCalculator(_maxPersonalArenaRate) * CURRENCY_PRECISION;
@@ -7080,11 +6690,8 @@ void Player::UpdateConquestCurrencyCap(uint32 currency)
if (!currencyEntry)
continue;
- uint32 precision = (currencyEntry->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? 100 : 1;
- uint32 cap = GetCurrencyWeekCap(currencyEntry);
-
WorldPacket packet(SMSG_SET_MAX_WEEKLY_QUANTITY, 8);
- packet << uint32(cap / precision);
+ packet << uint32(GetCurrencyWeekCap(currencyEntry));
packet << uint32(currenciesToUpdate[i]);
GetSession()->SendPacket(&packet);
}
@@ -9277,6 +8884,17 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid)
packet.Worldstates.emplace_back(4131, 0); // 10 WORLDSTATE_ALGALON_DESPAWN_TIMER
}
break;
+ // Violet Hold
+ case 4415:
+ if (instance && mapid == 608)
+ instance->FillInitialWorldStates(packet);
+ else
+ {
+ packet.Worldstates.emplace_back(3816, 0); // 9 WORLD_STATE_VH_SHOW
+ packet.Worldstates.emplace_back(3815, 100); // 10 WORLD_STATE_VH_PRISON_STATE
+ packet.Worldstates.emplace_back(3810, 0); // 11 WORLD_STATE_VH_WAVE_COUNT
+ }
+ break;
// Halls of Refection
case 4820:
if (instance && mapid == 668)
@@ -10873,7 +10491,7 @@ InventoryResult Player::CanEquipItem(uint8 slot, uint16 &dest, Item* pItem, bool
return EQUIP_ERR_CLIENT_LOCKED_OUT;
}
- ScalingStatDistributionEntry const* ssd = pProto->GetScalingStatDistribution() ? sScalingStatDistributionStore.LookupEntry(pProto->GetScalingStatDistribution()) : 0;
+ ScalingStatDistributionEntry const* ssd = pItem->GetScalingStatDistribution() ? sScalingStatDistributionStore.LookupEntry(pItem->GetScalingStatDistribution()) : 0;
// check allowed level (extend range to upper values if MaxLevel more or equal max player level, this let GM set high level with 1...max range items)
if (ssd && ssd->MaxLevel < DEFAULT_MAX_LEVEL && ssd->MaxLevel < getLevel() && !sDB2Manager.GetHeirloomByItemId(pProto->GetId()))
return EQUIP_ERR_NOT_EQUIPPABLE;
@@ -15058,8 +14676,7 @@ bool Player::SatisfyQuestStatus(Quest const* qInfo, bool msg)
bool Player::SatisfyQuestConditions(Quest const* qInfo, bool msg)
{
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_ACCEPT, qInfo->GetQuestId());
- if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_QUEST_ACCEPT, qInfo->GetQuestId(), this))
{
if (msg)
{
@@ -15310,6 +14927,16 @@ bool Player::GetQuestRewardStatus(uint32 quest_id) const
Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id);
if (qInfo)
{
+ if (qInfo->IsSeasonal() && !qInfo->IsRepeatable())
+ {
+ uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
+ if (m_seasonalquests.find(eventId) != m_seasonalquests.end())
+ return m_seasonalquests.find(eventId)->second.find(quest_id) != m_seasonalquests.find(eventId)->second.end();
+
+ return false;
+ }
+
+
// for repeatable quests: rewarded field is set after first reward only to prevent getting XP more than once
if (!qInfo->IsRepeatable())
return m_RewardedQuests.find(quest_id) != m_RewardedQuests.end();
@@ -15328,8 +14955,17 @@ QuestStatus Player::GetQuestStatus(uint32 quest_id) const
return itr->second.Status;
if (Quest const* qInfo = sObjectMgr->GetQuestTemplate(quest_id))
+ {
+ if (qInfo->IsSeasonal() && !qInfo->IsRepeatable())
+ {
+ uint16 eventId = sGameEventMgr->GetEventIdForQuest(qInfo);
+ if (m_seasonalquests.find(eventId) == m_seasonalquests.end() || m_seasonalquests.find(eventId)->second.find(quest_id) == m_seasonalquests.find(eventId)->second.end())
+ return QUEST_STATUS_NONE;
+ }
+
if (!qInfo->IsRepeatable() && m_RewardedQuests.find(quest_id) != m_RewardedQuests.end())
return QUEST_STATUS_REWARDED;
+ }
}
return QUEST_STATUS_NONE;
}
@@ -15460,8 +15096,7 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
if (!quest)
continue;
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
- if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId(), this))
continue;
QuestStatus status = GetQuestStatus(questId);
@@ -15488,8 +15123,7 @@ QuestGiverStatus Player::GetQuestDialogStatus(Object* questgiver)
if (!quest)
continue;
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId());
- if (!sConditionMgr->IsObjectMeetToConditions(this, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK, quest->GetQuestId(), this))
continue;
QuestStatus status = GetQuestStatus(questId);
@@ -18735,7 +18369,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setString(index++, GetName());
stmt->setUInt8(index++, getRace());
stmt->setUInt8(index++, getClass());
- stmt->setUInt8(index++, getGender());
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt64(index++, GetMoney());
@@ -18857,7 +18491,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setString(index++, GetName());
stmt->setUInt8(index++, getRace());
stmt->setUInt8(index++, getClass());
- stmt->setUInt8(index++, getGender());
+ stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER)); // save gender from PLAYER_BYTES_3, UNIT_BYTES_0 changes with every transform effect
stmt->setUInt8(index++, getLevel());
stmt->setUInt32(index++, GetUInt32Value(PLAYER_XP));
stmt->setUInt64(index++, GetMoney());
@@ -20384,8 +20018,7 @@ void Player::VehicleSpellInitialize()
continue;
}
- ConditionList conditions = sConditionMgr->GetConditionsForVehicleSpell(vehicle->GetEntry(), spellId);
- if (!sConditionMgr->IsObjectMeetToConditions(this, vehicle, conditions))
+ if (!sConditionMgr->IsObjectMeetingVehicleSpellConditions(vehicle->GetEntry(), spellId, this, vehicle))
{
TC_LOG_DEBUG("condition", "VehicleSpellInitialize: conditions not met for Vehicle entry %u spell %u", vehicle->ToCreature()->GetEntry(), spellId);
data << uint16(0) << uint8(0) << uint8(i+8);
@@ -21113,8 +20746,7 @@ void Player::InitDisplayIds()
SetNativeDisplayId(info->displayId_m);
break;
default:
- TC_LOG_ERROR("entities.player", "Invalid gender %u for player", gender);
- return;
+ TC_LOG_ERROR("entities.player", "Player %s (%s) has invalid gender %u", GetName().c_str(), GetGUID().ToString().c_str(), gender);
}
}
@@ -21376,8 +21008,7 @@ bool Player::BuyItemFromVendorSlot(ObjectGuid vendorguid, uint32 vendorslot, uin
return false;
}
- ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(creature->GetEntry(), item);
- if (!sConditionMgr->IsObjectMeetToConditions(this, creature, conditions))
+ if (!sConditionMgr->IsObjectMeetingVendorItemConditions(creature->GetEntry(), item, this, creature))
{
TC_LOG_DEBUG("condition", "BuyItemFromVendor: conditions not met for creature entry %u item %u", creature->GetEntry(), item);
SendBuyError(BUY_ERR_CANT_FIND_ITEM, creature, item, 0);
@@ -23316,16 +22947,18 @@ void Player::UpdateForQuestWorldObjects()
{
//! This code doesn't look right, but it was logically converted to condition system to do the exact
//! same thing it did before. It definitely needs to be overlooked for intended functionality.
- ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), _itr->second.spellId);
- bool buildUpdateBlock = false;
- for (ConditionList::const_iterator jtr = conds.begin(); jtr != conds.end() && !buildUpdateBlock; ++jtr)
- if ((*jtr)->ConditionType == CONDITION_QUESTREWARDED || (*jtr)->ConditionType == CONDITION_QUESTTAKEN)
- buildUpdateBlock = true;
-
- if (buildUpdateBlock)
+ if (ConditionContainer const* conds = sConditionMgr->GetConditionsForSpellClickEvent(obj->GetEntry(), _itr->second.spellId))
{
- obj->BuildValuesUpdateBlockForPlayer(&udata, this);
- break;
+ bool buildUpdateBlock = false;
+ for (ConditionContainer::const_iterator jtr = conds->begin(); jtr != conds->end() && !buildUpdateBlock; ++jtr)
+ if ((*jtr)->ConditionType == CONDITION_QUESTREWARDED || (*jtr)->ConditionType == CONDITION_QUESTTAKEN)
+ buildUpdateBlock = true;
+
+ if (buildUpdateBlock)
+ {
+ obj->BuildValuesUpdateBlockForPlayer(&udata, this);
+ break;
+ }
}
}
}
@@ -25086,9 +24719,7 @@ bool Player::CanSeeSpellClickOn(Creature const* c) const
if (!itr->second.IsFitToRequirements(this, c))
return false;
- ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(c->GetEntry(), itr->second.spellId);
- ConditionSourceInfo info = ConditionSourceInfo(const_cast<Player*>(this), const_cast<Creature*>(c));
- if (sConditionMgr->IsObjectMeetToConditions(info, conds))
+ if (sConditionMgr->IsObjectMeetingSpellClickConditions(c->GetEntry(), itr->second.spellId, const_cast<Player*>(this), const_cast<Creature*>(c)))
return true;
}
@@ -25660,52 +25291,27 @@ void Player::SendRefundInfo(Item* item)
return;
}
- ObjectGuid guid = item->GetGUID();
- WorldPacket data(SMSG_SET_ITEM_PURCHASE_DATA, 8 + 4 + 4 + 4 + 4 * 4 + 4 * 4 + 4 + 4);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[1]);
- data.FlushBits();
-
- data.WriteByteSeq(guid[7]);
- data << uint32(GetTotalPlayedTime() - item->GetPlayedTime());
+ WorldPackets::Item::SetItemPurchaseData setItemPurchaseData;
+ setItemPurchaseData.ItemGUID = item->GetGUID();
+ setItemPurchaseData.PurchaseTime = GetTotalPlayedTime() - item->GetPlayedTime();
+ setItemPurchaseData.Contents.Money = item->GetPaidMoney();
+
for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
{
- data << uint32(iece->RequiredItemCount[i]);
- data << uint32(iece->RequiredItem[i]);
+ setItemPurchaseData.Contents.Items[i].ItemCount = iece->RequiredItemCount[i];
+ setItemPurchaseData.Contents.Items[i].ItemID = iece->RequiredItem[i];
}
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[2]);
- for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data
{
if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
- {
- data << uint32(0);
- data << uint32(0);
continue;
- }
- CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
- uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
-
- data << uint32(iece->RequiredCurrencyCount[i] / precision);
- data << uint32(iece->RequiredCurrency[i]);
+ setItemPurchaseData.Contents.Currencies[i].CurrencyCount = iece->RequiredCurrencyCount[i];
+ setItemPurchaseData.Contents.Currencies[i].CurrencyID = iece->RequiredCurrency[i];
}
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[5]);
- data << uint32(0);
- data.WriteByteSeq(guid[0]);
- data << uint32(item->GetPaidMoney()); // money cost
- GetSession()->SendPacket(&data);
+ GetSession()->SendPacket(setItemPurchaseData.Write());
}
bool Player::AddItem(uint32 itemId, uint32 count)
@@ -25733,57 +25339,30 @@ bool Player::AddItem(uint32 itemId, uint32 count)
void Player::SendItemRefundResult(Item* item, ItemExtendedCostEntry const* iece, uint8 error)
{
- ObjectGuid guid = item->GetGUID();
- WorldPacket data(SMSG_ITEM_PURCHASE_REFUND_RESULT, 1 + 1 + 8 + 4*8 + 4 + 4*8 + 1);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[2]);
- data.WriteBit(!error);
- data.WriteBit(item->GetPaidMoney() > 0);
- data.FlushBits();
+ WorldPackets::Item::ItemPurchaseRefundResult itemPurchaseRefundResult;
+ itemPurchaseRefundResult.ItemGUID = item->GetGUID();
+ itemPurchaseRefundResult.Result = error;
if (!error)
{
- for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i)
+ itemPurchaseRefundResult.Contents = boost::in_place();
+ itemPurchaseRefundResult.Contents->Money = item->GetPaidMoney();
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
{
- if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
- {
- data << uint32(0);
- data << uint32(0);
- continue;
- }
-
- CurrencyTypesEntry const* currencyType = sCurrencyTypesStore.LookupEntry(iece->RequiredCurrency[i]);
- uint32 precision = (currencyType && currencyType->Flags & CURRENCY_FLAG_HIGH_PRECISION) ? CURRENCY_PRECISION : 1;
-
- data << uint32(iece->RequiredCurrencyCount[i] / precision);
- data << uint32(iece->RequiredCurrency[i]);
+ itemPurchaseRefundResult.Contents->Items[i].ItemCount = iece->RequiredItemCount[i];
+ itemPurchaseRefundResult.Contents->Items[i].ItemID = iece->RequiredItem[i];
}
- data << uint32(item->GetPaidMoney()); // money cost
-
- for (uint8 i = 0; i < MAX_ITEM_EXT_COST_ITEMS; ++i) // item cost data
+ for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // currency cost data
{
- data << uint32(iece->RequiredItemCount[i]);
- data << uint32(iece->RequiredItem[i]);
+ if (iece->RequirementFlags & (ITEM_EXT_COST_CURRENCY_REQ_IS_SEASON_EARNED_1 << i))
+ continue;
+
+ itemPurchaseRefundResult.Contents->Currencies[i].CurrencyCount = iece->RequiredCurrencyCount[i];
+ itemPurchaseRefundResult.Contents->Currencies[i].CurrencyID = iece->RequiredCurrency[i];
}
}
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[5]);
-
- data << uint8(error); // error code
- GetSession()->SendPacket(&data);
+ GetSession()->SendPacket(itemPurchaseRefundResult.Write());
}
void Player::RefundItem(Item* item)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 60447757035..be6f8e619ab 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -28,10 +28,12 @@
#include "PetDefines.h"
#include "QuestDef.h"
#include "SpellMgr.h"
+#include "SpellHistory.h"
#include "Unit.h"
#include "Opcodes.h"
#include "WorldSession.h"
#include "PlayerTaxi.h"
+#include "TradeData.h"
struct CreatureTemplate;
struct Mail;
@@ -833,14 +835,6 @@ struct ItemPosCount
};
typedef std::vector<ItemPosCount> ItemPosCountVec;
-enum TradeSlots
-{
- TRADE_SLOT_COUNT = 7,
- TRADE_SLOT_TRADED_COUNT = 6,
- TRADE_SLOT_NONTRADED = 6,
- TRADE_SLOT_INVALID = -1
-};
-
enum TransferAbortReason
{
TRANSFER_ABORT_NONE = 0,
@@ -1132,65 +1126,6 @@ struct VoidStorageItem
std::vector<int32> BonusListIDs;
};
-class TradeData
-{
- public: // constructors
- TradeData(Player* player, Player* trader) :
- m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false),
- m_money(0), m_spell(0), m_spellCastItem(), m_clientStateIndex(1), m_serverStateIndex(1) { }
-
- Player* GetTrader() const { return m_trader; }
- TradeData* GetTraderData() const;
-
- Item* GetItem(TradeSlots slot) const;
- bool HasItem(ObjectGuid itemGuid) const;
- TradeSlots GetTradeSlotForItem(ObjectGuid itemGuid) const;
- void SetItem(TradeSlots slot, Item* item);
-
- uint32 GetSpell() const { return m_spell; }
- void SetSpell(uint32 spell_id, Item* castItem = NULL);
-
- Item* GetSpellCastItem() const;
- bool HasSpellCastItem() const { return !m_spellCastItem.IsEmpty(); }
-
- uint64 GetMoney() const { return m_money; }
- void SetMoney(uint64 money);
-
- bool IsAccepted() const { return m_accepted; }
- void SetAccepted(bool state, bool crosssend = false);
-
- bool IsInAcceptProcess() const { return m_acceptProccess; }
- void SetInAcceptProcess(bool state) { m_acceptProccess = state; }
-
- uint32 GetClientStateIndex() const { return m_clientStateIndex; }
- void UpdateClientStateIndex() { ++m_clientStateIndex; }
-
- uint32 GetServerStateIndex() const { return m_serverStateIndex; }
- void UpdateServerStateIndex() { m_serverStateIndex = rand32(); }
-
- private: // internal functions
-
- void Update(bool for_trader = true);
-
- private: // fields
-
- Player* m_player; // Player who own of this TradeData
- Player* m_trader; // Player who trade with m_player
-
- bool m_accepted; // m_player press accept for trade list
- bool m_acceptProccess; // one from player/trader press accept and this processed
-
- uint64 m_money; // m_player place money to trade
-
- uint32 m_spell; // m_player apply spell to non-traded slot item
- ObjectGuid m_spellCastItem; // applied spell cast by item use
-
- ObjectGuid m_items[TRADE_SLOT_COUNT]; // traded items from m_player side including non-traded slot
-
- uint32 m_clientStateIndex;
- uint32 m_serverStateIndex;
-};
-
struct ResurrectionData
{
ObjectGuid GUID;
@@ -1200,38 +1135,6 @@ struct ResurrectionData
uint32 Aura;
};
-class KillRewarder
-{
-public:
- KillRewarder(Player* killer, Unit* victim, bool isBattleGround);
-
- void Reward();
-
-private:
- void _InitXP(Player* player);
- void _InitGroupData();
-
- void _RewardHonor(Player* player);
- void _RewardXP(Player* player, float rate);
- void _RewardReputation(Player* player, float rate);
- void _RewardKillCredit(Player* player);
- void _RewardPlayer(Player* player, bool isDungeon);
- void _RewardGroup();
-
- Player* _killer;
- Unit* _victim;
- Group* _group;
- float _groupRate;
- Player* _maxNotGrayMember;
- uint32 _count;
- uint32 _sumLevel;
- uint32 _xp;
- bool _isFullXP;
- uint8 _maxLevel;
- bool _isBattleGround;
- bool _isPvP;
-};
-
static uint32 const DefaultTalentRowLevels[MAX_TALENT_TIERS] = { 15, 30, 45, 60, 75, 90, 100 };
static uint32 const DKTalentRowLevels[MAX_TALENT_TIERS] = { 57, 58, 59, 60, 75, 90, 100 };
@@ -1445,7 +1348,6 @@ class Player : public Unit, public GridObject<Player>
InventoryResult CanUseItem(Item* pItem, bool not_loading = true) const;
bool HasItemTotemCategory(uint32 TotemCategory) const;
InventoryResult CanUseItem(ItemTemplate const* pItem) const;
- InventoryResult CanUseAmmo(uint32 item) const;
InventoryResult CanRollForItemInLFG(ItemTemplate const* item, WorldObject const* lootedObject) const;
Item* StoreNewItem(ItemPosCountVec const& pos, uint32 itemId, bool update, int32 randomPropertyId = 0, GuidSet const& allowedLooters = GuidSet(), std::vector<int32> const& bonusListIDs = std::vector<int32>());
Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update);
@@ -1470,11 +1372,11 @@ class Player : public Unit, public GridObject<Player>
/// send conquest currency points and their cap week/arena
void SendPvpRewards() const;
/// return count of currency witch has plr
- uint32 GetCurrency(uint32 id, bool usePrecision) const;
+ uint32 GetCurrency(uint32 id) const;
/// return count of currency gaind on current week
- uint32 GetCurrencyOnWeek(uint32 id, bool usePrecision) const;
+ uint32 GetCurrencyOnWeek(uint32 id) const;
/// return week cap by currency id
- uint32 GetCurrencyWeekCap(uint32 id, bool usePrecision) const;
+ uint32 GetCurrencyWeekCap(uint32 id) const;
/// return presence related currency
bool HasCurrency(uint32 id, uint32 count) const;
/// initialize currency count for custom initialization at create character
@@ -1529,7 +1431,7 @@ class Player : public Unit, public GridObject<Player>
float GetReputationPriceDiscount(Creature const* creature) const;
- Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : NULL; }
+ Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : nullptr; }
TradeData* GetTradeData() const { return m_trade; }
void TradeCancel(bool sendback);
@@ -2642,7 +2544,6 @@ class Player : public Unit, public GridObject<Player>
void _LoadGroup(PreparedQueryResult result);
void _LoadSkills(PreparedQueryResult result);
void _LoadSpells(PreparedQueryResult result);
- void _LoadFriendList(PreparedQueryResult result);
bool _LoadHomeBind(PreparedQueryResult result);
void _LoadDeclinedNames(PreparedQueryResult result);
void _LoadArenaTeamInfo(PreparedQueryResult result);
diff --git a/src/server/game/Entities/Player/TradeData.cpp b/src/server/game/Entities/Player/TradeData.cpp
new file mode 100644
index 00000000000..d879c9df61c
--- /dev/null
+++ b/src/server/game/Entities/Player/TradeData.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2008-2015 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 "TradeData.h"
+#include "Player.h"
+#include "TradePackets.h"
+
+TradeData* TradeData::GetTraderData() const
+{
+ return _trader->GetTradeData();
+}
+
+Item* TradeData::GetItem(TradeSlots slot) const
+{
+ return !_items[slot].IsEmpty() ? _player->GetItemByGuid(_items[slot]) : nullptr;
+}
+
+bool TradeData::HasItem(ObjectGuid itemGuid) const
+{
+ for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
+ if (_items[i] == itemGuid)
+ return true;
+
+ return false;
+}
+
+TradeSlots TradeData::GetTradeSlotForItem(ObjectGuid itemGuid) const
+{
+ for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i)
+ if (_items[i] == itemGuid)
+ return TradeSlots(i);
+
+ return TRADE_SLOT_INVALID;
+}
+
+Item* TradeData::GetSpellCastItem() const
+{
+ return !_spellCastItem.IsEmpty() ? _player->GetItemByGuid(_spellCastItem) : nullptr;
+}
+
+void TradeData::SetItem(TradeSlots slot, Item* item, bool update /*= false*/)
+{
+ ObjectGuid itemGuid;
+ if (item)
+ itemGuid = item->GetGUID();
+
+ if (_items[slot] == itemGuid && !update)
+ return;
+
+ _items[slot] = itemGuid;
+
+ SetAccepted(false);
+ GetTraderData()->SetAccepted(false);
+
+ UpdateServerStateIndex();
+
+ Update();
+
+ // need remove possible trader spell applied to changed item
+ if (slot == TRADE_SLOT_NONTRADED)
+ GetTraderData()->SetSpell(0);
+
+ // need remove possible player spell applied (possible move reagent)
+ SetSpell(0);
+}
+
+void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= nullptr*/)
+{
+ ObjectGuid itemGuid = castItem ? castItem->GetGUID() : ObjectGuid::Empty;
+
+ if (_spell == spell_id && _spellCastItem == itemGuid)
+ return;
+
+ _spell = spell_id;
+ _spellCastItem = itemGuid;
+
+ SetAccepted(false);
+ GetTraderData()->SetAccepted(false);
+
+ UpdateServerStateIndex();
+
+ Update(true); // send spell info to item owner
+ Update(false); // send spell info to caster self
+}
+
+void TradeData::SetMoney(uint64 money)
+{
+ if (_money == money)
+ return;
+
+ if (!_player->HasEnoughMoney(money))
+ {
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_FAILED;
+ info.BagResult = EQUIP_ERR_NOT_ENOUGH_MONEY;
+ _player->GetSession()->SendTradeStatus(info);
+ return;
+ }
+
+ _money = money;
+
+ SetAccepted(false);
+ GetTraderData()->SetAccepted(false);
+
+ UpdateServerStateIndex();
+
+ Update(true);
+}
+
+void TradeData::Update(bool forTrader /*= true*/) const
+{
+ if (forTrader)
+ _trader->GetSession()->SendUpdateTrade(true); // player state for trader
+ else
+ _player->GetSession()->SendUpdateTrade(false); // player state for player
+}
+
+void TradeData::SetAccepted(bool state, bool forTrader /*= false*/)
+{
+ _accepted = state;
+
+ if (!state)
+ {
+ WorldPackets::Trade::TradeStatus info;
+ info.Status = TRADE_STATUS_UNACCEPTED;
+ if (forTrader)
+ _trader->GetSession()->SendTradeStatus(info);
+ else
+ _player->GetSession()->SendTradeStatus(info);
+ }
+}
diff --git a/src/server/game/Entities/Player/TradeData.h b/src/server/game/Entities/Player/TradeData.h
new file mode 100644
index 00000000000..733d4702b1f
--- /dev/null
+++ b/src/server/game/Entities/Player/TradeData.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef TradeData_h__
+#define TradeData_h__
+
+#include "ObjectGuid.h"
+
+enum TradeSlots
+{
+ TRADE_SLOT_COUNT = 7,
+ TRADE_SLOT_TRADED_COUNT = 6,
+ TRADE_SLOT_NONTRADED = 6,
+ TRADE_SLOT_INVALID = -1
+};
+
+class Item;
+class Player;
+
+class TradeData
+{
+public:
+ TradeData(Player* player, Player* trader) :
+ _player(player), _trader(trader), _accepted(false), _acceptProccess(false),
+ _money(0), _spell(0), _spellCastItem(), _clientStateIndex(1), _serverStateIndex(1) { }
+
+ Player* GetTrader() const { return _trader; }
+ TradeData* GetTraderData() const;
+
+ Item* GetItem(TradeSlots slot) const;
+ bool HasItem(ObjectGuid itemGuid) const;
+ TradeSlots GetTradeSlotForItem(ObjectGuid itemGuid) const;
+ void SetItem(TradeSlots slot, Item* item, bool update = false);
+
+ uint32 GetSpell() const { return _spell; }
+ void SetSpell(uint32 spell_id, Item* castItem = nullptr);
+
+ Item* GetSpellCastItem() const;
+ bool HasSpellCastItem() const { return !_spellCastItem.IsEmpty(); }
+
+ uint64 GetMoney() const { return _money; }
+ void SetMoney(uint64 money);
+
+ bool IsAccepted() const { return _accepted; }
+ void SetAccepted(bool state, bool forTrader = false);
+
+ bool IsInAcceptProcess() const { return _acceptProccess; }
+ void SetInAcceptProcess(bool state) { _acceptProccess = state; }
+
+ uint32 GetClientStateIndex() const { return _clientStateIndex; }
+ void UpdateClientStateIndex() { ++_clientStateIndex; }
+
+ uint32 GetServerStateIndex() const { return _serverStateIndex; }
+ void UpdateServerStateIndex() { _serverStateIndex = rand32(); }
+
+private:
+ void Update(bool for_trader = true) const;
+
+ Player* _player; // Player who own of this TradeData
+ Player* _trader; // Player who trade with _player
+
+ bool _accepted; // _player press accept for trade list
+ bool _acceptProccess; // one from player/trader press accept and this processed
+
+ uint64 _money; // _player place money to trade
+
+ uint32 _spell; // _player apply spell to non-traded slot item
+ ObjectGuid _spellCastItem; // applied spell cast by item use
+
+ ObjectGuid _items[TRADE_SLOT_COUNT]; // traded items from _player side including non-traded slot
+
+ uint32 _clientStateIndex;
+ uint32 _serverStateIndex;
+};
+
+#endif // TradeData_h__
diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp
index f85860dfde3..1451b018a39 100644
--- a/src/server/game/Entities/Unit/StatSystem.cpp
+++ b/src/server/game/Entities/Unit/StatSystem.cpp
@@ -681,19 +681,19 @@ void Player::UpdateArmorPenetration(int32 amount)
void Player::UpdateMeleeHitChances()
{
- m_modMeleeHitChance = (float)GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modMeleeHitChance = 7.5f + (float)GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
m_modMeleeHitChance += GetRatingBonusValue(CR_HIT_MELEE);
}
void Player::UpdateRangedHitChances()
{
- m_modRangedHitChance = (float)GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
+ m_modRangedHitChance = 7.5f + (float)GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE);
m_modRangedHitChance += GetRatingBonusValue(CR_HIT_RANGED);
}
void Player::UpdateSpellHitChances()
{
- m_modSpellHitChance = (float)GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
+ m_modSpellHitChance = 15.0f + (float)GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE);
m_modSpellHitChance += GetRatingBonusValue(CR_HIT_SPELL);
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 9d18fddb2b6..bd928270f14 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -263,9 +263,18 @@ Unit::Unit(bool isWorldObject) :
m_createStats[i] = 0.0f;
m_attacking = NULL;
- m_modMeleeHitChance = 0.0f;
- m_modRangedHitChance = 0.0f;
- m_modSpellHitChance = 0.0f;
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ m_modMeleeHitChance = 7.5f;
+ m_modRangedHitChance = 7.5f;
+ m_modSpellHitChance = 15.0f;
+ }
+ else
+ {
+ m_modMeleeHitChance = 0.0f;
+ m_modRangedHitChance = 0.0f;
+ m_modSpellHitChance = 0.0f;
+ }
m_baseSpellCritChance = 5;
m_CombatTimer = 0;
@@ -1055,7 +1064,6 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama
{
damageInfo->HitInfo |= SPELL_HIT_TYPE_CRIT;
damage = SpellCriticalDamageBonus(spellInfo, damage, victim);
-
}
ApplyResilience(victim, &damage);
@@ -1912,42 +1920,29 @@ void Unit::HandleProcExtraAttackFor(Unit* victim)
}
}
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit* victim, WeaponAttackType attType) const
+MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const
{
- // This is only wrapper
+ if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
+ return MELEE_HIT_EVADE;
// Miss chance based on melee
//float miss_chance = MeleeMissChanceCalc(victim, attType);
- float miss_chance = MeleeSpellMissChance(victim, attType, 0);
+ int32 miss_chance = int32(MeleeSpellMissChance(victim, attType, 0) * 100);
// Critical hit chance
- float crit_chance = GetUnitCriticalChance(attType, victim);
+ int32 crit_chance = int32(GetUnitCriticalChance(attType, victim) * 100);
// stunned target cannot dodge and this is check in GetUnitDodgeChance() (returned 0 in this case)
- float dodge_chance = victim->GetUnitDodgeChance();
- float block_chance = victim->GetUnitBlockChance();
- float parry_chance = victim->GetUnitParryChance();
-
- // Useful if want to specify crit & miss chances for melee, else it could be removed
- TC_LOG_DEBUG("entities.unit", "MELEE OUTCOME: miss %f crit %f dodge %f parry %f block %f", miss_chance, crit_chance, dodge_chance, parry_chance, block_chance);
+ int32 dodge_chance = int32(victim->GetUnitDodgeChanceAgainst(this) * 100);
+ int32 block_chance = int32(victim->GetUnitBlockChanceAgainst(this) * 100);
+ int32 parry_chance = int32(victim->GetUnitParryChanceAgainst(this) * 100);
- return RollMeleeOutcomeAgainst(victim, attType, int32(crit_chance*100), int32(miss_chance*100), int32(dodge_chance*100), int32(parry_chance*100), int32(block_chance*100));
-}
-
-MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const
-{
- if (victim->GetTypeId() == TYPEID_UNIT && victim->ToCreature()->IsInEvadeMode())
- return MELEE_HIT_EVADE;
-
- int32 attackerMaxSkillValueForLevel = GetMaxSkillValueForLevel(victim);
- int32 victimMaxSkillValueForLevel = victim->GetMaxSkillValueForLevel(this);
-
- // bonus from skills is 0.04%
- int32 skillBonus = 4 * (attackerMaxSkillValueForLevel - victimMaxSkillValueForLevel);
int32 sum = 0, tmp = 0;
int32 roll = urand (0, 10000);
- TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: skill bonus of %d for attacker", skillBonus);
+ int32 attackerLevel = getLevelForTarget(victim);
+ int32 victimLevel = getLevelForTarget(this);
+
TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: rolled %d, miss %d, dodge %d, parry %d, block %d, crit %d",
roll, miss_chance, dodge_chance, parry_chance, block_chance, crit_chance);
@@ -1982,15 +1977,14 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
dodge_chance -= GetTotalAuraModifier(SPELL_AURA_MOD_EXPERTISE) * 25;
// Modify dodge chance by attacker SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
- dodge_chance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE) * 100;
- dodge_chance = int32 (float (dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
+ dodge_chance += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE) * 100;
+ dodge_chance = int32(float(dodge_chance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
tmp = dodge_chance;
if ((tmp > 0) // check if unit _can_ dodge
- && ((tmp -= skillBonus) > 0)
&& roll < (sum += tmp))
{
- TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: DODGE <%d, %d)", sum-tmp, sum);
+ TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: DODGE <%d, %d)", sum - tmp, sum);
return MELEE_HIT_DODGE;
}
}
@@ -2012,7 +2006,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
{
int32 tmp2 = int32(parry_chance);
if (tmp2 > 0 // check if unit _can_ parry
- && (tmp2 -= skillBonus) > 0
&& roll < (sum += tmp2))
{
TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: PARRY <%d, %d)", sum-tmp2, sum);
@@ -2024,7 +2017,6 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
{
tmp = block_chance;
if (tmp > 0 // check if unit _can_ block
- && (tmp -= skillBonus) > 0
&& roll < (sum += tmp))
{
TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: BLOCK <%d, %d)", sum-tmp, sum);
@@ -2049,13 +2041,10 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
if (attType != RANGED_ATTACK &&
(GetTypeId() == TYPEID_PLAYER || IsPet()) &&
victim->GetTypeId() != TYPEID_PLAYER && !victim->IsPet() &&
- getLevel() < victim->getLevelForTarget(this))
+ attackerLevel + 3 < victimLevel)
{
// cap possible value (with bonuses > max skill)
- int32 skill = attackerMaxSkillValueForLevel;
-
- tmp = (10 + (victimMaxSkillValueForLevel - skill)) * 100;
- tmp = tmp > 4000 ? 4000 : tmp;
+ tmp = (10 + 10 * (victimLevel - attackerLevel)) * 100;
if (roll < (sum += tmp))
{
TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: GLANCING <%d, %d)", sum-4000, sum);
@@ -2064,24 +2053,17 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackT
}
// mobs can score crushing blows if they're 4 or more levels above victim
- if (getLevelForTarget(victim) >= victim->getLevelForTarget(this) + 4 &&
+ if (attackerLevel >= victimLevel + 4 &&
// can be from by creature (if can) or from controlled player that considered as creature
!IsControlledByPlayer() &&
!(GetTypeId() == TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_CRUSH))
{
- // when their weapon skill is 15 or more above victim's defense skill
- tmp = victimMaxSkillValueForLevel;
- // tmp = mob's level * 5 - player's current defense skill
- tmp = attackerMaxSkillValueForLevel - tmp;
- if (tmp >= 15)
+ // add 2% chance per level, min. is 15%
+ tmp = attackerLevel - victimLevel * 1000 - 1500;
+ if (roll < (sum += tmp))
{
- // add 2% chance per lacking skill point, min. is 15%
- tmp = tmp * 200 - 1500;
- if (roll < (sum += tmp))
- {
- TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: CRUSHING <%d, %d)", sum-tmp, sum);
- return MELEE_HIT_CRUSHING;
- }
+ TC_LOG_DEBUG("entities.unit", "RollMeleeOutcomeAgainst: CRUSHING <%d, %d)", sum-tmp, sum);
+ return MELEE_HIT_CRUSHING;
}
}
@@ -2176,7 +2158,7 @@ bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttac
victim->ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_NO_BLOCK)
return false;
- if (roll_chance_f(victim->GetUnitBlockChance()))
+ if (roll_chance_f(victim->GetUnitBlockChanceAgainst(this)))
return true;
}
return false;
@@ -2353,7 +2335,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canDodge)
{
// Roll dodge
- int32 dodgeChance = int32(victim->GetUnitDodgeChance() * 100.0f);
+ int32 dodgeChance = int32(victim->GetUnitDodgeChanceAgainst(this) * 100.0f);
// Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE
dodgeChance += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE) * 100;
dodgeChance = int32(float(dodgeChance) * GetTotalAuraMultiplier(SPELL_AURA_MOD_ENEMY_DODGE));
@@ -2372,7 +2354,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canParry)
{
// Roll parry
- int32 parryChance = int32(victim->GetUnitParryChance() * 100.0f);
+ int32 parryChance = int32(victim->GetUnitParryChanceAgainst(this) * 100.0f);
// Reduce parry chance by attacker expertise rating
if (GetTypeId() == TYPEID_PLAYER)
parryChance -= int32(ToPlayer()->GetExpertiseDodgeOrParryReduction(attType) * 100.0f);
@@ -2388,7 +2370,7 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (canBlock)
{
- int32 blockChance = int32(victim->GetUnitBlockChance() * 100.0f);
+ int32 blockChance = int32(victim->GetUnitBlockChanceAgainst(this) * 100.0f);
if (blockChance < 0)
blockChance = 0;
tmp += blockChance;
@@ -2414,11 +2396,27 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo
if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTrigger())
thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel);
int32 leveldif = int32(victim->getLevelForTarget(this)) - thisLevel;
+ int32 levelBasedHitDiff = leveldif;
// Base hit chance from attacker and victim levels
int32 modHitChance = 100;
- if (leveldif > 3)
- modHitChance -= (leveldif - 3) * lchance;
+ if (levelBasedHitDiff >= 0)
+ {
+ if (victim->GetTypeId() != TYPEID_PLAYER)
+ {
+ modHitChance = 94 - 3 * std::min(levelBasedHitDiff, 3);
+ levelBasedHitDiff -= 3;
+ }
+ else
+ {
+ modHitChance = 96 - std::min(levelBasedHitDiff, 2);
+ levelBasedHitDiff -= 2;
+ }
+ if (levelBasedHitDiff > 0)
+ modHitChance -= lchance * std::min(levelBasedHitDiff, 7);
+ }
+ else
+ modHitChance = 97 - levelBasedHitDiff;
// Spellmod from SPELLMOD_RESIST_MISS_CHANCE
if (Player* modOwner = GetSpellModOwner())
@@ -2523,12 +2521,7 @@ SpellMissInfo Unit::SpellHitResult(Unit* victim, SpellInfo const* spellInfo, boo
return SPELL_MISS_NONE;
}
-uint32 Unit::GetUnitMeleeSkill(Unit const* target) const
-{
- return (target ? getLevelForTarget(target) : getLevel()) * 5;
-}
-
-float Unit::GetUnitDodgeChance() const
+float Unit::GetUnitDodgeChanceAgainst(Unit const* attacker) const
{
if (IsNonMeleeSpellCast(false) || HasUnitState(UNIT_STATE_CONTROLLED))
return 0.0f;
@@ -2541,14 +2534,16 @@ float Unit::GetUnitDodgeChance() const
return 0.0f;
else
{
- float dodge = 5.0f;
- dodge += GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT);
+ float dodge = 3.0f + GetTotalAuraModifier(SPELL_AURA_MOD_DODGE_PERCENT);
+ int32 levelDiff = getLevelForTarget(attacker) - attacker->getLevelForTarget(this);
+ if (levelDiff > 0)
+ dodge += 1.5f * levelDiff;
return dodge > 0.0f ? dodge : 0.0f;
}
}
}
-float Unit::GetUnitParryChance() const
+float Unit::GetUnitParryChanceAgainst(Unit const* attacker) const
{
if (IsNonMeleeSpellCast(false) || HasUnitState(UNIT_STATE_CONTROLLED))
return 0.0f;
@@ -2569,11 +2564,11 @@ float Unit::GetUnitParryChance() const
}
else if (GetTypeId() == TYPEID_UNIT)
{
- if (GetCreatureType() == CREATURE_TYPE_HUMANOID)
- {
- chance = 5.0f;
- chance += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT);
- }
+ chance = 6.0f;
+ int32 levelDiff = getLevelForTarget(attacker) - attacker->getLevelForTarget(this);
+ if (levelDiff > 0)
+ chance += 1.5f * levelDiff;
+ chance += GetTotalAuraModifier(SPELL_AURA_MOD_PARRY_PERCENT);
}
return chance > 0.0f ? chance : 0.0f;
@@ -2591,7 +2586,7 @@ float Unit::GetUnitMissChance(WeaponAttackType attType) const
return miss_chance;
}
-float Unit::GetUnitBlockChance() const
+float Unit::GetUnitBlockChanceAgainst(Unit const* attacker) const
{
if (IsNonMeleeSpellCast(false) || HasUnitState(UNIT_STATE_CONTROLLED))
return 0.0f;
@@ -2601,7 +2596,7 @@ float Unit::GetUnitBlockChance() const
if (player->CanBlock())
{
Item* tmpitem = player->GetUseableItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND);
- if (tmpitem && !tmpitem->IsBroken())
+ if (tmpitem && !tmpitem->IsBroken() && tmpitem->GetTemplate()->GetInventoryType() == INVTYPE_SHIELD)
return GetFloatValue(PLAYER_BLOCK_PERCENTAGE);
}
// is player but has no block ability or no not broken shield equipped
@@ -2613,7 +2608,10 @@ float Unit::GetUnitBlockChance() const
return 0.0f;
else
{
- float block = 5.0f;
+ float block = 3.0f;
+ int32 levelDiff = getLevelForTarget(attacker) - attacker->getLevelForTarget(this);
+ if (levelDiff > 0)
+ block += 1.5f * levelDiff;
block += GetTotalAuraModifier(SPELL_AURA_MOD_BLOCK_PERCENT);
return block > 0.0f ? block : 0.0f;
}
@@ -11901,7 +11899,7 @@ void CharmInfo::InitPossessCreateSpells()
{
uint32 spellId = _unit->ToCreature()->m_spells[i];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (spellInfo && !spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD))
+ if (spellInfo)
{
if (spellInfo->IsPassive())
_unit->CastSpell(_unit, spellInfo, true);
@@ -11929,7 +11927,7 @@ void CharmInfo::InitCharmCreateSpells()
uint32 spellId = _unit->ToCreature()->m_spells[x];
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
- if (!spellInfo || spellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD))
+ if (!spellInfo)
{
_charmspells[x].SetActionAndType(spellId, ACT_DISABLED);
continue;
@@ -12303,9 +12301,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit* target, uint32 procFlag, u
continue;
// do checks using conditions table
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id);
- ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
- if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPELL_PROC, spellProto->Id, eventInfo.GetActor(), eventInfo.GetActionTarget()))
continue;
// AuraScript Hook
@@ -12780,6 +12776,9 @@ bool Unit::IsPolymorphed() const
void Unit::SetDisplayId(uint32 modelId)
{
SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId);
+ // Set Gender by modelId
+ if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId))
+ SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender);
}
void Unit::RestoreDisplayId()
@@ -14494,32 +14493,14 @@ void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack)
aura->SetStackAmount(stack);
}
-void Unit::SendPlaySpellVisualKit(uint32 id, uint32 unkParam)
-{
- ObjectGuid guid = GetGUID();
-
- WorldPacket data(SMSG_PLAY_SPELL_VISUAL_KIT, 4 + 4+ 4 + 8);
- data << uint32(0);
- data << uint32(id); // SpellVisualKit.dbc index
- data << uint32(unkParam);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[6]);
- data.FlushBits();
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[5]);
- SendMessageToSet(&data, true);
+void Unit::SendPlaySpellVisualKit(uint32 id, uint32 type)
+{
+ WorldPackets::Spells::PlaySpellVisualKit playSpellVisualKit;
+ playSpellVisualKit.Unit = GetGUID();
+ playSpellVisualKit.KitRecID = id;
+ playSpellVisualKit.KitType = type;
+ playSpellVisualKit.Duration = 0;
+ SendMessageToSet(playSpellVisualKit.Write(), true);
}
void Unit::ApplyResilience(Unit const* victim, int32* damage) const
@@ -14574,8 +14555,8 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u
// Limit miss chance from 0 to 60%
if (missChance < 0.0f)
return 0.0f;
- if (missChance > 60.0f)
- return 60.0f;
+ if (missChance > 77.0f)
+ return 77.0f;
return missChance;
}
@@ -14646,38 +14627,14 @@ void Unit::UpdateObjectVisibility(bool forced)
void Unit::SendMoveKnockBack(Player* player, float speedXY, float speedZ, float vcos, float vsin)
{
- ObjectGuid guid = GetGUID();
- WorldPacket data(SMSG_MOVE_KNOCK_BACK, (1+8+4+4+4+4+4));
- data.WriteBit(guid[0]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[4]);
-
- data.WriteByteSeq(guid[1]);
-
- data << float(vsin);
- data << uint32(0);
-
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[7]);
-
- data << float(speedXY);
-
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[5]);
- data.WriteByteSeq(guid[3]);
-
- data << float(speedZ);
- data << float(vcos);
-
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[0]);
-
- player->GetSession()->SendPacket(&data);
+ WorldPackets::Movement::MoveKnockBack moveKnockBack;
+ moveKnockBack.MoverGUID = GetGUID();
+ moveKnockBack.SequenceIndex = m_movementCounter++;
+ moveKnockBack.HorzSpeed = speedXY;
+ moveKnockBack.VertSpeed = speedZ;
+ moveKnockBack.Direction.x = vcos;
+ moveKnockBack.Direction.y = vsin;
+ player->GetSession()->SendPacket(moveKnockBack.Write());
}
void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ)
@@ -15210,9 +15167,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
continue;
//! Check database conditions
- ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId);
- ConditionSourceInfo info = ConditionSourceInfo(clicker, this);
- if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
+ if (!sConditionMgr->IsObjectMeetingSpellClickConditions(spellClickEntry, itr->second.spellId, clicker, this))
continue;
Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
@@ -15460,8 +15415,10 @@ void Unit::SendTeleportPacket(Position& pos)
{
WorldPackets::Movement::MoveTeleport moveTeleport;
moveTeleport.MoverGUID = GetGUID();
- moveTeleport.TransportGUID = GetTransGUID();
moveTeleport.Pos.Relocate(pos);
+ if (TransportBase* transportBase = GetDirectTransport())
+ transportBase->CalculatePassengerOffset(moveTeleport.Pos.m_positionX, moveTeleport.Pos.m_positionY, moveTeleport.Pos.m_positionZ);
+ moveTeleport.TransportGUID = GetTransGUID();
moveTeleport.Facing = GetOrientation();
moveTeleport.SequenceIndex = m_movementCounter++;
ToPlayer()->SendDirectMessage(moveTeleport.Write());
@@ -16096,6 +16053,41 @@ bool Unit::SetHover(bool enable, bool packetOnly /*= false*/)
return true;
}
+bool Unit::SetCollision(bool disable)
+{
+ if (disable == HasUnitMovementFlag(MOVEMENTFLAG_DISABLE_COLLISION))
+ return false;
+
+ if (disable)
+ AddUnitMovementFlag(MOVEMENTFLAG_DISABLE_COLLISION);
+ else
+ RemoveUnitMovementFlag(MOVEMENTFLAG_DISABLE_COLLISION);
+
+ static OpcodeServer const collisionOpcodeTable[2][2] =
+ {
+ { SMSG_MOVE_SPLINE_ENABLE_COLLISION, SMSG_MOVE_ENABLE_COLLISION },
+ { SMSG_MOVE_SPLINE_DISABLE_COLLISION, SMSG_MOVE_DISABLE_COLLISION }
+ };
+
+ bool player = GetTypeId() == TYPEID_PLAYER && ToPlayer()->m_mover->GetTypeId() == TYPEID_PLAYER;
+
+ if (player)
+ {
+ WorldPackets::Movement::MoveSetFlag packet(collisionOpcodeTable[disable][1]);
+ packet.MoverGUID = GetGUID();
+ packet.SequenceIndex = m_movementCounter++;
+ SendMessageToSet(packet.Write(), true);
+ }
+ else
+ {
+ WorldPackets::Movement::MoveSplineSetFlag packet(collisionOpcodeTable[disable][0]);
+ packet.MoverGUID = GetGUID();
+ SendMessageToSet(packet.Write(), true);
+ }
+
+ return true;
+}
+
void Unit::SendSetVehicleRecId(uint32 vehicleId)
{
if (Player* player = ToPlayer())
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index c6a012ac1b7..94eac857b24 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -820,7 +820,7 @@ enum MovementFlags
// to properly calculate all movement
MOVEMENTFLAG_MASK_CREATURE_ALLOWED =
MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | MOVEMENTFLAG_SWIMMING |
- MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER,
+ MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER | MOVEMENTFLAG_DISABLE_COLLISION,
/// @todo if needed: add more flags to this masks that are exclusive to players
MOVEMENTFLAG_MASK_PLAYER_ONLY =
@@ -828,7 +828,7 @@ enum MovementFlags
/// Movement flags that have change status opcodes associated for players
MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT |
- MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER
+ MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER | MOVEMENTFLAG_DISABLE_COLLISION
};
enum MovementFlags2
@@ -1535,9 +1535,9 @@ class Unit : public WorldObject
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo);
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool canReflect = false);
- float GetUnitDodgeChance() const;
- float GetUnitParryChance() const;
- float GetUnitBlockChance() const;
+ float GetUnitDodgeChanceAgainst(Unit const* attacker) const;
+ float GetUnitParryChanceAgainst(Unit const* attacker) const;
+ float GetUnitBlockChanceAgainst(Unit const* attacker) const;
float GetUnitMissChance(WeaponAttackType attType) const;
float GetUnitCriticalChance(WeaponAttackType attackType, const Unit* victim) const;
int32 GetMechanicResistChance(SpellInfo const* spellInfo) const;
@@ -1545,13 +1545,10 @@ class Unit : public WorldObject
virtual uint32 GetBlockPercent() const { return 30; }
- uint32 GetUnitMeleeSkill(Unit const* target = NULL) const;
-
float GetWeaponProcChance() const;
float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spellProto) const;
- MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackType attType) const;
- MeleeHitOutcome RollMeleeOutcomeAgainst (const Unit* victim, WeaponAttackType attType, int32 crit_chance, int32 miss_chance, int32 dodge_chance, int32 parry_chance, int32 block_chance) const;
+ MeleeHitOutcome RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const;
bool IsVendor() const { return HasFlag64(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_VENDOR); }
bool IsTrainer() const { return HasFlag64(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_TRAINER); }
@@ -1626,7 +1623,7 @@ class Unit : public WorldObject
Aura* AddAura(uint32 spellId, Unit* target);
Aura* AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
- void SendPlaySpellVisualKit(uint32 id, uint32 unkParam);
+ void SendPlaySpellVisualKit(uint32 id, uint32 type);
void DeMorph();
@@ -1667,6 +1664,7 @@ class Unit : public WorldObject
bool SetWaterWalking(bool enable, bool packetOnly = false);
bool SetFeatherFall(bool enable, bool packetOnly = false);
bool SetHover(bool enable, bool packetOnly = false);
+ bool SetCollision(bool disable);
void SendSetVehicleRecId(uint32 vehicleId);
void SetInFront(WorldObject const* target);
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 5e5ec3be6eb..2a0a4cbe917 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -524,7 +524,7 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.RegenHealth = fields[74].GetBool();
creatureTemplate.MechanicImmuneMask = fields[75].GetUInt32();
creatureTemplate.flags_extra = fields[76].GetUInt32();
- creatureTemplate.ScriptID = GetScriptId(fields[77].GetCString());
+ creatureTemplate.ScriptID = GetScriptId(fields[77].GetString());
}
void ObjectMgr::LoadCreatureTemplateAddons()
@@ -577,6 +577,12 @@ void ObjectMgr::LoadCreatureTemplateAddons()
if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_template_addon`.", entry, spellId);
+ if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellId) != creatureAddon.auras.end())
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has duplicate aura (spell %u) in `auras` field in `creature_template_addon`.", entry, spellId);
+ continue;
+ }
+
creatureAddon.auras[i++] = spellId;
}
@@ -1028,6 +1034,12 @@ void ObjectMgr::LoadCreatureAddons()
if (AdditionalSpellInfo->HasAura(DIFFICULTY_NONE, SPELL_AURA_CONTROL_VEHICLE))
TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has SPELL_AURA_CONTROL_VEHICLE aura %u defined in `auras` field in `creature_addon`.", guid, spellId);
+ if (std::find(creatureAddon.auras.begin(), creatureAddon.auras.end(), spellId) != creatureAddon.auras.end())
+ {
+ TC_LOG_ERROR("sql.sql", "Creature (GUID: " UI64FMTD ") has duplicate aura (spell %u) in `auras` field in `creature_addon`.", guid, spellId);
+ continue;
+ }
+
creatureAddon.auras[i++] = spellId;
}
@@ -2733,7 +2745,7 @@ void ObjectMgr::LoadItemScriptNames()
continue;
}
- _itemTemplateStore[itemId].ScriptId = GetScriptId(fields[1].GetCString());
+ _itemTemplateStore[itemId].ScriptId = GetScriptId(fields[1].GetString());
++count;
} while (result->NextRow());
}
@@ -4935,8 +4947,8 @@ void ObjectMgr::LoadSpellScriptNames()
Field* fields = result->Fetch();
- int32 spellId = fields[0].GetInt32();
- char const* scriptName = fields[1].GetCString();
+ int32 spellId = fields[0].GetInt32();
+ std::string const scriptName = fields[1].GetString();
bool allRanks = false;
if (spellId < 0)
@@ -4948,18 +4960,18 @@ void ObjectMgr::LoadSpellScriptNames()
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
{
- TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) does not exist.", scriptName, fields[0].GetInt32());
+ TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) does not exist.", scriptName.c_str(), fields[0].GetInt32());
continue;
}
if (allRanks)
{
if (!spellInfo->IsRanked())
- TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) has no ranks of spell.", scriptName, fields[0].GetInt32());
+ TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) has no ranks of spell.", scriptName.c_str(), fields[0].GetInt32());
if (spellInfo->GetFirstRankSpell()->Id != uint32(spellId))
{
- TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is not first rank of spell.", scriptName, fields[0].GetInt32());
+ TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is not first rank of spell.", scriptName.c_str(), fields[0].GetInt32());
continue;
}
while (spellInfo)
@@ -4971,7 +4983,7 @@ void ObjectMgr::LoadSpellScriptNames()
else
{
if (spellInfo->IsRanked())
- TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName, spellId);
+ TC_LOG_ERROR("sql.sql", "Scriptname: `%s` spell (Id: %d) is ranked spell. Perhaps not all ranks are assigned to this script.", scriptName.c_str(), spellId);
_spellScriptsStore.insert(SpellScriptsContainer::value_type(spellInfo->Id, GetScriptId(scriptName)));
}
@@ -5009,7 +5021,7 @@ void ObjectMgr::ValidateSpellScripts()
bool valid = true;
if (!spellScript && !auraScript)
{
- TC_LOG_ERROR("scripts", "Functions GetSpellScript() and GetAuraScript() of script `%s` do not return objects - script skipped", GetScriptName(sitr->second->second));
+ TC_LOG_ERROR("scripts", "Functions GetSpellScript() and GetAuraScript() of script `%s` do not return objects - script skipped", GetScriptName(sitr->second->second).c_str());
valid = false;
}
if (spellScript)
@@ -5149,7 +5161,7 @@ void ObjectMgr::LoadInstanceTemplate()
instanceTemplate.AllowMount = fields[3].GetBool();
instanceTemplate.Parent = uint32(fields[1].GetUInt16());
- instanceTemplate.ScriptId = sObjectMgr->GetScriptId(fields[2].GetCString());
+ instanceTemplate.ScriptId = sObjectMgr->GetScriptId(fields[2].GetString());
_instanceTemplateStore[mapID] = instanceTemplate;
@@ -5641,8 +5653,8 @@ void ObjectMgr::LoadAreaTriggerScripts()
{
Field* fields = result->Fetch();
- uint32 triggerId = fields[0].GetUInt32();
- char const* scriptName = fields[1].GetCString();
+ uint32 triggerId = fields[0].GetUInt32();
+ std::string const scriptName = fields[1].GetString();
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(triggerId);
if (!atEntry)
@@ -5862,7 +5874,8 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float
// not need to check validity of map object; MapId _MUST_ be valid here
if (range.first == range.second && !map->IsBattlegroundOrArena())
{
- TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.", zoneId, team);
+ if (zoneId != 0) // zone == 0 can't be fixed, used by bliz for bugged zones
+ TC_LOG_ERROR("sql.sql", "Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.", zoneId, team);
return GetDefaultGraveYard(team);
}
@@ -6533,7 +6546,7 @@ void ObjectMgr::LoadGameObjectTemplate()
got.unkInt32 = fields[43].GetInt32();
got.AIName = fields[44].GetString();
- got.ScriptId = GetScriptId(fields[45].GetCString());
+ got.ScriptId = GetScriptId(fields[45].GetString());
// Checks
@@ -8527,11 +8540,17 @@ void ObjectMgr::LoadScriptNames()
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " ScriptNames in %u ms", _scriptNamesStore.size(), GetMSTimeDiffToNow(oldMSTime));
}
-uint32 ObjectMgr::GetScriptId(char const* name)
+std::string const& ObjectMgr::GetScriptName(uint32 id) const
+{
+ static std::string const empty = "";
+ return id < _scriptNamesStore.size() ? _scriptNamesStore[id] : empty;
+}
+
+uint32 ObjectMgr::GetScriptId(std::string const& name)
{
// use binary search to find the script name in the sorted vector
// assume "" is the first element
- if (!name)
+ if (name.empty())
return 0;
ScriptNameContainer::const_iterator itr = std::lower_bound(_scriptNamesStore.begin(), _scriptNamesStore.end(), name);
@@ -8873,8 +8892,7 @@ void ObjectMgr::LoadTerrainSwapDefaults()
uint32 mapId = fields[0].GetUInt32();
- MapEntry const* map = sMapStore.LookupEntry(mapId);
- if (!map)
+ if (!sMapStore.LookupEntry(mapId))
{
TC_LOG_ERROR("sql.sql", "Map %u defined in `terrain_swap_defaults` does not exist, skipped.", mapId);
continue;
@@ -8882,14 +8900,15 @@ void ObjectMgr::LoadTerrainSwapDefaults()
uint32 terrainSwap = fields[1].GetUInt32();
- map = sMapStore.LookupEntry(terrainSwap);
- if (!map)
+ if (!sMapStore.LookupEntry(terrainSwap))
{
TC_LOG_ERROR("sql.sql", "TerrainSwapMap %u defined in `terrain_swap_defaults` does not exist, skipped.", terrainSwap);
continue;
}
- _terrainMapDefaultStore[mapId].push_back(terrainSwap);
+ PhaseInfoStruct defaultSwap;
+ defaultSwap.Id = terrainSwap;
+ _terrainMapDefaultStore[mapId].push_back(defaultSwap);
++count;
} while (result->NextRow());
@@ -8926,7 +8945,8 @@ void ObjectMgr::LoadTerrainPhaseInfo()
continue;
}
- uint32 terrainSwap = fields[1].GetUInt32();
+ PhaseInfoStruct terrainSwap;
+ terrainSwap.Id = fields[1].GetUInt32();
_terrainPhaseInfoStore[phaseId].push_back(terrainSwap);
@@ -8995,9 +9015,9 @@ void ObjectMgr::LoadAreaPhases()
{
Field* fields = result->Fetch();
+ PhaseInfoStruct phase;
uint32 area = fields[0].GetUInt32();
- uint32 phase = fields[1].GetUInt32();
-
+ phase.Id = fields[1].GetUInt32();
_phases[area].push_back(phase);
++count;
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 62791734b72..6b3712e0b92 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -516,14 +516,14 @@ struct GossipMenuItems
uint32 BoxMoney;
std::string BoxText;
uint32 BoxBroadcastTextId;
- ConditionList Conditions;
+ ConditionContainer Conditions;
};
struct GossipMenus
{
uint32 entry;
uint32 text_id;
- ConditionList conditions;
+ ConditionContainer conditions;
};
typedef std::multimap<uint32, GossipMenus> GossipMenusContainer;
@@ -681,8 +681,15 @@ struct DungeonEncounter
typedef std::list<DungeonEncounter const*> DungeonEncounterList;
typedef std::unordered_map<uint64, DungeonEncounterList> DungeonEncounterContainer;
-typedef std::unordered_map<uint32, std::list<uint32>> TerrainPhaseInfo;
-typedef std::unordered_map<uint32, std::list<uint32>> PhaseInfo;
+struct PhaseInfoStruct
+{
+ uint32 Id;
+ ConditionContainer Conditions;
+};
+
+typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> TerrainPhaseInfo; // terrain swap
+typedef std::unordered_map<uint32, std::vector<uint32>> TerrainUIPhaseInfo; // worldmaparea swap
+typedef std::unordered_map<uint32, std::vector<PhaseInfoStruct>> PhaseInfo; // phase
class PlayerDumpReader;
@@ -1266,8 +1273,8 @@ class ObjectMgr
bool IsVendorItemValid(uint32 vendor_entry, uint32 id, int32 maxcount, uint32 ptime, uint32 ExtendedCost, uint8 type, Player* player = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const;
void LoadScriptNames();
- char const* GetScriptName(uint32 id) const { return id < _scriptNamesStore.size() ? _scriptNamesStore[id].c_str() : ""; }
- uint32 GetScriptId(char const* name);
+ std::string const& GetScriptName(uint32 id) const;
+ uint32 GetScriptId(std::string const& name);
SpellClickInfoMapBounds GetSpellClickInfoMapBounds(uint32 creature_id) const
{
@@ -1293,12 +1300,37 @@ class ObjectMgr
return _gossipMenuItemsStore.equal_range(uiMenuId);
}
- std::list<uint32>& GetPhaseTerrainSwaps(uint32 phaseid) { return _terrainPhaseInfoStore[phaseid]; }
- std::list<uint32>& GetDefaultTerrainSwaps(uint32 mapid) { return _terrainMapDefaultStore[mapid]; }
- std::list<uint32>& GetTerrainWorldMaps(uint32 terrainId) { return _terrainWorldMapStore[terrainId]; }
- TerrainPhaseInfo& GetDefaultTerrainSwapStore() { return _terrainMapDefaultStore; }
- std::list<uint32>& GetPhasesForArea(uint32 area) { return _phases[area]; }
- PhaseInfo& GetAreaPhases() { return _phases; }
+ std::vector<PhaseInfoStruct> const* GetPhaseTerrainSwaps(uint32 phaseid) const
+ {
+ auto itr = _terrainPhaseInfoStore.find(phaseid);
+ return itr != _terrainPhaseInfoStore.end() ? &itr->second : nullptr;
+ }
+ std::vector<PhaseInfoStruct> const* GetDefaultTerrainSwaps(uint32 mapid) const
+ {
+ auto itr = _terrainMapDefaultStore.find(mapid);
+ return itr != _terrainMapDefaultStore.end() ? &itr->second : nullptr;
+ }
+ std::vector<uint32> const* GetTerrainWorldMaps(uint32 terrainId) const
+ {
+ auto itr = _terrainWorldMapStore.find(terrainId);
+ return itr != _terrainWorldMapStore.end() ? &itr->second : nullptr;
+ }
+ std::vector<PhaseInfoStruct> const* GetPhasesForArea(uint32 area) const
+ {
+ auto itr = _phases.find(area);
+ return itr != _phases.end() ? &itr->second : nullptr;
+ }
+ TerrainPhaseInfo const& GetDefaultTerrainSwapStore() const { return _terrainMapDefaultStore; }
+ PhaseInfo const& GetAreaPhases() const { return _phases; }
+ // condition loading helpers
+ std::vector<PhaseInfoStruct>* GetPhasesForAreaForLoading(uint32 area)
+ {
+ auto itr = _phases.find(area);
+ return itr != _phases.end() ? &itr->second : nullptr;
+ }
+ TerrainPhaseInfo& GetPhaseTerrainSwapStoreForLoading() { return _terrainPhaseInfoStore; }
+ TerrainPhaseInfo& GetDefaultTerrainSwapStoreForLoading() { return _terrainMapDefaultStore; }
+ PhaseInfo& GetAreaPhasesForLoading() { return _phases; }
// for wintergrasp only
GraveYardContainer GraveYardStore;
@@ -1440,7 +1472,7 @@ class ObjectMgr
TerrainPhaseInfo _terrainPhaseInfoStore;
TerrainPhaseInfo _terrainMapDefaultStore;
- TerrainPhaseInfo _terrainWorldMapStore;
+ TerrainUIPhaseInfo _terrainWorldMapStore;
PhaseInfo _phases;
private:
diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp
index ac853ada5d2..cd6cec78d56 100644
--- a/src/server/game/Grids/ObjectGridLoader.cpp
+++ b/src/server/game/Grids/ObjectGridLoader.cpp
@@ -153,7 +153,12 @@ void ObjectWorldLoader::Visit(CorpseMapType& /*m*/)
for (Corpse* corpse : *corpses)
{
corpse->AddToWorld();
- i_grid.GetGridType(i_cell.CellX(), i_cell.CellY()).AddWorldObject(corpse);
+ GridType& cell = i_grid.GetGridType(i_cell.CellX(), i_cell.CellY());
+ if (corpse->IsWorldObject())
+ cell.AddWorldObject(corpse);
+ else
+ cell.AddGridObject(corpse);
+
++i_corpses;
}
}
@@ -231,7 +236,7 @@ void ObjectGridCleaner::Visit(GridRefManager<T> &m)
template void ObjectGridUnloader::Visit(CreatureMapType &);
template void ObjectGridUnloader::Visit(GameObjectMapType &);
template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
-template void ObjectGridUnloader::Visit(CorpseMapType &);
+
template void ObjectGridUnloader::Visit(AreaTriggerMapType &);
template void ObjectGridCleaner::Visit(CreatureMapType &);
template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h
index 778bb531e89..eb5d549e1c9 100644
--- a/src/server/game/Grids/ObjectGridLoader.h
+++ b/src/server/game/Grids/ObjectGridLoader.h
@@ -83,6 +83,7 @@ class ObjectGridCleaner
class ObjectGridUnloader
{
public:
+ void Visit(CorpseMapType& /*m*/) { } // corpses are deleted with Map
template<class T> void Visit(GridRefManager<T> &m);
};
#endif
diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp
index 542ebee4950..f14f9bb85be 100644
--- a/src/server/game/Handlers/BattlefieldHandler.cpp
+++ b/src/server/game/Handlers/BattlefieldHandler.cpp
@@ -25,290 +25,115 @@
#include "Battlefield.h"
#include "BattlefieldMgr.h"
+#include "BattlefieldPackets.h"
/**
- * @fn void WorldSession::SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint32 acceptTime)
+ * @fn void WorldSession::SendBfInvitePlayerToWar(uint64 queueId, uint32 zoneId, uint32 acceptTime)
*
* @brief This send to player windows for invite player to join the war.
*
- * @param guid The guid of Bf
+ * @param queueId The queue id of Bf
* @param zoneId The zone where the battle is (4197 for wg)
* @param acceptTime Time in second that the player have for accept
*/
-void WorldSession::SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint32 acceptTime)
+void WorldSession::SendBfInvitePlayerToWar(uint64 queueId, uint32 zoneId, uint32 acceptTime)
{
- WorldPacket data(SMSG_BF_MGR_ENTRY_INVITE, 16);
-
- data.WriteBit(guid[5]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[2]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[0]);
-
- data.WriteByteSeq(guid[6]);
- data << uint32(zoneId); // Zone Id
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[0]);
- data << uint32(time(NULL) + acceptTime); // Invite lasts until
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[5]);
- SendPacket(&data);
+ WorldPackets::Battlefield::BFMgrEntryInvite bfMgrEntryInvite;
+ bfMgrEntryInvite.QueueID = queueId;
+ bfMgrEntryInvite.AreaID = zoneId;
+ bfMgrEntryInvite.ExpireTime = time(nullptr) + acceptTime;
+ SendPacket(bfMgrEntryInvite.Write());
}
/**
- * @fn void WorldSession::SendBfInvitePlayerToQueue(ObjectGuid guid)
+ * @fn void WorldSession::SendBfInvitePlayerToQueue(uint64 queueId, int8 battleState)
*
* @brief This send invitation to player to join the queue.
*
- * @param guid The guid of Bf
+ * @param queueId The queue id of Bf
*/
-void WorldSession::SendBfInvitePlayerToQueue(ObjectGuid guid)
+void WorldSession::SendBfInvitePlayerToQueue(uint64 queueId, int8 battleState)
{
- WorldPacket data(SMSG_BF_MGR_QUEUE_INVITE, 5);
-
- data.WriteBit(1); // unk
- data.WriteBit(0); // Has Warmup
- data.WriteBit(1); // unk
- data.WriteBit(guid[0]);
- data.WriteBit(1); // unk
- data.WriteBit(guid[2]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[3]);
- data.WriteBit(1); // unk
- data.WriteBit(0); // unk
- data.WriteBit(guid[1]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[4]);
- data.WriteBit(1); // unk
- data.WriteBit(guid[7]);
-
- data.FlushBits();
-
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[6]);
- data << uint8(1); // Warmup
- data.WriteByteSeq(guid[5]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[7]);
- SendPacket(&data);
+ WorldPackets::Battlefield::BFMgrQueueInvite bfMgrQueueInvite;
+ bfMgrQueueInvite.QueueID = queueId;
+ bfMgrQueueInvite.BattleState = battleState;
+ SendPacket(bfMgrQueueInvite.Write());
}
/**
- * @fn void WorldSession::SendBfQueueInviteResponse(ObjectGuid guid, uint32 zoneId, bool canQueue, bool full)
+ * @fn void WorldSession::SendBfQueueInviteResponse(uint64 queueId, uint32 zoneId, int8 battleStatus, bool canQueue, bool loggingIn)
*
* @brief This send packet for inform player that he join queue.
*
- * @param guid The guid of Bf
+ * @param queueId The queue id of Bf
* @param zoneId The zone where the battle is (4197 for wg)
+ * @param battleStatus Battlefield status
* @param canQueue if able to queue
- * @param full on log in is full
+ * @param loggingIn on log in send queue status
*/
-void WorldSession::SendBfQueueInviteResponse(ObjectGuid guid, uint32 zoneId, bool canQueue, bool full)
+void WorldSession::SendBfQueueInviteResponse(uint64 queueId, uint32 zoneId, int8 battleStatus, bool canQueue /*= true*/, bool loggingIn /*= false*/)
{
- const bool hasSecondGuid = false;
- const bool warmup = true;
-
- WorldPacket data(SMSG_BF_MGR_QUEUE_REQUEST_RESPONSE, 16);
-
- data.WriteBit(guid[1]);
- data.WriteBit(guid[6]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[7]);
- data.WriteBit(full); // Logging In, VERIFYME
- data.WriteBit(guid[0]);
- data.WriteBit(!hasSecondGuid);
- data.WriteBit(guid[4]);
-
- // if (hasSecondGuid) 7 3 0 4 2 6 1 5
-
- data.WriteBit(guid[3]);
- data.WriteBit(guid[2]);
-
- // if (hasSecondGuid) 2 5 3 0 4 6 1 7
-
- data.FlushBits();
-
- data << uint8(canQueue); // Accepted
-
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[0]);
-
- data << uint8(warmup);
-
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[5]);
-
- data << uint32(zoneId);
-
- SendPacket(&data);
+ WorldPackets::Battlefield::BFMgrQueueRequestResponse bfMgrQueueRequestResponse;
+ bfMgrQueueRequestResponse.QueueID = queueId;
+ bfMgrQueueRequestResponse.AreaID = zoneId;
+ bfMgrQueueRequestResponse.Result = canQueue ? 1 : 0;
+ bfMgrQueueRequestResponse.BattleState = battleStatus;
+ bfMgrQueueRequestResponse.LoggingIn = loggingIn;
+ SendPacket(bfMgrQueueRequestResponse.Write());
}
/**
- * @fn void WorldSession::SendBfEntered(ObjectGuid guid)
+ * @fn void WorldSession::SendBfEntered(uint64 queueId, bool relocated, bool onOffense)
*
* @brief This is call when player accept to join war.
*
- * @param guid The guid of Bf
+ * @param queueId The queue id of Bf
+ * @param relocated Whether player is added to Bf on the spot or teleported from queue
+ * @param onOffense Whether player belongs to attacking team or not
*/
-void WorldSession::SendBfEntered(ObjectGuid guid)
+void WorldSession::SendBfEntered(uint64 queueId, bool relocated, bool onOffense)
{
- uint8 isAFK = _player->isAFK() ? 1 : 0;
-
- WorldPacket data(SMSG_BF_MGR_ENTERING, 11);
-
- data.WriteBit(0); // unk
- data.WriteBit(isAFK); // Clear AFK
- data.WriteBit(guid[1]);
- data.WriteBit(guid[4]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[3]);
- data.WriteBit(0); // unk
- data.WriteBit(guid[6]);
- data.WriteBit(guid[7]);
- data.WriteBit(guid[2]);
-
- data.FlushBits();
-
- data.WriteByteSeq(guid[5]);
- data.WriteByteSeq(guid[3]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[6]);
-
- SendPacket(&data);
+ WorldPackets::Battlefield::BFMgrEntering bfMgrEntering;
+ bfMgrEntering.ClearedAFK = _player->isAFK();
+ bfMgrEntering.Relocated = relocated;
+ bfMgrEntering.OnOffense = onOffense;
+ bfMgrEntering.QueueID = queueId;
+ SendPacket(bfMgrEntering.Write());
}
/**
- * @fn void WorldSession::SendBfLeaveMessage(ObjectGuid guid, BFLeaveReason reason)
+ * @fn void WorldSession::SendBfLeaveMessage(uint64 queueId, int8 battleState, bool relocated, BFLeaveReason reason)
*
* @brief This is call when player leave battlefield zone.
*
- * @param guid The guid of Bf
+ * @param queueId The queue id of Bf
+ * @param battleState Battlefield status
+ * @param relocated Whether player is added to Bf on the spot or teleported from queue
* @param reason Reason why player left battlefield
*/
-void WorldSession::SendBfLeaveMessage(ObjectGuid guid, BFLeaveReason reason /*= BF_LEAVE_REASON_EXITED*/)
-{
- WorldPacket data(SMSG_BF_MGR_EJECTED, 11);
-
- data.WriteBit(guid[2]);
- data.WriteBit(guid[5]);
- data.WriteBit(guid[1]);
- data.WriteBit(guid[0]);
- data.WriteBit(guid[3]);
- data.WriteBit(guid[6]);
- data.WriteBit(0); // Relocated
- data.WriteBit(guid[7]);
- data.WriteBit(guid[4]);
-
- data.FlushBits();
-
- data << uint8(2); // BattleStatus
- data.WriteByteSeq(guid[1]);
- data.WriteByteSeq(guid[7]);
- data.WriteByteSeq(guid[4]);
- data.WriteByteSeq(guid[2]);
- data.WriteByteSeq(guid[3]);
- data << uint8(reason); // Reason
- data.WriteByteSeq(guid[6]);
- data.WriteByteSeq(guid[0]);
- data.WriteByteSeq(guid[5]);
-
- SendPacket(&data);
-}
-
-/**
- * @fn void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData)
- *
- * @brief Send by client when he click on accept for queue.
- */
-void WorldSession::HandleBfQueueInviteResponse(WorldPacket& recvData)
+void WorldSession::SendBfLeaveMessage(uint64 queueId, int8 battleState, bool relocated, BFLeaveReason reason /*= BF_LEAVE_REASON_EXITED*/)
{
- uint8 accepted;
- ObjectGuid guid;
-
- guid[2] = recvData.ReadBit();
- guid[0] = recvData.ReadBit();
- guid[4] = recvData.ReadBit();
- guid[3] = recvData.ReadBit();
- guid[5] = recvData.ReadBit();
- guid[7] = recvData.ReadBit();
- accepted = recvData.ReadBit();
- guid[1] = recvData.ReadBit();
- guid[6] = recvData.ReadBit();
-
- recvData.ReadByteSeq(guid[1]);
- recvData.ReadByteSeq(guid[3]);
- recvData.ReadByteSeq(guid[2]);
- recvData.ReadByteSeq(guid[4]);
- recvData.ReadByteSeq(guid[6]);
- recvData.ReadByteSeq(guid[7]);
- recvData.ReadByteSeq(guid[0]);
- recvData.ReadByteSeq(guid[5]);
-
- TC_LOG_ERROR("misc", "HandleQueueInviteResponse: %s, accepted: %u", guid.ToString().c_str(), accepted);
-
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
- if (!bf)
- return;
-
- if (accepted)
- bf->PlayerAcceptInviteToQueue(_player);
+ WorldPackets::Battlefield::BFMgrEjected bfMgrEjected;
+ bfMgrEjected.QueueID = queueId;
+ bfMgrEjected.Reason = reason;
+ bfMgrEjected.BattleState = battleState;
+ bfMgrEjected.Relocated = relocated;
+ SendPacket(bfMgrEjected.Write());
}
/**
- * @fn void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData)
+ * @fn void WorldSession::HandleBfEntryInviteResponse(WorldPackets::Battlefield::BFMgrEntryInviteResponse& bfMgrEntryInviteResponse)
*
* @brief Send by client on clicking in accept or refuse of invitation windows for join game.
*/
-void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData)
+void WorldSession::HandleBfEntryInviteResponse(WorldPackets::Battlefield::BFMgrEntryInviteResponse& bfMgrEntryInviteResponse)
{
- uint8 accepted;
- ObjectGuid guid;
-
- guid[6] = recvData.ReadBit();
- guid[1] = recvData.ReadBit();
- accepted = recvData.ReadBit();
- guid[5] = recvData.ReadBit();
- guid[3] = recvData.ReadBit();
- guid[2] = recvData.ReadBit();
- guid[0] = recvData.ReadBit();
- guid[7] = recvData.ReadBit();
- guid[4] = recvData.ReadBit();
-
- recvData.ReadByteSeq(guid[0]);
- recvData.ReadByteSeq(guid[3]);
- recvData.ReadByteSeq(guid[4]);
- recvData.ReadByteSeq(guid[2]);
- recvData.ReadByteSeq(guid[1]);
- recvData.ReadByteSeq(guid[6]);
- recvData.ReadByteSeq(guid[7]);
- recvData.ReadByteSeq(guid[5]);
-
- TC_LOG_ERROR("misc", "HandleBattlefieldInviteResponse: GUID: %s, accepted: %u", guid.ToString().c_str(), accepted);
-
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByQueueId(bfMgrEntryInviteResponse.QueueID);
if (!bf)
return;
// If player accept invitation
- if (accepted)
+ if (bfMgrEntryInviteResponse.AcceptedInvite)
{
bf->PlayerAcceptInviteToWar(_player);
}
@@ -320,35 +145,28 @@ void WorldSession::HandleBfEntryInviteResponse(WorldPacket& recvData)
}
/**
- * @fn void WorldSession::HandleBfExitRequest(WorldPacket& recvData)
+ * @fn void WorldSession::HandleBfQueueInviteResponse(WorldPackets::Battlefield::BFMgrQueueInviteResponse& bfMgrQueueInviteResponse)
*
- * @brief Send by client when exited battlefield
+ * @brief Send by client when he click on accept for queue.
*/
-void WorldSession::HandleBfExitRequest(WorldPacket& recvData)
+void WorldSession::HandleBfQueueInviteResponse(WorldPackets::Battlefield::BFMgrQueueInviteResponse& bfMgrQueueInviteResponse)
{
- ObjectGuid guid;
-
- guid[2] = recvData.ReadBit();
- guid[0] = recvData.ReadBit();
- guid[3] = recvData.ReadBit();
- guid[7] = recvData.ReadBit();
- guid[4] = recvData.ReadBit();
- guid[5] = recvData.ReadBit();
- guid[6] = recvData.ReadBit();
- guid[1] = recvData.ReadBit();
-
- recvData.ReadByteSeq(guid[5]);
- recvData.ReadByteSeq(guid[2]);
- recvData.ReadByteSeq(guid[0]);
- recvData.ReadByteSeq(guid[1]);
- recvData.ReadByteSeq(guid[4]);
- recvData.ReadByteSeq(guid[3]);
- recvData.ReadByteSeq(guid[7]);
- recvData.ReadByteSeq(guid[6]);
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByQueueId(bfMgrQueueInviteResponse.QueueID);
+ if (!bf)
+ return;
- TC_LOG_ERROR("misc", "HandleBfExitRequest: GUID: %s", guid.ToString().c_str());
+ if (bfMgrQueueInviteResponse.AcceptedInvite)
+ bf->PlayerAcceptInviteToQueue(_player);
+}
- Battlefield* bf = sBattlefieldMgr->GetBattlefieldByGUID(guid);
+/**
+ * @fn void WorldSession::HandleBfExitRequest(WorldPackets::Battlefield::BFMgrQueueExitRequest& bfMgrQueueExitRequest)
+ *
+ * @brief Send by client when exited battlefield
+ */
+void WorldSession::HandleBfQueueExitRequest(WorldPackets::Battlefield::BFMgrQueueExitRequest& bfMgrQueueExitRequest)
+{
+ Battlefield* bf = sBattlefieldMgr->GetBattlefieldByQueueId(bfMgrQueueExitRequest.QueueID);
if (!bf)
return;
diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp
index c200c0851b2..88ad8358484 100644
--- a/src/server/game/Handlers/ChatHandler.cpp
+++ b/src/server/game/Handlers/ChatHandler.cpp
@@ -635,31 +635,9 @@ void WorldSession::HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet)
creature->AI()->ReceiveEmote(_player, packet.SoundIndex);
}
-void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData)
+void WorldSession::HandleChatIgnoredOpcode(WorldPackets::Chat::ChatReportIgnored& chatReportIgnored)
{
- ObjectGuid guid;
- uint8 unk;
-
- recvData >> unk; // probably related to spam reporting
- guid[5] = recvData.ReadBit();
- guid[2] = recvData.ReadBit();
- guid[6] = recvData.ReadBit();
- guid[4] = recvData.ReadBit();
- guid[7] = recvData.ReadBit();
- guid[0] = recvData.ReadBit();
- guid[1] = recvData.ReadBit();
- guid[3] = recvData.ReadBit();
-
- recvData.ReadByteSeq(guid[0]);
- recvData.ReadByteSeq(guid[6]);
- recvData.ReadByteSeq(guid[5]);
- recvData.ReadByteSeq(guid[1]);
- recvData.ReadByteSeq(guid[4]);
- recvData.ReadByteSeq(guid[3]);
- recvData.ReadByteSeq(guid[7]);
- recvData.ReadByteSeq(guid[2]);
-
- Player* player = ObjectAccessor::FindConnectedPlayer(guid);
+ Player* player = ObjectAccessor::FindConnectedPlayer(chatReportIgnored.IgnoredGUID);
if (!player || !player->GetSession())
return;
diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp
index ccd3dd77109..92d94e65649 100644
--- a/src/server/game/Handlers/ItemHandler.cpp
+++ b/src/server/game/Handlers/ItemHandler.cpp
@@ -598,8 +598,7 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid)
continue;
}
- ConditionList conditions = sConditionMgr->GetConditionsForNpcVendorEvent(vendor->GetEntry(), vendorItem->item);
- if (!sConditionMgr->IsObjectMeetToConditions(_player, vendor, conditions))
+ if (!sConditionMgr->IsObjectMeetingVendorItemConditions(vendor->GetEntry(), vendorItem->item, _player, vendor))
{
TC_LOG_DEBUG("condition", "SendListInventory: conditions not met for creature entry %u item %u", vendor->GetEntry(), vendorItem->item);
continue;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 76303c063e5..33c15e271c7 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -115,8 +115,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG
if (Player* playerQuestObject = object->ToPlayer())
{
- if ((!_player->GetDivider().IsEmpty() && _player->GetDivider() != packet.QuestGiverGUID) ||
- ((object != _player && !playerQuestObject->CanShareQuest(packet.QuestID))))
+ if ((_player->GetDivider().IsEmpty() && _player->GetDivider() != packet.QuestGiverGUID) || !playerQuestObject->CanShareQuest(packet.QuestID))
{
CLOSE_GOSSIP_CLEAR_DIVIDER();
return;
diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp
index 678b2b72120..b7191644306 100644
--- a/src/server/game/Handlers/TradeHandler.cpp
+++ b/src/server/game/Handlers/TradeHandler.cpp
@@ -29,6 +29,7 @@
#include "Language.h"
#include "AccountMgr.h"
#include "TradePackets.h"
+#include "TradeData.h"
void WorldSession::SendTradeStatus(WorldPackets::Trade::TradeStatus& info)
{
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 80024879a43..122c08acc1d 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -319,6 +319,11 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
return false;
}
+bool InstanceScript::_SkipCheckRequiredBosses(Player const* player /*= nullptr*/) const
+{
+ return player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES);
+}
+
void InstanceScript::Load(char const* data)
{
if (!data)
@@ -654,3 +659,25 @@ void InstanceScript::UpdatePhasing()
if (Player* player = itr->GetSource())
player->SendUpdatePhasing();
}
+
+std::string InstanceScript::GetBossStateName(uint8 state)
+{
+ // See enum EncounterState in InstanceScript.h
+ switch (state)
+ {
+ case NOT_STARTED:
+ return "NOT_STARTED";
+ case IN_PROGRESS:
+ return "IN_PROGRESS";
+ case FAIL:
+ return "FAIL";
+ case DONE:
+ return "DONE";
+ case SPECIAL:
+ return "SPECIAL";
+ case TO_BE_DECIDED:
+ return "TO_BE_DECIDED";
+ default:
+ return "INVALID";
+ }
+}
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index d932c24abf3..d5fa76a1b06 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -224,6 +224,7 @@ class InstanceScript : public ZoneScript
virtual bool SetBossState(uint32 id, EncounterState state);
EncounterState GetBossState(uint32 id) const { return id < bosses.size() ? bosses[id].state : TO_BE_DECIDED; }
+ static std::string GetBossStateName(uint8 state);
BossBoundaryMap const* GetBossBoundary(uint32 id) const { return id < bosses.size() ? &bosses[id].boundary : NULL; }
// Achievement criteria additional requirements check
@@ -280,6 +281,8 @@ class InstanceScript : public ZoneScript
void WriteSaveDataBossStates(std::ostringstream& data);
virtual void WriteSaveDataMore(std::ostringstream& /*data*/) { }
+ bool _SkipCheckRequiredBosses(Player const* player = nullptr) const;
+
private:
static void LoadObjectData(ObjectData const* creatureData, ObjectInfoMap& objectInfo);
diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp
index 9ef0f8c7c57..42f9845f433 100644
--- a/src/server/game/Loot/LootMgr.cpp
+++ b/src/server/game/Loot/LootMgr.cpp
@@ -96,7 +96,7 @@ class LootTemplate::LootGroup // A set of loot def
void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const;
LootStoreItemList* GetExplicitlyChancedItemList() { return &ExplicitlyChanced; }
LootStoreItemList* GetEqualChancedItemList() { return &EqualChanced; }
- void CopyConditions(ConditionList conditions);
+ void CopyConditions(ConditionContainer conditions);
private:
LootStoreItemList ExplicitlyChanced; // Entries with chances defined in DB
LootStoreItemList EqualChanced; // Zero chances - every entry takes the same chance
@@ -219,7 +219,7 @@ void LootStore::ResetConditions()
{
for (LootTemplateMap::iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr)
{
- ConditionList empty;
+ ConditionContainer empty;
itr->second->CopyConditions(empty);
}
}
@@ -1160,7 +1160,7 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const* player) const
return false;
}
-void LootTemplate::LootGroup::CopyConditions(ConditionList /*conditions*/)
+void LootTemplate::LootGroup::CopyConditions(ConditionContainer /*conditions*/)
{
for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i)
(*i)->conditions.clear();
@@ -1265,7 +1265,7 @@ void LootTemplate::AddEntry(LootStoreItem* item)
Entries.push_back(item);
}
-void LootTemplate::CopyConditions(const ConditionList& conditions)
+void LootTemplate::CopyConditions(const ConditionContainer& conditions)
{
for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i)
(*i)->conditions.clear();
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 5610c876f2d..7f997fd59a5 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -141,7 +141,7 @@ struct LootStoreItem
uint8 groupid : 7;
uint8 mincount; // mincount for drop items
uint8 maxcount; // max drop count for the item mincount or Ref multiplicator
- ConditionList conditions; // additional loot condition
+ ConditionContainer conditions; // additional loot condition
// Constructor
// displayid is filled in IsValid() which must be called after
@@ -160,7 +160,7 @@ struct LootItem
uint32 randomSuffix;
int32 randomPropertyId;
std::vector<int32> BonusListIDs;
- ConditionList conditions; // additional loot condition
+ ConditionContainer conditions; // additional loot condition
GuidSet allowedGUIDs;
uint8 count : 8;
bool is_looted : 1;
@@ -260,7 +260,7 @@ class LootTemplate
void AddEntry(LootStoreItem* item);
// Rolls for every item in the template and adds the rolled items the the loot
void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0) const;
- void CopyConditions(const ConditionList& conditions);
+ void CopyConditions(const ConditionContainer& conditions);
void CopyConditions(LootItem* li) const;
// True if template includes at least 1 quest drop entry
diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp
index 85cc87eaa6e..e625cc9c70b 100644
--- a/src/server/game/Maps/Map.cpp
+++ b/src/server/game/Maps/Map.cpp
@@ -298,6 +298,25 @@ void Map::AddToGrid(DynamicObject* obj, Cell const& cell)
obj->SetCurrentCell(cell);
}
+template<>
+void Map::AddToGrid(Corpse* obj, Cell const& cell)
+{
+ NGridType* grid = getNGrid(cell.GridX(), cell.GridY());
+ // Corpses are a special object type - they can be added to grid via a call to AddToMap
+ // or loaded through ObjectGridLoader.
+ // Both corpses loaded from database and these freshly generated by Player::CreateCoprse are added to _corpsesByCell
+ // ObjectGridLoader loads all corpses from _corpsesByCell even if they were already added to grid before it was loaded
+ // so we need to explicitly check it here (Map::AddToGrid is only called from Player::BuildPlayerRepop, not from ObjectGridLoader)
+ // to avoid failing an assertion in GridObject::AddToGrid
+ if (grid->isGridObjectDataLoaded())
+ {
+ if (obj->IsWorldObject())
+ grid->GetGridType(cell.CellX(), cell.CellY()).AddWorldObject(obj);
+ else
+ grid->GetGridType(cell.CellX(), cell.CellY()).AddGridObject(obj);
+ }
+}
+
template<class T>
void Map::SwitchGridContainers(T* /*obj*/, bool /*on*/) { }
@@ -1612,6 +1631,20 @@ void Map::UnloadAll()
RemoveFromMap<Transport>(transport, true);
}
+
+ for (auto& cellCorpsePair : _corpsesByCell)
+ {
+ for (Corpse* corpse : cellCorpsePair.second)
+ {
+ corpse->RemoveFromWorld();
+ corpse->ResetMap();
+ delete corpse;
+ }
+ }
+
+ _corpsesByCell.clear();
+ _corpsesByPlayer.clear();
+ _corpseBones.clear();
}
// *****************************
@@ -3180,7 +3213,7 @@ void InstanceMap::CreateInstanceData(bool load)
i_data->SetCompletedEncountersMask(fields[1].GetUInt32());
if (!data.empty())
{
- TC_LOG_DEBUG("maps", "Loading instance data for `%s` with id %u", sObjectMgr->GetScriptName(i_script_id), i_InstanceId);
+ TC_LOG_DEBUG("maps", "Loading instance data for `%s` with id %u", sObjectMgr->GetScriptName(i_script_id).c_str(), i_InstanceId);
i_data->Load(data.c_str());
}
}
@@ -3659,14 +3692,16 @@ void Map::AddCorpse(Corpse* corpse)
{
corpse->SetMap(this);
- CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- _corpsesByCell[cellCoord.GetId()].insert(corpse);
- _corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
+ _corpsesByCell[corpse->GetCellCoord().GetId()].insert(corpse);
+ if (corpse->GetType() != CORPSE_BONES)
+ _corpsesByPlayer[corpse->GetOwnerGUID()] = corpse;
+ else
+ _corpseBones.insert(corpse);
}
void Map::RemoveCorpse(Corpse* corpse)
{
- ASSERT(corpse && corpse->GetType() != CORPSE_BONES);
+ ASSERT(corpse);
corpse->DestroyForNearbyPlayers();
if (corpse->IsInGrid())
@@ -3677,9 +3712,11 @@ void Map::RemoveCorpse(Corpse* corpse)
corpse->ResetMap();
}
- CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY());
- _corpsesByCell[cellCoord.GetId()].erase(corpse);
- _corpsesByPlayer.erase(corpse->GetOwnerGUID());
+ _corpsesByCell[corpse->GetCellCoord().GetId()].erase(corpse);
+ if (corpse->GetType() != CORPSE_BONES)
+ _corpsesByPlayer.erase(corpse->GetOwnerGUID());
+ else
+ _corpseBones.erase(corpse);
}
Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/)
@@ -3710,12 +3747,12 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
for (uint8 i = OBJECT_FIELD_GUID + 4; i < CORPSE_END; ++i) // don't overwrite guid
bones->SetUInt32Value(i, corpse->GetUInt32Value(i));
- bones->SetGridCoord(corpse->GetGridCoord());
+ bones->SetCellCoord(corpse->GetCellCoord());
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty);
- bones->SetGuidValue(OBJECT_FIELD_DATA, corpse->GetGuidValue(OBJECT_FIELD_DATA));
+ bones->SetGuidValue(OBJECT_FIELD_DATA, ObjectGuid::Empty);
for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i)
if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i))
@@ -3723,6 +3760,8 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*=
bones->CopyPhaseFrom(corpse);
+ AddCorpse(bones);
+
// add bones in grid store if grid loaded where corpse placed
AddToMap(bones);
}
@@ -3746,6 +3785,17 @@ void Map::RemoveOldCorpses()
for (ObjectGuid const& ownerGuid : corpses)
ConvertCorpseToBones(ownerGuid);
+
+ std::vector<Corpse*> expiredBones;
+ for (Corpse* bones : _corpseBones)
+ if (bones->IsExpired(now))
+ expiredBones.push_back(bones);
+
+ for (Corpse* bones : expiredBones)
+ {
+ RemoveCorpse(bones);
+ delete bones;
+ }
}
void Map::SendZoneDynamicInfo(Player* player)
diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h
index 596a753ad34..ec8f789980c 100644
--- a/src/server/game/Maps/Map.h
+++ b/src/server/game/Maps/Map.h
@@ -733,6 +733,7 @@ class Map : public GridRefManager<NGridType>
GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore;
std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell;
std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer;
+ std::unordered_set<Corpse*> _corpseBones;
std::unordered_set<Object*> _updateObjects;
};
diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h
index de18a0215c2..71d0c056028 100644
--- a/src/server/game/Miscellaneous/Language.h
+++ b/src/server/game/Miscellaneous/Language.h
@@ -389,7 +389,8 @@ enum TrinityStrings
LANG_COMMAND_CHEAT_POWER = 361,
LANG_COMMAND_CHEAT_WW = 362,
LANG_COMMAND_WHISPEROFFPLAYER = 363,
- // Room for more level 2 364-399 not used
+ LANG_COMMAND_CHEAT_TAXINODES = 364,
+ // Room for more level 2 365-399 not used
// level 3 chat
LANG_SCRIPTS_RELOADED = 400,
@@ -1211,5 +1212,6 @@ enum TrinityStrings
LANG_NPCINFO_INHABIT_TYPE = 11008,
LANG_NPCINFO_FLAGS_EXTRA = 11009
+
};
#endif
diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp
index 117f4b675bf..ad6f1b457aa 100644
--- a/src/server/game/Movement/MotionMaster.cpp
+++ b/src/server/game/Movement/MotionMaster.cpp
@@ -417,6 +417,24 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool
init.Launch();
}
+void MotionMaster::MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk)
+{
+ Movement::PointsArray path(pathPoints, pathPoints + pathSize);
+
+ Movement::MoveSplineInit init(_owner);
+ init.MovebyPath(path);
+ init.SetSmooth();
+ init.SetWalk(walk);
+ init.Launch();
+
+ // This code is not correct
+ // EffectMovementGenerator does not affect UNIT_STATE_ROAMING | UNIT_STATE_ROAMING_MOVE
+ // need to call PointMovementGenerator with various pointIds
+ Mutate(new EffectMovementGenerator(pointId), MOTION_SLOT_ACTIVE);
+ //Position pos(pathPoints[pathSize - 1].x, pathPoints[pathSize - 1].y, pathPoints[pathSize - 1].z);
+ //MovePoint(EVENT_CHARGE_PREPATH, pos, false);
+}
+
void MotionMaster::MoveFall(uint32 id /*=0*/)
{
// use larger distance for vmap height search than in most other cases
diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h
index c8da50364ba..9a8950de9f7 100644
--- a/src/server/game/Movement/MotionMaster.h
+++ b/src/server/game/Movement/MotionMaster.h
@@ -185,6 +185,7 @@ class MotionMaster //: private std::stack<MovementGenerator *>
{ MoveJump(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speedXY, speedZ, id); }
void MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id = EVENT_JUMP);
void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount);
+ void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk);
void MoveFall(uint32 id = 0);
void MoveSeekAssistance(float x, float y, float z);
diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
index 4245bffb864..7ab7534199a 100644
--- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
+++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp
@@ -33,7 +33,7 @@ void HomeMovementGenerator<Creature>::DoFinalize(Creature* owner)
{
owner->ClearUnitState(UNIT_STATE_EVADE);
owner->SetWalk(true);
- owner->LoadCreaturesAddon(true);
+ owner->LoadCreaturesAddon();
owner->AI()->JustReachedHome();
}
}
diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
index b07d21436b2..65b9f67342a 100644
--- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
+++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp
@@ -71,7 +71,7 @@ void OutdoorPvPMgr::InitOutdoorPvP()
OutdoorPvPData* data = new OutdoorPvPData();
OutdoorPvPTypes realTypeId = OutdoorPvPTypes(typeId);
data->TypeId = realTypeId;
- data->ScriptId = sObjectMgr->GetScriptId(fields[1].GetCString());
+ data->ScriptId = sObjectMgr->GetScriptId(fields[1].GetString());
m_OutdoorPvPDatas[realTypeId] = data;
++count;
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index aa8be4946e4..40e522a185e 100644
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -93,6 +93,7 @@ void AddSC_npcs_special();
void AddSC_npc_taxi();
void AddSC_achievement_scripts();
void AddSC_action_ip_logger();
+void AddSC_duel_reset();
//eastern kingdoms
void AddSC_alterac_valley(); //Alterac Valley
@@ -113,11 +114,8 @@ void AddSC_blackrock_caverns();
void AddSC_instance_blackrock_caverns();
void AddSC_blackrock_depths(); //Blackrock Depths
void AddSC_boss_ambassador_flamelash();
-void AddSC_boss_anubshiah();
void AddSC_boss_draganthaurissan();
void AddSC_boss_general_angerforge();
-void AddSC_boss_gorosh_the_dervish();
-void AddSC_boss_grizzle();
void AddSC_boss_high_interrogator_gerstahn();
void AddSC_boss_magmus();
void AddSC_boss_moira_bronzebeard();
@@ -812,6 +810,7 @@ void AddWorldScripts()
// To avoid duplicate code, we check once /*ONLY*/ if logging is permitted or not.
if (sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
+ AddSC_duel_reset();
#endif
}
@@ -836,11 +835,8 @@ void AddEasternKingdomsScripts()
AddSC_instance_blackrock_caverns();
AddSC_blackrock_depths(); //Blackrock Depths
AddSC_boss_ambassador_flamelash();
- AddSC_boss_anubshiah();
AddSC_boss_draganthaurissan();
AddSC_boss_general_angerforge();
- AddSC_boss_gorosh_the_dervish();
- AddSC_boss_grizzle();
AddSC_boss_high_interrogator_gerstahn();
AddSC_boss_magmus();
AddSC_boss_moira_bronzebeard();
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 817859d208e..4ad2e8af23d 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -33,6 +33,7 @@
#include "Player.h"
#include "WorldPacket.h"
#include "WorldSession.h"
+#include "Chat.h"
// namespace
// {
@@ -40,6 +41,60 @@
UnusedScriptNamesContainer UnusedScriptNames;
// }
+// Trait which indicates whether this script type
+// must be assigned in the database.
+template<typename>
+struct is_script_database_bound
+ : std::false_type { };
+
+template<>
+struct is_script_database_bound<SpellScriptLoader>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<InstanceMapScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<ItemScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<CreatureScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<GameObjectScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<AreaTriggerScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<BattlegroundScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<OutdoorPvPScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<WeatherScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<ConditionScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<TransportScript>
+ : std::true_type { };
+
+template<>
+struct is_script_database_bound<AchievementCriteriaScript>
+ : std::true_type { };
+
// This is the global static registry of scripts.
template<class TScript>
class ScriptRegistry
@@ -70,78 +125,83 @@ class ScriptRegistry
}
}
- if (script->IsDatabaseBound())
+ AddScript(is_script_database_bound<TScript>{}, script);
+ }
+
+ // Gets a script by its ID (assigned by ObjectMgr).
+ static TScript* GetScriptById(uint32 id)
+ {
+ ScriptMapIterator it = ScriptPointerList.find(id);
+ if (it != ScriptPointerList.end())
+ return it->second;
+
+ return NULL;
+ }
+
+ private:
+
+ // Adds a database bound script
+ static void AddScript(std::true_type, TScript* const script)
+ {
+ // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
+ // through a script name (or similar).
+ uint32 id = sObjectMgr->GetScriptId(script->GetName());
+ if (id)
{
- // Get an ID for the script. An ID only exists if it's a script that is assigned in the database
- // through a script name (or similar).
- uint32 id = sObjectMgr->GetScriptId(script->GetName().c_str());
- if (id)
+ // Try to find an existing script.
+ bool existing = false;
+ for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
{
- // Try to find an existing script.
- bool existing = false;
- for (ScriptMapIterator it = ScriptPointerList.begin(); it != ScriptPointerList.end(); ++it)
- {
- // If the script names match...
- if (it->second->GetName() == script->GetName())
- {
- // ... It exists.
- existing = true;
- break;
- }
- }
-
- // If the script isn't assigned -> assign it!
- if (!existing)
+ // If the script names match...
+ if (it->second->GetName() == script->GetName())
{
- ScriptPointerList[id] = script;
- sScriptMgr->IncrementScriptCount();
-
- #ifdef SCRIPTS
- UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName());
- if (itr != UnusedScriptNames.end() && *itr == script->GetName())
- UnusedScriptNames.erase(itr);
- #endif
+ // ... It exists.
+ existing = true;
+ break;
}
- else
- {
- // If the script is already assigned -> delete it!
- TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, so the script can't work.",
- script->GetName().c_str());
+ }
- ABORT(); // Error that should be fixed ASAP.
- }
+ // If the script isn't assigned -> assign it!
+ if (!existing)
+ {
+ ScriptPointerList[id] = script;
+ sScriptMgr->IncrementScriptCount();
+
+ #ifdef SCRIPTS
+ UnusedScriptNamesContainer::iterator itr = std::lower_bound(UnusedScriptNames.begin(), UnusedScriptNames.end(), script->GetName());
+ if (itr != UnusedScriptNames.end() && *itr == script->GetName())
+ UnusedScriptNames.erase(itr);
+ #endif
}
else
{
- // The script uses a script name from database, but isn't assigned to anything.
- TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.", script->GetName().c_str());
+ // If the script is already assigned -> delete it!
+ TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, so the script can't work.",
+ script->GetName().c_str());
- // Avoid calling "delete script;" because we are currently in the script constructor
- // In a valid scenario this will not happen because every script has a name assigned in the database
- UnusedScripts.push_back(script);
- return;
+ ABORT(); // Error that should be fixed ASAP.
}
}
else
{
- // We're dealing with a code-only script; just add it.
- ScriptPointerList[_scriptIdCounter++] = script;
- sScriptMgr->IncrementScriptCount();
+ // The script uses a script name from database, but isn't assigned to anything.
+ TC_LOG_ERROR("sql.sql", "Script named '%s' does not have a script name assigned in database.", script->GetName().c_str());
+
+ // Avoid calling "delete script;" because we are currently in the script constructor
+ // In a valid scenario this will not happen because every script has a name assigned in the database
+ UnusedScripts.push_back(script);
+ return;
}
}
- // Gets a script by its ID (assigned by ObjectMgr).
- static TScript* GetScriptById(uint32 id)
+ // Adds a non database bound script
+ static void AddScript(std::false_type, TScript* const script)
{
- ScriptMapIterator it = ScriptPointerList.find(id);
- if (it != ScriptPointerList.end())
- return it->second;
-
- return NULL;
+ // We're dealing with a code-only script; just add it.
+ ScriptPointerList[_scriptIdCounter++] = script;
+ sScriptMgr->IncrementScriptCount();
}
- private:
-
// Counter used for code-only scripts.
static uint32 _scriptIdCounter;
};
@@ -975,12 +1035,15 @@ OutdoorPvP* ScriptMgr::CreateOutdoorPvP(OutdoorPvPData const* data)
return tmpscript->GetOutdoorPvP();
}
-std::vector<ChatCommand*> ScriptMgr::GetChatCommands()
+std::vector<ChatCommand> ScriptMgr::GetChatCommands()
{
- std::vector<ChatCommand*> table;
+ std::vector<ChatCommand> table;
FOR_SCRIPTS_RET(CommandScript, itr, end, table)
- table.push_back(itr->second->GetCommands());
+ {
+ std::vector<ChatCommand> cmds = itr->second->GetCommands();
+ table.insert(table.end(), cmds.begin(), cmds.end());
+ }
return table;
}
@@ -1033,7 +1096,7 @@ void ScriptMgr::OnAuctionExpire(AuctionHouseObject* ah, AuctionEntry* entry)
FOREACH_SCRIPT(AuctionHouseScript)->OnAuctionExpire(ah, entry);
}
-bool ScriptMgr::OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo)
+bool ScriptMgr::OnConditionCheck(Condition const* condition, ConditionSourceInfo& sourceInfo)
{
ASSERT(condition);
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 588d909ae94..fc84d3d2275 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -152,10 +152,6 @@ class ScriptObject
public:
- // Do not override this in scripts; it should be overridden by the various script type classes. It indicates
- // whether or not this script type must be assigned in the database.
- virtual bool IsDatabaseBound() const { return false; }
-
const std::string& GetName() const { return _name; }
protected:
@@ -197,8 +193,6 @@ class SpellScriptLoader : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Should return a fully valid SpellScript pointer.
virtual SpellScript* GetSpellScript() const { return NULL; }
@@ -355,8 +349,6 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Gets an InstanceScript object for this instance.
virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; }
};
@@ -376,8 +368,6 @@ class ItemScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when a dummy spell effect is triggered on the item.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Item* /*target*/) { return false; }
@@ -425,8 +415,6 @@ class CreatureScript : public UnitScript, public UpdatableScript<Creature>
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when a dummy spell effect is triggered on the creature.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Creature* /*target*/) { return false; }
@@ -463,8 +451,6 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when a dummy spell effect is triggered on the gameobject.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, GameObject* /*target*/) { return false; }
@@ -510,8 +496,6 @@ class AreaTriggerScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when the area trigger is activated by a player.
virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/, bool /*entered*/) { return false; }
};
@@ -524,8 +508,6 @@ class BattlegroundScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Should return a fully valid Battleground object for the type ID.
virtual Battleground* GetBattleground() const = 0;
};
@@ -538,8 +520,6 @@ class OutdoorPvPScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Should return a fully valid OutdoorPvP object for the type ID.
virtual OutdoorPvP* GetOutdoorPvP() const = 0;
};
@@ -553,7 +533,7 @@ class CommandScript : public ScriptObject
public:
// Should return a pointer to a valid command table (ChatCommand array) to be used by ChatHandler.
- virtual ChatCommand* GetCommands() const = 0;
+ virtual std::vector<ChatCommand> GetCommands() const = 0;
};
class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
@@ -564,8 +544,6 @@ class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when the weather changes in the zone this script is associated with.
virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { }
};
@@ -599,10 +577,8 @@ class ConditionScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when a single condition is checked for a player.
- virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
+ virtual bool OnConditionCheck(Condition const* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
};
class VehicleScript : public ScriptObject
@@ -647,8 +623,6 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport>
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when a player boards the transport.
virtual void OnAddPassenger(Transport* /*transport*/, Player* /*player*/) { }
@@ -670,8 +644,6 @@ class AchievementCriteriaScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return true; }
-
// Called when an additional criteria is checked.
virtual bool OnCheck(Player* source, Unit* target) = 0;
};
@@ -808,8 +780,6 @@ class GuildScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return false; }
-
// Called when a member is added to the guild.
virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8& /*plRank*/) { }
@@ -851,8 +821,6 @@ class GroupScript : public ScriptObject
public:
- bool IsDatabaseBound() const final override { return false; }
-
// Called when a member is added to a group.
virtual void OnAddMember(Group* /*group*/, ObjectGuid /*guid*/) { }
@@ -1013,7 +981,7 @@ class ScriptMgr
public: /* CommandScript */
- std::vector<ChatCommand*> GetChatCommands();
+ std::vector<ChatCommand> GetChatCommands();
public: /* WeatherScript */
@@ -1029,7 +997,7 @@ class ScriptMgr
public: /* ConditionScript */
- bool OnConditionCheck(Condition* condition, ConditionSourceInfo& sourceInfo);
+ bool OnConditionCheck(Condition const* condition, ConditionSourceInfo& sourceInfo);
public: /* VehicleScript */
diff --git a/src/server/game/Server/Packets/BattlefieldPackets.cpp b/src/server/game/Server/Packets/BattlefieldPackets.cpp
new file mode 100644
index 00000000000..69bfb990dc5
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlefieldPackets.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008-2015 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 "BattlefieldPackets.h"
+
+WorldPacket const* WorldPackets::Battlefield::BFMgrEntryInvite::Write()
+{
+ _worldPacket << uint64(QueueID);
+ _worldPacket << uint32(AreaID);
+ _worldPacket << uint32(ExpireTime);
+ return &_worldPacket;
+}
+
+void WorldPackets::Battlefield::BFMgrEntryInviteResponse::Read()
+{
+ _worldPacket >> QueueID;
+ AcceptedInvite = _worldPacket.ReadBit();
+}
+
+WorldPacket const* WorldPackets::Battlefield::BFMgrQueueInvite::Write()
+{
+ _worldPacket << uint64(QueueID);
+ _worldPacket << int8(BattleState);
+ _worldPacket << uint32(Timeout);
+ _worldPacket << int32(MinLevel);
+ _worldPacket << int32(MaxLevel);
+ _worldPacket << int32(MapID);
+ _worldPacket << uint32(InstanceID);
+ _worldPacket.WriteBit(Index);
+ _worldPacket.FlushBits();
+ return &_worldPacket;
+}
+
+void WorldPackets::Battlefield::BFMgrQueueInviteResponse::Read()
+{
+ _worldPacket >> QueueID;
+ AcceptedInvite = _worldPacket.ReadBit();
+}
+
+WorldPacket const* WorldPackets::Battlefield::BFMgrQueueRequestResponse::Write()
+{
+ _worldPacket << uint64(QueueID);
+ _worldPacket << int32(AreaID);
+ _worldPacket << int8(Result);
+ _worldPacket << FailedPlayerGUID;
+ _worldPacket << int8(BattleState);
+ _worldPacket.WriteBit(LoggingIn);
+ _worldPacket.FlushBits();
+ return &_worldPacket;
+}
+
+void WorldPackets::Battlefield::BFMgrQueueExitRequest::Read()
+{
+ _worldPacket >> QueueID;
+}
+
+WorldPacket const* WorldPackets::Battlefield::BFMgrEntering::Write()
+{
+ _worldPacket.WriteBit(ClearedAFK);
+ _worldPacket.WriteBit(Relocated);
+ _worldPacket.WriteBit(OnOffense);
+ _worldPacket << uint64(QueueID);
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Battlefield::BFMgrEjected::Write()
+{
+ _worldPacket << uint64(QueueID);
+ _worldPacket << int8(Reason);
+ _worldPacket << int8(BattleState);
+ _worldPacket.WriteBit(Relocated);
+ _worldPacket.FlushBits();
+ return &_worldPacket;
+}
diff --git a/src/server/game/Server/Packets/BattlefieldPackets.h b/src/server/game/Server/Packets/BattlefieldPackets.h
new file mode 100644
index 00000000000..c27a2c67ab0
--- /dev/null
+++ b/src/server/game/Server/Packets/BattlefieldPackets.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef BattlefieldPackets_h__
+#define BattlefieldPackets_h__
+
+#include "Packet.h"
+#include "ObjectGuid.h"
+
+namespace WorldPackets
+{
+ namespace Battlefield
+ {
+ class BFMgrEntryInvite final : public ServerPacket
+ {
+ public:
+ BFMgrEntryInvite() : ServerPacket(SMSG_BF_MGR_ENTRY_INVITE, 8 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 QueueID = 0;
+ int32 AreaID = 0;
+ time_t ExpireTime = time_t(0);
+ };
+
+ class BFMgrEntryInviteResponse final : public ClientPacket
+ {
+ public:
+ BFMgrEntryInviteResponse(WorldPacket&& packet) : ClientPacket(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 QueueID = 0;
+ bool AcceptedInvite = false;
+ };
+
+ class BFMgrQueueInvite final : public ServerPacket
+ {
+ public:
+ BFMgrQueueInvite() : ServerPacket(SMSG_BF_MGR_QUEUE_INVITE, 8 + 4 + 4 + 4 + 4 + 4 + 1 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 QueueID = 0;
+ int8 BattleState = 0;
+ uint32 Timeout = std::numeric_limits<uint32>::max(); // unused in client
+ int32 MinLevel = 0; // unused in client
+ int32 MaxLevel = 0; // unused in client
+ int32 MapID = 0; // unused in client
+ uint32 InstanceID = 0; // unused in client
+ int8 Index = 0; // unused in client
+ };
+
+ class BFMgrQueueInviteResponse final : public ClientPacket
+ {
+ public:
+ BFMgrQueueInviteResponse(WorldPacket&& packet) : ClientPacket(CMSG_BF_MGR_QUEUE_INVITE_RESPONSE, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 QueueID = 0;
+ bool AcceptedInvite = false;
+ };
+
+ class BFMgrQueueRequestResponse final : public ServerPacket
+ {
+ public:
+ BFMgrQueueRequestResponse() : ServerPacket(SMSG_BF_MGR_QUEUE_REQUEST_RESPONSE, 8 + 4 + 1 + 16 + 1 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 QueueID = 0;
+ int32 AreaID = 0;
+ int8 Result = 0;
+ ObjectGuid FailedPlayerGUID;
+ int8 BattleState = 0;
+ bool LoggingIn = false;
+ };
+
+ class BFMgrQueueExitRequest final : public ClientPacket
+ {
+ public:
+ BFMgrQueueExitRequest(WorldPacket&& packet) : ClientPacket(CMSG_BF_MGR_QUEUE_EXIT_REQUEST, std::move(packet)) { }
+
+ void Read() override;
+
+ uint64 QueueID = 0;
+ };
+
+ class BFMgrEntering final : public ServerPacket
+ {
+ public:
+ BFMgrEntering() : ServerPacket(SMSG_BF_MGR_ENTERING, 1 + 8) { }
+
+ WorldPacket const* Write() override;
+
+ bool ClearedAFK = false;
+ bool Relocated = false;
+ bool OnOffense = false;
+ uint64 QueueID = 0;
+ };
+
+ class BFMgrEjected final : public ServerPacket
+ {
+ public:
+ BFMgrEjected() : ServerPacket(SMSG_BF_MGR_EJECTED, 8 + 1 + 1 + 1) { }
+
+ WorldPacket const* Write() override;
+
+ uint64 QueueID = 0;
+ int8 Reason = 0;
+ int8 BattleState = 0;
+ bool Relocated = false;
+ };
+ }
+}
+
+#endif // BattlefieldPackets_h__
diff --git a/src/server/game/Server/Packets/ChatPackets.cpp b/src/server/game/Server/Packets/ChatPackets.cpp
index 5d242e430ce..9913ccde14f 100644
--- a/src/server/game/Server/Packets/ChatPackets.cpp
+++ b/src/server/game/Server/Packets/ChatPackets.cpp
@@ -265,3 +265,9 @@ WorldPacket const* WorldPackets::Chat::DefenseMessage::Write()
return &_worldPacket;
}
+
+void WorldPackets::Chat::ChatReportIgnored::Read()
+{
+ _worldPacket >> IgnoredGUID;
+ _worldPacket >> Reason;
+}
diff --git a/src/server/game/Server/Packets/ChatPackets.h b/src/server/game/Server/Packets/ChatPackets.h
index fa4b83ef5ef..66a38192836 100644
--- a/src/server/game/Server/Packets/ChatPackets.h
+++ b/src/server/game/Server/Packets/ChatPackets.h
@@ -289,6 +289,17 @@ namespace WorldPackets
int32 ZoneID = 0;
std::string MessageText;
};
+
+ class ChatReportIgnored final : public ClientPacket
+ {
+ public:
+ ChatReportIgnored(WorldPacket&& packet) : ClientPacket(CMSG_CHAT_REPORT_IGNORED, std::move(packet)) { }
+
+ void Read() override;
+
+ ObjectGuid IgnoredGUID;
+ uint8 Reason = 0;
+ };
}
}
diff --git a/src/server/game/Server/Packets/ItemPackets.cpp b/src/server/game/Server/Packets/ItemPackets.cpp
index b6b69b84eac..81b1c845ac9 100644
--- a/src/server/game/Server/Packets/ItemPackets.cpp
+++ b/src/server/game/Server/Packets/ItemPackets.cpp
@@ -71,6 +71,63 @@ void WorldPackets::Item::GetItemPurchaseData::Read()
_worldPacket >> ItemGUID;
}
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemPurchaseRefundItem& refundItem)
+{
+ data << refundItem.ItemID;
+ data << refundItem.ItemCount;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemPurchaseRefundCurrency& refundCurrency)
+{
+ data << refundCurrency.CurrencyID;
+ data << refundCurrency.CurrencyCount;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Item::ItemPurchaseContents& purchaseContents)
+{
+ data << purchaseContents.Money;
+ for (uint32 i = 0; i < 5; ++i)
+ data << purchaseContents.Items[i];
+
+ for (uint32 i = 0; i < 5; ++i)
+ data << purchaseContents.Currencies[i];
+
+ return data;
+}
+
+WorldPacket const* WorldPackets::Item::SetItemPurchaseData::Write()
+{
+ _worldPacket << ItemGUID;
+ _worldPacket << Contents;
+ _worldPacket << Flags;
+ _worldPacket << PurchaseTime;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Item::ItemPurchaseRefundResult::Write()
+{
+ _worldPacket << ItemGUID;
+ _worldPacket << uint8(Result);
+ _worldPacket.WriteBit(Contents.is_initialized());
+ _worldPacket.FlushBits();
+ if (Contents)
+ _worldPacket << *Contents;
+
+ return &_worldPacket;
+}
+
+WorldPacket const* WorldPackets::Item::ItemExpirePurchaseRefund::Write()
+{
+ _worldPacket << ItemGUID;
+
+ return &_worldPacket;
+}
+
void WorldPackets::Item::RepairItem::Read()
{
_worldPacket >> NpcGUID;
diff --git a/src/server/game/Server/Packets/ItemPackets.h b/src/server/game/Server/Packets/ItemPackets.h
index db7e9a01c0a..5435559fc74 100644
--- a/src/server/game/Server/Packets/ItemPackets.h
+++ b/src/server/game/Server/Packets/ItemPackets.h
@@ -115,6 +115,60 @@ namespace WorldPackets
ObjectGuid ItemGUID;
};
+ struct ItemPurchaseRefundItem
+ {
+ int32 ItemID = 0;
+ int32 ItemCount = 0;
+ };
+
+ struct ItemPurchaseRefundCurrency
+ {
+ int32 CurrencyID = 0;
+ int32 CurrencyCount = 0;
+ };
+
+ struct ItemPurchaseContents
+ {
+ uint32 Money = 0;
+ ItemPurchaseRefundItem Items[5] = { };
+ ItemPurchaseRefundCurrency Currencies[5] = { };
+ };
+
+ class SetItemPurchaseData final : public ServerPacket
+ {
+ public:
+ SetItemPurchaseData() : ServerPacket(SMSG_SET_ITEM_PURCHASE_DATA, 4 + 4 + 4 + 5 * (4 + 4) + 5 * (4 + 4) + 16) { }
+
+ WorldPacket const* Write() override;
+
+ uint32 PurchaseTime = 0;
+ uint32 Flags = 0;
+ ItemPurchaseContents Contents;
+ ObjectGuid ItemGUID;
+ };
+
+ class ItemPurchaseRefundResult final : public ServerPacket
+ {
+ public:
+ ItemPurchaseRefundResult() : ServerPacket(SMSG_ITEM_PURCHASE_REFUND_RESULT, 1 + 4 + 5 * (4 + 4) + 5 * (4 + 4) + 16) { }
+
+ WorldPacket const* Write() override;
+
+ uint8 Result = 0;
+ ObjectGuid ItemGUID;
+ Optional<ItemPurchaseContents> Contents;
+ };
+
+ class ItemExpirePurchaseRefund final : public ServerPacket
+ {
+ public:
+ ItemExpirePurchaseRefund() : ServerPacket(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, 16) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid ItemGUID;
+ };
+
class RepairItem final : public ClientPacket
{
public:
diff --git a/src/server/game/Server/Packets/MovementPackets.cpp b/src/server/game/Server/Packets/MovementPackets.cpp
index 5b6b9803b4a..33f67842bfe 100644
--- a/src/server/game/Server/Packets/MovementPackets.cpp
+++ b/src/server/game/Server/Packets/MovementPackets.cpp
@@ -630,6 +630,17 @@ WorldPacket const* WorldPackets::Movement::MoveSetActiveMover::Write()
return &_worldPacket;
}
+WorldPacket const* WorldPackets::Movement::MoveKnockBack::Write()
+{
+ _worldPacket << MoverGUID;
+ _worldPacket << uint32(SequenceIndex);
+ _worldPacket << Direction;
+ _worldPacket << float(HorzSpeed);
+ _worldPacket << float(VertSpeed);
+
+ return &_worldPacket;
+}
+
WorldPacket const* WorldPackets::Movement::MoveUpdateKnockBack::Write()
{
_worldPacket << *movementInfo;
diff --git a/src/server/game/Server/Packets/MovementPackets.h b/src/server/game/Server/Packets/MovementPackets.h
index d94911af15f..0a1c30c9d12 100644
--- a/src/server/game/Server/Packets/MovementPackets.h
+++ b/src/server/game/Server/Packets/MovementPackets.h
@@ -334,6 +334,20 @@ namespace WorldPackets
ObjectGuid MoverGUID;
};
+ class MoveKnockBack final : public ServerPacket
+ {
+ public:
+ MoveKnockBack() : ServerPacket(SMSG_MOVE_KNOCK_BACK, 16 + 8 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid MoverGUID;
+ G3D::Vector2 Direction;
+ float HorzSpeed = 0.0f;
+ uint32 SequenceIndex = 0;
+ float VertSpeed = 0.0f;
+ };
+
class MoveUpdateKnockBack final : public ServerPacket
{
public:
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index 9fc835b00c3..a908864c6a5 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -642,6 +642,16 @@ WorldPacket const* WorldPackets::Spells::CancelSpellVisual::Write()
return &_worldPacket;
}
+WorldPacket const* WorldPackets::Spells::PlaySpellVisualKit::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << int32(KitRecID);
+ _worldPacket << int32(KitType);
+ _worldPacket << uint32(Duration);
+
+ return &_worldPacket;
+}
+
void WorldPackets::Spells::CancelCast::Read()
{
_worldPacket >> SpellID;
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index 39491b27130..451caf6d577 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -616,6 +616,19 @@ namespace WorldPackets
int32 SpellVisualID = 0;
};
+ class PlaySpellVisualKit final : public ServerPacket
+ {
+ public:
+ PlaySpellVisualKit() : ServerPacket(SMSG_PLAY_SPELL_VISUAL_KIT, 16 + 4 + 4 + 4) { }
+
+ WorldPacket const* Write() override;
+
+ ObjectGuid Unit;
+ int32 KitRecID = 0;
+ int32 KitType = 0;
+ uint32 Duration = 0;
+ };
+
class CancelCast final : public ClientPacket
{
public:
diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp
index c59a4bb3175..6acb1cfb3a3 100644
--- a/src/server/game/Server/Protocol/Opcodes.cpp
+++ b/src/server/game/Server/Protocol/Opcodes.cpp
@@ -21,6 +21,7 @@
#include "Packets/AchievementPackets.h"
#include "Packets/AuctionHousePackets.h"
#include "Packets/BankPackets.h"
+#include "Packets/BattlefieldPackets.h"
#include "Packets/BattlegroundPackets.h"
#include "Packets/BattlePetPackets.h"
#include "Packets/BlackMarketPackets.h"
@@ -217,9 +218,9 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_BATTLE_PET_SUMMON, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::BattlePet::BattlePetSummon, &WorldSession::HandleBattlePetSummon);
DEFINE_HANDLER(CMSG_BATTLE_PET_UPDATE_NOTIFY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BEGIN_TRADE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Trade::BeginTrade, &WorldSession::HandleBeginTradeOpcode);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleBfEntryInviteResponse );
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_EXIT_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfExitRequest);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_BF_MGR_QUEUE_INVITE_RESPONSE, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::HandleBfQueueInviteResponse );
+ DEFINE_HANDLER(CMSG_BF_MGR_ENTRY_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battlefield::BFMgrEntryInviteResponse, &WorldSession::HandleBfEntryInviteResponse);
+ DEFINE_HANDLER(CMSG_BF_MGR_QUEUE_EXIT_REQUEST, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battlefield::BFMgrQueueExitRequest, &WorldSession::HandleBfQueueExitRequest);
+ DEFINE_HANDLER(CMSG_BF_MGR_QUEUE_INVITE_RESPONSE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Battlefield::BFMgrQueueInviteResponse, &WorldSession::HandleBfQueueInviteResponse);
DEFINE_HANDLER(CMSG_BF_MGR_QUEUE_REQUEST, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_BINDER_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::NPC::Hello, &WorldSession::HandleBinderActivateOpcode);
DEFINE_HANDLER(CMSG_BLACK_MARKET_BID_ON_ITEM, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -317,7 +318,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_CHAT_MESSAGE_YELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatMessage, &WorldSession::HandleChatMessageOpcode);
DEFINE_HANDLER(CMSG_CHAT_REGISTER_ADDON_PREFIXES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatRegisterAddonPrefixes, &WorldSession::HandleAddonRegisteredPrefixesOpcode);
DEFINE_HANDLER(CMSG_CHAT_REPORT_FILTERED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
- DEFINE_OPCODE_HANDLER_OLD(CMSG_CHAT_REPORT_IGNORED, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, &WorldSession::HandleChatIgnoredOpcode );
+ DEFINE_HANDLER(CMSG_CHAT_REPORT_IGNORED, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatReportIgnored, &WorldSession::HandleChatIgnoredOpcode);
DEFINE_HANDLER(CMSG_CHAT_UNREGISTER_ALL_ADDON_PREFIXES, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Chat::ChatUnregisterAllAddonPrefixes, &WorldSession::HandleUnregisterAllAddonPrefixesOpcode);
DEFINE_HANDLER(CMSG_CHECK_RAF_EMAIL_ENABLED, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_CHECK_WOW_TOKEN_VETERAN_ELIGIBILITY, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -398,7 +399,7 @@ void OpcodeTable::Initialize()
DEFINE_HANDLER(CMSG_GENERATE_RANDOM_CHARACTER_NAME, STATUS_AUTHED, PROCESS_THREADUNSAFE, WorldPackets::Character::GenerateRandomCharacterName, &WorldSession::HandleRandomizeCharNameOpcode);
DEFINE_HANDLER(CMSG_GET_CHALLENGE_MODE_REWARDS, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
DEFINE_HANDLER(CMSG_GET_GARRISON_INFO, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Garrison::GetGarrisonInfo, &WorldSession::HandleGetGarrisonInfo);
- DEFINE_HANDLER(CMSG_GET_ITEM_PURCHASE_DATA, STATUS_UNHANDLED, PROCESS_THREADUNSAFE, WorldPackets::Item::GetItemPurchaseData, &WorldSession::HandleGetItemPurchaseData);
+ DEFINE_HANDLER(CMSG_GET_ITEM_PURCHASE_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Item::GetItemPurchaseData, &WorldSession::HandleGetItemPurchaseData);
DEFINE_HANDLER(CMSG_GET_MIRROR_IMAGE_DATA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, WorldPackets::Spells::GetMirrorImageData, &WorldSession::HandleMirrorImageDataRequest);
DEFINE_HANDLER(CMSG_GET_PVP_OPTIONS_ENABLED, STATUS_LOGGEDIN, PROCESS_INPLACE, WorldPackets::Battleground::GetPVPOptionsEnabled, &WorldSession::HandleGetPVPOptionsEnabled);
DEFINE_HANDLER(CMSG_GET_REMAINING_GAME_TIME, STATUS_UNHANDLED, PROCESS_INPLACE, WorldPackets::Null, &WorldSession::Handle_NULL);
@@ -841,9 +842,9 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ABORT_NEW_WORLD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_CRITERIA_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_DATA_TIMES, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_HEIRLOOM_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_MOUNT_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACCOUNT_TOYS_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_DELETED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACHIEVEMENT_EARNED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ACTIVATE_TAXI_REPLY, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -856,7 +857,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AE_LOOT_TARGETS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AE_LOOT_TARGET_ACK, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_AI_REACTION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACCOUNT_CRITERIA, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACCOUNT_CRITERIA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_ACHIEVEMENT_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ALL_GUILD_ACHIEVEMENTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ARCHAEOLOGY_SURVERY_CAST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -930,12 +931,12 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BATTLE_PET_UPDATES, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_DROP_TIMER_CANCELLED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_DROP_TIMER_STARTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_EJECTED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_EJECTED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_EJECT_PENDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_ENTERING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_ENTRY_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_QUEUE_INVITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_QUEUE_REQUEST_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_ENTERING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_ENTRY_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_QUEUE_INVITE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_QUEUE_REQUEST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_QUEUE_STATUS_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BF_MGR_STATE_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_BINDER_CONFIRM, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1034,7 +1035,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPLETE_SHIPMENT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COMPRESSED_PACKET, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONNECT_TO, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONQUEST_FORMULA_CONSTANTS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONSOLE_WRITE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTACT_LIST, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CONTROL_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1042,7 +1043,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_CHEAT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_COOLDOWN_EVENT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_LOCATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_RECLAIM_DELAY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CORPSE_TRANSPORT_QUERY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_CHAR, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_CREATE_SHIPMENT_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1088,7 +1089,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EQUIPMENT_SET_ID, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPECTED_SPAM_RECORDS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_EXPLORATION_EXPERIENCE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_FACTION_BONUS_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_FACTION_BONUS_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FAILED_PLAYER_CONDITION, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_FEATURE_SYSTEM_STATUS_GLUE_SCREEN, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1216,7 +1217,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NAME_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_NEWS_DELETED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PARTY_STATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_PERMISSIONS_QUERY_RESULTS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_RANKS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_GUILD_REPUTATION_REACTION_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1232,7 +1233,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INCREASE_CAST_TIME_FOR_SPELL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIALIZE_FACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INITIAL_SETUP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_INIT_WORLD_STATES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_HONOR_STATS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_PVP, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_INSPECT_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1259,9 +1260,9 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_IS_QUEST_COMPLETE_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_CHANGED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PURCHASE_REFUND_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_EXPIRE_PURCHASE_REFUND, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PURCHASE_REFUND_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_PUSH_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_KICK_REASON, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1277,7 +1278,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_LIST_UPDATE_BLACKLIST, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_LIST_UPDATE_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_OFFER_CONTINUE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PARTY_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_INFO, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PLAYER_REWARD, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LFG_PROPOSAL_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1299,7 +1300,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_ACCOUNT_RESTORE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_CHARACTER_COPY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LIVE_REGION_GET_ACCOUNT_CHARACTER_LIST_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_CUF_PROFILES, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_EQUIPMENT_SET, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOAD_SELECTED_TROPHY_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_LOGIN_SET_TIME_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1336,13 +1337,13 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOTD, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOUNT_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_APPLY_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_COLLISION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_DISABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_COLLISION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ENABLE_TRANSITION_BETWEEN_SWIM_AND_FLY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_KNOCK_BACK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_REMOVE_MOVEMENT_FORCE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_ROOT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_ACTIVE_MOVER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1367,9 +1368,9 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_WALK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SET_WATER_WALK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SKIP_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_DISABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_DISABLE_COLLISION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_DISABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ENABLE_COLLISION, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ENABLE_COLLISION, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ENABLE_GRAVITY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_ROOT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_FEATHER_FALL, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1389,8 +1390,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_MODE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WALK_SPEED, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_SET_WATER_WALK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_START_SWIM, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_STOP_SWIM, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_START_SWIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_STOP_SWIM, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNROOT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_FLYING, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MOVE_SPLINE_UNSET_HOVER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1476,8 +1477,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_STABLE_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_TAME_FAILURE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PET_UNLEARNED_SPELLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PHASE_SHIFT_CHANGE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PHASE_SHIFT_CHANGE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYED_TIME, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_BOUND, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SAVE_GUILD_EMBLEM, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAYER_SKINNED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1490,7 +1491,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPEAKERBOT_SOUND, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_PONG, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_POWER_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1511,11 +1512,11 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_NPC_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PAGE_TEXT_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PETITION_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PET_NAME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PET_NAME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_PLAYER_NAME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUEST_INFO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_QUEST_INFO_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUERY_TIME_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_COMPLETION_NPC_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_CONFIRM_ACCEPT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_FORCE_REMOVED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_QUEST_GIVER_INVALID_QUEST, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1559,7 +1560,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REMOVE_LOSS_OF_CONTROL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPLACE_TROPHY_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REPORT_PVP_PLAYER_AFK_RESULT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_CEMETERY_LIST_RESPONSE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_REQUEST_PVP_REWARDS_RESPONSE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESEARCH_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_RESET_COMPRESSION_CONTEXT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1603,20 +1604,20 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_FIRST_ACHIEVEMENTS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SERVER_TIME, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SETUP_RESEARCH_HISTORY, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_AI_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ALL_TASK_PROGRESS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ANIM_TIER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_CURRENCY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DF_FAST_LAUNCH_RESULT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_DUNGEON_DIFFICULTY, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_AT_WAR, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_AT_WAR, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_NOT_VISIBLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_STANDING, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FACTION_VISIBLE, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ITEM_PURCHASE_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_ITEM_PURCHASE_DATA, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_LOOT_METHOD_FAILED, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MAX_WEEKLY_QUANTITY, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_MELEE_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
@@ -1630,7 +1631,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TASK_COMPLETE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_TIME_ZONE_INFORMATION, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SET_VEHICLE_REC_ID, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_BANK, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_MAILBOX, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_NEUTRAL_PLAYER_FACTION_SELECT_UI, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SHOW_TAXI_NODES, STATUS_NEVER, CONNECTION_TYPE_REALM);
@@ -1662,8 +1663,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPELL_UPDATE_CHAIN_TARGETS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_SPIRIT_HEALER_CONFIRM, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_STAND_STATE_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMERS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_ELAPSED_TIMERS, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_LOOT_ROLL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_MIRROR_TIMER, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_START_TIMER, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1722,7 +1723,7 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_USERLIST_UPDATE, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_USE_EQUIPMENT_SET_RESULT, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_VENDOR_INVENTORY, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_VIGNETTE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_VIGNETTE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_CHAT_STATUS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_PARENTAL_CONTROLS, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_VOICE_SESSION_LEAVE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
@@ -1736,8 +1737,8 @@ void OpcodeTable::Initialize()
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WAIT_QUEUE_UPDATE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARDEN_DATA, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WARGAME_REQUEST_SUCCESSFULLY_SENT_TO_OPPONENT, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEATHER, STATUS_NEVER, CONNECTION_TYPE_REALM);
- DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEATHER, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
+ DEFINE_SERVER_OPCODE_HANDLER(SMSG_WEEKLY_SPELL_USAGE, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHO, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WHO_IS, STATUS_NEVER, CONNECTION_TYPE_REALM);
DEFINE_SERVER_OPCODE_HANDLER(SMSG_WORLD_SERVER_INFO, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h
index dd86bd003dd..016e6d46162 100644
--- a/src/server/game/Server/Protocol/Opcodes.h
+++ b/src/server/game/Server/Protocol/Opcodes.h
@@ -724,7 +724,7 @@ enum OpcodeServer : uint32
SMSG_ABORT_NEW_WORLD = 0x01F3,
SMSG_ACCOUNT_CRITERIA_UPDATE = 0x1E2A,
SMSG_ACCOUNT_DATA_TIMES = 0x09FB,
- SMSG_ACCOUNT_HEIRLOOM_UPDATE = 0xBADD, // no client handler
+ SMSG_ACCOUNT_HEIRLOOM_UPDATE = 0x082B, // no client handler
SMSG_ACCOUNT_MOUNT_UPDATE = 0x03B4,
SMSG_ACCOUNT_TOYS_UPDATE = 0x013B,
SMSG_ACHIEVEMENT_DELETED = 0x0064,
diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp
index 2189fbffeff..f0126cd2782 100644
--- a/src/server/game/Server/WorldSession.cpp
+++ b/src/server/game/Server/WorldSession.cpp
@@ -1411,6 +1411,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co
case CMSG_STAND_STATE_CHANGE: // not profiled
case CMSG_RANDOM_ROLL: // not profiled
case CMSG_TIME_SYNC_RESPONSE: // not profiled
+ case CMSG_MOVE_FORCE_RUN_SPEED_CHANGE_ACK: // not profiled
{
// "0" is a magic number meaning there's no limit for the opcode.
// All the opcodes above must cause little CPU usage and no sync/async database queries at all
diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h
index 2fb51482cbf..3134ad331b1 100644
--- a/src/server/game/Server/WorldSession.h
+++ b/src/server/game/Server/WorldSession.h
@@ -104,6 +104,13 @@ namespace WorldPackets
class BuyBankSlot;
}
+ namespace Battlefield
+ {
+ class BFMgrEntryInviteResponse;
+ class BFMgrQueueInviteResponse;
+ class BFMgrQueueExitRequest;
+ }
+
namespace Battleground
{
class AreaSpiritHealerQuery;
@@ -219,6 +226,7 @@ namespace WorldPackets
class EmoteClient;
class ChatRegisterAddonPrefixes;
class ChatUnregisterAllAddonPrefixes;
+ class ChatReportIgnored;
}
namespace Combat
@@ -718,11 +726,13 @@ enum BarberShopResult
enum BFLeaveReason
{
- BF_LEAVE_REASON_CLOSE = 0x00000001,
- //BF_LEAVE_REASON_UNK1 = 0x00000002, (not used)
- //BF_LEAVE_REASON_UNK2 = 0x00000004, (not used)
- BF_LEAVE_REASON_EXITED = 0x00000008,
- BF_LEAVE_REASON_LOW_LEVEL = 0x00000010
+ BF_LEAVE_REASON_CLOSE = 1,
+ //BF_LEAVE_REASON_UNK1 = 2, (not used)
+ //BF_LEAVE_REASON_UNK2 = 4, (not used)
+ BF_LEAVE_REASON_EXITED = 8,
+ BF_LEAVE_REASON_LOW_LEVEL = 10,
+ BF_LEAVE_REASON_NOT_WHILE_IN_RAID = 15,
+ BF_LEAVE_REASON_DESERTER = 16
};
enum ChatRestrictionType
@@ -903,9 +913,6 @@ class WorldSession
void SendPetitionQueryOpcode(ObjectGuid petitionguid);
- // Spell
- void HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets);
-
// Pet
void SendQueryPetNameResponse(ObjectGuid guid);
void SendStablePet(ObjectGuid guid);
@@ -1381,7 +1388,7 @@ class WorldSession
void SendPlayerAmbiguousNotice(std::string const& name);
void SendChatRestrictedNotice(ChatRestrictionType restriction);
void HandleTextEmoteOpcode(WorldPackets::Chat::CTextEmote& packet);
- void HandleChatIgnoredOpcode(WorldPacket& recvPacket);
+ void HandleChatIgnoredOpcode(WorldPackets::Chat::ChatReportIgnored& chatReportIgnored);
void HandleUnregisterAllAddonPrefixesOpcode(WorldPackets::Chat::ChatUnregisterAllAddonPrefixes& packet);
void HandleAddonRegisteredPrefixesOpcode(WorldPackets::Chat::ChatRegisterAddonPrefixes& packet);
@@ -1446,14 +1453,14 @@ class WorldSession
void HandleRequestBattlefieldStatusOpcode(WorldPackets::Battleground::RequestBattlefieldStatus& requestBattlefieldStatus);
// Battlefield
- void SendBfInvitePlayerToWar(ObjectGuid guid, uint32 zoneId, uint32 time);
- void SendBfInvitePlayerToQueue(ObjectGuid guid);
- void SendBfQueueInviteResponse(ObjectGuid guid, uint32 zoneId, bool canQueue = true, bool full = false);
- void SendBfEntered(ObjectGuid guid);
- void SendBfLeaveMessage(ObjectGuid guid, BFLeaveReason reason = BF_LEAVE_REASON_EXITED);
- void HandleBfQueueInviteResponse(WorldPacket& recvData);
- void HandleBfEntryInviteResponse(WorldPacket& recvData);
- void HandleBfExitRequest(WorldPacket& recvData);
+ void SendBfInvitePlayerToWar(uint64 queueId, uint32 zoneId, uint32 acceptTime);
+ void SendBfInvitePlayerToQueue(uint64 queueId, int8 battleState);
+ void SendBfQueueInviteResponse(uint64 queueId, uint32 zoneId, int8 battleStatus, bool canQueue = true, bool loggingIn = false);
+ void SendBfEntered(uint64 queueId, bool relocated, bool onOffense);
+ void SendBfLeaveMessage(uint64 queueId, int8 battleState, bool relocated, BFLeaveReason reason = BF_LEAVE_REASON_EXITED);
+ void HandleBfEntryInviteResponse(WorldPackets::Battlefield::BFMgrEntryInviteResponse& bfMgrEntryInviteResponse);
+ void HandleBfQueueInviteResponse(WorldPackets::Battlefield::BFMgrQueueInviteResponse& bfMgrQueueInviteResponse);
+ void HandleBfQueueExitRequest(WorldPackets::Battlefield::BFMgrQueueExitRequest& bfMgrQueueExitRequest);
void HandleWardenDataOpcode(WorldPacket& recvData);
void HandleWorldTeleportOpcode(WorldPackets::Misc::WorldTeleport& worldTeleport);
diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp
index 7f9b398e50d..030ca1966f8 100644
--- a/src/server/game/Server/WorldSocket.cpp
+++ b/src/server/game/Server/WorldSocket.cpp
@@ -130,6 +130,7 @@ bool WorldSocket::Update()
if (_queryFuture.valid() && _queryFuture.wait_for(std::chrono::seconds(0)) == std::future_status::ready)
{
auto callback = std::move(_queryCallback);
+ _queryCallback = nullptr;
callback(_queryFuture.get());
}
}
@@ -532,11 +533,11 @@ struct AccountInfo
uint32 Id;
bool IsLockedToIP;
std::string LastIP;
+ std::string LockCountry;
LocaleConstant Locale;
std::string OS;
bool IsBanned;
- std::string LockCountry;
} BattleNet;
struct
@@ -555,9 +556,9 @@ struct AccountInfo
explicit AccountInfo(Field* fields)
{
- // 0 1 2 3 4 5 6 7 8 9 10
- // SELECT a.id, a.sessionkey, ba.last_ip, ba.locked, a.expansion, a.mutetime, ba.locale, a.recruiter, ba.os, ba.id, aa.gmLevel,
- // 11 12 13
+ // 0 1 2 3 4 5 6 7 8 9 10 11
+ // SELECT a.id, a.sessionkey, ba.last_ip, ba.locked, ba.lock_country, a.expansion, a.mutetime, ba.locale, a.recruiter, ba.os, ba.id, aa.gmLevel,
+ // 12 13 14
// bab.unbandate > UNIX_TIMESTAMP() OR bab.unbandate = bab.bandate, ab.unbandate > UNIX_TIMESTAMP() OR ab.unbandate = ab.bandate, r.id
// FROM account a LEFT JOIN battlenet_accounts ba ON a.battlenet_account = ba.id LEFT JOIN account_access aa ON a.id = aa.id AND aa.RealmID IN (-1, ?)
// LEFT JOIN battlenet_account_bans bab ON ba.id = bab.id LEFT JOIN account_banned ab ON a.id = ab.id LEFT JOIN account r ON a.id = r.recruiter
@@ -566,16 +567,17 @@ struct AccountInfo
Game.SessionKey.SetHexStr(fields[1].GetCString());
BattleNet.LastIP = fields[2].GetString();
BattleNet.IsLockedToIP = fields[3].GetBool();
- Game.Expansion = fields[4].GetUInt8();
- Game.MuteTime = fields[5].GetInt64();
- BattleNet.Locale = LocaleConstant(fields[6].GetUInt8());
- Game.Recruiter = fields[7].GetUInt32();
- BattleNet.OS = fields[8].GetString();
- BattleNet.Id = fields[9].GetUInt32();
- Game.Security = AccountTypes(fields[10].GetUInt8());
- BattleNet.IsBanned = fields[11].GetUInt64() != 0;
- Game.IsBanned = fields[12].GetUInt64() != 0;
- Game.IsRectuiter = fields[13].GetUInt32() != 0;
+ BattleNet.LockCountry = fields[4].GetString();
+ Game.Expansion = fields[5].GetUInt8();
+ Game.MuteTime = fields[6].GetInt64();
+ BattleNet.Locale = LocaleConstant(fields[7].GetUInt8());
+ Game.Recruiter = fields[8].GetUInt32();
+ BattleNet.OS = fields[9].GetString();
+ BattleNet.Id = fields[10].GetUInt32();
+ Game.Security = AccountTypes(fields[11].GetUInt8());
+ BattleNet.IsBanned = fields[12].GetUInt64() != 0;
+ Game.IsBanned = fields[13].GetUInt64() != 0;
+ Game.IsRectuiter = fields[14].GetUInt32() != 0;
uint32 world_expansion = sWorld->getIntConfig(CONFIG_EXPANSION);
if (Game.Expansion > world_expansion)
@@ -697,7 +699,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<WorldPackets::Auth::
return;
}
}
- else if (!account.BattleNet.LockCountry.empty() && !_ipCountry.empty())
+ else if (!account.BattleNet.LockCountry.empty() && account.BattleNet.LockCountry != "00" && !_ipCountry.empty())
{
if (account.BattleNet.LockCountry != _ipCountry)
{
diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp
index 8df9ce86f9a..2c9a2a7bcfd 100644
--- a/src/server/game/Skills/SkillExtraItems.cpp
+++ b/src/server/game/Skills/SkillExtraItems.cpp
@@ -20,11 +20,98 @@
#include "DatabaseEnv.h"
#include "Log.h"
#include "Player.h"
+#include "ObjectMgr.h"
#include <map>
// some type definitions
// no use putting them in the header file, they're only used in this .cpp
+// struct to store information about perfection procs
+// one entry per spell
+struct SkillPerfectItemEntry
+{
+ // the spell id of the spell required - it's named "specialization" to conform with SkillExtraItemEntry
+ uint32 requiredSpecialization;
+ // perfection proc chance
+ float perfectCreateChance;
+ // itemid of the resulting perfect item
+ uint32 perfectItemType;
+
+ SkillPerfectItemEntry()
+ : requiredSpecialization(0), perfectCreateChance(0.0f), perfectItemType(0) { }
+ SkillPerfectItemEntry(uint32 rS, float pCC, uint32 pIT)
+ : requiredSpecialization(rS), perfectCreateChance(pCC), perfectItemType(pIT) { }
+};
+
+// map to store perfection info. key = spellId of the creation spell, value is the perfectitementry as specified above
+typedef std::map<uint32, SkillPerfectItemEntry> SkillPerfectItemMap;
+
+SkillPerfectItemMap SkillPerfectItemStore;
+
+// loads the perfection proc info from DB
+void LoadSkillPerfectItemTable()
+{
+ uint32 oldMSTime = getMSTime();
+
+ SkillPerfectItemStore.clear(); // reload capability
+
+ // 0 1 2 3
+ QueryResult result = WorldDatabase.Query("SELECT spellId, requiredSpecialization, perfectCreateChance, perfectItemType FROM skill_perfect_item_template");
+
+ if (!result)
+ {
+ TC_LOG_ERROR("server.loading", ">> Loaded 0 spell perfection definitions. DB table `skill_perfect_item_template` is empty.");
+ return;
+ }
+
+ uint32 count = 0;
+
+ do /* fetch data and run sanity checks */
+ {
+ Field* fields = result->Fetch();
+
+ uint32 spellId = fields[0].GetUInt32();
+
+ if (!sSpellMgr->GetSpellInfo(spellId))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent spell id in `skill_perfect_item_template`!", spellId);
+ continue;
+ }
+
+ uint32 requiredSpecialization = fields[1].GetUInt32();
+ if (!sSpellMgr->GetSpellInfo(requiredSpecialization))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has non-existent required specialization spell id %u in `skill_perfect_item_template`!", spellId, requiredSpecialization);
+ continue;
+ }
+
+ float perfectCreateChance = fields[2].GetFloat();
+ if (perfectCreateChance <= 0.0f)
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u has impossibly low proc chance in `skill_perfect_item_template`!", spellId);
+ continue;
+ }
+
+ uint32 perfectItemType = fields[3].GetUInt32();
+ if (!sObjectMgr->GetItemTemplate(perfectItemType))
+ {
+ TC_LOG_ERROR("sql.sql", "Skill perfection data for spell %u references non-existent perfect item id %u in `skill_perfect_item_template`!", spellId, perfectItemType);
+ continue;
+ }
+
+ SkillPerfectItemEntry& skillPerfectItemEntry = SkillPerfectItemStore[spellId];
+
+ skillPerfectItemEntry.requiredSpecialization = requiredSpecialization;
+ skillPerfectItemEntry.perfectCreateChance = perfectCreateChance;
+ skillPerfectItemEntry.perfectItemType = perfectItemType;
+
+ ++count;
+ }
+ while (result->NextRow());
+
+ TC_LOG_INFO("server.loading", ">> Loaded %u spell perfection definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+}
+
// struct to store information about extra item creation
// one entry for every spell that is able to create an extra item
struct SkillExtraItemEntry
@@ -112,6 +199,30 @@ void LoadSkillExtraItemTable()
TC_LOG_INFO("server.loading", ">> Loaded %u spell specialization definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
+bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
+{
+ SkillPerfectItemMap::const_iterator ret = SkillPerfectItemStore.find(spellId);
+ // no entry in DB means no perfection proc possible
+ if (ret == SkillPerfectItemStore.end())
+ return false;
+
+ SkillPerfectItemEntry const* thisEntry = &ret->second;
+ // lack of entry means no perfection proc possible
+ if (!thisEntry)
+ return false;
+
+ // if you don't have the spell needed, then no procs for you
+ if (!player->HasSpell(thisEntry->requiredSpecialization))
+ return false;
+
+ // set values as appropriate
+ perfectCreateChance = thisEntry->perfectCreateChance;
+ perfectItemType = thisEntry->perfectItemType;
+
+ // and tell the caller to start rolling the dice
+ return true;
+}
+
bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax)
{
// get the info for the specified spell
diff --git a/src/server/game/Skills/SkillExtraItems.h b/src/server/game/Skills/SkillExtraItems.h
index 0cdfff74ed2..118c49ed00f 100644
--- a/src/server/game/Skills/SkillExtraItems.h
+++ b/src/server/game/Skills/SkillExtraItems.h
@@ -23,6 +23,10 @@
// predef classes used in functions
class Player;
+// returns true and sets the appropriate info if the player can create a perfect item with the given spellId
+bool CanCreatePerfectItem(Player* player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType);
+// load perfection proc info from DB
+void LoadSkillPerfectItemTable();
// returns true and sets the appropriate info if the player can create extra items with the given spellId
bool CanCreateExtraItems(Player* player, uint32 spellId, float &additionalChance, uint8 &additionalMax);
// function to load the extra item creation info from DB
diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp
index 0d9d010743c..dd5519dc7b1 100644
--- a/src/server/game/Spells/Auras/SpellAuras.cpp
+++ b/src/server/game/Spells/Auras/SpellAuras.cpp
@@ -1855,9 +1855,7 @@ bool Aura::IsProcTriggeredOnEvent(AuraApplication* aurApp, ProcEventInfo& eventI
return false;
// do checks using conditions table
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId());
- ConditionSourceInfo condInfo = ConditionSourceInfo(eventInfo.GetActor(), eventInfo.GetActionTarget());
- if (!sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPELL_PROC, GetId(), eventInfo.GetActor(), eventInfo.GetActionTarget()))
return false;
// AuraScript Hook
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index a441da8fbe9..d5b6baaf056 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -57,6 +57,7 @@
#include "SpellPackets.h"
#include "CombatLogPackets.h"
#include "SpellHistory.h"
+#include "TradeData.h"
extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS];
@@ -1030,7 +1031,7 @@ void Spell::SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTar
break;
}
- ConditionList* condList = effect->ImplicitTargetConditions;
+ ConditionContainer* condList = effect->ImplicitTargetConditions;
// handle emergency case - try to use other provided targets if no conditions provided
if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
@@ -1119,7 +1120,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge
SpellEffectInfo const* effect = GetEffect(effIndex);
if (!effect)
return;
- ConditionList* condList = effect->ImplicitTargetConditions;
+ ConditionContainer* condList = effect->ImplicitTargetConditions;
float coneAngle = float(M_PI) / 2;
float radius = effect->CalcRadius(m_caster) * m_spellValue->RadiusMod;
@@ -1749,7 +1750,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint32 effIndex)
}
}
-uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList)
+uint32 Spell::GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList)
{
// this function selects which containers need to be searched for spell target
uint32 retMask = GRID_MAP_TYPE_MASK_ALL;
@@ -1817,7 +1818,7 @@ void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* refere
}
}
-WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
+WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList)
{
WorldObject* target = NULL;
uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
@@ -1829,7 +1830,7 @@ WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objec
return target;
}
-void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList)
+void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList)
{
uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
if (!containerTypeMask)
@@ -1839,7 +1840,7 @@ void Spell::SearchAreaTargets(std::list<WorldObject*>& targets, float range, Pos
SearchTargets<Trinity::WorldObjectListSearcher<Trinity::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
}
-void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionList* condList, bool isChainHeal)
+void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal)
{
// max dist for jump target selection
float jumpRadius = 0.0f;
@@ -4821,10 +4822,8 @@ SpellCastResult Spell::CheckCast(bool strict)
// check spell cast conditions from database
{
- ConditionSourceInfo condInfo = ConditionSourceInfo(m_caster);
- condInfo.mConditionTargets[1] = m_targets.GetObjectTarget();
- ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
- if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
+ ConditionSourceInfo condInfo = ConditionSourceInfo(m_caster, m_targets.GetObjectTarget());
+ if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id, condInfo))
{
// mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
@@ -7362,7 +7361,7 @@ namespace Trinity
{
WorldObjectSpellTargetCheck::WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
- SpellTargetCheckTypes selectionType, ConditionList* condList) : _caster(caster), _referer(referer), _spellInfo(spellInfo),
+ SpellTargetCheckTypes selectionType, ConditionContainer* condList) : _caster(caster), _referer(referer), _spellInfo(spellInfo),
_targetSelectionType(selectionType), _condList(condList)
{
if (condList)
@@ -7436,7 +7435,7 @@ bool WorldObjectSpellTargetCheck::operator()(WorldObject* target)
}
WorldObjectSpellNearbyTargetCheck::WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
- SpellTargetCheckTypes selectionType, ConditionList* condList)
+ SpellTargetCheckTypes selectionType, ConditionContainer* condList)
: WorldObjectSpellTargetCheck(caster, caster, spellInfo, selectionType, condList), _range(range), _position(caster) { }
bool WorldObjectSpellNearbyTargetCheck::operator()(WorldObject* target)
@@ -7451,7 +7450,7 @@ bool WorldObjectSpellNearbyTargetCheck::operator()(WorldObject* target)
}
WorldObjectSpellAreaTargetCheck::WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
- Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
+ Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList)
: WorldObjectSpellTargetCheck(caster, referer, spellInfo, selectionType, condList), _range(range), _position(position) { }
bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
@@ -7462,7 +7461,7 @@ bool WorldObjectSpellAreaTargetCheck::operator()(WorldObject* target)
}
WorldObjectSpellConeTargetCheck::WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
- SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList)
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList)
: WorldObjectSpellAreaTargetCheck(range, caster, caster, caster, spellInfo, selectionType, condList), _coneAngle(coneAngle) { }
bool WorldObjectSpellConeTargetCheck::operator()(WorldObject* target)
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index 0728ee46e8c..96136374dd4 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -464,12 +464,12 @@ class Spell
void SelectEffectTypeImplicitTargets(uint32 effIndex);
- uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList* condList);
+ uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList);
template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius);
- WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList = NULL);
- void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList* condList);
- void SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionList* condList, bool isChainHeal);
+ WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList = NULL);
+ void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList);
+ void SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal);
GameObject* SearchSpellFocus();
@@ -857,10 +857,10 @@ namespace Trinity
SpellInfo const* _spellInfo;
SpellTargetCheckTypes _targetSelectionType;
ConditionSourceInfo* _condSrcInfo;
- ConditionList* _condList;
+ ConditionContainer* _condList;
WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
- SpellTargetCheckTypes selectionType, ConditionList* condList);
+ SpellTargetCheckTypes selectionType, ConditionContainer* condList);
~WorldObjectSpellTargetCheck();
bool operator()(WorldObject* target);
};
@@ -870,7 +870,7 @@ namespace Trinity
float _range;
Position const* _position;
WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
- SpellTargetCheckTypes selectionType, ConditionList* condList);
+ SpellTargetCheckTypes selectionType, ConditionContainer* condList);
bool operator()(WorldObject* target);
};
@@ -879,7 +879,7 @@ namespace Trinity
float _range;
Position const* _position;
WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
- Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList);
+ Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList);
bool operator()(WorldObject* target);
};
@@ -887,7 +887,7 @@ namespace Trinity
{
float _coneAngle;
WorldObjectSpellConeTargetCheck(float coneAngle, float range, Unit* caster,
- SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionList* condList);
+ SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList);
bool operator()(WorldObject* target);
};
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 77f3d2b905e..3431eb71898 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -1456,6 +1456,22 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype, std::vector<int32> const
if (num_to_add > pProto->GetMaxStackSize())
num_to_add = pProto->GetMaxStackSize();
+ /* == gem perfection handling == */
+
+ // the chance of getting a perfect result
+ float perfectCreateChance = 0.0f;
+ // the resulting perfect item if successful
+ uint32 perfectItemType = itemtype;
+ // get perfection capability and chance
+ if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
+ if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
+ newitemid = perfectItemType; // the perfect item replaces the regular one
+
+ /* == gem perfection handling over == */
+
+
+ /* == profession specialization handling == */
+
// init items_count to 1, since 1 item will be created regardless of specialization
int items_count=1;
// the chance to create additional items
@@ -1464,15 +1480,16 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype, std::vector<int32> const
uint8 additionalMaxNum=0;
// get the chance and maximum number for creating extra items
if (CanCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
- {
// roll with this chance till we roll not to create or we create the max num
while (roll_chance_f(additionalCreateChance) && items_count <= additionalMaxNum)
++items_count;
- }
// really will be created more items
num_to_add *= items_count;
+ /* == profession specialization handling over == */
+
+
// can the player store the new item?
ItemPosCountVec dest;
uint32 no_space = 0;
@@ -4114,11 +4131,14 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex /*effIndex*/)
if (effectInfo->MiscValue)
{
uint32 enchant_id = effectInfo->MiscValue;
- int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
+ int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
if (!duration)
- duration = damage;//+1; //Base points after ..
+ duration = damage;//+1; //Base points after ..
if (!duration)
- duration = 10; //10 seconds for enchants which don't have listed duration
+ duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
+
+ if (m_spellInfo->Id == 14792) // Venomhide Poison
+ duration = 5 * MINUTE * IN_MILLISECONDS;
SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
if (!pEnchant)
@@ -4132,7 +4152,7 @@ void Spell::EffectEnchantHeldItem(SpellEffIndex /*effIndex*/)
return;
// Apply the temporary enchantment
- item->SetEnchantment(slot, enchant_id, duration*IN_MILLISECONDS, 0, m_caster->GetGUID());
+ item->SetEnchantment(slot, enchant_id, duration, 0, m_caster->GetGUID());
item_owner->ApplyEnchantment(item, slot, true);
}
}
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp
index 3b86e3d594b..c2d1356e61a 100644
--- a/src/server/game/Spells/SpellHistory.cpp
+++ b/src/server/game/Spells/SpellHistory.cpp
@@ -870,6 +870,60 @@ void SpellHistory::SendClearCooldowns(std::vector<int32> const& cooldowns) const
}
}
+void SpellHistory::SaveCooldownStateBeforeDuel()
+{
+ _spellCooldownsBeforeDuel = _spellCooldowns;
+}
+
+void SpellHistory::RestoreCooldownStateAfterDuel()
+{
+ if (Player* player = _owner->ToPlayer())
+ {
+ // add all profession CDs created while in duel (if any)
+ for (auto const& c : _spellCooldowns)
+ {
+ SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(c.first);
+
+ if (spellInfo->RecoveryTime > 10 * MINUTE * IN_MILLISECONDS ||
+ spellInfo->CategoryRecoveryTime > 10 * MINUTE * IN_MILLISECONDS)
+ _spellCooldownsBeforeDuel[c.first] = _spellCooldowns[c.first];
+ }
+
+ _spellCooldowns = _spellCooldownsBeforeDuel;
+
+ // update the client: clear all cooldowns
+ std::vector<int32> resetCooldowns;
+ resetCooldowns.reserve(_spellCooldowns.size());
+
+ for (auto const& c : _spellCooldowns)
+ resetCooldowns.push_back(c.first);
+
+ if (resetCooldowns.empty())
+ return;
+
+ SendClearCooldowns(resetCooldowns);
+
+ // update the client: restore old cooldowns
+ WorldPackets::Spells::SpellCooldown spellCooldown;
+ spellCooldown.Caster = _owner->GetGUID();
+ spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
+
+ for (auto const& c : _spellCooldowns)
+ {
+ Clock::time_point now = Clock::now();
+ uint32 cooldownDuration = c.second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(c.second.CooldownEnd - now).count() : 0;
+
+ // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs
+ if (cooldownDuration == 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS)
+ continue;
+
+ spellCooldown.SpellCooldowns.emplace_back(c.first, cooldownDuration);
+ }
+
+ player->SendDirectMessage(spellCooldown.Write());
+ }
+}
+
template void SpellHistory::LoadFromDB<Player>(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
template void SpellHistory::LoadFromDB<Pet>(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
template void SpellHistory::SaveToDB<Player>(SQLTransaction& trans);
diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h
index 0a504668997..1a6fc205f96 100644
--- a/src/server/game/Spells/SpellHistory.h
+++ b/src/server/game/Spells/SpellHistory.h
@@ -144,6 +144,10 @@ public:
void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 duration);
void CancelGlobalCooldown(SpellInfo const* spellInfo);
+ uint16 GetArenaCooldownsSize();
+ void SaveCooldownStateBeforeDuel();
+ void RestoreCooldownStateAfterDuel();
+
private:
Player* GetPlayerOwner() const;
void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
@@ -155,6 +159,7 @@ private:
Unit* _owner;
CooldownStorageType _spellCooldowns;
+ CooldownStorageType _spellCooldownsBeforeDuel;
CategoryCooldownStorageType _categoryCooldowns;
Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL];
ChargeStorageType _categoryCharges;
diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp
index 50921c28a61..e91dadca57e 100644
--- a/src/server/game/Spells/SpellInfo.cpp
+++ b/src/server/game/Spells/SpellInfo.cpp
@@ -2729,7 +2729,8 @@ std::vector<SpellInfo::CostData> SpellInfo::CalcPowerCost(Unit const* caster, Sp
else
collector(sDB2Manager.GetSpellPowers(Id, caster->GetMap()->GetDifficultyID()));
- std::remove_if(costs.begin(), costs.end(), [](CostData const& cost) { return cost.Amount <= 0; });
+ // POWER_RUNES is handled by SpellRuneCost.db2, and cost.Amount is always 0 (see Spell::TakeRunePower)
+ costs.erase(std::remove_if(costs.begin(), costs.end(), [](CostData const& cost) { return cost.Power != POWER_RUNES && cost.Amount <= 0; }), costs.end());
return costs;
}
@@ -3285,7 +3286,7 @@ void SpellInfo::_UnloadImplicitTargetConditionLists()
{
if (SpellEffectInfo const* effect = GetEffect(d, i))
{
- ConditionList* cur = effect->ImplicitTargetConditions;
+ ConditionContainer* cur = effect->ImplicitTargetConditions;
if (!cur)
continue;
for (uint8 j = i; j < _effects.size(); ++j)
diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h
index 86d8addfbdb..6a56b876ccc 100644
--- a/src/server/game/Spells/SpellInfo.h
+++ b/src/server/game/Spells/SpellInfo.h
@@ -263,7 +263,7 @@ public:
uint32 TriggerSpell;
flag128 SpellClassMask;
float BonusCoefficientFromAP;
- std::list<Condition*>* ImplicitTargetConditions;
+ std::vector<Condition*>* ImplicitTargetConditions;
// SpellScalingEntry
struct ScalingInfo
{
diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp
index 9d5237fa591..75f419dc99e 100644
--- a/src/server/game/Spells/SpellMgr.cpp
+++ b/src/server/game/Spells/SpellMgr.cpp
@@ -3120,11 +3120,13 @@ void SpellMgr::LoadSpellInfoCorrections()
case 28796: // Poison Bolt Volly - Faerlina
spellInfo->MaxAffectedTargets = 5;
break;
+ case 54835: // Curse of the Plaguebringer - Noth (H)
+ spellInfo->MaxAffectedTargets = 8;
+ break;
case 40827: // Sinful Beam
case 40859: // Sinister Beam
case 40860: // Vile Beam
case 40861: // Wicked Beam
- case 54835: // Curse of the Plaguebringer - Noth (H)
case 54098: // Poison Bolt Volly - Faerlina (H)
spellInfo->MaxAffectedTargets = 10;
break;
@@ -3226,6 +3228,19 @@ void SpellMgr::LoadSpellInfoCorrections()
//! HACK: This spell break quest complete for alliance and on retail not used °_O
const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->Effect = 0;
break;
+ // VIOLET HOLD SPELLS
+ //
+ case 54258: // Water Globule (Ichoron)
+ case 54264: // Water Globule (Ichoron)
+ case 54265: // Water Globule (Ichoron)
+ case 54266: // Water Globule (Ichoron)
+ case 54267: // Water Globule (Ichoron)
+ // in 3.3.5 there is only one radius in dbc which is 0 yards in this case
+ // use max radius from 4.3.4
+ const_cast<SpellEffectInfo*>(spellInfo->GetEffect(EFFECT_0))->RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_25_YARDS);
+ break;
+ // ENDOF VIOLET HOLD
+ //
// ULDUAR SPELLS
//
case 62374: // Pursued (Flame Leviathan)
diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp
index 8ab122a82bb..f80e2977b1e 100644
--- a/src/server/game/Weather/WeatherMgr.cpp
+++ b/src/server/game/Weather/WeatherMgr.cpp
@@ -132,7 +132,7 @@ void LoadWeatherData()
}
}
- wzc.ScriptId = sObjectMgr->GetScriptId(fields[13].GetCString());
+ wzc.ScriptId = sObjectMgr->GetScriptId(fields[13].GetString());
++count;
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index 872f3bb160a..fa0b67082d2 100644
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -1278,6 +1278,7 @@ void World::LoadConfigSettings(bool reload)
if (m_bool_configs[CONFIG_START_ALL_SPELLS])
TC_LOG_WARN("server.loading", "PlayerStart.AllSpells enabled - may not function as intended!");
m_int_configs[CONFIG_HONOR_AFTER_DUEL] = sConfigMgr->GetIntDefault("HonorPointsAfterDuel", 0);
+ m_bool_configs[CONFIG_RESET_DUEL_COOLDOWNS] = sConfigMgr->GetBoolDefault("ResetDuelCooldowns", false);
m_bool_configs[CONFIG_START_ALL_EXPLORED] = sConfigMgr->GetBoolDefault("PlayerStart.MapsExplored", false);
m_bool_configs[CONFIG_START_ALL_REP] = sConfigMgr->GetBoolDefault("PlayerStart.AllReputation", false);
m_bool_configs[CONFIG_ALWAYS_MAXSKILL] = sConfigMgr->GetBoolDefault("AlwaysMaxWeaponSkill", false);
@@ -1750,6 +1751,9 @@ void World::SetInitialWorldSettings()
TC_LOG_INFO("server.loading", "Loading Skill Extra Item Table...");
LoadSkillExtraItemTable();
+ TC_LOG_INFO("server.loading", "Loading Skill Perfection Data Table...");
+ LoadSkillPerfectItemTable();
+
TC_LOG_INFO("server.loading", "Loading Skill Fishing base level requirements...");
sObjectMgr->LoadFishingBaseSkillLevel();
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index f7b61452fda..153a7730bef 100644
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -176,6 +176,7 @@ enum WorldBoolConfigs
CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA,
CONFIG_FEATURE_SYSTEM_BPAY_STORE_ENABLED,
CONFIG_FEATURE_SYSTEM_CHARACTER_UNDELETE_ENABLED,
+ CONFIG_RESET_DUEL_COOLDOWNS,
BOOL_CONFIG_VALUE_COUNT
};
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 2e08b53bffd..fe10319f986 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -33,45 +33,40 @@ class account_commandscript : public CommandScript
public:
account_commandscript() : CommandScript("account_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand accountSetSecTable[] =
+ static std::vector<ChatCommand> accountSetSecTable =
{
- { "regmail", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_REGMAIL, true, &HandleAccountSetRegEmailCommand, "", NULL },
- { "email", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_EMAIL, true, &HandleAccountSetEmailCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "regmail", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_REGMAIL, true, &HandleAccountSetRegEmailCommand, "" },
+ { "email", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_EMAIL, true, &HandleAccountSetEmailCommand, "" },
};
- static ChatCommand accountSetCommandTable[] =
+ static std::vector<ChatCommand> accountSetCommandTable =
{
- { "addon", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_ADDON, true, &HandleAccountSetAddonCommand, "", NULL },
+ { "addon", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_ADDON, true, &HandleAccountSetAddonCommand, "" },
{ "sec", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_SEC, true, NULL, "", accountSetSecTable },
- { "gmlevel", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_GMLEVEL, true, &HandleAccountSetGmLevelCommand, "", NULL },
- { "password", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "gmlevel", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_GMLEVEL, true, &HandleAccountSetGmLevelCommand, "" },
+ { "password", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "" },
};
- static ChatCommand accountLockCommandTable[] =
+ static std::vector<ChatCommand> accountLockCommandTable =
{
- { "country", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, false, &HandleAccountLockCountryCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, false, &HandleAccountLockIpCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "country", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY, false, &HandleAccountLockCountryCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP, false, &HandleAccountLockIpCommand, "" },
};
- static ChatCommand accountCommandTable[] =
+ static std::vector<ChatCommand> accountCommandTable =
{
- { "addon", rbac::RBAC_PERM_COMMAND_ACCOUNT_ADDON, false, &HandleAccountAddonCommand, "", NULL },
- { "create", rbac::RBAC_PERM_COMMAND_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_ACCOUNT_DELETE, true, &HandleAccountDeleteCommand, "", NULL },
- { "email", rbac::RBAC_PERM_COMMAND_ACCOUNT_EMAIL, false, &HandleAccountEmailCommand, "", NULL },
- { "onlinelist", rbac::RBAC_PERM_COMMAND_ACCOUNT_ONLINE_LIST, true, &HandleAccountOnlineListCommand, "", NULL },
+ { "addon", rbac::RBAC_PERM_COMMAND_ACCOUNT_ADDON, false, &HandleAccountAddonCommand, "" },
+ { "create", rbac::RBAC_PERM_COMMAND_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_ACCOUNT_DELETE, true, &HandleAccountDeleteCommand, "" },
+ { "email", rbac::RBAC_PERM_COMMAND_ACCOUNT_EMAIL, false, &HandleAccountEmailCommand, "" },
+ { "onlinelist", rbac::RBAC_PERM_COMMAND_ACCOUNT_ONLINE_LIST, true, &HandleAccountOnlineListCommand, "" },
{ "lock", rbac::RBAC_PERM_COMMAND_ACCOUNT_LOCK, false, NULL, "", accountLockCommandTable },
{ "set", rbac::RBAC_PERM_COMMAND_ACCOUNT_SET, true, NULL, "", accountSetCommandTable },
- { "password", rbac::RBAC_PERM_COMMAND_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_ACCOUNT, false, &HandleAccountCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "password", rbac::RBAC_PERM_COMMAND_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_ACCOUNT, false, &HandleAccountCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "account", rbac::RBAC_PERM_COMMAND_ACCOUNT, true, NULL, "", accountCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_achievement.cpp b/src/server/scripts/Commands/cs_achievement.cpp
index 8a038844ec1..ea77bc1f189 100644
--- a/src/server/scripts/Commands/cs_achievement.cpp
+++ b/src/server/scripts/Commands/cs_achievement.cpp
@@ -33,17 +33,15 @@ class achievement_commandscript : public CommandScript
public:
achievement_commandscript() : CommandScript("achievement_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand achievementCommandTable[] =
+ static std::vector<ChatCommand> achievementCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_ACHIEVEMENT_ADD, false, &HandleAchievementAddCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_ACHIEVEMENT_ADD, false, &HandleAchievementAddCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "achievement", rbac::RBAC_PERM_COMMAND_ACHIEVEMENT, false, NULL, "", achievementCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_ahbot.cpp b/src/server/scripts/Commands/cs_ahbot.cpp
index 559a775da31..44889fccd37 100644
--- a/src/server/scripts/Commands/cs_ahbot.cpp
+++ b/src/server/scripts/Commands/cs_ahbot.cpp
@@ -33,44 +33,40 @@ class ahbot_commandscript : public CommandScript
public:
ahbot_commandscript(): CommandScript("ahbot_commandscript") {}
- ChatCommand* GetCommands() const
+ std::vector<ChatCommand> GetCommands() const
{
- static ChatCommand ahbotItemsAmountCommandTable[] =
+ static std::vector<ChatCommand> ahbotItemsAmountCommandTable =
{
- { "gray", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>, "", NULL },
- { "white", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>, "", NULL },
- { "green", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>, "", NULL },
- { "blue", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>, "", NULL },
- { "purple", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>, "", NULL },
- { "orange", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>, "", NULL },
- { "yellow", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, &HandleAHBotItemsAmountCommand, "", NULL },
- { NULL, 0, true, NULL, "", NULL }
+ { "gray", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GRAY, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GRAY>, "" },
+ { "white", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_WHITE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_WHITE>, "" },
+ { "green", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_GREEN, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_GREEN>, "" },
+ { "blue", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_BLUE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_BLUE>, "" },
+ { "purple", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_PURPLE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_PURPLE>, "" },
+ { "orange", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_ORANGE, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_ORANGE>, "" },
+ { "yellow", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS_YELLOW, true, &HandleAHBotItemsAmountQualityCommand<AUCTION_QUALITY_YELLOW>, "" },
+ { "", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, &HandleAHBotItemsAmountCommand, "" },
};
- static ChatCommand ahbotItemsRatioCommandTable[] =
+ static std::vector<ChatCommand> ahbotItemsRatioCommandTable =
{
- { "alliance", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>, "", NULL },
- { "horde", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>, "", NULL },
- { "neutral", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, &HandleAHBotItemsRatioCommand, "", NULL },
- { NULL, 0, true, NULL, "", NULL }
+ { "alliance", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_ALLIANCE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_ALLIANCE>, "" },
+ { "horde", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_HORDE, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_HORDE>, "" },
+ { "neutral", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO_NEUTRAL, true, &HandleAHBotItemsRatioHouseCommand<AUCTION_HOUSE_NEUTRAL>, "" },
+ { "", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, &HandleAHBotItemsRatioCommand, "" },
};
- static ChatCommand ahbotCommandTable[] =
+ static std::vector<ChatCommand> ahbotCommandTable =
{
{ "items", rbac::RBAC_PERM_COMMAND_AHBOT_ITEMS, true, NULL, "", ahbotItemsAmountCommandTable },
{ "ratio", rbac::RBAC_PERM_COMMAND_AHBOT_RATIO, true, NULL, "", ahbotItemsRatioCommandTable },
- { "rebuild", rbac::RBAC_PERM_COMMAND_AHBOT_REBUILD, true, &HandleAHBotRebuildCommand, "", NULL },
- { "reload", rbac::RBAC_PERM_COMMAND_AHBOT_RELOAD, true, &HandleAHBotReloadCommand, "", NULL },
- { "status", rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, true, &HandleAHBotStatusCommand, "", NULL },
- { NULL, 0, true, NULL, "", NULL }
+ { "rebuild", rbac::RBAC_PERM_COMMAND_AHBOT_REBUILD, true, &HandleAHBotRebuildCommand, "" },
+ { "reload", rbac::RBAC_PERM_COMMAND_AHBOT_RELOAD, true, &HandleAHBotReloadCommand, "" },
+ { "status", rbac::RBAC_PERM_COMMAND_AHBOT_STATUS, true, &HandleAHBotStatusCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "ahbot", rbac::RBAC_PERM_COMMAND_AHBOT, false, NULL, "", ahbotCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
diff --git a/src/server/scripts/Commands/cs_arena.cpp b/src/server/scripts/Commands/cs_arena.cpp
index 596aeca95df..4598b3e178b 100644
--- a/src/server/scripts/Commands/cs_arena.cpp
+++ b/src/server/scripts/Commands/cs_arena.cpp
@@ -34,22 +34,20 @@ class arena_commandscript : public CommandScript
public:
arena_commandscript() : CommandScript("arena_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand arenaCommandTable[] =
+ static std::vector<ChatCommand> arenaCommandTable =
{
- { "create", rbac::RBAC_PERM_COMMAND_ARENA_CREATE, true, &HandleArenaCreateCommand, "", NULL },
- { "disband", rbac::RBAC_PERM_COMMAND_ARENA_DISBAND, true, &HandleArenaDisbandCommand, "", NULL },
- { "rename", rbac::RBAC_PERM_COMMAND_ARENA_RENAME, true, &HandleArenaRenameCommand, "", NULL },
- { "captain", rbac::RBAC_PERM_COMMAND_ARENA_CAPTAIN, false, &HandleArenaCaptainCommand, "", NULL },
- { "info", rbac::RBAC_PERM_COMMAND_ARENA_INFO, true, &HandleArenaInfoCommand, "", NULL },
- { "lookup", rbac::RBAC_PERM_COMMAND_ARENA_LOOKUP, false, &HandleArenaLookupCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "create", rbac::RBAC_PERM_COMMAND_ARENA_CREATE, true, &HandleArenaCreateCommand, "" },
+ { "disband", rbac::RBAC_PERM_COMMAND_ARENA_DISBAND, true, &HandleArenaDisbandCommand, "" },
+ { "rename", rbac::RBAC_PERM_COMMAND_ARENA_RENAME, true, &HandleArenaRenameCommand, "" },
+ { "captain", rbac::RBAC_PERM_COMMAND_ARENA_CAPTAIN, false, &HandleArenaCaptainCommand, "" },
+ { "info", rbac::RBAC_PERM_COMMAND_ARENA_INFO, true, &HandleArenaInfoCommand, "" },
+ { "lookup", rbac::RBAC_PERM_COMMAND_ARENA_LOOKUP, false, &HandleArenaLookupCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "arena", rbac::RBAC_PERM_COMMAND_ARENA, false, NULL, "", arenaCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_ban.cpp b/src/server/scripts/Commands/cs_ban.cpp
index 1b0f8fec4a3..1b34e9bfb8d 100644
--- a/src/server/scripts/Commands/cs_ban.cpp
+++ b/src/server/scripts/Commands/cs_ban.cpp
@@ -35,45 +35,40 @@ class ban_commandscript : public CommandScript
public:
ban_commandscript() : CommandScript("ban_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand unbanCommandTable[] =
+ static std::vector<ChatCommand> unbanCommandTable =
{
- { "account", rbac::RBAC_PERM_COMMAND_UNBAN_ACCOUNT, true, &HandleUnBanAccountCommand, "", NULL },
- { "character", rbac::RBAC_PERM_COMMAND_UNBAN_CHARACTER, true, &HandleUnBanCharacterCommand, "", NULL },
- { "playeraccount", rbac::RBAC_PERM_COMMAND_UNBAN_PLAYERACCOUNT, true, &HandleUnBanAccountByCharCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_UNBAN_IP, true, &HandleUnBanIPCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "account", rbac::RBAC_PERM_COMMAND_UNBAN_ACCOUNT, true, &HandleUnBanAccountCommand, "" },
+ { "character", rbac::RBAC_PERM_COMMAND_UNBAN_CHARACTER, true, &HandleUnBanCharacterCommand, "" },
+ { "playeraccount", rbac::RBAC_PERM_COMMAND_UNBAN_PLAYERACCOUNT, true, &HandleUnBanAccountByCharCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_UNBAN_IP, true, &HandleUnBanIPCommand, "" },
};
- static ChatCommand banlistCommandTable[] =
+ static std::vector<ChatCommand> banlistCommandTable =
{
- { "account", rbac::RBAC_PERM_COMMAND_BANLIST_ACCOUNT, true, &HandleBanListAccountCommand, "", NULL },
- { "character", rbac::RBAC_PERM_COMMAND_BANLIST_CHARACTER, true, &HandleBanListCharacterCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_BANLIST_IP, true, &HandleBanListIPCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "account", rbac::RBAC_PERM_COMMAND_BANLIST_ACCOUNT, true, &HandleBanListAccountCommand, "" },
+ { "character", rbac::RBAC_PERM_COMMAND_BANLIST_CHARACTER, true, &HandleBanListCharacterCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_BANLIST_IP, true, &HandleBanListIPCommand, "" },
};
- static ChatCommand baninfoCommandTable[] =
+ static std::vector<ChatCommand> baninfoCommandTable =
{
- { "account", rbac::RBAC_PERM_COMMAND_BANINFO_ACCOUNT, true, &HandleBanInfoAccountCommand, "", NULL },
- { "character", rbac::RBAC_PERM_COMMAND_BANINFO_CHARACTER, true, &HandleBanInfoCharacterCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_BANINFO_IP, true, &HandleBanInfoIPCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "account", rbac::RBAC_PERM_COMMAND_BANINFO_ACCOUNT, true, &HandleBanInfoAccountCommand, "" },
+ { "character", rbac::RBAC_PERM_COMMAND_BANINFO_CHARACTER, true, &HandleBanInfoCharacterCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_BANINFO_IP, true, &HandleBanInfoIPCommand, "" },
};
- static ChatCommand banCommandTable[] =
+ static std::vector<ChatCommand> banCommandTable =
{
- { "account", rbac::RBAC_PERM_COMMAND_BAN_ACCOUNT, true, &HandleBanAccountCommand, "", NULL },
- { "character", rbac::RBAC_PERM_COMMAND_BAN_CHARACTER, true, &HandleBanCharacterCommand, "", NULL },
- { "playeraccount", rbac::RBAC_PERM_COMMAND_BAN_PLAYERACCOUNT, true, &HandleBanAccountByCharCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_BAN_IP, true, &HandleBanIPCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "account", rbac::RBAC_PERM_COMMAND_BAN_ACCOUNT, true, &HandleBanAccountCommand, "" },
+ { "character", rbac::RBAC_PERM_COMMAND_BAN_CHARACTER, true, &HandleBanCharacterCommand, "" },
+ { "playeraccount", rbac::RBAC_PERM_COMMAND_BAN_PLAYERACCOUNT, true, &HandleBanAccountByCharCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_BAN_IP, true, &HandleBanIPCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "ban", rbac::RBAC_PERM_COMMAND_BAN, true, NULL, "", banCommandTable },
{ "baninfo", rbac::RBAC_PERM_COMMAND_BANINFO, true, NULL, "", baninfoCommandTable },
{ "banlist", rbac::RBAC_PERM_COMMAND_BANLIST, true, NULL, "", banlistCommandTable },
{ "unban", rbac::RBAC_PERM_COMMAND_UNBAN, true, NULL, "", unbanCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_battlenet_account.cpp b/src/server/scripts/Commands/cs_battlenet_account.cpp
index 9c6098f70d9..2498ca7bd5d 100644
--- a/src/server/scripts/Commands/cs_battlenet_account.cpp
+++ b/src/server/scripts/Commands/cs_battlenet_account.cpp
@@ -28,37 +28,33 @@ class battlenet_account_commandscript : public CommandScript
public:
battlenet_account_commandscript() : CommandScript("battlenet_account_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand accountSetCommandTable[] =
+ static std::vector<ChatCommand> accountSetCommandTable =
{
- { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET_PASSWORD, true, &HandleAccountSetPasswordCommand, "" },
};
- static ChatCommand accountLockCommandTable[] =
+ static std::vector<ChatCommand> accountLockCommandTable =
{
- { "country", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "", NULL },
- { "ip", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "country", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_COUNTRY, true, &HandleAccountLockCountryCommand, "" },
+ { "ip", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LOCK_IP, true, &HandleAccountLockIpCommand, "" },
};
- static ChatCommand accountCommandTable[] =
+ static std::vector<ChatCommand> accountCommandTable =
{
- { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "", NULL },
- { "gameaccountcreate", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE_GAME, true, &HandleGameAccountCreateCommand, "", NULL },
+ { "create", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE, true, &HandleAccountCreateCommand, "" },
+ { "gameaccountcreate", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_CREATE_GAME, true, &HandleGameAccountCreateCommand, "" },
{ "lock", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, false, NULL, "", accountLockCommandTable },
{ "set", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_SET, true, NULL, "", accountSetCommandTable },
- { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "", NULL },
- { "link", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LINK, true, &HandleAccountLinkCommand, "", NULL },
- { "unlink", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_UNLINK, true, &HandleAccountUnlinkCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "password", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_PASSWORD, false, &HandleAccountPasswordCommand, "" },
+ { "link", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_LINK, true, &HandleAccountLinkCommand, "" },
+ { "unlink", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT_UNLINK, true, &HandleAccountUnlinkCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "bnetaccount", rbac::RBAC_PERM_COMMAND_BNET_ACCOUNT, true, NULL, "", accountCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
diff --git a/src/server/scripts/Commands/cs_bf.cpp b/src/server/scripts/Commands/cs_bf.cpp
index 830e801bcef..7101b89b5fa 100644
--- a/src/server/scripts/Commands/cs_bf.cpp
+++ b/src/server/scripts/Commands/cs_bf.cpp
@@ -31,21 +31,19 @@ class bf_commandscript : public CommandScript
public:
bf_commandscript() : CommandScript("bf_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand battlefieldcommandTable[] =
+ static std::vector<ChatCommand> battlefieldcommandTable =
{
- { "start", rbac::RBAC_PERM_COMMAND_BF_START, false, &HandleBattlefieldStart, "", NULL },
- { "stop", rbac::RBAC_PERM_COMMAND_BF_STOP, false, &HandleBattlefieldEnd, "", NULL },
- { "switch", rbac::RBAC_PERM_COMMAND_BF_SWITCH, false, &HandleBattlefieldSwitch, "", NULL },
- { "timer", rbac::RBAC_PERM_COMMAND_BF_TIMER, false, &HandleBattlefieldTimer, "", NULL },
- { "enable", rbac::RBAC_PERM_COMMAND_BF_ENABLE, false, &HandleBattlefieldEnable, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "start", rbac::RBAC_PERM_COMMAND_BF_START, false, &HandleBattlefieldStart, "" },
+ { "stop", rbac::RBAC_PERM_COMMAND_BF_STOP, false, &HandleBattlefieldEnd, "" },
+ { "switch", rbac::RBAC_PERM_COMMAND_BF_SWITCH, false, &HandleBattlefieldSwitch, "" },
+ { "timer", rbac::RBAC_PERM_COMMAND_BF_TIMER, false, &HandleBattlefieldTimer, "" },
+ { "enable", rbac::RBAC_PERM_COMMAND_BF_ENABLE, false, &HandleBattlefieldEnable, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "bf", rbac::RBAC_PERM_COMMAND_BF, false, NULL, "", battlefieldcommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp
index d5c7470a0ec..5252d5e368a 100644
--- a/src/server/scripts/Commands/cs_cast.cpp
+++ b/src/server/scripts/Commands/cs_cast.cpp
@@ -33,22 +33,20 @@ class cast_commandscript : public CommandScript
public:
cast_commandscript() : CommandScript("cast_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand castCommandTable[] =
+ static std::vector<ChatCommand> castCommandTable =
{
- { "back", rbac::RBAC_PERM_COMMAND_CAST_BACK, false, &HandleCastBackCommand, "", NULL },
- { "dist", rbac::RBAC_PERM_COMMAND_CAST_DIST, false, &HandleCastDistCommand, "", NULL },
- { "self", rbac::RBAC_PERM_COMMAND_CAST_SELF, false, &HandleCastSelfCommand, "", NULL },
- { "target", rbac::RBAC_PERM_COMMAND_CAST_TARGET, false, &HandleCastTargetCommad, "", NULL },
- { "dest", rbac::RBAC_PERM_COMMAND_CAST_DEST, false, &HandleCastDestCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_CAST, false, &HandleCastCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "back", rbac::RBAC_PERM_COMMAND_CAST_BACK, false, &HandleCastBackCommand, "" },
+ { "dist", rbac::RBAC_PERM_COMMAND_CAST_DIST, false, &HandleCastDistCommand, "" },
+ { "self", rbac::RBAC_PERM_COMMAND_CAST_SELF, false, &HandleCastSelfCommand, "" },
+ { "target", rbac::RBAC_PERM_COMMAND_CAST_TARGET, false, &HandleCastTargetCommad, "" },
+ { "dest", rbac::RBAC_PERM_COMMAND_CAST_DEST, false, &HandleCastDestCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_CAST, false, &HandleCastCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "cast", rbac::RBAC_PERM_COMMAND_CAST, false, NULL, "", castCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -122,7 +120,7 @@ public:
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
-
+
if (!CheckSpellExistsAndIsValid(handler, spellId))
return false;
@@ -220,7 +218,7 @@ public:
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
-
+
if (!CheckSpellExistsAndIsValid(handler, spellId))
return false;
@@ -253,7 +251,7 @@ public:
uint32 spellId = handler->extractSpellIdFromLink((char*)args);
if (!spellId)
return false;
-
+
if (!CheckSpellExistsAndIsValid(handler, spellId))
return false;
diff --git a/src/server/scripts/Commands/cs_character.cpp b/src/server/scripts/Commands/cs_character.cpp
index ef39e2feb98..3ab06b0fc11 100644
--- a/src/server/scripts/Commands/cs_character.cpp
+++ b/src/server/scripts/Commands/cs_character.cpp
@@ -35,43 +35,39 @@ class character_commandscript : public CommandScript
public:
character_commandscript() : CommandScript("character_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand pdumpCommandTable[] =
+ static std::vector<ChatCommand> pdumpCommandTable =
{
- { "load", rbac::RBAC_PERM_COMMAND_PDUMP_LOAD, true, &HandlePDumpLoadCommand, "", NULL },
- { "write", rbac::RBAC_PERM_COMMAND_PDUMP_WRITE, true, &HandlePDumpWriteCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "load", rbac::RBAC_PERM_COMMAND_PDUMP_LOAD, true, &HandlePDumpLoadCommand, "" },
+ { "write", rbac::RBAC_PERM_COMMAND_PDUMP_WRITE, true, &HandlePDumpWriteCommand, "" },
};
- static ChatCommand characterDeletedCommandTable[] =
+ static std::vector<ChatCommand> characterDeletedCommandTable =
{
- { "delete", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_DELETE, true, &HandleCharacterDeletedDeleteCommand, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_LIST, true, &HandleCharacterDeletedListCommand, "", NULL },
- { "restore", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_RESTORE, true, &HandleCharacterDeletedRestoreCommand, "", NULL },
- { "old", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_OLD, true, &HandleCharacterDeletedOldCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "delete", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_DELETE, true, &HandleCharacterDeletedDeleteCommand, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_LIST, true, &HandleCharacterDeletedListCommand, "" },
+ { "restore", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_RESTORE, true, &HandleCharacterDeletedRestoreCommand, "" },
+ { "old", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED_OLD, true, &HandleCharacterDeletedOldCommand, "" },
};
- static ChatCommand characterCommandTable[] =
+ static std::vector<ChatCommand> characterCommandTable =
{
- { "customize", rbac::RBAC_PERM_COMMAND_CHARACTER_CUSTOMIZE, true, &HandleCharacterCustomizeCommand, "", NULL },
- { "changefaction", rbac::RBAC_PERM_COMMAND_CHARACTER_CHANGEFACTION, true, &HandleCharacterChangeFactionCommand, "", NULL },
- { "changerace", rbac::RBAC_PERM_COMMAND_CHARACTER_CHANGERACE, true, &HandleCharacterChangeRaceCommand, "", NULL },
+ { "customize", rbac::RBAC_PERM_COMMAND_CHARACTER_CUSTOMIZE, true, &HandleCharacterCustomizeCommand, "", },
+ { "changefaction", rbac::RBAC_PERM_COMMAND_CHARACTER_CHANGEFACTION, true, &HandleCharacterChangeFactionCommand, "", },
+ { "changerace", rbac::RBAC_PERM_COMMAND_CHARACTER_CHANGERACE, true, &HandleCharacterChangeRaceCommand, "", },
{ "deleted", rbac::RBAC_PERM_COMMAND_CHARACTER_DELETED, true, NULL, "", characterDeletedCommandTable },
- { "erase", rbac::RBAC_PERM_COMMAND_CHARACTER_ERASE, true, &HandleCharacterEraseCommand, "", NULL },
- { "level", rbac::RBAC_PERM_COMMAND_CHARACTER_LEVEL, true, &HandleCharacterLevelCommand, "", NULL },
- { "rename", rbac::RBAC_PERM_COMMAND_CHARACTER_RENAME, true, &HandleCharacterRenameCommand, "", NULL },
- { "reputation", rbac::RBAC_PERM_COMMAND_CHARACTER_REPUTATION, true, &HandleCharacterReputationCommand, "", NULL },
- { "titles", rbac::RBAC_PERM_COMMAND_CHARACTER_TITLES, true, &HandleCharacterTitlesCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "erase", rbac::RBAC_PERM_COMMAND_CHARACTER_ERASE, true, &HandleCharacterEraseCommand, "", },
+ { "level", rbac::RBAC_PERM_COMMAND_CHARACTER_LEVEL, true, &HandleCharacterLevelCommand, "", },
+ { "rename", rbac::RBAC_PERM_COMMAND_CHARACTER_RENAME, true, &HandleCharacterRenameCommand, "", },
+ { "reputation", rbac::RBAC_PERM_COMMAND_CHARACTER_REPUTATION, true, &HandleCharacterReputationCommand, "", },
+ { "titles", rbac::RBAC_PERM_COMMAND_CHARACTER_TITLES, true, &HandleCharacterTitlesCommand, "", },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "character", rbac::RBAC_PERM_COMMAND_CHARACTER, true, NULL, "", characterCommandTable },
- { "levelup", rbac::RBAC_PERM_COMMAND_LEVELUP, false, &HandleLevelUpCommand, "", NULL },
+ { "levelup", rbac::RBAC_PERM_COMMAND_LEVELUP, false, &HandleLevelUpCommand, "" },
{ "pdump", rbac::RBAC_PERM_COMMAND_PDUMP, true, NULL, "", pdumpCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_cheat.cpp b/src/server/scripts/Commands/cs_cheat.cpp
index 07fae339996..6262d380075 100644
--- a/src/server/scripts/Commands/cs_cheat.cpp
+++ b/src/server/scripts/Commands/cs_cheat.cpp
@@ -24,7 +24,6 @@ EndScriptData */
#include "Chat.h"
#include "Language.h"
-#include "ObjectMgr.h"
#include "Player.h"
#include "ScriptMgr.h"
@@ -33,27 +32,24 @@ class cheat_commandscript : public CommandScript
public:
cheat_commandscript() : CommandScript("cheat_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
-
- static ChatCommand cheatCommandTable[] =
+ static std::vector<ChatCommand> cheatCommandTable =
{
- { "god", rbac::RBAC_PERM_COMMAND_CHEAT_GOD, false, &HandleGodModeCheatCommand, "", NULL },
- { "casttime", rbac::RBAC_PERM_COMMAND_CHEAT_CASTTIME, false, &HandleCasttimeCheatCommand, "", NULL },
- { "cooldown", rbac::RBAC_PERM_COMMAND_CHEAT_COOLDOWN, false, &HandleCoolDownCheatCommand, "", NULL },
- { "power", rbac::RBAC_PERM_COMMAND_CHEAT_POWER, false, &HandlePowerCheatCommand, "", NULL },
- { "waterwalk", rbac::RBAC_PERM_COMMAND_CHEAT_WATERWALK, false, &HandleWaterWalkCheatCommand, "", NULL },
- { "status", rbac::RBAC_PERM_COMMAND_CHEAT_STATUS, false, &HandleCheatStatusCommand, "", NULL },
- { "taxi", rbac::RBAC_PERM_COMMAND_CHEAT_TAXI, false, &HandleTaxiCheatCommand, "", NULL },
- { "explore", rbac::RBAC_PERM_COMMAND_CHEAT_EXPLORE, false, &HandleExploreCheatCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "god", rbac::RBAC_PERM_COMMAND_CHEAT_GOD, false, &HandleGodModeCheatCommand, "" },
+ { "casttime", rbac::RBAC_PERM_COMMAND_CHEAT_CASTTIME, false, &HandleCasttimeCheatCommand, "" },
+ { "cooldown", rbac::RBAC_PERM_COMMAND_CHEAT_COOLDOWN, false, &HandleCoolDownCheatCommand, "" },
+ { "power", rbac::RBAC_PERM_COMMAND_CHEAT_POWER, false, &HandlePowerCheatCommand, "" },
+ { "waterwalk", rbac::RBAC_PERM_COMMAND_CHEAT_WATERWALK, false, &HandleWaterWalkCheatCommand, "" },
+ { "status", rbac::RBAC_PERM_COMMAND_CHEAT_STATUS, false, &HandleCheatStatusCommand, "" },
+ { "taxi", rbac::RBAC_PERM_COMMAND_CHEAT_TAXI, false, &HandleTaxiCheatCommand, "" },
+ { "explore", rbac::RBAC_PERM_COMMAND_CHEAT_EXPLORE, false, &HandleExploreCheatCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "cheat", rbac::RBAC_PERM_COMMAND_CHEAT, false, NULL, "", cheatCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -166,8 +162,8 @@ public:
{
Player* player = handler->GetSession()->GetPlayer();
- const char* enabled = "enabled";
- const char* disabled = "disabled";
+ const char* enabled = "ON";
+ const char* disabled = "OFF";
handler->SendSysMessage(LANG_COMMAND_CHEAT_STATUS);
handler->PSendSysMessage(LANG_COMMAND_CHEAT_GOD, player->GetCommandStatus(CHEAT_GOD) ? enabled : disabled);
@@ -175,6 +171,7 @@ public:
handler->PSendSysMessage(LANG_COMMAND_CHEAT_CT, player->GetCommandStatus(CHEAT_CASTTIME) ? enabled : disabled);
handler->PSendSysMessage(LANG_COMMAND_CHEAT_POWER, player->GetCommandStatus(CHEAT_POWER) ? enabled : disabled);
handler->PSendSysMessage(LANG_COMMAND_CHEAT_WW, player->GetCommandStatus(CHEAT_WATERWALK) ? enabled : disabled);
+ handler->PSendSysMessage(LANG_COMMAND_CHEAT_TAXINODES, player->isTaxiCheater() ? enabled : disabled);
return true;
}
@@ -187,13 +184,7 @@ public:
Player* target = handler->GetSession()->GetPlayer();
if (!*args)
- {
argstr = (target->GetCommandStatus(CHEAT_WATERWALK)) ? "off" : "on";
- if (target->GetCommandStatus(CHEAT_WATERWALK))
- argstr = "off";
- else
- argstr = "on";
- }
if (argstr == "off")
{
@@ -215,15 +206,8 @@ public:
static bool HandleTaxiCheatCommand(ChatHandler* handler, const char* args)
{
- if (!*args)
- {
- handler->SendSysMessage(LANG_USE_BOL);
- handler->SetSentErrorMessage(true);
- return false;
- }
std::string argstr = (char*)args;
-
Player* chr = handler->getSelectedPlayer();
if (!chr)
@@ -231,24 +215,28 @@ public:
else if (handler->HasLowerSecurity(chr, ObjectGuid::Empty)) // check online security
return false;
- if (argstr == "on")
- {
- chr->SetTaxiCheater(true);
- handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str());
- if (handler->needReportToTarget(chr))
- ChatHandler(chr->GetSession()).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str());
- return true;
- }
+ if (!*args)
+ argstr = (chr->isTaxiCheater()) ? "off" : "on";
+
if (argstr == "off")
+
{
chr->SetTaxiCheater(false);
handler->PSendSysMessage(LANG_YOU_REMOVE_TAXIS, handler->GetNameLink(chr).c_str());
if (handler->needReportToTarget(chr))
ChatHandler(chr->GetSession()).PSendSysMessage(LANG_YOURS_TAXIS_REMOVED, handler->GetNameLink().c_str());
-
return true;
}
+ else if (argstr == "on")
+ {
+ chr->SetTaxiCheater(true);
+ handler->PSendSysMessage(LANG_YOU_GIVE_TAXIS, handler->GetNameLink(chr).c_str());
+ if (handler->needReportToTarget(chr))
+ ChatHandler(chr->GetSession()).PSendSysMessage(LANG_YOURS_TAXIS_ADDED, handler->GetNameLink().c_str());
+ return true;
+ }
+
handler->SendSysMessage(LANG_USE_BOL);
handler->SetSentErrorMessage(true);
@@ -260,10 +248,11 @@ public:
if (!*args)
return false;
+ // std::int flag = (char*)args;
int flag = atoi((char*)args);
Player* chr = handler->getSelectedPlayer();
- if (chr == NULL)
+ if (!chr)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index bade0600b9b..07c9af94bf4 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -33,6 +33,7 @@ EndScriptData */
#include "GossipDef.h"
#include "Transport.h"
#include "Language.h"
+#include "MapManager.h"
#include "MovementPackets.h"
#include "SpellPackets.h"
#include "ScenePackets.h"
@@ -44,67 +45,64 @@ class debug_commandscript : public CommandScript
public:
debug_commandscript() : CommandScript("debug_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand debugPlayCommandTable[] =
+ static std::vector<ChatCommand> debugPlayCommandTable =
{
- { "cinematic", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_CINEMATIC, false, &HandleDebugPlayCinematicCommand, "", NULL },
- { "movie", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_MOVIE, false, &HandleDebugPlayMovieCommand, "", NULL },
- { "sound", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_SOUND, false, &HandleDebugPlaySoundCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "cinematic", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_CINEMATIC, false, &HandleDebugPlayCinematicCommand, "" },
+ { "movie", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_MOVIE, false, &HandleDebugPlayMovieCommand, "" },
+ { "sound", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY_SOUND, false, &HandleDebugPlaySoundCommand, "" },
};
- static ChatCommand debugSendCommandTable[] =
+ static std::vector<ChatCommand> debugSendCommandTable =
{
- { "buyerror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_BUYERROR, false, &HandleDebugSendBuyErrorCommand, "", NULL },
- { "channelnotify", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_CHANNELNOTIFY, false, &HandleDebugSendChannelNotifyCommand, "", NULL },
- { "chatmessage", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_CHATMESSAGE, false, &HandleDebugSendChatMsgCommand, "", NULL },
- { "equiperror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_EQUIPERROR, false, &HandleDebugSendEquipErrorCommand, "", NULL },
- { "largepacket", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_LARGEPACKET, false, &HandleDebugSendLargePacketCommand, "", NULL },
- { "opcode", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_OPCODE, false, &HandleDebugSendOpcodeCommand, "", NULL },
- { "qpartymsg", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_QPARTYMSG, false, &HandleDebugSendQuestPartyMsgCommand, "", NULL },
- { "qinvalidmsg", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_QINVALIDMSG, false, &HandleDebugSendQuestInvalidMsgCommand, "", NULL },
- { "sellerror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SELLERROR, false, &HandleDebugSendSellErrorCommand, "", NULL },
- { "setphaseshift", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SETPHASESHIFT, false, &HandleDebugSendSetPhaseShiftCommand, "", NULL },
- { "spellfail", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SPELLFAIL, false, &HandleDebugSendSpellFailCommand, "", NULL },
- { "playscene", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_PLAYSCENE, false, &HandleDebugSendPlaySceneCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "buyerror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_BUYERROR, false, &HandleDebugSendBuyErrorCommand, "" },
+ { "channelnotify", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_CHANNELNOTIFY, false, &HandleDebugSendChannelNotifyCommand, "" },
+ { "chatmessage", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_CHATMESSAGE, false, &HandleDebugSendChatMsgCommand, "" },
+ { "equiperror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_EQUIPERROR, false, &HandleDebugSendEquipErrorCommand, "" },
+ { "largepacket", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_LARGEPACKET, false, &HandleDebugSendLargePacketCommand, "" },
+ { "opcode", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_OPCODE, false, &HandleDebugSendOpcodeCommand, "" },
+ { "qpartymsg", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_QPARTYMSG, false, &HandleDebugSendQuestPartyMsgCommand, "" },
+ { "qinvalidmsg", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_QINVALIDMSG, false, &HandleDebugSendQuestInvalidMsgCommand, "" },
+ { "sellerror", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SELLERROR, false, &HandleDebugSendSellErrorCommand, "" },
+ { "setphaseshift", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SETPHASESHIFT, false, &HandleDebugSendSetPhaseShiftCommand, "" },
+ { "spellfail", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_SPELLFAIL, false, &HandleDebugSendSpellFailCommand, "" },
+ { "playscene", rbac::RBAC_PERM_COMMAND_DEBUG_SEND_PLAYSCENE, false, &HandleDebugSendPlaySceneCommand, "" },
};
- static ChatCommand debugCommandTable[] =
+ static std::vector<ChatCommand> debugCommandTable =
{
- { "setbit", rbac::RBAC_PERM_COMMAND_DEBUG_SETBIT, false, &HandleDebugSet32BitCommand, "", NULL },
- { "threat", rbac::RBAC_PERM_COMMAND_DEBUG_THREAT, false, &HandleDebugThreatListCommand, "", NULL },
- { "hostil", rbac::RBAC_PERM_COMMAND_DEBUG_HOSTIL, false, &HandleDebugHostileRefListCommand, "", NULL },
- { "anim", rbac::RBAC_PERM_COMMAND_DEBUG_ANIM, false, &HandleDebugAnimCommand, "", NULL },
- { "arena", rbac::RBAC_PERM_COMMAND_DEBUG_ARENA, false, &HandleDebugArenaCommand, "", NULL },
- { "bg", rbac::RBAC_PERM_COMMAND_DEBUG_BG, false, &HandleDebugBattlegroundCommand, "", NULL },
- { "getitemstate", rbac::RBAC_PERM_COMMAND_DEBUG_GETITEMSTATE, false, &HandleDebugGetItemStateCommand, "", NULL },
- { "lootrecipient", rbac::RBAC_PERM_COMMAND_DEBUG_LOOTRECIPIENT, false, &HandleDebugGetLootRecipientCommand, "", NULL },
- { "getvalue", rbac::RBAC_PERM_COMMAND_DEBUG_GETVALUE, false, &HandleDebugGetValueCommand, "", NULL },
- { "getitemvalue", rbac::RBAC_PERM_COMMAND_DEBUG_GETITEMVALUE, false, &HandleDebugGetItemValueCommand, "", NULL },
- { "Mod32Value", rbac::RBAC_PERM_COMMAND_DEBUG_MOD32VALUE, false, &HandleDebugMod32ValueCommand, "", NULL },
+ { "setbit", rbac::RBAC_PERM_COMMAND_DEBUG_SETBIT, false, &HandleDebugSet32BitCommand, "" },
+ { "threat", rbac::RBAC_PERM_COMMAND_DEBUG_THREAT, false, &HandleDebugThreatListCommand, "" },
+ { "hostil", rbac::RBAC_PERM_COMMAND_DEBUG_HOSTIL, false, &HandleDebugHostileRefListCommand, "" },
+ { "anim", rbac::RBAC_PERM_COMMAND_DEBUG_ANIM, false, &HandleDebugAnimCommand, "" },
+ { "arena", rbac::RBAC_PERM_COMMAND_DEBUG_ARENA, false, &HandleDebugArenaCommand, "" },
+ { "bg", rbac::RBAC_PERM_COMMAND_DEBUG_BG, false, &HandleDebugBattlegroundCommand, "" },
+ { "getitemstate", rbac::RBAC_PERM_COMMAND_DEBUG_GETITEMSTATE, false, &HandleDebugGetItemStateCommand, "" },
+ { "lootrecipient", rbac::RBAC_PERM_COMMAND_DEBUG_LOOTRECIPIENT, false, &HandleDebugGetLootRecipientCommand, "" },
+ { "getvalue", rbac::RBAC_PERM_COMMAND_DEBUG_GETVALUE, false, &HandleDebugGetValueCommand, "" },
+ { "getitemvalue", rbac::RBAC_PERM_COMMAND_DEBUG_GETITEMVALUE, false, &HandleDebugGetItemValueCommand, "" },
+ { "Mod32Value", rbac::RBAC_PERM_COMMAND_DEBUG_MOD32VALUE, false, &HandleDebugMod32ValueCommand, "" },
{ "play", rbac::RBAC_PERM_COMMAND_DEBUG_PLAY, false, NULL, "", debugPlayCommandTable },
{ "send", rbac::RBAC_PERM_COMMAND_DEBUG_SEND, false, NULL, "", debugSendCommandTable },
- { "setaurastate", rbac::RBAC_PERM_COMMAND_DEBUG_SETAURASTATE, false, &HandleDebugSetAuraStateCommand, "", NULL },
- { "setitemvalue", rbac::RBAC_PERM_COMMAND_DEBUG_SETITEMVALUE, false, &HandleDebugSetItemValueCommand, "", NULL },
- { "setvalue", rbac::RBAC_PERM_COMMAND_DEBUG_SETVALUE, false, &HandleDebugSetValueCommand, "", NULL },
- { "spawnvehicle", rbac::RBAC_PERM_COMMAND_DEBUG_SPAWNVEHICLE, false, &HandleDebugSpawnVehicleCommand, "", NULL },
- { "setvid", rbac::RBAC_PERM_COMMAND_DEBUG_SETVID, false, &HandleDebugSetVehicleIdCommand, "", NULL },
- { "entervehicle", rbac::RBAC_PERM_COMMAND_DEBUG_ENTERVEHICLE, false, &HandleDebugEnterVehicleCommand, "", NULL },
- { "uws", rbac::RBAC_PERM_COMMAND_DEBUG_UWS, false, &HandleDebugUpdateWorldStateCommand, "", NULL },
- { "update", rbac::RBAC_PERM_COMMAND_DEBUG_UPDATE, false, &HandleDebugUpdateCommand, "", NULL },
- { "itemexpire", rbac::RBAC_PERM_COMMAND_DEBUG_ITEMEXPIRE, false, &HandleDebugItemExpireCommand, "", NULL },
- { "areatriggers", rbac::RBAC_PERM_COMMAND_DEBUG_AREATRIGGERS, false, &HandleDebugAreaTriggersCommand, "", NULL },
- { "los", rbac::RBAC_PERM_COMMAND_DEBUG_LOS, false, &HandleDebugLoSCommand, "", NULL },
- { "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "", NULL },
- { "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "", NULL },
- { "phase", rbac::RBAC_PERM_COMMAND_DEBUG_PHASE, false, &HandleDebugPhaseCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "setaurastate", rbac::RBAC_PERM_COMMAND_DEBUG_SETAURASTATE, false, &HandleDebugSetAuraStateCommand, "" },
+ { "setitemvalue", rbac::RBAC_PERM_COMMAND_DEBUG_SETITEMVALUE, false, &HandleDebugSetItemValueCommand, "" },
+ { "setvalue", rbac::RBAC_PERM_COMMAND_DEBUG_SETVALUE, false, &HandleDebugSetValueCommand, "" },
+ { "spawnvehicle", rbac::RBAC_PERM_COMMAND_DEBUG_SPAWNVEHICLE, false, &HandleDebugSpawnVehicleCommand, "" },
+ { "setvid", rbac::RBAC_PERM_COMMAND_DEBUG_SETVID, false, &HandleDebugSetVehicleIdCommand, "" },
+ { "entervehicle", rbac::RBAC_PERM_COMMAND_DEBUG_ENTERVEHICLE, false, &HandleDebugEnterVehicleCommand, "" },
+ { "uws", rbac::RBAC_PERM_COMMAND_DEBUG_UWS, false, &HandleDebugUpdateWorldStateCommand, "" },
+ { "update", rbac::RBAC_PERM_COMMAND_DEBUG_UPDATE, false, &HandleDebugUpdateCommand, "" },
+ { "itemexpire", rbac::RBAC_PERM_COMMAND_DEBUG_ITEMEXPIRE, false, &HandleDebugItemExpireCommand, "" },
+ { "areatriggers", rbac::RBAC_PERM_COMMAND_DEBUG_AREATRIGGERS, false, &HandleDebugAreaTriggersCommand, "" },
+ { "los", rbac::RBAC_PERM_COMMAND_DEBUG_LOS, false, &HandleDebugLoSCommand, "" },
+ { "moveflags", rbac::RBAC_PERM_COMMAND_DEBUG_MOVEFLAGS, false, &HandleDebugMoveflagsCommand, "" },
+ { "transport", rbac::RBAC_PERM_COMMAND_DEBUG_TRANSPORT, false, &HandleDebugTransportCommand, "" },
+ { "loadcells", rbac::RBAC_PERM_COMMAND_DEBUG_LOADCELLS, false, &HandleDebugLoadCellsCommand, "",},
+ { "phase", rbac::RBAC_PERM_COMMAND_DEBUG_PHASE, false, &HandleDebugPhaseCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "debug", rbac::RBAC_PERM_COMMAND_DEBUG, true, NULL, "", debugCommandTable },
- { "wpgps", rbac::RBAC_PERM_COMMAND_WPGPS, false, &HandleWPGPSCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "wpgps", rbac::RBAC_PERM_COMMAND_WPGPS, false, &HandleWPGPSCommand, "" },
};
return commandTable;
}
@@ -1397,6 +1395,30 @@ public:
return true;
}
+ static bool HandleDebugLoadCellsCommand(ChatHandler* handler, char const* args)
+ {
+ Player* player = handler->GetSession()->GetPlayer();
+ if (!player)
+ return false;
+
+ Map* map = nullptr;
+
+ if (*args)
+ {
+ int32 mapId = atoi(args);
+ map = sMapMgr->FindBaseNonInstanceMap(mapId);
+ }
+ if (!map)
+ map = player->GetMap();
+
+ for (uint32 cellX = 0; cellX < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellX++)
+ for (uint32 cellY = 0; cellY < TOTAL_NUMBER_OF_CELLS_PER_MAP; cellY++)
+ map->LoadGrid((cellX + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL, (cellY + 0.5f - CENTER_GRID_CELL_ID) * SIZE_OF_GRID_CELL);
+
+ handler->PSendSysMessage("Cells loaded (mapId: %u)", map->GetId());
+ return true;
+ }
+
static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* /*args*/)
{
Unit* target = handler->getSelectedUnit();
diff --git a/src/server/scripts/Commands/cs_deserter.cpp b/src/server/scripts/Commands/cs_deserter.cpp
index 2887ac8c134..9f461207707 100644
--- a/src/server/scripts/Commands/cs_deserter.cpp
+++ b/src/server/scripts/Commands/cs_deserter.cpp
@@ -43,31 +43,27 @@ public:
* @brief Returns the command structure for the system.
*/
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand deserterInstanceCommandTable[] =
+ static std::vector<ChatCommand> deserterInstanceCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_DESERTER_INSTANCE_ADD, false, &HandleDeserterInstanceAdd, "", NULL },
- { "remove", rbac::RBAC_PERM_COMMAND_DESERTER_INSTANCE_REMOVE, false, &HandleDeserterInstanceRemove, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_DESERTER_INSTANCE_ADD, false, &HandleDeserterInstanceAdd, "" },
+ { "remove", rbac::RBAC_PERM_COMMAND_DESERTER_INSTANCE_REMOVE, false, &HandleDeserterInstanceRemove, "" },
};
- static ChatCommand deserterBGCommandTable[] =
+ static std::vector<ChatCommand> deserterBGCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_DESERTER_BG_ADD, false, &HandleDeserterBGAdd, "", NULL },
- { "remove", rbac::RBAC_PERM_COMMAND_DESERTER_BG_REMOVE, false, &HandleDeserterBGRemove, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_DESERTER_BG_ADD, false, &HandleDeserterBGAdd, "" },
+ { "remove", rbac::RBAC_PERM_COMMAND_DESERTER_BG_REMOVE, false, &HandleDeserterBGRemove, "" },
};
- static ChatCommand deserterCommandTable[] =
+ static std::vector<ChatCommand> deserterCommandTable =
{
{ "instance", rbac::RBAC_PERM_COMMAND_DESERTER_INSTANCE, false, NULL, "", deserterInstanceCommandTable },
{ "bg", rbac::RBAC_PERM_COMMAND_DESERTER_BG, false, NULL, "", deserterBGCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "deserter", rbac::RBAC_PERM_COMMAND_DESERTER, false, NULL, "", deserterCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_disable.cpp b/src/server/scripts/Commands/cs_disable.cpp
index 14f76945a80..8c73f3f41de 100644
--- a/src/server/scripts/Commands/cs_disable.cpp
+++ b/src/server/scripts/Commands/cs_disable.cpp
@@ -37,42 +37,38 @@ class disable_commandscript : public CommandScript
public:
disable_commandscript() : CommandScript("disable_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand removeDisableCommandTable[] =
+ static std::vector<ChatCommand> removeDisableCommandTable =
{
- { "spell", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_SPELL, true, &HandleRemoveDisableSpellCommand, "", NULL },
- { "quest", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_QUEST, true, &HandleRemoveDisableQuestCommand, "", NULL },
- { "map", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_MAP, true, &HandleRemoveDisableMapCommand, "", NULL },
- { "battleground", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_BATTLEGROUND, true, &HandleRemoveDisableBattlegroundCommand, "", NULL },
- { "achievement_criteria", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_ACHIEVEMENT_CRITERIA, true, &HandleRemoveDisableAchievementCriteriaCommand, "", NULL },
- { "outdoorpvp", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_OUTDOORPVP, true, &HandleRemoveDisableOutdoorPvPCommand, "", NULL },
- { "vmap", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_VMAP, true, &HandleRemoveDisableVmapCommand, "", NULL },
- { "mmap", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_MMAP, true, &HandleRemoveDisableMMapCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "spell", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_SPELL, true, &HandleRemoveDisableSpellCommand, "" },
+ { "quest", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_QUEST, true, &HandleRemoveDisableQuestCommand, "" },
+ { "map", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_MAP, true, &HandleRemoveDisableMapCommand, "" },
+ { "battleground", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_BATTLEGROUND, true, &HandleRemoveDisableBattlegroundCommand, "" },
+ { "achievement_criteria", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_ACHIEVEMENT_CRITERIA, true, &HandleRemoveDisableAchievementCriteriaCommand, "" },
+ { "outdoorpvp", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_OUTDOORPVP, true, &HandleRemoveDisableOutdoorPvPCommand, "" },
+ { "vmap", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_VMAP, true, &HandleRemoveDisableVmapCommand, "" },
+ { "mmap", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE_MMAP, true, &HandleRemoveDisableMMapCommand, "" },
};
- static ChatCommand addDisableCommandTable[] =
+ static std::vector<ChatCommand> addDisableCommandTable =
{
- { "spell", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_SPELL, true, &HandleAddDisableSpellCommand, "", NULL },
- { "quest", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_QUEST, true, &HandleAddDisableQuestCommand, "", NULL },
- { "map", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_MAP, true, &HandleAddDisableMapCommand, "", NULL },
- { "battleground", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_BATTLEGROUND, true, &HandleAddDisableBattlegroundCommand, "", NULL },
- { "achievement_criteria", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_ACHIEVEMENT_CRITERIA, true, &HandleAddDisableAchievementCriteriaCommand, "", NULL },
- { "outdoorpvp", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_OUTDOORPVP, true, &HandleAddDisableOutdoorPvPCommand, "", NULL },
- { "vmap", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_VMAP, true, &HandleAddDisableVmapCommand, "", NULL },
- { "mmap", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_MMAP, true, &HandleAddDisableMMapCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "spell", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_SPELL, true, &HandleAddDisableSpellCommand, "" },
+ { "quest", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_QUEST, true, &HandleAddDisableQuestCommand, "" },
+ { "map", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_MAP, true, &HandleAddDisableMapCommand, "" },
+ { "battleground", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_BATTLEGROUND, true, &HandleAddDisableBattlegroundCommand, "" },
+ { "achievement_criteria", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_ACHIEVEMENT_CRITERIA, true, &HandleAddDisableAchievementCriteriaCommand, "" },
+ { "outdoorpvp", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_OUTDOORPVP, true, &HandleAddDisableOutdoorPvPCommand, "" },
+ { "vmap", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_VMAP, true, &HandleAddDisableVmapCommand, "" },
+ { "mmap", rbac::RBAC_PERM_COMMAND_DISABLE_ADD_MMAP, true, &HandleAddDisableMMapCommand, "" },
};
- static ChatCommand disableCommandTable[] =
+ static std::vector<ChatCommand> disableCommandTable =
{
{ "add", rbac::RBAC_PERM_COMMAND_DISABLE_ADD, true, NULL, "", addDisableCommandTable },
{ "remove", rbac::RBAC_PERM_COMMAND_DISABLE_REMOVE, true, NULL, "", removeDisableCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "disable", rbac::RBAC_PERM_COMMAND_DISABLE, false, NULL, "", disableCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_event.cpp b/src/server/scripts/Commands/cs_event.cpp
index 37495289149..352bce4e7f0 100644
--- a/src/server/scripts/Commands/cs_event.cpp
+++ b/src/server/scripts/Commands/cs_event.cpp
@@ -33,20 +33,18 @@ class event_commandscript : public CommandScript
public:
event_commandscript() : CommandScript("event_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand eventCommandTable[] =
+ static std::vector<ChatCommand> eventCommandTable =
{
- { "activelist", rbac::RBAC_PERM_COMMAND_EVENT_ACTIVELIST, true, &HandleEventActiveListCommand, "", NULL },
- { "start", rbac::RBAC_PERM_COMMAND_EVENT_START, true, &HandleEventStartCommand, "", NULL },
- { "stop", rbac::RBAC_PERM_COMMAND_EVENT_STOP, true, &HandleEventStopCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_EVENT, true, &HandleEventInfoCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "activelist", rbac::RBAC_PERM_COMMAND_EVENT_ACTIVELIST, true, &HandleEventActiveListCommand, "" },
+ { "start", rbac::RBAC_PERM_COMMAND_EVENT_START, true, &HandleEventStartCommand, "" },
+ { "stop", rbac::RBAC_PERM_COMMAND_EVENT_STOP, true, &HandleEventStopCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_EVENT, true, &HandleEventInfoCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "event", rbac::RBAC_PERM_COMMAND_EVENT, false, NULL, "", eventCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_gm.cpp b/src/server/scripts/Commands/cs_gm.cpp
index 14be108f878..8b3c8c92e81 100644
--- a/src/server/scripts/Commands/cs_gm.cpp
+++ b/src/server/scripts/Commands/cs_gm.cpp
@@ -36,22 +36,20 @@ class gm_commandscript : public CommandScript
public:
gm_commandscript() : CommandScript("gm_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand gmCommandTable[] =
+ static std::vector<ChatCommand> gmCommandTable =
{
- { "chat", rbac::RBAC_PERM_COMMAND_GM_CHAT, false, &HandleGMChatCommand, "", NULL },
- { "fly", rbac::RBAC_PERM_COMMAND_GM_FLY, false, &HandleGMFlyCommand, "", NULL },
- { "ingame", rbac::RBAC_PERM_COMMAND_GM_INGAME, true, &HandleGMListIngameCommand, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_GM_LIST, true, &HandleGMListFullCommand, "", NULL },
- { "visible", rbac::RBAC_PERM_COMMAND_GM_VISIBLE, false, &HandleGMVisibleCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_GM, false, &HandleGMCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "chat", rbac::RBAC_PERM_COMMAND_GM_CHAT, false, &HandleGMChatCommand, "" },
+ { "fly", rbac::RBAC_PERM_COMMAND_GM_FLY, false, &HandleGMFlyCommand, "" },
+ { "ingame", rbac::RBAC_PERM_COMMAND_GM_INGAME, true, &HandleGMListIngameCommand, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_GM_LIST, true, &HandleGMListFullCommand, "" },
+ { "visible", rbac::RBAC_PERM_COMMAND_GM_VISIBLE, false, &HandleGMVisibleCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_GM, false, &HandleGMCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "gm", rbac::RBAC_PERM_COMMAND_GM, false, NULL, "", gmCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp
index 19b714f6e61..ea93185ddce 100644
--- a/src/server/scripts/Commands/cs_go.cpp
+++ b/src/server/scripts/Commands/cs_go.cpp
@@ -36,30 +36,28 @@ class go_commandscript : public CommandScript
public:
go_commandscript() : CommandScript("go_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand goCommandTable[] =
- {
- { "creature", rbac::RBAC_PERM_COMMAND_GO_CREATURE, false, &HandleGoCreatureCommand, "", NULL },
- { "graveyard", rbac::RBAC_PERM_COMMAND_GO_GRAVEYARD, false, &HandleGoGraveyardCommand, "", NULL },
- { "grid", rbac::RBAC_PERM_COMMAND_GO_GRID, false, &HandleGoGridCommand, "", NULL },
- { "object", rbac::RBAC_PERM_COMMAND_GO_OBJECT, false, &HandleGoObjectCommand, "", NULL },
- { "quest", rbac::RBAC_PERM_COMMAND_GO_QUEST, false, &HandleGoQuestCommand, "", NULL },
- { "taxinode", rbac::RBAC_PERM_COMMAND_GO_TAXINODE, false, &HandleGoTaxinodeCommand, "", NULL },
- { "trigger", rbac::RBAC_PERM_COMMAND_GO_TRIGGER, false, &HandleGoTriggerCommand, "", NULL },
- { "zonexy", rbac::RBAC_PERM_COMMAND_GO_ZONEXY, false, &HandleGoZoneXYCommand, "", NULL },
- { "xyz", rbac::RBAC_PERM_COMMAND_GO_XYZ, false, &HandleGoXYZCommand, "", NULL },
- { "bugticket", rbac::RBAC_PERM_COMMAND_GO_BUG_TICKET, false, &HandleGoTicketCommand<BugTicket>, "", NULL },
- { "complaintticket", rbac::RBAC_PERM_COMMAND_GO_COMPLAINT_TICKET, false, &HandleGoTicketCommand<ComplaintTicket>, "", NULL },
- { "suggestionticket", rbac::RBAC_PERM_COMMAND_GO_SUGGESTION_TICKET, false, &HandleGoTicketCommand<SuggestionTicket>, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_GO, false, &HandleGoXYZCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ static std::vector<ChatCommand> goCommandTable =
+ {
+ { "creature", rbac::RBAC_PERM_COMMAND_GO_CREATURE, false, &HandleGoCreatureCommand, "" },
+ { "graveyard", rbac::RBAC_PERM_COMMAND_GO_GRAVEYARD, false, &HandleGoGraveyardCommand, "" },
+ { "grid", rbac::RBAC_PERM_COMMAND_GO_GRID, false, &HandleGoGridCommand, "" },
+ { "object", rbac::RBAC_PERM_COMMAND_GO_OBJECT, false, &HandleGoObjectCommand, "" },
+ { "quest", rbac::RBAC_PERM_COMMAND_GO_QUEST, false, &HandleGoQuestCommand, "" },
+ { "taxinode", rbac::RBAC_PERM_COMMAND_GO_TAXINODE, false, &HandleGoTaxinodeCommand, "" },
+ { "trigger", rbac::RBAC_PERM_COMMAND_GO_TRIGGER, false, &HandleGoTriggerCommand, "" },
+ { "zonexy", rbac::RBAC_PERM_COMMAND_GO_ZONEXY, false, &HandleGoZoneXYCommand, "" },
+ { "xyz", rbac::RBAC_PERM_COMMAND_GO_XYZ, false, &HandleGoXYZCommand, "" },
+ { "bugticket", rbac::RBAC_PERM_COMMAND_GO_BUG_TICKET, false, &HandleGoTicketCommand<BugTicket>, "" },
+ { "complaintticket", rbac::RBAC_PERM_COMMAND_GO_COMPLAINT_TICKET, false, &HandleGoTicketCommand<ComplaintTicket>, "" },
+ { "suggestionticket", rbac::RBAC_PERM_COMMAND_GO_SUGGESTION_TICKET, false, &HandleGoTicketCommand<SuggestionTicket>, "" },
+ { "", rbac::RBAC_PERM_COMMAND_GO, false, &HandleGoXYZCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "go", rbac::RBAC_PERM_COMMAND_GO, false, NULL, "", goCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp
index ad877bdefb4..62f81a40104 100644
--- a/src/server/scripts/Commands/cs_gobject.cpp
+++ b/src/server/scripts/Commands/cs_gobject.cpp
@@ -37,37 +37,33 @@ class gobject_commandscript : public CommandScript
public:
gobject_commandscript() : CommandScript("gobject_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand gobjectAddCommandTable[] =
+ static std::vector<ChatCommand> gobjectAddCommandTable =
{
- { "temp", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD_TEMP, false, &HandleGameObjectAddTempCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD, false, &HandleGameObjectAddCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "temp", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD_TEMP, false, &HandleGameObjectAddTempCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD, false, &HandleGameObjectAddCommand, "" },
};
- static ChatCommand gobjectSetCommandTable[] =
+ static std::vector<ChatCommand> gobjectSetCommandTable =
{
- { "phase", rbac::RBAC_PERM_COMMAND_GOBJECT_SET_PHASE, false, &HandleGameObjectSetPhaseCommand, "", NULL },
- { "state", rbac::RBAC_PERM_COMMAND_GOBJECT_SET_STATE, false, &HandleGameObjectSetStateCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "phase", rbac::RBAC_PERM_COMMAND_GOBJECT_SET_PHASE, false, &HandleGameObjectSetPhaseCommand, "" },
+ { "state", rbac::RBAC_PERM_COMMAND_GOBJECT_SET_STATE, false, &HandleGameObjectSetStateCommand, "" },
};
- static ChatCommand gobjectCommandTable[] =
+ static std::vector<ChatCommand> gobjectCommandTable =
{
- { "activate", rbac::RBAC_PERM_COMMAND_GOBJECT_ACTIVATE, false, &HandleGameObjectActivateCommand, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_GOBJECT_DELETE, false, &HandleGameObjectDeleteCommand, "", NULL },
- { "info", rbac::RBAC_PERM_COMMAND_GOBJECT_INFO, false, &HandleGameObjectInfoCommand, "", NULL },
- { "move", rbac::RBAC_PERM_COMMAND_GOBJECT_MOVE, false, &HandleGameObjectMoveCommand, "", NULL },
- { "near", rbac::RBAC_PERM_COMMAND_GOBJECT_NEAR, false, &HandleGameObjectNearCommand, "", NULL },
- { "target", rbac::RBAC_PERM_COMMAND_GOBJECT_TARGET, false, &HandleGameObjectTargetCommand, "", NULL },
- { "turn", rbac::RBAC_PERM_COMMAND_GOBJECT_TURN, false, &HandleGameObjectTurnCommand, "", NULL },
+ { "activate", rbac::RBAC_PERM_COMMAND_GOBJECT_ACTIVATE, false, &HandleGameObjectActivateCommand, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_GOBJECT_DELETE, false, &HandleGameObjectDeleteCommand, "" },
+ { "info", rbac::RBAC_PERM_COMMAND_GOBJECT_INFO, false, &HandleGameObjectInfoCommand, "" },
+ { "move", rbac::RBAC_PERM_COMMAND_GOBJECT_MOVE, false, &HandleGameObjectMoveCommand, "" },
+ { "near", rbac::RBAC_PERM_COMMAND_GOBJECT_NEAR, false, &HandleGameObjectNearCommand, "" },
+ { "target", rbac::RBAC_PERM_COMMAND_GOBJECT_TARGET, false, &HandleGameObjectTargetCommand, "" },
+ { "turn", rbac::RBAC_PERM_COMMAND_GOBJECT_TURN, false, &HandleGameObjectTurnCommand, "" },
{ "add", rbac::RBAC_PERM_COMMAND_GOBJECT_ADD, false, NULL, "", gobjectAddCommandTable },
{ "set", rbac::RBAC_PERM_COMMAND_GOBJECT_SET, false, NULL, "", gobjectSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "gobject", rbac::RBAC_PERM_COMMAND_GOBJECT, false, NULL, "", gobjectCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp
index 5e5694ba23a..0dbb196bf38 100644
--- a/src/server/scripts/Commands/cs_group.cpp
+++ b/src/server/scripts/Commands/cs_group.cpp
@@ -28,23 +28,21 @@ class group_commandscript : public CommandScript
public:
group_commandscript() : CommandScript("group_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand groupCommandTable[] =
+ static std::vector<ChatCommand> groupCommandTable =
{
- { "leader", rbac::RBAC_PERM_COMMAND_GROUP_LEADER, false, &HandleGroupLeaderCommand, "", NULL },
- { "disband", rbac::RBAC_PERM_COMMAND_GROUP_DISBAND, false, &HandleGroupDisbandCommand, "", NULL },
- { "remove", rbac::RBAC_PERM_COMMAND_GROUP_REMOVE, false, &HandleGroupRemoveCommand, "", NULL },
- { "join", rbac::RBAC_PERM_COMMAND_GROUP_JOIN, false, &HandleGroupJoinCommand, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_GROUP_LIST, false, &HandleGroupListCommand, "", NULL },
- { "summon", rbac::RBAC_PERM_COMMAND_GROUP_SUMMON, false, &HandleGroupSummonCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "leader", rbac::RBAC_PERM_COMMAND_GROUP_LEADER, false, &HandleGroupLeaderCommand, "" },
+ { "disband", rbac::RBAC_PERM_COMMAND_GROUP_DISBAND, false, &HandleGroupDisbandCommand, "" },
+ { "remove", rbac::RBAC_PERM_COMMAND_GROUP_REMOVE, false, &HandleGroupRemoveCommand, "" },
+ { "join", rbac::RBAC_PERM_COMMAND_GROUP_JOIN, false, &HandleGroupJoinCommand, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_GROUP_LIST, false, &HandleGroupListCommand, "" },
+ { "summon", rbac::RBAC_PERM_COMMAND_GROUP_SUMMON, false, &HandleGroupSummonCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "group", rbac::RBAC_PERM_COMMAND_GROUP, false, NULL, "", groupCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_guild.cpp b/src/server/scripts/Commands/cs_guild.cpp
index 88ded7a376c..7375dd48f49 100644
--- a/src/server/scripts/Commands/cs_guild.cpp
+++ b/src/server/scripts/Commands/cs_guild.cpp
@@ -36,23 +36,21 @@ class guild_commandscript : public CommandScript
public:
guild_commandscript() : CommandScript("guild_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand guildCommandTable[] =
+ static std::vector<ChatCommand> guildCommandTable =
{
- { "create", rbac::RBAC_PERM_COMMAND_GUILD_CREATE, true, &HandleGuildCreateCommand, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_GUILD_DELETE, true, &HandleGuildDeleteCommand, "", NULL },
- { "invite", rbac::RBAC_PERM_COMMAND_GUILD_INVITE, true, &HandleGuildInviteCommand, "", NULL },
- { "uninvite", rbac::RBAC_PERM_COMMAND_GUILD_UNINVITE, true, &HandleGuildUninviteCommand, "", NULL },
- { "rank", rbac::RBAC_PERM_COMMAND_GUILD_RANK, true, &HandleGuildRankCommand, "", NULL },
- { "rename", rbac::RBAC_PERM_COMMAND_GUILD_RENAME, true, &HandleGuildRenameCommand, "", NULL },
- { "info", rbac::RBAC_PERM_COMMAND_GUILD_INFO, true, &HandleGuildInfoCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "create", rbac::RBAC_PERM_COMMAND_GUILD_CREATE, true, &HandleGuildCreateCommand, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_GUILD_DELETE, true, &HandleGuildDeleteCommand, "" },
+ { "invite", rbac::RBAC_PERM_COMMAND_GUILD_INVITE, true, &HandleGuildInviteCommand, "" },
+ { "uninvite", rbac::RBAC_PERM_COMMAND_GUILD_UNINVITE, true, &HandleGuildUninviteCommand, "" },
+ { "rank", rbac::RBAC_PERM_COMMAND_GUILD_RANK, true, &HandleGuildRankCommand, "" },
+ { "rename", rbac::RBAC_PERM_COMMAND_GUILD_RENAME, true, &HandleGuildRenameCommand, "" },
+ { "info", rbac::RBAC_PERM_COMMAND_GUILD_INFO, true, &HandleGuildInfoCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "guild", rbac::RBAC_PERM_COMMAND_GUILD, true, NULL, "", guildCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_honor.cpp b/src/server/scripts/Commands/cs_honor.cpp
index ad2c53415bb..e8b41309d47 100644
--- a/src/server/scripts/Commands/cs_honor.cpp
+++ b/src/server/scripts/Commands/cs_honor.cpp
@@ -33,26 +33,23 @@ class honor_commandscript : public CommandScript
public:
honor_commandscript() : CommandScript("honor_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand honorAddCommandTable[] =
+ static std::vector<ChatCommand> honorAddCommandTable =
{
- { "kill", rbac::RBAC_PERM_COMMAND_HONOR_ADD_KILL, false, &HandleHonorAddKillCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_HONOR_ADD, false, &HandleHonorAddCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "kill", rbac::RBAC_PERM_COMMAND_HONOR_ADD_KILL, false, &HandleHonorAddKillCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_HONOR_ADD, false, &HandleHonorAddCommand, "" },
};
- static ChatCommand honorCommandTable[] =
+ static std::vector<ChatCommand> honorCommandTable =
{
{ "add", rbac::RBAC_PERM_COMMAND_HONOR_ADD, false, NULL, "", honorAddCommandTable },
- { "update", rbac::RBAC_PERM_COMMAND_HONOR_UPDATE, false, &HandleHonorUpdateCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "update", rbac::RBAC_PERM_COMMAND_HONOR_UPDATE, false, &HandleHonorUpdateCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "honor", rbac::RBAC_PERM_COMMAND_HONOR, false, NULL, "", honorCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_instance.cpp b/src/server/scripts/Commands/cs_instance.cpp
index e722ec95945..4ebc257b58b 100644
--- a/src/server/scripts/Commands/cs_instance.cpp
+++ b/src/server/scripts/Commands/cs_instance.cpp
@@ -36,23 +36,21 @@ class instance_commandscript : public CommandScript
public:
instance_commandscript() : CommandScript("instance_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand instanceCommandTable[] =
+ static std::vector<ChatCommand> instanceCommandTable =
{
- { "listbinds", rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS, false, &HandleInstanceListBindsCommand, "", NULL },
- { "unbind", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleInstanceUnbindCommand, "", NULL },
- { "stats", rbac::RBAC_PERM_COMMAND_INSTANCE_STATS, true, &HandleInstanceStatsCommand, "", NULL },
- { "savedata", rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA, false, &HandleInstanceSaveDataCommand, "", NULL },
- { "setbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_SET_BOSS_STATE, true, &HandleInstanceSetBossStateCommand, "", NULL },
- { "getbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_GET_BOSS_STATE, true, &HandleInstanceGetBossStateCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "listbinds", rbac::RBAC_PERM_COMMAND_INSTANCE_LISTBINDS, false, &HandleInstanceListBindsCommand, "" },
+ { "unbind", rbac::RBAC_PERM_COMMAND_INSTANCE_UNBIND, false, &HandleInstanceUnbindCommand, "" },
+ { "stats", rbac::RBAC_PERM_COMMAND_INSTANCE_STATS, true, &HandleInstanceStatsCommand, "" },
+ { "savedata", rbac::RBAC_PERM_COMMAND_INSTANCE_SAVEDATA, false, &HandleInstanceSaveDataCommand, "" },
+ { "setbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_SET_BOSS_STATE, true, &HandleInstanceSetBossStateCommand, "" },
+ { "getbossstate", rbac::RBAC_PERM_COMMAND_INSTANCE_GET_BOSS_STATE, true, &HandleInstanceGetBossStateCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "instance", rbac::RBAC_PERM_COMMAND_INSTANCE, true, NULL, "", instanceCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
@@ -254,7 +252,8 @@ public:
}
map->GetInstanceScript()->SetBossState(encounterId, EncounterState(state));
- handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state);
+ std::string stateName = InstanceScript::GetBossStateName(state);
+ handler->PSendSysMessage(LANG_COMMAND_INST_SET_BOSS_STATE, encounterId, state, stateName);
return true;
}
@@ -318,7 +317,8 @@ public:
}
uint32 state = map->GetInstanceScript()->GetBossState(encounterId);
- handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state);
+ std::string stateName = InstanceScript::GetBossStateName(state);
+ handler->PSendSysMessage(LANG_COMMAND_INST_GET_BOSS_STATE, encounterId, state, stateName);
return true;
}
};
diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp
index d41c9c5d2c2..ef26e9fc8d2 100644
--- a/src/server/scripts/Commands/cs_learn.cpp
+++ b/src/server/scripts/Commands/cs_learn.cpp
@@ -36,40 +36,36 @@ class learn_commandscript : public CommandScript
public:
learn_commandscript() : CommandScript("learn_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand learnAllMyCommandTable[] =
+ static std::vector<ChatCommand> learnAllMyCommandTable =
{
- { "class", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_CLASS, false, &HandleLearnAllMyClassCommand, "", NULL },
- { "pettalents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_PETTALENTS, false, &HandleLearnAllMyPetTalentsCommand, "", NULL },
- { "spells", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, false, &HandleLearnAllMySpellsCommand, "", NULL },
- { "talents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_TALENTS, false, &HandleLearnAllMyTalentsCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "class", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_CLASS, false, &HandleLearnAllMyClassCommand, "" },
+ { "pettalents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_PETTALENTS, false, &HandleLearnAllMyPetTalentsCommand, "" },
+ { "spells", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_SPELLS, false, &HandleLearnAllMySpellsCommand, "" },
+ { "talents", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY_TALENTS, false, &HandleLearnAllMyTalentsCommand, "" },
};
- static ChatCommand learnAllCommandTable[] =
+ static std::vector<ChatCommand> learnAllCommandTable =
{
{ "my", rbac::RBAC_PERM_COMMAND_LEARN_ALL_MY, false, NULL, "", learnAllMyCommandTable },
- { "gm", rbac::RBAC_PERM_COMMAND_LEARN_ALL_GM, false, &HandleLearnAllGMCommand, "", NULL },
- { "crafts", rbac::RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS, false, &HandleLearnAllCraftsCommand, "", NULL },
- { "default", rbac::RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT, false, &HandleLearnAllDefaultCommand, "", NULL },
- { "lang", rbac::RBAC_PERM_COMMAND_LEARN_ALL_LANG, false, &HandleLearnAllLangCommand, "", NULL },
- { "recipes", rbac::RBAC_PERM_COMMAND_LEARN_ALL_RECIPES, false, &HandleLearnAllRecipesCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "gm", rbac::RBAC_PERM_COMMAND_LEARN_ALL_GM, false, &HandleLearnAllGMCommand, "" },
+ { "crafts", rbac::RBAC_PERM_COMMAND_LEARN_ALL_CRAFTS, false, &HandleLearnAllCraftsCommand, "" },
+ { "default", rbac::RBAC_PERM_COMMAND_LEARN_ALL_DEFAULT, false, &HandleLearnAllDefaultCommand, "" },
+ { "lang", rbac::RBAC_PERM_COMMAND_LEARN_ALL_LANG, false, &HandleLearnAllLangCommand, "" },
+ { "recipes", rbac::RBAC_PERM_COMMAND_LEARN_ALL_RECIPES, false, &HandleLearnAllRecipesCommand, "" },
};
- static ChatCommand learnCommandTable[] =
+ static std::vector<ChatCommand> learnCommandTable =
{
{ "all", rbac::RBAC_PERM_COMMAND_LEARN_ALL, false, NULL, "", learnAllCommandTable },
- { "", rbac::RBAC_PERM_COMMAND_LEARN, false, &HandleLearnCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "", rbac::RBAC_PERM_COMMAND_LEARN, false, &HandleLearnCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "learn", rbac::RBAC_PERM_COMMAND_LEARN, false, NULL, "", learnCommandTable },
- { "unlearn", rbac::RBAC_PERM_COMMAND_UNLEARN, false, &HandleUnLearnCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "unlearn", rbac::RBAC_PERM_COMMAND_UNLEARN, false, &HandleUnLearnCommand, "" },
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp
index b81a98459b7..92bc7c5f543 100644
--- a/src/server/scripts/Commands/cs_lfg.cpp
+++ b/src/server/scripts/Commands/cs_lfg.cpp
@@ -19,7 +19,9 @@
#include "Chat.h"
#include "Language.h"
#include "LFGMgr.h"
+#include "ObjectMgr.h"
#include "Group.h"
+#include "GroupMgr.h"
#include "Player.h"
void GetPlayerInfo(ChatHandler* handler, Player* player)
@@ -41,22 +43,20 @@ class lfg_commandscript : public CommandScript
public:
lfg_commandscript() : CommandScript("lfg_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand lfgCommandTable[] =
+ static std::vector<ChatCommand> lfgCommandTable =
{
- { "player", rbac::RBAC_PERM_COMMAND_LFG_PLAYER, false, &HandleLfgPlayerInfoCommand, "", NULL },
- { "group", rbac::RBAC_PERM_COMMAND_LFG_GROUP, false, &HandleLfgGroupInfoCommand, "", NULL },
- { "queue", rbac::RBAC_PERM_COMMAND_LFG_QUEUE, true, &HandleLfgQueueInfoCommand, "", NULL },
- { "clean", rbac::RBAC_PERM_COMMAND_LFG_CLEAN, true, &HandleLfgCleanCommand, "", NULL },
- { "options", rbac::RBAC_PERM_COMMAND_LFG_OPTIONS, true, &HandleLfgOptionsCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "player", rbac::RBAC_PERM_COMMAND_LFG_PLAYER, false, &HandleLfgPlayerInfoCommand, "" },
+ { "group", rbac::RBAC_PERM_COMMAND_LFG_GROUP, false, &HandleLfgGroupInfoCommand, "" },
+ { "queue", rbac::RBAC_PERM_COMMAND_LFG_QUEUE, true, &HandleLfgQueueInfoCommand, "" },
+ { "clean", rbac::RBAC_PERM_COMMAND_LFG_CLEAN, true, &HandleLfgCleanCommand, "" },
+ { "options", rbac::RBAC_PERM_COMMAND_LFG_OPTIONS, true, &HandleLfgOptionsCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "lfg", rbac::RBAC_PERM_COMMAND_LFG, true, NULL, "", lfgCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -74,25 +74,55 @@ public:
static bool HandleLfgGroupInfoCommand(ChatHandler* handler, char const* args)
{
- Player* target = NULL;
- std::string playerName;
- if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName))
+ Player* playerTarget;
+ ObjectGuid guidTarget;
+ std::string nameTarget;
+
+ ObjectGuid parseGUID = ObjectGuid::Create<HighGuid::Player>(uint64(atoull(args)));
+
+ if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget))
+ {
+ playerTarget = ObjectAccessor::FindPlayer(parseGUID);
+ guidTarget = parseGUID;
+ }
+ else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget))
return false;
- Group* grp = target->GetGroup();
- if (!grp)
+ Group* groupTarget = NULL;
+
+ if (playerTarget)
+ groupTarget = playerTarget->GetGroup();
+ else
+ {
+ PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER);
+ stmt->setUInt32(0, guidTarget.GetCounter());
+ PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt);
+ if (resultGroup)
+ groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32());
+ }
+ if (!groupTarget)
{
- handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, playerName.c_str());
- return true;
+ handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, nameTarget.c_str());
+ handler->SetSentErrorMessage(true);
+ return false;
}
- ObjectGuid guid = grp->GetGUID();
+ ObjectGuid guid = groupTarget->GetGUID();
std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid));
- handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(),
+ handler->PSendSysMessage(LANG_LFG_GROUP_INFO, groupTarget->isLFGGroup(),
state.c_str(), sLFGMgr->GetDungeon(guid));
- for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next())
- GetPlayerInfo(handler, itr->GetSource());
+ Group::MemberSlotList const& members = groupTarget->GetMemberSlots();
+
+ for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
+ {
+ Group::MemberSlot const& slot = *itr;
+ Player* p = ObjectAccessor::FindPlayer((*itr).guid);
+ if (p)
+ GetPlayerInfo(handler, p);
+ else
+ handler->PSendSysMessage("%s is offline.", slot.name.c_str());
+ }
return true;
}
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 9951688dcf7..91add2c2391 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -36,21 +36,19 @@ class list_commandscript : public CommandScript
public:
list_commandscript() : CommandScript("list_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand listCommandTable[] =
+ static std::vector<ChatCommand> listCommandTable =
{
- { "creature", rbac::RBAC_PERM_COMMAND_LIST_CREATURE, true, &HandleListCreatureCommand, "", NULL },
- { "item", rbac::RBAC_PERM_COMMAND_LIST_ITEM, true, &HandleListItemCommand, "", NULL },
- { "object", rbac::RBAC_PERM_COMMAND_LIST_OBJECT, true, &HandleListObjectCommand, "", NULL },
- { "auras", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleListAurasCommand, "", NULL },
- { "mail", rbac::RBAC_PERM_COMMAND_LIST_MAIL, true, &HandleListMailCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "creature", rbac::RBAC_PERM_COMMAND_LIST_CREATURE, true, &HandleListCreatureCommand, "" },
+ { "item", rbac::RBAC_PERM_COMMAND_LIST_ITEM, true, &HandleListItemCommand, "" },
+ { "object", rbac::RBAC_PERM_COMMAND_LIST_OBJECT, true, &HandleListObjectCommand, "" },
+ { "auras", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleListAurasCommand, "" },
+ { "mail", rbac::RBAC_PERM_COMMAND_LIST_MAIL, true, &HandleListMailCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "list", rbac::RBAC_PERM_COMMAND_LIST,true, NULL, "", listCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index 8fa5bd079e6..a05c88a43d2 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -37,47 +37,43 @@ class lookup_commandscript : public CommandScript
public:
lookup_commandscript() : CommandScript("lookup_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand lookupPlayerCommandTable[] =
+ static std::vector<ChatCommand> lookupPlayerCommandTable =
{
- { "ip", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_IP, true, &HandleLookupPlayerIpCommand, "", NULL },
- { "account", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_ACCOUNT, true, &HandleLookupPlayerAccountCommand, "", NULL },
- { "email", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_EMAIL, true, &HandleLookupPlayerEmailCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "ip", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_IP, true, &HandleLookupPlayerIpCommand, "" },
+ { "account", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_ACCOUNT, true, &HandleLookupPlayerAccountCommand, "" },
+ { "email", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER_EMAIL, true, &HandleLookupPlayerEmailCommand, "" },
};
- static ChatCommand lookupSpellCommandTable[] =
+ static std::vector<ChatCommand> lookupSpellCommandTable =
{
- { "id", rbac::RBAC_PERM_COMMAND_LOOKUP_SPELL_ID, true, &HandleLookupSpellIdCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_LOOKUP_SPELL, true, &HandleLookupSpellCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "id", rbac::RBAC_PERM_COMMAND_LOOKUP_SPELL_ID, true, &HandleLookupSpellIdCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_LOOKUP_SPELL, true, &HandleLookupSpellCommand, "" },
};
- static ChatCommand lookupCommandTable[] =
+ static std::vector<ChatCommand> lookupCommandTable =
{
- { "area", rbac::RBAC_PERM_COMMAND_LOOKUP_AREA, true, &HandleLookupAreaCommand, "", NULL },
- { "creature", rbac::RBAC_PERM_COMMAND_LOOKUP_CREATURE, true, &HandleLookupCreatureCommand, "", NULL },
- { "event", rbac::RBAC_PERM_COMMAND_LOOKUP_EVENT, true, &HandleLookupEventCommand, "", NULL },
- { "faction", rbac::RBAC_PERM_COMMAND_LOOKUP_FACTION, true, &HandleLookupFactionCommand, "", NULL },
- { "item", rbac::RBAC_PERM_COMMAND_LOOKUP_ITEM, true, &HandleLookupItemCommand, "", NULL },
- { "itemset", rbac::RBAC_PERM_COMMAND_LOOKUP_ITEMSET, true, &HandleLookupItemSetCommand, "", NULL },
- { "object", rbac::RBAC_PERM_COMMAND_LOOKUP_OBJECT, true, &HandleLookupObjectCommand, "", NULL },
- { "quest", rbac::RBAC_PERM_COMMAND_LOOKUP_QUEST, true, &HandleLookupQuestCommand, "", NULL },
+ { "area", rbac::RBAC_PERM_COMMAND_LOOKUP_AREA, true, &HandleLookupAreaCommand, "" },
+ { "creature", rbac::RBAC_PERM_COMMAND_LOOKUP_CREATURE, true, &HandleLookupCreatureCommand, "" },
+ { "event", rbac::RBAC_PERM_COMMAND_LOOKUP_EVENT, true, &HandleLookupEventCommand, "" },
+ { "faction", rbac::RBAC_PERM_COMMAND_LOOKUP_FACTION, true, &HandleLookupFactionCommand, "" },
+ { "item", rbac::RBAC_PERM_COMMAND_LOOKUP_ITEM, true, &HandleLookupItemCommand, "" },
+ { "itemset", rbac::RBAC_PERM_COMMAND_LOOKUP_ITEMSET, true, &HandleLookupItemSetCommand, "" },
+ { "object", rbac::RBAC_PERM_COMMAND_LOOKUP_OBJECT, true, &HandleLookupObjectCommand, "" },
+ { "quest", rbac::RBAC_PERM_COMMAND_LOOKUP_QUEST, true, &HandleLookupQuestCommand, "" },
{ "player", rbac::RBAC_PERM_COMMAND_LOOKUP_PLAYER, true, NULL, "", lookupPlayerCommandTable },
- { "skill", rbac::RBAC_PERM_COMMAND_LOOKUP_SKILL, true, &HandleLookupSkillCommand, "", NULL },
+ { "skill", rbac::RBAC_PERM_COMMAND_LOOKUP_SKILL, true, &HandleLookupSkillCommand, "" },
{ "spell", rbac::RBAC_PERM_COMMAND_LOOKUP_SPELL, true, NULL, "", lookupSpellCommandTable },
- { "taxinode", rbac::RBAC_PERM_COMMAND_LOOKUP_TAXINODE, true, &HandleLookupTaxiNodeCommand, "", NULL },
- { "tele", rbac::RBAC_PERM_COMMAND_LOOKUP_TELE, true, &HandleLookupTeleCommand, "", NULL },
- { "title", rbac::RBAC_PERM_COMMAND_LOOKUP_TITLE, true, &HandleLookupTitleCommand, "", NULL },
- { "map", rbac::RBAC_PERM_COMMAND_LOOKUP_MAP, true, &HandleLookupMapCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "taxinode", rbac::RBAC_PERM_COMMAND_LOOKUP_TAXINODE, true, &HandleLookupTaxiNodeCommand, "" },
+ { "tele", rbac::RBAC_PERM_COMMAND_LOOKUP_TELE, true, &HandleLookupTeleCommand, "" },
+ { "title", rbac::RBAC_PERM_COMMAND_LOOKUP_TITLE, true, &HandleLookupTitleCommand, "" },
+ { "map", rbac::RBAC_PERM_COMMAND_LOOKUP_MAP, true, &HandleLookupMapCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "lookup", rbac::RBAC_PERM_COMMAND_LOOKUP, true, NULL, "", lookupCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_message.cpp b/src/server/scripts/Commands/cs_message.cpp
index be3a027277c..b6cc364e352 100644
--- a/src/server/scripts/Commands/cs_message.cpp
+++ b/src/server/scripts/Commands/cs_message.cpp
@@ -34,29 +34,26 @@ class message_commandscript : public CommandScript
public:
message_commandscript() : CommandScript("message_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand channelSetCommandTable[] =
+ static std::vector<ChatCommand> channelSetCommandTable =
{
- { "ownership", rbac::RBAC_PERM_COMMAND_CHANNEL_SET_OWNERSHIP, false, &HandleChannelSetOwnership, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "ownership", rbac::RBAC_PERM_COMMAND_CHANNEL_SET_OWNERSHIP, false, &HandleChannelSetOwnership, "" },
};
- static ChatCommand channelCommandTable[] =
+ static std::vector<ChatCommand> channelCommandTable =
{
{ "set", rbac::RBAC_PERM_COMMAND_CHANNEL_SET, true, NULL, "", channelSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "channel", rbac::RBAC_PERM_COMMAND_CHANNEL, true, NULL, "", channelCommandTable },
- { "nameannounce", rbac::RBAC_PERM_COMMAND_NAMEANNOUNCE, true, &HandleNameAnnounceCommand, "", NULL },
- { "gmnameannounce", rbac::RBAC_PERM_COMMAND_GMNAMEANNOUNCE, true, &HandleGMNameAnnounceCommand, "", NULL },
- { "announce", rbac::RBAC_PERM_COMMAND_ANNOUNCE, true, &HandleAnnounceCommand, "", NULL },
- { "gmannounce", rbac::RBAC_PERM_COMMAND_GMANNOUNCE, true, &HandleGMAnnounceCommand, "", NULL },
- { "notify", rbac::RBAC_PERM_COMMAND_NOTIFY, true, &HandleNotifyCommand, "", NULL },
- { "gmnotify", rbac::RBAC_PERM_COMMAND_GMNOTIFY, true, &HandleGMNotifyCommand, "", NULL },
- { "whispers", rbac::RBAC_PERM_COMMAND_WHISPERS, false, &HandleWhispersCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "nameannounce", rbac::RBAC_PERM_COMMAND_NAMEANNOUNCE, true, &HandleNameAnnounceCommand, "" },
+ { "gmnameannounce", rbac::RBAC_PERM_COMMAND_GMNAMEANNOUNCE, true, &HandleGMNameAnnounceCommand, "" },
+ { "announce", rbac::RBAC_PERM_COMMAND_ANNOUNCE, true, &HandleAnnounceCommand, "" },
+ { "gmannounce", rbac::RBAC_PERM_COMMAND_GMANNOUNCE, true, &HandleGMAnnounceCommand, "" },
+ { "notify", rbac::RBAC_PERM_COMMAND_NOTIFY, true, &HandleNotifyCommand, "" },
+ { "gmnotify", rbac::RBAC_PERM_COMMAND_GMNOTIFY, true, &HandleGMNotifyCommand, "" },
+ { "whispers", rbac::RBAC_PERM_COMMAND_WHISPERS, false, &HandleWhispersCommand, "" },
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index f69d8d537fd..c7d8106a372 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -45,62 +45,61 @@ class misc_commandscript : public CommandScript
public:
misc_commandscript() : CommandScript("misc_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand commandTable[] =
- {
- { "additem", rbac::RBAC_PERM_COMMAND_ADDITEM, false, &HandleAddItemCommand, "", NULL },
- { "additemset", rbac::RBAC_PERM_COMMAND_ADDITEMSET, false, &HandleAddItemSetCommand, "", NULL },
- { "appear", rbac::RBAC_PERM_COMMAND_APPEAR, false, &HandleAppearCommand, "", NULL },
- { "aura", rbac::RBAC_PERM_COMMAND_AURA, false, &HandleAuraCommand, "", NULL },
- { "bank", rbac::RBAC_PERM_COMMAND_BANK, false, &HandleBankCommand, "", NULL },
- { "bindsight", rbac::RBAC_PERM_COMMAND_BINDSIGHT, false, &HandleBindSightCommand, "", NULL },
- { "combatstop", rbac::RBAC_PERM_COMMAND_COMBATSTOP, true, &HandleCombatStopCommand, "", NULL },
- { "cometome", rbac::RBAC_PERM_COMMAND_COMETOME, false, &HandleComeToMeCommand, "", NULL },
- { "commands", rbac::RBAC_PERM_COMMAND_COMMANDS, true, &HandleCommandsCommand, "", NULL },
- { "cooldown", rbac::RBAC_PERM_COMMAND_COOLDOWN, false, &HandleCooldownCommand, "", NULL },
- { "damage", rbac::RBAC_PERM_COMMAND_DAMAGE, false, &HandleDamageCommand, "", NULL },
- { "dev", rbac::RBAC_PERM_COMMAND_DEV, false, &HandleDevCommand, "", NULL },
- { "die", rbac::RBAC_PERM_COMMAND_DIE, false, &HandleDieCommand, "", NULL },
- { "dismount", rbac::RBAC_PERM_COMMAND_DISMOUNT, false, &HandleDismountCommand, "", NULL },
- { "distance", rbac::RBAC_PERM_COMMAND_DISTANCE, false, &HandleGetDistanceCommand, "", NULL },
- { "freeze", rbac::RBAC_PERM_COMMAND_FREEZE, false, &HandleFreezeCommand, "", NULL },
- { "gps", rbac::RBAC_PERM_COMMAND_GPS, false, &HandleGPSCommand, "", NULL },
- { "guid", rbac::RBAC_PERM_COMMAND_GUID, false, &HandleGUIDCommand, "", NULL },
- { "help", rbac::RBAC_PERM_COMMAND_HELP, true, &HandleHelpCommand, "", NULL },
- { "hidearea", rbac::RBAC_PERM_COMMAND_HIDEAREA, false, &HandleHideAreaCommand, "", NULL },
- { "itemmove", rbac::RBAC_PERM_COMMAND_ITEMMOVE, false, &HandleItemMoveCommand, "", NULL },
- { "kick", rbac::RBAC_PERM_COMMAND_KICK, true, &HandleKickPlayerCommand, "", NULL },
- { "linkgrave", rbac::RBAC_PERM_COMMAND_LINKGRAVE, false, &HandleLinkGraveCommand, "", NULL },
- { "listfreeze", rbac::RBAC_PERM_COMMAND_LISTFREEZE, false, &HandleListFreezeCommand, "", NULL },
- { "maxskill", rbac::RBAC_PERM_COMMAND_MAXSKILL, false, &HandleMaxSkillCommand, "", NULL },
- { "movegens", rbac::RBAC_PERM_COMMAND_MOVEGENS, false, &HandleMovegensCommand, "", NULL },
- { "mute", rbac::RBAC_PERM_COMMAND_MUTE, true, &HandleMuteCommand, "", NULL },
- { "mutehistory", rbac::RBAC_PERM_COMMAND_MUTEHISTORY, true, &HandleMuteInfoCommand, "", NULL },
- { "neargrave", rbac::RBAC_PERM_COMMAND_NEARGRAVE, false, &HandleNearGraveCommand, "", NULL },
- { "pinfo", rbac::RBAC_PERM_COMMAND_PINFO, true, &HandlePInfoCommand, "", NULL },
- { "playall", rbac::RBAC_PERM_COMMAND_PLAYALL, false, &HandlePlayAllCommand, "", NULL },
- { "possess", rbac::RBAC_PERM_COMMAND_POSSESS, false, &HandlePossessCommand, "", NULL },
- { "pvpstats", rbac::RBAC_PERM_COMMAND_PVPSTATS, true, &HandlePvPstatsCommand, "", NULL },
- { "recall", rbac::RBAC_PERM_COMMAND_RECALL, false, &HandleRecallCommand, "", NULL },
- { "repairitems", rbac::RBAC_PERM_COMMAND_REPAIRITEMS, true, &HandleRepairitemsCommand, "", NULL },
- { "respawn", rbac::RBAC_PERM_COMMAND_RESPAWN, false, &HandleRespawnCommand, "", NULL },
- { "revive", rbac::RBAC_PERM_COMMAND_REVIVE, true, &HandleReviveCommand, "", NULL },
- { "saveall", rbac::RBAC_PERM_COMMAND_SAVEALL, true, &HandleSaveAllCommand, "", NULL },
- { "save", rbac::RBAC_PERM_COMMAND_SAVE, false, &HandleSaveCommand, "", NULL },
- { "setskill", rbac::RBAC_PERM_COMMAND_SETSKILL, false, &HandleSetSkillCommand, "", NULL },
- { "showarea", rbac::RBAC_PERM_COMMAND_SHOWAREA, false, &HandleShowAreaCommand, "", NULL },
- { "summon", rbac::RBAC_PERM_COMMAND_SUMMON, false, &HandleSummonCommand, "", NULL },
- { "unaura", rbac::RBAC_PERM_COMMAND_UNAURA, false, &HandleUnAuraCommand, "", NULL },
- { "unbindsight", rbac::RBAC_PERM_COMMAND_UNBINDSIGHT, false, HandleUnbindSightCommand, "", NULL },
- { "unfreeze", rbac::RBAC_PERM_COMMAND_UNFREEZE, false, &HandleUnFreezeCommand, "", NULL },
- { "unmute", rbac::RBAC_PERM_COMMAND_UNMUTE, true, &HandleUnmuteCommand, "", NULL },
- { "unpossess", rbac::RBAC_PERM_COMMAND_UNPOSSESS, false, &HandleUnPossessCommand, "", NULL },
- { "unstuck", rbac::RBAC_PERM_COMMAND_UNSTUCK, true, &HandleUnstuckCommand, "", NULL },
- { "wchange", rbac::RBAC_PERM_COMMAND_WCHANGE, false, &HandleChangeWeather, "", NULL },
- { "mailbox", rbac::RBAC_PERM_COMMAND_MAILBOX, false, &HandleMailBoxCommand, "", NULL },
- { "auras ", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleAurasCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ static std::vector<ChatCommand> commandTable =
+ {
+ { "additem", rbac::RBAC_PERM_COMMAND_ADDITEM, false, &HandleAddItemCommand, "" },
+ { "additemset", rbac::RBAC_PERM_COMMAND_ADDITEMSET, false, &HandleAddItemSetCommand, "" },
+ { "appear", rbac::RBAC_PERM_COMMAND_APPEAR, false, &HandleAppearCommand, "" },
+ { "aura", rbac::RBAC_PERM_COMMAND_AURA, false, &HandleAuraCommand, "" },
+ { "bank", rbac::RBAC_PERM_COMMAND_BANK, false, &HandleBankCommand, "" },
+ { "bindsight", rbac::RBAC_PERM_COMMAND_BINDSIGHT, false, &HandleBindSightCommand, "" },
+ { "combatstop", rbac::RBAC_PERM_COMMAND_COMBATSTOP, true, &HandleCombatStopCommand, "" },
+ { "cometome", rbac::RBAC_PERM_COMMAND_COMETOME, false, &HandleComeToMeCommand, "" },
+ { "commands", rbac::RBAC_PERM_COMMAND_COMMANDS, true, &HandleCommandsCommand, "" },
+ { "cooldown", rbac::RBAC_PERM_COMMAND_COOLDOWN, false, &HandleCooldownCommand, "" },
+ { "damage", rbac::RBAC_PERM_COMMAND_DAMAGE, false, &HandleDamageCommand, "" },
+ { "dev", rbac::RBAC_PERM_COMMAND_DEV, false, &HandleDevCommand, "" },
+ { "die", rbac::RBAC_PERM_COMMAND_DIE, false, &HandleDieCommand, "" },
+ { "dismount", rbac::RBAC_PERM_COMMAND_DISMOUNT, false, &HandleDismountCommand, "" },
+ { "distance", rbac::RBAC_PERM_COMMAND_DISTANCE, false, &HandleGetDistanceCommand, "" },
+ { "freeze", rbac::RBAC_PERM_COMMAND_FREEZE, false, &HandleFreezeCommand, "" },
+ { "gps", rbac::RBAC_PERM_COMMAND_GPS, false, &HandleGPSCommand, "" },
+ { "guid", rbac::RBAC_PERM_COMMAND_GUID, false, &HandleGUIDCommand, "" },
+ { "help", rbac::RBAC_PERM_COMMAND_HELP, true, &HandleHelpCommand, "" },
+ { "hidearea", rbac::RBAC_PERM_COMMAND_HIDEAREA, false, &HandleHideAreaCommand, "" },
+ { "itemmove", rbac::RBAC_PERM_COMMAND_ITEMMOVE, false, &HandleItemMoveCommand, "" },
+ { "kick", rbac::RBAC_PERM_COMMAND_KICK, true, &HandleKickPlayerCommand, "" },
+ { "linkgrave", rbac::RBAC_PERM_COMMAND_LINKGRAVE, false, &HandleLinkGraveCommand, "" },
+ { "listfreeze", rbac::RBAC_PERM_COMMAND_LISTFREEZE, false, &HandleListFreezeCommand, "" },
+ { "maxskill", rbac::RBAC_PERM_COMMAND_MAXSKILL, false, &HandleMaxSkillCommand, "" },
+ { "movegens", rbac::RBAC_PERM_COMMAND_MOVEGENS, false, &HandleMovegensCommand, "" },
+ { "mute", rbac::RBAC_PERM_COMMAND_MUTE, true, &HandleMuteCommand, "" },
+ { "mutehistory", rbac::RBAC_PERM_COMMAND_MUTEHISTORY, true, &HandleMuteInfoCommand, "" },
+ { "neargrave", rbac::RBAC_PERM_COMMAND_NEARGRAVE, false, &HandleNearGraveCommand, "" },
+ { "pinfo", rbac::RBAC_PERM_COMMAND_PINFO, true, &HandlePInfoCommand, "" },
+ { "playall", rbac::RBAC_PERM_COMMAND_PLAYALL, false, &HandlePlayAllCommand, "" },
+ { "possess", rbac::RBAC_PERM_COMMAND_POSSESS, false, &HandlePossessCommand, "" },
+ { "pvpstats", rbac::RBAC_PERM_COMMAND_PVPSTATS, true, &HandlePvPstatsCommand, "" },
+ { "recall", rbac::RBAC_PERM_COMMAND_RECALL, false, &HandleRecallCommand, "" },
+ { "repairitems", rbac::RBAC_PERM_COMMAND_REPAIRITEMS, true, &HandleRepairitemsCommand, "" },
+ { "respawn", rbac::RBAC_PERM_COMMAND_RESPAWN, false, &HandleRespawnCommand, "" },
+ { "revive", rbac::RBAC_PERM_COMMAND_REVIVE, true, &HandleReviveCommand, "" },
+ { "saveall", rbac::RBAC_PERM_COMMAND_SAVEALL, true, &HandleSaveAllCommand, "" },
+ { "save", rbac::RBAC_PERM_COMMAND_SAVE, false, &HandleSaveCommand, "" },
+ { "setskill", rbac::RBAC_PERM_COMMAND_SETSKILL, false, &HandleSetSkillCommand, "" },
+ { "showarea", rbac::RBAC_PERM_COMMAND_SHOWAREA, false, &HandleShowAreaCommand, "" },
+ { "summon", rbac::RBAC_PERM_COMMAND_SUMMON, false, &HandleSummonCommand, "" },
+ { "unaura", rbac::RBAC_PERM_COMMAND_UNAURA, false, &HandleUnAuraCommand, "" },
+ { "unbindsight", rbac::RBAC_PERM_COMMAND_UNBINDSIGHT, false, HandleUnbindSightCommand, "" },
+ { "unfreeze", rbac::RBAC_PERM_COMMAND_UNFREEZE, false, &HandleUnFreezeCommand, "" },
+ { "unmute", rbac::RBAC_PERM_COMMAND_UNMUTE, true, &HandleUnmuteCommand, "" },
+ { "unpossess", rbac::RBAC_PERM_COMMAND_UNPOSSESS, false, &HandleUnPossessCommand, "" },
+ { "unstuck", rbac::RBAC_PERM_COMMAND_UNSTUCK, true, &HandleUnstuckCommand, "" },
+ { "wchange", rbac::RBAC_PERM_COMMAND_WCHANGE, false, &HandleChangeWeather, "" },
+ { "mailbox", rbac::RBAC_PERM_COMMAND_MAILBOX, false, &HandleMailBoxCommand, "" },
+ { "auras ", rbac::RBAC_PERM_COMMAND_LIST_AURAS, false, &HandleAurasCommand, "" },
};
return commandTable;
}
@@ -1181,6 +1180,17 @@ public:
if (count == 0)
count = 1;
+ std::vector<int32> bonusListIDs;
+ char const* bonuses = strtok(NULL, " ");
+
+ // semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
+ if (bonuses)
+ {
+ Tokenizer tokens(bonuses, ';');
+ for (char const* token : tokens)
+ bonusListIDs.push_back(atoul(token));
+ }
+
Player* player = handler->GetSession()->GetPlayer();
Player* playerTarget = handler->getSelectedPlayer();
if (!playerTarget)
@@ -1220,7 +1230,7 @@ public:
return false;
}
- Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId));
+ Item* item = playerTarget->StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId), GuidSet(), bonusListIDs);
// remove binding (let GM give it to another player later)
if (player == playerTarget)
@@ -1260,6 +1270,17 @@ public:
return false;
}
+ std::vector<int32> bonusListIDs;
+ char const* bonuses = strtok(NULL, " ");
+
+ // semicolon separated bonuslist ids (parse them after all arguments are extracted by strtok!)
+ if (bonuses)
+ {
+ Tokenizer tokens(bonuses, ';');
+ for (char const* token : tokens)
+ bonusListIDs.push_back(atoul(token));
+ }
+
Player* player = handler->GetSession()->GetPlayer();
Player* playerTarget = handler->getSelectedPlayer();
if (!playerTarget)
@@ -1278,7 +1299,7 @@ public:
InventoryResult msg = playerTarget->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itr->second.GetId(), 1);
if (msg == EQUIP_ERR_OK)
{
- Item* item = playerTarget->StoreNewItem(dest, itr->second.GetId(), true);
+ Item* item = playerTarget->StoreNewItem(dest, itr->second.GetId(), true, 0, GuidSet(), bonusListIDs);
// remove binding (let GM give it to another player later)
if (player == playerTarget)
diff --git a/src/server/scripts/Commands/cs_mmaps.cpp b/src/server/scripts/Commands/cs_mmaps.cpp
index a21fe324de3..a1e2e591ffa 100644
--- a/src/server/scripts/Commands/cs_mmaps.cpp
+++ b/src/server/scripts/Commands/cs_mmaps.cpp
@@ -42,22 +42,20 @@ class mmaps_commandscript : public CommandScript
public:
mmaps_commandscript() : CommandScript("mmaps_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand mmapCommandTable[] =
+ static std::vector<ChatCommand> mmapCommandTable =
{
- { "loadedtiles", rbac::RBAC_PERM_COMMAND_MMAP_LOADEDTILES, false, &HandleMmapLoadedTilesCommand, "", NULL },
- { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "", NULL },
- { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "", NULL },
- { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "", NULL },
- { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "loadedtiles", rbac::RBAC_PERM_COMMAND_MMAP_LOADEDTILES, false, &HandleMmapLoadedTilesCommand, "" },
+ { "loc", rbac::RBAC_PERM_COMMAND_MMAP_LOC, false, &HandleMmapLocCommand, "" },
+ { "path", rbac::RBAC_PERM_COMMAND_MMAP_PATH, false, &HandleMmapPathCommand, "" },
+ { "stats", rbac::RBAC_PERM_COMMAND_MMAP_STATS, false, &HandleMmapStatsCommand, "" },
+ { "testarea", rbac::RBAC_PERM_COMMAND_MMAP_TESTAREA, false, &HandleMmapTestArea, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "mmap", rbac::RBAC_PERM_COMMAND_MMAP, true, NULL, "", mmapCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp
index 56f540514d7..674b6dd74ee 100644
--- a/src/server/scripts/Commands/cs_modify.cpp
+++ b/src/server/scripts/Commands/cs_modify.cpp
@@ -36,49 +36,46 @@ class modify_commandscript : public CommandScript
public:
modify_commandscript() : CommandScript("modify_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand modifyspeedCommandTable[] =
+ static std::vector<ChatCommand> modifyspeedCommandTable =
{
- { "all", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_ALL, false, &HandleModifyASpeedCommand, "", NULL },
- { "backwalk", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_BACKWALK, false, &HandleModifyBWalkCommand, "", NULL },
- { "fly", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_FLY, false, &HandleModifyFlyCommand, "", NULL },
- { "walk", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_WALK, false, &HandleModifySpeedCommand, "", NULL },
- { "swim", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_SWIM, false, &HandleModifySwimCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED, false, &HandleModifyASpeedCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "all", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_ALL, false, &HandleModifyASpeedCommand, "" },
+ { "backwalk", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_BACKWALK, false, &HandleModifyBWalkCommand, "" },
+ { "fly", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_FLY, false, &HandleModifyFlyCommand, "" },
+ { "walk", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_WALK, false, &HandleModifySpeedCommand, "" },
+ { "swim", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED_SWIM, false, &HandleModifySwimCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED, false, &HandleModifyASpeedCommand, "" },
};
- static ChatCommand modifyCommandTable[] =
+ static std::vector<ChatCommand> modifyCommandTable =
{
- { "bit", rbac::RBAC_PERM_COMMAND_MODIFY_BIT, false, &HandleModifyBitCommand, "", NULL },
- { "currency", rbac::RBAC_PERM_COMMAND_MODIFY_CURRENCY, false, &HandleModifyCurrencyCommand, "", NULL },
- { "drunk", rbac::RBAC_PERM_COMMAND_MODIFY_DRUNK, false, &HandleModifyDrunkCommand, "", NULL },
- { "energy", rbac::RBAC_PERM_COMMAND_MODIFY_ENERGY, false, &HandleModifyEnergyCommand, "", NULL },
- { "faction", rbac::RBAC_PERM_COMMAND_MODIFY_FACTION, false, &HandleModifyFactionCommand, "", NULL },
- { "gender", rbac::RBAC_PERM_COMMAND_MODIFY_GENDER, false, &HandleModifyGenderCommand, "", NULL },
- { "honor", rbac::RBAC_PERM_COMMAND_MODIFY_HONOR, false, &HandleModifyHonorCommand, "", NULL },
- { "hp", rbac::RBAC_PERM_COMMAND_MODIFY_HP, false, &HandleModifyHPCommand, "", NULL },
- { "mana", rbac::RBAC_PERM_COMMAND_MODIFY_MANA, false, &HandleModifyManaCommand, "", NULL },
- { "money", rbac::RBAC_PERM_COMMAND_MODIFY_MONEY, false, &HandleModifyMoneyCommand, "", NULL },
- { "mount", rbac::RBAC_PERM_COMMAND_MODIFY_MOUNT, false, &HandleModifyMountCommand, "", NULL },
- { "phase", rbac::RBAC_PERM_COMMAND_MODIFY_PHASE, false, &HandleModifyPhaseCommand, "", NULL },
- { "rage", rbac::RBAC_PERM_COMMAND_MODIFY_RAGE, false, &HandleModifyRageCommand, "", NULL },
- { "reputation", rbac::RBAC_PERM_COMMAND_MODIFY_REPUTATION, false, &HandleModifyRepCommand, "", NULL },
- { "runicpower", rbac::RBAC_PERM_COMMAND_MODIFY_RUNICPOWER, false, &HandleModifyRunicPowerCommand, "", NULL },
- { "scale", rbac::RBAC_PERM_COMMAND_MODIFY_SCALE, false, &HandleModifyScaleCommand, "", NULL },
+ { "bit", rbac::RBAC_PERM_COMMAND_MODIFY_BIT, false, &HandleModifyBitCommand, "" },
+ { "currency", rbac::RBAC_PERM_COMMAND_MODIFY_CURRENCY, false, &HandleModifyCurrencyCommand, "" },
+ { "drunk", rbac::RBAC_PERM_COMMAND_MODIFY_DRUNK, false, &HandleModifyDrunkCommand, "" },
+ { "energy", rbac::RBAC_PERM_COMMAND_MODIFY_ENERGY, false, &HandleModifyEnergyCommand, "" },
+ { "faction", rbac::RBAC_PERM_COMMAND_MODIFY_FACTION, false, &HandleModifyFactionCommand, "" },
+ { "gender", rbac::RBAC_PERM_COMMAND_MODIFY_GENDER, false, &HandleModifyGenderCommand, "" },
+ { "honor", rbac::RBAC_PERM_COMMAND_MODIFY_HONOR, false, &HandleModifyHonorCommand, "" },
+ { "hp", rbac::RBAC_PERM_COMMAND_MODIFY_HP, false, &HandleModifyHPCommand, "" },
+ { "mana", rbac::RBAC_PERM_COMMAND_MODIFY_MANA, false, &HandleModifyManaCommand, "" },
+ { "money", rbac::RBAC_PERM_COMMAND_MODIFY_MONEY, false, &HandleModifyMoneyCommand, "" },
+ { "mount", rbac::RBAC_PERM_COMMAND_MODIFY_MOUNT, false, &HandleModifyMountCommand, "" },
+ { "phase", rbac::RBAC_PERM_COMMAND_MODIFY_PHASE, false, &HandleModifyPhaseCommand, "" },
+ { "rage", rbac::RBAC_PERM_COMMAND_MODIFY_RAGE, false, &HandleModifyRageCommand, "" },
+ { "reputation", rbac::RBAC_PERM_COMMAND_MODIFY_REPUTATION, false, &HandleModifyRepCommand, "" },
+ { "runicpower", rbac::RBAC_PERM_COMMAND_MODIFY_RUNICPOWER, false, &HandleModifyRunicPowerCommand, "" },
+ { "scale", rbac::RBAC_PERM_COMMAND_MODIFY_SCALE, false, &HandleModifyScaleCommand, "" },
{ "speed", rbac::RBAC_PERM_COMMAND_MODIFY_SPEED, false, NULL, "", modifyspeedCommandTable },
- { "spell", rbac::RBAC_PERM_COMMAND_MODIFY_SPELL, false, &HandleModifySpellCommand, "", NULL },
- { "standstate", rbac::RBAC_PERM_COMMAND_MODIFY_STANDSTATE, false, &HandleModifyStandStateCommand, "", NULL },
- { "talentpoints", rbac::RBAC_PERM_COMMAND_MODIFY_TALENTPOINTS, false, &HandleModifyTalentCommand, "", NULL },
- { "xp", rbac::RBAC_PERM_COMMAND_MODIFY_XP, false, &HandleModifyXPCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "spell", rbac::RBAC_PERM_COMMAND_MODIFY_SPELL, false, &HandleModifySpellCommand, "" },
+ { "standstate", rbac::RBAC_PERM_COMMAND_MODIFY_STANDSTATE, false, &HandleModifyStandStateCommand, "" },
+ { "talentpoints", rbac::RBAC_PERM_COMMAND_MODIFY_TALENTPOINTS, false, &HandleModifyTalentCommand, "" },
+ { "xp", rbac::RBAC_PERM_COMMAND_MODIFY_XP, false, &HandleModifyXPCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
- { "morph", rbac::RBAC_PERM_COMMAND_MORPH, false, &HandleModifyMorphCommand, "", NULL },
- { "demorph", rbac::RBAC_PERM_COMMAND_DEMORPH, false, &HandleDeMorphCommand, "", NULL },
+ { "morph", rbac::RBAC_PERM_COMMAND_MORPH, false, &HandleModifyMorphCommand, "" },
+ { "demorph", rbac::RBAC_PERM_COMMAND_DEMORPH, false, &HandleDeMorphCommand, "" },
{ "modify", rbac::RBAC_PERM_COMMAND_MODIFY, false, NULL, "", modifyCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -136,7 +133,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -164,17 +161,6 @@ public:
if (!*args)
return false;
- // char* pmana = strtok((char*)args, " ");
- // if (!pmana)
- // return false;
-
- // char* pmanaMax = strtok(NULL, " ");
- // if (!pmanaMax)
- // return false;
-
- // int32 manam = atoi(pmanaMax);
- // int32 mana = atoi(pmana);
-
int32 energy = atoi((char*)args)*10;
int32 energym = atoi((char*)args)*10;
@@ -185,7 +171,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -215,17 +201,6 @@ public:
if (!*args)
return false;
- // char* pmana = strtok((char*)args, " ");
- // if (!pmana)
- // return false;
-
- // char* pmanaMax = strtok(NULL, " ");
- // if (!pmanaMax)
- // return false;
-
- // int32 manam = atoi(pmanaMax);
- // int32 mana = atoi(pmana);
-
int32 rage = atoi((char*)args)*10;
int32 ragem = atoi((char*)args)*10;
@@ -236,7 +211,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -274,7 +249,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -390,7 +365,7 @@ public:
else
mark = atoi(pmark);
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (target == NULL)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -949,7 +924,7 @@ public:
return false;
}
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -990,7 +965,7 @@ public:
if (!*args)
return false;
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_NO_CHAR_SELECTED);
@@ -1115,7 +1090,7 @@ public:
if (!*args)
return false;
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -1131,7 +1106,7 @@ public:
target->ModifyCurrency(CURRENCY_TYPE_HONOR_POINTS, amount, true, true);
- handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_HONOR_POINTS, false));
+ handler->PSendSysMessage(LANG_COMMAND_MODIFY_HONOR, handler->GetNameLink(target).c_str(), target->GetCurrency(CURRENCY_TYPE_HONOR_POINTS));
return true;
}
@@ -1145,7 +1120,7 @@ public:
if (drunklevel > 100)
drunklevel = 100;
- if (Player* target = handler->getSelectedPlayer())
+ if (Player* target = handler->getSelectedPlayerOrSelf())
target->SetDrunkValue(drunklevel);
return true;
@@ -1156,7 +1131,7 @@ public:
if (!*args)
return false;
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
handler->SendSysMessage(LANG_PLAYER_NOT_FOUND);
@@ -1309,7 +1284,7 @@ public:
if (!*args)
return false;
- Player* target = handler->getSelectedPlayer();
+ Player* target = handler->getSelectedPlayerOrSelf();
if (!target)
{
diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp
index 2c91a9e6e3e..e30bf1f162b 100644
--- a/src/server/scripts/Commands/cs_npc.cpp
+++ b/src/server/scripts/Commands/cs_npc.cpp
@@ -171,70 +171,62 @@ class npc_commandscript : public CommandScript
public:
npc_commandscript() : CommandScript("npc_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand npcAddCommandTable[] =
- {
- { "formation", rbac::RBAC_PERM_COMMAND_NPC_ADD_FORMATION, false, &HandleNpcAddFormationCommand, "", NULL },
- { "item", rbac::RBAC_PERM_COMMAND_NPC_ADD_ITEM, false, &HandleNpcAddVendorItemCommand, "", NULL },
- { "move", rbac::RBAC_PERM_COMMAND_NPC_ADD_MOVE, false, &HandleNpcAddMoveCommand, "", NULL },
- { "temp", rbac::RBAC_PERM_COMMAND_NPC_ADD_TEMP, false, &HandleNpcAddTempSpawnCommand, "", NULL },
- //{ "weapon", rbac::RBAC_PERM_COMMAND_NPC_ADD_WEAPON, false, &HandleNpcAddWeaponCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, &HandleNpcAddCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ static std::vector<ChatCommand> npcAddCommandTable =
+ {
+ { "formation", rbac::RBAC_PERM_COMMAND_NPC_ADD_FORMATION, false, &HandleNpcAddFormationCommand, "" },
+ { "item", rbac::RBAC_PERM_COMMAND_NPC_ADD_ITEM, false, &HandleNpcAddVendorItemCommand, "" },
+ { "move", rbac::RBAC_PERM_COMMAND_NPC_ADD_MOVE, false, &HandleNpcAddMoveCommand, "" },
+ { "temp", rbac::RBAC_PERM_COMMAND_NPC_ADD_TEMP, false, &HandleNpcAddTempSpawnCommand, "" },
+ //{ "weapon", rbac::RBAC_PERM_COMMAND_NPC_ADD_WEAPON, false, &HandleNpcAddWeaponCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, &HandleNpcAddCommand, "" },
};
- static ChatCommand npcDeleteCommandTable[] =
+ static std::vector<ChatCommand> npcDeleteCommandTable =
{
- { "item", rbac::RBAC_PERM_COMMAND_NPC_DELETE_ITEM, false, &HandleNpcDeleteVendorItemCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, &HandleNpcDeleteCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "item", rbac::RBAC_PERM_COMMAND_NPC_DELETE_ITEM, false, &HandleNpcDeleteVendorItemCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, &HandleNpcDeleteCommand, "" },
};
- static ChatCommand npcFollowCommandTable[] =
+ static std::vector<ChatCommand> npcFollowCommandTable =
{
- { "stop", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW_STOP, false, &HandleNpcUnFollowCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, &HandleNpcFollowCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "stop", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW_STOP, false, &HandleNpcUnFollowCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, &HandleNpcFollowCommand, "" },
};
- static ChatCommand npcSetCommandTable[] =
- {
- { "allowmove", rbac::RBAC_PERM_COMMAND_NPC_SET_ALLOWMOVE, false, &HandleNpcSetAllowMovementCommand, "", NULL },
- { "entry", rbac::RBAC_PERM_COMMAND_NPC_SET_ENTRY, false, &HandleNpcSetEntryCommand, "", NULL },
- { "factionid", rbac::RBAC_PERM_COMMAND_NPC_SET_FACTIONID, false, &HandleNpcSetFactionIdCommand, "", NULL },
- { "flag", rbac::RBAC_PERM_COMMAND_NPC_SET_FLAG, false, &HandleNpcSetFlagCommand, "", NULL },
- { "level", rbac::RBAC_PERM_COMMAND_NPC_SET_LEVEL, false, &HandleNpcSetLevelCommand, "", NULL },
- { "link", rbac::RBAC_PERM_COMMAND_NPC_SET_LINK, false, &HandleNpcSetLinkCommand, "", NULL },
- { "model", rbac::RBAC_PERM_COMMAND_NPC_SET_MODEL, false, &HandleNpcSetModelCommand, "", NULL },
- { "movetype", rbac::RBAC_PERM_COMMAND_NPC_SET_MOVETYPE, false, &HandleNpcSetMoveTypeCommand, "", NULL },
- { "phase", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseCommand, "", NULL },
- { "phasegroup", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseGroup, "", NULL },
- { "spawndist", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNDIST, false, &HandleNpcSetSpawnDistCommand, "", NULL },
- { "spawntime", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNTIME, false, &HandleNpcSetSpawnTimeCommand, "", NULL },
- { "data", rbac::RBAC_PERM_COMMAND_NPC_SET_DATA, false, &HandleNpcSetDataCommand, "", NULL },
- //{ "name", rbac::RBAC_PERM_COMMAND_NPC_SET_NAME, false, &HandleNpcSetNameCommand, "", NULL },
- //{ "subname", rbac::RBAC_PERM_COMMAND_NPC_SET_SUBNAME, false, &HandleNpcSetSubNameCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ static std::vector<ChatCommand> npcSetCommandTable =
+ {
+ { "allowmove", rbac::RBAC_PERM_COMMAND_NPC_SET_ALLOWMOVE, false, &HandleNpcSetAllowMovementCommand, "" },
+ { "entry", rbac::RBAC_PERM_COMMAND_NPC_SET_ENTRY, false, &HandleNpcSetEntryCommand, "" },
+ { "factionid", rbac::RBAC_PERM_COMMAND_NPC_SET_FACTIONID, false, &HandleNpcSetFactionIdCommand, "" },
+ { "flag", rbac::RBAC_PERM_COMMAND_NPC_SET_FLAG, false, &HandleNpcSetFlagCommand, "" },
+ { "level", rbac::RBAC_PERM_COMMAND_NPC_SET_LEVEL, false, &HandleNpcSetLevelCommand, "" },
+ { "link", rbac::RBAC_PERM_COMMAND_NPC_SET_LINK, false, &HandleNpcSetLinkCommand, "" },
+ { "model", rbac::RBAC_PERM_COMMAND_NPC_SET_MODEL, false, &HandleNpcSetModelCommand, "" },
+ { "movetype", rbac::RBAC_PERM_COMMAND_NPC_SET_MOVETYPE, false, &HandleNpcSetMoveTypeCommand, "" },
+ { "phase", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseCommand, "" },
+ { "phasegroup", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseGroup, "" },
+ { "spawndist", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNDIST, false, &HandleNpcSetSpawnDistCommand, "" },
+ { "spawntime", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNTIME, false, &HandleNpcSetSpawnTimeCommand, "" },
+ { "data", rbac::RBAC_PERM_COMMAND_NPC_SET_DATA, false, &HandleNpcSetDataCommand, "" },
};
- static ChatCommand npcCommandTable[] =
- {
- { "info", rbac::RBAC_PERM_COMMAND_NPC_INFO, false, &HandleNpcInfoCommand, "", NULL },
- { "near", rbac::RBAC_PERM_COMMAND_NPC_NEAR, false, &HandleNpcNearCommand, "", NULL },
- { "move", rbac::RBAC_PERM_COMMAND_NPC_MOVE, false, &HandleNpcMoveCommand, "", NULL },
- { "playemote", rbac::RBAC_PERM_COMMAND_NPC_PLAYEMOTE, false, &HandleNpcPlayEmoteCommand, "", NULL },
- { "say", rbac::RBAC_PERM_COMMAND_NPC_SAY, false, &HandleNpcSayCommand, "", NULL },
- { "textemote", rbac::RBAC_PERM_COMMAND_NPC_TEXTEMOTE, false, &HandleNpcTextEmoteCommand, "", NULL },
- { "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "", NULL },
- { "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "", NULL },
- { "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "", NULL },
+ static std::vector<ChatCommand> npcCommandTable =
+ {
+ { "info", rbac::RBAC_PERM_COMMAND_NPC_INFO, false, &HandleNpcInfoCommand, "" },
+ { "near", rbac::RBAC_PERM_COMMAND_NPC_NEAR, false, &HandleNpcNearCommand, "" },
+ { "move", rbac::RBAC_PERM_COMMAND_NPC_MOVE, false, &HandleNpcMoveCommand, "" },
+ { "playemote", rbac::RBAC_PERM_COMMAND_NPC_PLAYEMOTE, false, &HandleNpcPlayEmoteCommand, "" },
+ { "say", rbac::RBAC_PERM_COMMAND_NPC_SAY, false, &HandleNpcSayCommand, "" },
+ { "textemote", rbac::RBAC_PERM_COMMAND_NPC_TEXTEMOTE, false, &HandleNpcTextEmoteCommand, "" },
+ { "whisper", rbac::RBAC_PERM_COMMAND_NPC_WHISPER, false, &HandleNpcWhisperCommand, "" },
+ { "yell", rbac::RBAC_PERM_COMMAND_NPC_YELL, false, &HandleNpcYellCommand, "" },
+ { "tame", rbac::RBAC_PERM_COMMAND_NPC_TAME, false, &HandleNpcTameCommand, "" },
{ "add", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, NULL, "", npcAddCommandTable },
{ "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, NULL, "", npcDeleteCommandTable },
{ "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, NULL, "", npcFollowCommandTable },
{ "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, NULL, "", npcSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "npc", rbac::RBAC_PERM_COMMAND_NPC, false, NULL, "", npcCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -1594,98 +1586,6 @@ public:
*/
return true;
}
-
- static bool HandleNpcSetNameCommand(ChatHandler* /*handler*/, char const* /*args*/)
- {
- /* Temp. disabled
- if (!*args)
- return false;
-
- if (strlen((char*)args)>75)
- {
- handler->PSendSysMessage(LANG_TOO_LONG_NAME, strlen((char*)args)-75);
- return true;
- }
-
- for (uint8 i = 0; i < strlen(args); ++i)
- {
- if (!isalpha(args[i]) && args[i] != ' ')
- {
- handler->SendSysMessage(LANG_CHARS_ONLY);
- return false;
- }
- }
-
- uint64 guid;
- guid = handler->GetSession()->GetPlayer()->GetSelection();
- if (guid == 0)
- {
- handler->SendSysMessage(LANG_NO_SELECTION);
- return true;
- }
-
- Creature* creature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid);
-
- if (!creature)
- {
- handler->SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
-
- creature->SetName(args);
- uint32 idname = sObjectMgr->AddCreatureTemplate(creature->GetName());
- creature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
-
- creature->SaveToDB();
- */
-
- return true;
- }
-
- static bool HandleNpcSetSubNameCommand(ChatHandler* /*handler*/, char const* /*args*/)
- {
- /* Temp. disabled
-
- if (!*args)
- args = "";
-
- if (strlen((char*)args)>75)
- {
- handler->PSendSysMessage(LANG_TOO_LONG_SUBNAME, strlen((char*)args)-75);
- return true;
- }
-
- for (uint8 i = 0; i < strlen(args); i++)
- {
- if (!isalpha(args[i]) && args[i] != ' ')
- {
- handler->SendSysMessage(LANG_CHARS_ONLY);
- return false;
- }
- }
- uint64 guid;
- guid = handler->GetSession()->GetPlayer()->GetSelection();
- if (guid == 0)
- {
- handler->SendSysMessage(LANG_NO_SELECTION);
- return true;
- }
-
- Creature* creature = ObjectAccessor::GetCreature(*handler->GetSession()->GetPlayer(), guid);
-
- if (!creature)
- {
- handler->SendSysMessage(LANG_SELECT_CREATURE);
- return true;
- }
-
- uint32 idname = sObjectMgr->AddCreatureSubName(creature->GetName(), args, creature->GetUInt32Value(UNIT_FIELD_DISPLAYID));
- creature->SetUInt32Value(OBJECT_FIELD_ENTRY, idname);
-
- creature->SaveToDB();
- */
- return true;
- }
};
void AddSC_npc_commandscript()
diff --git a/src/server/scripts/Commands/cs_pet.cpp b/src/server/scripts/Commands/cs_pet.cpp
index 943b779e7e7..61e3c10550a 100644
--- a/src/server/scripts/Commands/cs_pet.cpp
+++ b/src/server/scripts/Commands/cs_pet.cpp
@@ -27,20 +27,18 @@ class pet_commandscript : public CommandScript
public:
pet_commandscript() : CommandScript("pet_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand petCommandTable[] =
+ static std::vector<ChatCommand> petCommandTable =
{
- { "create", rbac::RBAC_PERM_COMMAND_PET_CREATE, false, &HandlePetCreateCommand, "", NULL },
- { "learn", rbac::RBAC_PERM_COMMAND_PET_LEARN, false, &HandlePetLearnCommand, "", NULL },
- { "unlearn", rbac::RBAC_PERM_COMMAND_PET_UNLEARN, false, &HandlePetUnlearnCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "create", rbac::RBAC_PERM_COMMAND_PET_CREATE, false, &HandlePetCreateCommand, "" },
+ { "learn", rbac::RBAC_PERM_COMMAND_PET_LEARN, false, &HandlePetLearnCommand, "" },
+ { "unlearn", rbac::RBAC_PERM_COMMAND_PET_UNLEARN, false, &HandlePetUnlearnCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "pet", rbac::RBAC_PERM_COMMAND_PET, false, NULL, "", petCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_quest.cpp b/src/server/scripts/Commands/cs_quest.cpp
index 297c5600929..3b5a9f2adde 100644
--- a/src/server/scripts/Commands/cs_quest.cpp
+++ b/src/server/scripts/Commands/cs_quest.cpp
@@ -33,20 +33,18 @@ class quest_commandscript : public CommandScript
public:
quest_commandscript() : CommandScript("quest_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand questCommandTable[] =
+ static std::vector<ChatCommand> questCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_QUEST_ADD, false, &HandleQuestAdd, "", NULL },
- { "complete", rbac::RBAC_PERM_COMMAND_QUEST_COMPLETE, false, &HandleQuestComplete, "", NULL },
- { "remove", rbac::RBAC_PERM_COMMAND_QUEST_REMOVE, false, &HandleQuestRemove, "", NULL },
- { "reward", rbac::RBAC_PERM_COMMAND_QUEST_REWARD, false, &HandleQuestReward, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_QUEST_ADD, false, &HandleQuestAdd, "" },
+ { "complete", rbac::RBAC_PERM_COMMAND_QUEST_COMPLETE, false, &HandleQuestComplete, "" },
+ { "remove", rbac::RBAC_PERM_COMMAND_QUEST_REMOVE, false, &HandleQuestRemove, "" },
+ { "reward", rbac::RBAC_PERM_COMMAND_QUEST_REWARD, false, &HandleQuestReward, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "quest", rbac::RBAC_PERM_COMMAND_QUEST, false, NULL, "", questCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_rbac.cpp b/src/server/scripts/Commands/cs_rbac.cpp
index 9a7848ce171..86d9ba17114 100644
--- a/src/server/scripts/Commands/cs_rbac.cpp
+++ b/src/server/scripts/Commands/cs_rbac.cpp
@@ -49,28 +49,25 @@ class rbac_commandscript : public CommandScript
public:
rbac_commandscript() : CommandScript("rbac_commandscript") { }
- ChatCommand* GetCommands() const
+ std::vector<ChatCommand> GetCommands() const
{
- static ChatCommand rbacAccountCommandTable[] =
+ static std::vector<ChatCommand> rbacAccountCommandTable =
{
- { "list", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, true, &HandleRBACPermListCommand, "", NULL },
- { "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "", NULL },
- { "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "", NULL },
- { "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "list", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_LIST, true, &HandleRBACPermListCommand, "" },
+ { "grant", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_GRANT, true, &HandleRBACPermGrantCommand, "" },
+ { "deny", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_DENY, true, &HandleRBACPermDenyCommand, "" },
+ { "revoke", rbac::RBAC_PERM_COMMAND_RBAC_ACC_PERM_REVOKE, true, &HandleRBACPermRevokeCommand, "" },
};
- static ChatCommand rbacCommandTable[] =
+ static std::vector<ChatCommand> rbacCommandTable =
{
{ "account", rbac::RBAC_PERM_COMMAND_RBAC_ACC, true, NULL, "", rbacAccountCommandTable },
- { "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, &HandleRBACListPermissionsCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "list", rbac::RBAC_PERM_COMMAND_RBAC_LIST, true, &HandleRBACListPermissionsCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "rbac", rbac::RBAC_PERM_COMMAND_RBAC, true, NULL, "", rbacCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp
index be025ea7180..dfddcaf395e 100644
--- a/src/server/scripts/Commands/cs_reload.cpp
+++ b/src/server/scripts/Commands/cs_reload.cpp
@@ -47,118 +47,115 @@ class reload_commandscript : public CommandScript
public:
reload_commandscript() : CommandScript("reload_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand reloadAllCommandTable[] =
+ static std::vector<ChatCommand> reloadAllCommandTable =
{
- { "achievement", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_ACHIEVEMENT, true, &HandleReloadAllAchievementCommand, "", NULL },
- { "area", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_AREA, true, &HandleReloadAllAreaCommand, "", NULL },
- { "gossips", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_GOSSIP, true, &HandleReloadAllGossipsCommand, "", NULL },
- { "item", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_ITEM, true, &HandleReloadAllItemCommand, "", NULL },
- { "locales", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_LOCALES, true, &HandleReloadAllLocalesCommand, "", NULL },
- { "loot", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_LOOT, true, &HandleReloadAllLootCommand, "", NULL },
- { "npc", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_NPC, true, &HandleReloadAllNpcCommand, "", NULL },
- { "quest", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_QUEST, true, &HandleReloadAllQuestCommand, "", NULL },
- { "scripts", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_SCRIPTS, true, &HandleReloadAllScriptsCommand, "", NULL },
- { "spell", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_SPELL, true, &HandleReloadAllSpellCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_RELOAD_ALL, true, &HandleReloadAllCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "achievement", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_ACHIEVEMENT, true, &HandleReloadAllAchievementCommand, "" },
+ { "area", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_AREA, true, &HandleReloadAllAreaCommand, "" },
+ { "gossips", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_GOSSIP, true, &HandleReloadAllGossipsCommand, "" },
+ { "item", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_ITEM, true, &HandleReloadAllItemCommand, "" },
+ { "locales", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_LOCALES, true, &HandleReloadAllLocalesCommand, "" },
+ { "loot", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_LOOT, true, &HandleReloadAllLootCommand, "" },
+ { "npc", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_NPC, true, &HandleReloadAllNpcCommand, "" },
+ { "quest", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_QUEST, true, &HandleReloadAllQuestCommand, "" },
+ { "scripts", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_SCRIPTS, true, &HandleReloadAllScriptsCommand, "" },
+ { "spell", rbac::RBAC_PERM_COMMAND_RELOAD_ALL_SPELL, true, &HandleReloadAllSpellCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_RELOAD_ALL, true, &HandleReloadAllCommand, "" },
};
- static ChatCommand reloadCommandTable[] =
+ static std::vector<ChatCommand> reloadCommandTable =
{
- { "auctions", rbac::RBAC_PERM_COMMAND_RELOAD_AUCTIONS, true, &HandleReloadAuctionsCommand, "", NULL },
- { "access_requirement", rbac::RBAC_PERM_COMMAND_RELOAD_ACCESS_REQUIREMENT, true, &HandleReloadAccessRequirementCommand, "", NULL },
- { "achievement_criteria_data", rbac::RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_CRITERIA_DATA, true, &HandleReloadAchievementCriteriaDataCommand, "", NULL },
- { "achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_REWARD, true, &HandleReloadAchievementRewardCommand, "", NULL },
+ { "auctions", rbac::RBAC_PERM_COMMAND_RELOAD_AUCTIONS, true, &HandleReloadAuctionsCommand, "" },
+ { "access_requirement", rbac::RBAC_PERM_COMMAND_RELOAD_ACCESS_REQUIREMENT, true, &HandleReloadAccessRequirementCommand, "" },
+ { "achievement_criteria_data", rbac::RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_CRITERIA_DATA, true, &HandleReloadAchievementCriteriaDataCommand, "" },
+ { "achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_ACHIEVEMENT_REWARD, true, &HandleReloadAchievementRewardCommand, "" },
{ "all", rbac::RBAC_PERM_COMMAND_RELOAD_ALL, true, NULL, "", reloadAllCommandTable },
- { "areatrigger_involvedrelation", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_INVOLVEDRELATION, true, &HandleReloadQuestAreaTriggersCommand, "", NULL },
- { "areatrigger_tavern", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN, true, &HandleReloadAreaTriggerTavernCommand, "", NULL },
- { "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "", NULL },
- { "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "", NULL },
- { "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "", NULL },
- { "character_template", rbac::RBAC_PERM_COMMAND_RELOAD_CHARACTER_TEMPLATE, true, &HandleReloadCharacterTemplate, "", NULL },
- { "command", rbac::RBAC_PERM_COMMAND_RELOAD_COMMAND, true, &HandleReloadCommandCommand, "", NULL },
- { "conditions", rbac::RBAC_PERM_COMMAND_RELOAD_CONDITIONS, true, &HandleReloadConditions, "", NULL },
- { "config", rbac::RBAC_PERM_COMMAND_RELOAD_CONFIG, true, &HandleReloadConfigCommand, "", NULL },
- { "creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_TEXT, true, &HandleReloadCreatureText, "", NULL },
- { "creature_questender", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTENDER, true, &HandleReloadCreatureQuestEnderCommand, "", NULL },
- { "creature_linked_respawn", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN, true, &HandleReloadLinkedRespawnCommand, "", NULL },
- { "creature_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesCreatureCommand, "", NULL },
- { "creature_onkill_reputation", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_ONKILL_REPUTATION, true, &HandleReloadOnKillReputationCommand, "", NULL },
- { "creature_queststarter", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTSTARTER, true, &HandleReloadCreatureQuestStarterCommand, "", NULL },
- { "creature_summon_groups", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_SUMMON_GROUPS, true, &HandleReloadCreatureSummonGroupsCommand, "", NULL },
- { "creature_template", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_TEMPLATE, true, &HandleReloadCreatureTemplateCommand, "", NULL },
- { "disables", rbac::RBAC_PERM_COMMAND_RELOAD_DISABLES, true, &HandleReloadDisablesCommand, "", NULL },
- { "disenchant_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_DISENCHANT_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesDisenchantCommand, "", NULL },
- { "event_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_EVENT_SCRIPTS, true, &HandleReloadEventScriptsCommand, "", NULL },
- { "fishing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_FISHING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesFishingCommand, "", NULL },
- { "graveyard_zone", rbac::RBAC_PERM_COMMAND_RELOAD_GRAVEYARD_ZONE, true, &HandleReloadGameGraveyardZoneCommand, "", NULL },
- { "game_tele", rbac::RBAC_PERM_COMMAND_RELOAD_GAME_TELE, true, &HandleReloadGameTeleCommand, "", NULL },
- { "gameobject_questender", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER, true, &HandleReloadGOQuestEnderCommand, "", NULL },
- { "gameobject_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesGameobjectCommand, "", NULL },
- { "gameobject_queststarter", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTSTARTER, true, &HandleReloadGOQuestStarterCommand, "", NULL },
- { "gossip_menu", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU, true, &HandleReloadGossipMenuCommand, "", NULL },
- { "gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION, true, &HandleReloadGossipMenuOptionCommand, "", NULL },
- { "item_enchantment_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_ENCHANTMENT_TEMPLATE, true, &HandleReloadItemEnchantementsCommand, "", NULL },
- { "item_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesItemCommand, "", NULL },
- { "lfg_dungeon_rewards", rbac::RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS, true, &HandleReloadLfgRewardsCommand, "", NULL },
- { "locales_achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD, true, &HandleReloadLocalesAchievementRewardCommand, "", NULL },
- { "locales_creature", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE, true, &HandleReloadLocalesCreatureCommand, "", NULL },
- { "locales_creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT, true, &HandleReloadLocalesCreatureTextCommand, "", NULL },
- { "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "", NULL },
- { "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "", NULL },
- { "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "", NULL },
- { "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "", NULL },
- { "mail_level_reward", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD, true, &HandleReloadMailLevelRewardCommand, "", NULL },
- { "mail_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMailCommand, "", NULL },
- { "milling_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMillingCommand, "", NULL },
- { "npc_spellclick_spells", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_SPELLCLICK_SPELLS, true, &HandleReloadSpellClickSpellsCommand, "", NULL },
- { "npc_trainer", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_TRAINER, true, &HandleReloadNpcTrainerCommand, "", NULL },
- { "npc_vendor", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_VENDOR, true, &HandleReloadNpcVendorCommand, "", NULL },
- { "page_text", rbac::RBAC_PERM_COMMAND_RELOAD_PAGE_TEXT, true, &HandleReloadPageTextsCommand, "", NULL },
- { "pickpocketing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesPickpocketingCommand, "", NULL },
- { "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "", NULL },
- { "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL },
- { "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "", NULL },
- { "quest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE, true, &HandleReloadQuestLocaleCommand, "", NULL },
- { "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "", NULL },
- { "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "", NULL },
- { "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "", NULL },
- { "reference_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_REFERENCE_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesReferenceCommand, "", NULL },
- { "reserved_name", rbac::RBAC_PERM_COMMAND_RELOAD_RESERVED_NAME, true, &HandleReloadReservedNameCommand, "", NULL },
- { "reputation_reward_rate", rbac::RBAC_PERM_COMMAND_RELOAD_REPUTATION_REWARD_RATE, true, &HandleReloadReputationRewardRateCommand, "", NULL },
- { "reputation_spillover_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPILLOVER_TEMPLATE, true, &HandleReloadReputationRewardRateCommand, "", NULL },
- { "skill_discovery_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_DISCOVERY_TEMPLATE, true, &HandleReloadSkillDiscoveryTemplateCommand, "", NULL },
- { "skill_extra_item_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE, true, &HandleReloadSkillExtraItemTemplateCommand, "", NULL },
- { "skill_fishing_base_level", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_FISHING_BASE_LEVEL, true, &HandleReloadSkillFishingBaseLevelCommand, "", NULL },
- { "skinning_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKINNING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSkinningCommand, "", NULL },
- { "smart_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS, true, &HandleReloadSmartScripts, "", NULL },
- { "spell_required", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED, true, &HandleReloadSpellRequiredCommand, "", NULL },
- { "spell_area", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_AREA, true, &HandleReloadSpellAreaCommand, "", NULL },
- { "spell_group", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP, true, &HandleReloadSpellGroupsCommand, "", NULL },
- { "spell_learn_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL, true, &HandleReloadSpellLearnSpellCommand, "", NULL },
- { "spell_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSpellCommand, "", NULL },
- { "spell_linked_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LINKED_SPELL, true, &HandleReloadSpellLinkedSpellCommand, "", NULL },
- { "spell_pet_auras", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PET_AURAS, true, &HandleReloadSpellPetAurasCommand, "", NULL },
- { "spell_proc_event", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PROC_EVENT, true, &HandleReloadSpellProcEventCommand, "", NULL },
- { "spell_proc", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PROC, true, &HandleReloadSpellProcsCommand, "", NULL },
- { "spell_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_SCRIPTS, true, &HandleReloadSpellScriptsCommand, "", NULL },
- { "spell_target_position", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_TARGET_POSITION, true, &HandleReloadSpellTargetPositionCommand, "", NULL },
- { "spell_threats", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_THREATS, true, &HandleReloadSpellThreatsCommand, "", NULL },
- { "spell_group_stack_rules", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES, true, &HandleReloadSpellGroupStackRulesCommand, "", NULL },
- { "support", rbac::RBAC_PERM_COMMAND_RELOAD_SUPPORT_SYSTEM, true, &HandleReloadSupportSystemCommand, "", NULL },
- { "trinity_string", rbac::RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING, true, &HandleReloadTrinityStringCommand, "", NULL },
- { "warden_action", rbac::RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION, true, &HandleReloadWardenactionCommand, "", NULL },
- { "waypoint_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS, true, &HandleReloadWpScriptsCommand, "", NULL },
- { "waypoint_data", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA, true, &HandleReloadWpCommand, "", NULL },
- { "vehicle_accessory", rbac::RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY, true, &HandleReloadVehicleAccessoryCommand, "", NULL },
- { "vehicle_template_accessory", rbac::RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE_ACCESSORY, true, &HandleReloadVehicleTemplateAccessoryCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "areatrigger_involvedrelation", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_INVOLVEDRELATION, true, &HandleReloadQuestAreaTriggersCommand, "" },
+ { "areatrigger_tavern", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TAVERN, true, &HandleReloadAreaTriggerTavernCommand, "" },
+ { "areatrigger_teleport", rbac::RBAC_PERM_COMMAND_RELOAD_AREATRIGGER_TELEPORT, true, &HandleReloadAreaTriggerTeleportCommand, "" },
+ { "autobroadcast", rbac::RBAC_PERM_COMMAND_RELOAD_AUTOBROADCAST, true, &HandleReloadAutobroadcastCommand, "" },
+ { "battleground_template", rbac::RBAC_PERM_COMMAND_RELOAD_BATTLEGROUND_TEMPLATE, true, &HandleReloadBattlegroundTemplate, "" },
+ { "character_template", rbac::RBAC_PERM_COMMAND_RELOAD_CHARACTER_TEMPLATE, true, &HandleReloadCharacterTemplate, "" },
+ { "command", rbac::RBAC_PERM_COMMAND_RELOAD_COMMAND, true, &HandleReloadCommandCommand, "" },
+ { "conditions", rbac::RBAC_PERM_COMMAND_RELOAD_CONDITIONS, true, &HandleReloadConditions, "" },
+ { "config", rbac::RBAC_PERM_COMMAND_RELOAD_CONFIG, true, &HandleReloadConfigCommand, "" },
+ { "creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_TEXT, true, &HandleReloadCreatureText, "" },
+ { "creature_questender", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTENDER, true, &HandleReloadCreatureQuestEnderCommand, "" },
+ { "creature_linked_respawn", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_LINKED_RESPAWN, true, &HandleReloadLinkedRespawnCommand, "" },
+ { "creature_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesCreatureCommand, "" },
+ { "creature_onkill_reputation", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_ONKILL_REPUTATION, true, &HandleReloadOnKillReputationCommand, "" },
+ { "creature_queststarter", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_QUESTSTARTER, true, &HandleReloadCreatureQuestStarterCommand, "" },
+ { "creature_summon_groups", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_SUMMON_GROUPS, true, &HandleReloadCreatureSummonGroupsCommand, "" },
+ { "creature_template", rbac::RBAC_PERM_COMMAND_RELOAD_CREATURE_TEMPLATE, true, &HandleReloadCreatureTemplateCommand, "" },
+ { "disables", rbac::RBAC_PERM_COMMAND_RELOAD_DISABLES, true, &HandleReloadDisablesCommand, "" },
+ { "disenchant_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_DISENCHANT_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesDisenchantCommand, "" },
+ { "event_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_EVENT_SCRIPTS, true, &HandleReloadEventScriptsCommand, "" },
+ { "fishing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_FISHING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesFishingCommand, "" },
+ { "graveyard_zone", rbac::RBAC_PERM_COMMAND_RELOAD_GRAVEYARD_ZONE, true, &HandleReloadGameGraveyardZoneCommand, "" },
+ { "game_tele", rbac::RBAC_PERM_COMMAND_RELOAD_GAME_TELE, true, &HandleReloadGameTeleCommand, "" },
+ { "gameobject_questender", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTENDER, true, &HandleReloadGOQuestEnderCommand, "" },
+ { "gameobject_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUEST_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesGameobjectCommand, "" },
+ { "gameobject_queststarter", rbac::RBAC_PERM_COMMAND_RELOAD_GAMEOBJECT_QUESTSTARTER, true, &HandleReloadGOQuestStarterCommand, "" },
+ { "gossip_menu", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU, true, &HandleReloadGossipMenuCommand, "" },
+ { "gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_GOSSIP_MENU_OPTION, true, &HandleReloadGossipMenuOptionCommand, "" },
+ { "item_enchantment_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_ENCHANTMENT_TEMPLATE, true, &HandleReloadItemEnchantementsCommand, "" },
+ { "item_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_ITEM_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesItemCommand, "" },
+ { "lfg_dungeon_rewards", rbac::RBAC_PERM_COMMAND_RELOAD_LFG_DUNGEON_REWARDS, true, &HandleReloadLfgRewardsCommand, "" },
+ { "locales_achievement_reward", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_ACHIEVEMENT_REWARD, true, &HandleReloadLocalesAchievementRewardCommand, "" },
+ { "locales_creature", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE, true, &HandleReloadLocalesCreatureCommand, "" },
+ { "locales_creature_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_CRETURE_TEXT, true, &HandleReloadLocalesCreatureTextCommand, "" },
+ { "locales_gameobject", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GAMEOBJECT, true, &HandleReloadLocalesGameobjectCommand, "" },
+ { "locales_gossip_menu_option", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_GOSSIP_MENU_OPTION, true, &HandleReloadLocalesGossipMenuOptionCommand, "" },
+ { "locales_page_text", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_PAGE_TEXT, true, &HandleReloadLocalesPageTextCommand, "" },
+ { "locales_points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_LOCALES_POINTS_OF_INTEREST, true, &HandleReloadLocalesPointsOfInterestCommand, "" },
+ { "mail_level_reward", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LEVEL_REWARD, true, &HandleReloadMailLevelRewardCommand, "" },
+ { "mail_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MAIL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMailCommand, "" },
+ { "milling_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_MILLING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesMillingCommand, "" },
+ { "npc_spellclick_spells", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_SPELLCLICK_SPELLS, true, &HandleReloadSpellClickSpellsCommand, "" },
+ { "npc_trainer", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_TRAINER, true, &HandleReloadNpcTrainerCommand, "" },
+ { "npc_vendor", rbac::RBAC_PERM_COMMAND_RELOAD_NPC_VENDOR, true, &HandleReloadNpcVendorCommand, "" },
+ { "page_text", rbac::RBAC_PERM_COMMAND_RELOAD_PAGE_TEXT, true, &HandleReloadPageTextsCommand, "" },
+ { "pickpocketing_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PICKPOCKETING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesPickpocketingCommand, "" },
+ { "points_of_interest", rbac::RBAC_PERM_COMMAND_RELOAD_POINTS_OF_INTEREST, true, &HandleReloadPointsOfInterestCommand, "" },
+ { "prospecting_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_PROSPECTING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesProspectingCommand, "" },
+ { "quest_greeting", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_GREETING, true, &HandleReloadQuestGreetingCommand, "" },
+ { "quest_locale", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_LOCALE, true, &HandleReloadQuestLocaleCommand, "" },
+ { "quest_poi", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_POI, true, &HandleReloadQuestPOICommand, "" },
+ { "quest_template", rbac::RBAC_PERM_COMMAND_RELOAD_QUEST_TEMPLATE, true, &HandleReloadQuestTemplateCommand, "" },
+ { "rbac", rbac::RBAC_PERM_COMMAND_RELOAD_RBAC, true, &HandleReloadRBACCommand, "" },
+ { "reference_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_REFERENCE_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesReferenceCommand, "" },
+ { "reserved_name", rbac::RBAC_PERM_COMMAND_RELOAD_RESERVED_NAME, true, &HandleReloadReservedNameCommand, "" },
+ { "reputation_reward_rate", rbac::RBAC_PERM_COMMAND_RELOAD_REPUTATION_REWARD_RATE, true, &HandleReloadReputationRewardRateCommand, "" },
+ { "reputation_spillover_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPILLOVER_TEMPLATE, true, &HandleReloadReputationRewardRateCommand, "" },
+ { "skill_discovery_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_DISCOVERY_TEMPLATE, true, &HandleReloadSkillDiscoveryTemplateCommand, "" },
+ { "skill_extra_item_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_EXTRA_ITEM_TEMPLATE, true, &HandleReloadSkillExtraItemTemplateCommand, "" },
+ { "skill_fishing_base_level", rbac::RBAC_PERM_COMMAND_RELOAD_SKILL_FISHING_BASE_LEVEL, true, &HandleReloadSkillFishingBaseLevelCommand, "" },
+ { "skinning_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SKINNING_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSkinningCommand, "" },
+ { "smart_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SMART_SCRIPTS, true, &HandleReloadSmartScripts, "" },
+ { "spell_required", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_REQUIRED, true, &HandleReloadSpellRequiredCommand, "" },
+ { "spell_area", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_AREA, true, &HandleReloadSpellAreaCommand, "" },
+ { "spell_group", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP, true, &HandleReloadSpellGroupsCommand, "" },
+ { "spell_learn_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LEARN_SPELL, true, &HandleReloadSpellLearnSpellCommand, "" },
+ { "spell_loot_template", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LOOT_TEMPLATE, true, &HandleReloadLootTemplatesSpellCommand, "" },
+ { "spell_linked_spell", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_LINKED_SPELL, true, &HandleReloadSpellLinkedSpellCommand, "" },
+ { "spell_pet_auras", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PET_AURAS, true, &HandleReloadSpellPetAurasCommand, "" },
+ { "spell_proc_event", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PROC_EVENT, true, &HandleReloadSpellProcEventCommand, "" },
+ { "spell_proc", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_PROC, true, &HandleReloadSpellProcsCommand, "" },
+ { "spell_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_SCRIPTS, true, &HandleReloadSpellScriptsCommand, "" },
+ { "spell_target_position", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_TARGET_POSITION, true, &HandleReloadSpellTargetPositionCommand, "" },
+ { "spell_threats", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_THREATS, true, &HandleReloadSpellThreatsCommand, "" },
+ { "spell_group_stack_rules", rbac::RBAC_PERM_COMMAND_RELOAD_SPELL_GROUP_STACK_RULES, true, &HandleReloadSpellGroupStackRulesCommand, "" },
+ { "support", rbac::RBAC_PERM_COMMAND_RELOAD_SUPPORT_SYSTEM, true, &HandleReloadSupportSystemCommand, "" },
+ { "trinity_string", rbac::RBAC_PERM_COMMAND_RELOAD_TRINITY_STRING, true, &HandleReloadTrinityStringCommand, "" },
+ { "warden_action", rbac::RBAC_PERM_COMMAND_RELOAD_WARDEN_ACTION, true, &HandleReloadWardenactionCommand, "" },
+ { "waypoint_scripts", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_SCRIPTS, true, &HandleReloadWpScriptsCommand, "" },
+ { "waypoint_data", rbac::RBAC_PERM_COMMAND_RELOAD_WAYPOINT_DATA, true, &HandleReloadWpCommand, "" },
+ { "vehicle_accessory", rbac::RBAC_PERM_COMMAND_RELOAD_VEHICLE_ACCESORY, true, &HandleReloadVehicleAccessoryCommand, "" },
+ { "vehicle_template_accessory", rbac::RBAC_PERM_COMMAND_RELOAD_VEHICLE_TEMPLATE_ACCESSORY, true, &HandleReloadVehicleTemplateAccessoryCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "reload", rbac::RBAC_PERM_COMMAND_RELOAD, true, NULL, "", reloadCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
@@ -755,12 +752,21 @@ public:
return true;
}
- static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler, const char* /*args*/)
+ static bool HandleReloadSkillPerfectItemTemplateCommand(ChatHandler* handler, const char* /*args*/)
+ { // latched onto HandleReloadSkillExtraItemTemplateCommand as it's part of that table group (and i don't want to chance all the command IDs)
+ TC_LOG_INFO("misc", "Re-Loading Skill Perfection Data Table...");
+ LoadSkillPerfectItemTable();
+ handler->SendGlobalGMSysMessage("DB table `skill_perfect_item_template` (perfect item procs when crafting) reloaded.");
+ return true;
+ }
+
+ static bool HandleReloadSkillExtraItemTemplateCommand(ChatHandler* handler, const char* args)
{
TC_LOG_INFO("misc", "Re-Loading Skill Extra Item Table...");
LoadSkillExtraItemTable();
handler->SendGlobalGMSysMessage("DB table `skill_extra_item_template` (extra item creation when crafting) reloaded.");
- return true;
+
+ return HandleReloadSkillPerfectItemTemplateCommand(handler, args);
}
static bool HandleReloadSkillFishingBaseLevelCommand(ChatHandler* handler, const char* /*args*/)
diff --git a/src/server/scripts/Commands/cs_reset.cpp b/src/server/scripts/Commands/cs_reset.cpp
index 9118b5b2c3d..dcae0ee11a0 100644
--- a/src/server/scripts/Commands/cs_reset.cpp
+++ b/src/server/scripts/Commands/cs_reset.cpp
@@ -35,23 +35,21 @@ class reset_commandscript : public CommandScript
public:
reset_commandscript() : CommandScript("reset_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand resetCommandTable[] =
+ static std::vector<ChatCommand> resetCommandTable =
{
- { "achievements", rbac::RBAC_PERM_COMMAND_RESET_ACHIEVEMENTS, true, &HandleResetAchievementsCommand, "", NULL },
- { "honor", rbac::RBAC_PERM_COMMAND_RESET_HONOR, true, &HandleResetHonorCommand, "", NULL },
- { "level", rbac::RBAC_PERM_COMMAND_RESET_LEVEL, true, &HandleResetLevelCommand, "", NULL },
- { "spells", rbac::RBAC_PERM_COMMAND_RESET_SPELLS, true, &HandleResetSpellsCommand, "", NULL },
- { "stats", rbac::RBAC_PERM_COMMAND_RESET_STATS, true, &HandleResetStatsCommand, "", NULL },
- { "talents", rbac::RBAC_PERM_COMMAND_RESET_TALENTS, true, &HandleResetTalentsCommand, "", NULL },
- { "all", rbac::RBAC_PERM_COMMAND_RESET_ALL, true, &HandleResetAllCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "achievements", rbac::RBAC_PERM_COMMAND_RESET_ACHIEVEMENTS, true, &HandleResetAchievementsCommand, "" },
+ { "honor", rbac::RBAC_PERM_COMMAND_RESET_HONOR, true, &HandleResetHonorCommand, "" },
+ { "level", rbac::RBAC_PERM_COMMAND_RESET_LEVEL, true, &HandleResetLevelCommand, "" },
+ { "spells", rbac::RBAC_PERM_COMMAND_RESET_SPELLS, true, &HandleResetSpellsCommand, "" },
+ { "stats", rbac::RBAC_PERM_COMMAND_RESET_STATS, true, &HandleResetStatsCommand, "" },
+ { "talents", rbac::RBAC_PERM_COMMAND_RESET_TALENTS, true, &HandleResetTalentsCommand, "" },
+ { "all", rbac::RBAC_PERM_COMMAND_RESET_ALL, true, &HandleResetAllCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "reset", rbac::RBAC_PERM_COMMAND_RESET, true, NULL, "", resetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_send.cpp b/src/server/scripts/Commands/cs_send.cpp
index 36c0f953c60..9812a20075d 100644
--- a/src/server/scripts/Commands/cs_send.cpp
+++ b/src/server/scripts/Commands/cs_send.cpp
@@ -27,21 +27,19 @@ class send_commandscript : public CommandScript
public:
send_commandscript() : CommandScript("send_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand sendCommandTable[] =
+ static std::vector<ChatCommand> sendCommandTable =
{
- { "items", rbac::RBAC_PERM_COMMAND_SEND_ITEMS, true, &HandleSendItemsCommand, "", NULL },
- { "mail", rbac::RBAC_PERM_COMMAND_SEND_MAIL, true, &HandleSendMailCommand, "", NULL },
- { "message", rbac::RBAC_PERM_COMMAND_SEND_MESSAGE, true, &HandleSendMessageCommand, "", NULL },
- { "money", rbac::RBAC_PERM_COMMAND_SEND_MONEY, true, &HandleSendMoneyCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "items", rbac::RBAC_PERM_COMMAND_SEND_ITEMS, true, &HandleSendItemsCommand, "" },
+ { "mail", rbac::RBAC_PERM_COMMAND_SEND_MAIL, true, &HandleSendMailCommand, "" },
+ { "message", rbac::RBAC_PERM_COMMAND_SEND_MESSAGE, true, &HandleSendMessageCommand, "" },
+ { "money", rbac::RBAC_PERM_COMMAND_SEND_MONEY, true, &HandleSendMoneyCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "send", rbac::RBAC_PERM_COMMAND_SEND, false, NULL, "", sendCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_server.cpp b/src/server/scripts/Commands/cs_server.cpp
index 15078e4cc78..e50577fb877 100644
--- a/src/server/scripts/Commands/cs_server.cpp
+++ b/src/server/scripts/Commands/cs_server.cpp
@@ -35,64 +35,57 @@ class server_commandscript : public CommandScript
public:
server_commandscript() : CommandScript("server_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand serverIdleRestartCommandTable[] =
+ static std::vector<ChatCommand> serverIdleRestartCommandTable =
{
- { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "", NULL },
- { "" , rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, &HandleServerIdleRestartCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "" , rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, &HandleServerIdleRestartCommand, "" },
};
- static ChatCommand serverIdleShutdownCommandTable[] =
+ static std::vector<ChatCommand> serverIdleShutdownCommandTable =
{
- { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "", NULL },
- { "" , rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, &HandleServerIdleShutDownCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "" , rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, &HandleServerIdleShutDownCommand, "" },
};
- static ChatCommand serverRestartCommandTable[] =
+ static std::vector<ChatCommand> serverRestartCommandTable =
{
- { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "", NULL },
- { "" , rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, &HandleServerRestartCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_RESTART_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "" , rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, &HandleServerRestartCommand, "" },
};
- static ChatCommand serverShutdownCommandTable[] =
+ static std::vector<ChatCommand> serverShutdownCommandTable =
{
- { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "", NULL },
- { "" , rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, &HandleServerShutDownCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "cancel", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN_CANCEL, true, &HandleServerShutDownCancelCommand, "" },
+ { "" , rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, &HandleServerShutDownCommand, "" },
};
- static ChatCommand serverSetCommandTable[] =
+ static std::vector<ChatCommand> serverSetCommandTable =
{
- { "difftime", rbac::RBAC_PERM_COMMAND_SERVER_SET_DIFFTIME, true, &HandleServerSetDiffTimeCommand, "", NULL },
- { "loglevel", rbac::RBAC_PERM_COMMAND_SERVER_SET_LOGLEVEL, true, &HandleServerSetLogLevelCommand, "", NULL },
- { "motd", rbac::RBAC_PERM_COMMAND_SERVER_SET_MOTD, true, &HandleServerSetMotdCommand, "", NULL },
- { "closed", rbac::RBAC_PERM_COMMAND_SERVER_SET_CLOSED, true, &HandleServerSetClosedCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "difftime", rbac::RBAC_PERM_COMMAND_SERVER_SET_DIFFTIME, true, &HandleServerSetDiffTimeCommand, "" },
+ { "loglevel", rbac::RBAC_PERM_COMMAND_SERVER_SET_LOGLEVEL, true, &HandleServerSetLogLevelCommand, "" },
+ { "motd", rbac::RBAC_PERM_COMMAND_SERVER_SET_MOTD, true, &HandleServerSetMotdCommand, "" },
+ { "closed", rbac::RBAC_PERM_COMMAND_SERVER_SET_CLOSED, true, &HandleServerSetClosedCommand, "" },
};
- static ChatCommand serverCommandTable[] =
+ static std::vector<ChatCommand> serverCommandTable =
{
- { "corpses", rbac::RBAC_PERM_COMMAND_SERVER_CORPSES, true, &HandleServerCorpsesCommand, "", NULL },
- { "exit", rbac::RBAC_PERM_COMMAND_SERVER_EXIT, true, &HandleServerExitCommand, "", NULL },
+ { "corpses", rbac::RBAC_PERM_COMMAND_SERVER_CORPSES, true, &HandleServerCorpsesCommand, "" },
+ { "exit", rbac::RBAC_PERM_COMMAND_SERVER_EXIT, true, &HandleServerExitCommand, "" },
{ "idlerestart", rbac::RBAC_PERM_COMMAND_SERVER_IDLERESTART, true, NULL, "", serverIdleRestartCommandTable },
{ "idleshutdown", rbac::RBAC_PERM_COMMAND_SERVER_IDLESHUTDOWN, true, NULL, "", serverIdleShutdownCommandTable },
- { "info", rbac::RBAC_PERM_COMMAND_SERVER_INFO, true, &HandleServerInfoCommand, "", NULL },
- { "motd", rbac::RBAC_PERM_COMMAND_SERVER_MOTD, true, &HandleServerMotdCommand, "", NULL },
- { "plimit", rbac::RBAC_PERM_COMMAND_SERVER_PLIMIT, true, &HandleServerPLimitCommand, "", NULL },
+ { "info", rbac::RBAC_PERM_COMMAND_SERVER_INFO, true, &HandleServerInfoCommand, "" },
+ { "motd", rbac::RBAC_PERM_COMMAND_SERVER_MOTD, true, &HandleServerMotdCommand, "" },
+ { "plimit", rbac::RBAC_PERM_COMMAND_SERVER_PLIMIT, true, &HandleServerPLimitCommand, "" },
{ "restart", rbac::RBAC_PERM_COMMAND_SERVER_RESTART, true, NULL, "", serverRestartCommandTable },
{ "shutdown", rbac::RBAC_PERM_COMMAND_SERVER_SHUTDOWN, true, NULL, "", serverShutdownCommandTable },
{ "set", rbac::RBAC_PERM_COMMAND_SERVER_SET, true, NULL, "", serverSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "server", rbac::RBAC_PERM_COMMAND_SERVER, true, NULL, "", serverCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp
index 09930770f63..b2bedf8d99c 100644
--- a/src/server/scripts/Commands/cs_tele.cpp
+++ b/src/server/scripts/Commands/cs_tele.cpp
@@ -35,21 +35,19 @@ class tele_commandscript : public CommandScript
public:
tele_commandscript() : CommandScript("tele_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand teleCommandTable[] =
+ static std::vector<ChatCommand> teleCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_TELE_ADD, false, &HandleTeleAddCommand, "", NULL },
- { "del", rbac::RBAC_PERM_COMMAND_TELE_DEL, true, &HandleTeleDelCommand, "", NULL },
- { "name", rbac::RBAC_PERM_COMMAND_TELE_NAME, true, &HandleTeleNameCommand, "", NULL },
- { "group", rbac::RBAC_PERM_COMMAND_TELE_GROUP, false, &HandleTeleGroupCommand, "", NULL },
- { "", rbac::RBAC_PERM_COMMAND_TELE, false, &HandleTeleCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_TELE_ADD, false, &HandleTeleAddCommand, "" },
+ { "del", rbac::RBAC_PERM_COMMAND_TELE_DEL, true, &HandleTeleDelCommand, "" },
+ { "name", rbac::RBAC_PERM_COMMAND_TELE_NAME, true, &HandleTeleNameCommand, "" },
+ { "group", rbac::RBAC_PERM_COMMAND_TELE_GROUP, false, &HandleTeleGroupCommand, "" },
+ { "", rbac::RBAC_PERM_COMMAND_TELE, false, &HandleTeleCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "tele", rbac::RBAC_PERM_COMMAND_TELE, false, NULL, "", teleCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_ticket.cpp b/src/server/scripts/Commands/cs_ticket.cpp
index db24295bb21..254ee1f2878 100644
--- a/src/server/scripts/Commands/cs_ticket.cpp
+++ b/src/server/scripts/Commands/cs_ticket.cpp
@@ -95,7 +95,7 @@ public:
return true;
}
- ChatCommand* GetCommands() const override;
+ std::vector<ChatCommand> GetCommands() const override;
};
template<typename T>
@@ -364,65 +364,59 @@ bool ticket_commandscript::HandleTicketGetByIdCommand(ChatHandler* handler, char
return true;
}
-ChatCommand* ticket_commandscript::GetCommands() const
+std::vector<ChatCommand> ticket_commandscript::GetCommands() const
{
- static ChatCommand ticketBugCommandTable[] =
+ static std::vector<ChatCommand> ticketBugCommandTable =
{
- { "assign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_ASSIGN, true, &HandleTicketAssignToCommand<BugTicket>, "", NULL },
- { "close", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSE, true, &HandleTicketCloseByIdCommand<BugTicket>, "", NULL },
- { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSEDLIST, true, &HandleTicketListClosedCommand<BugTicket>, "", NULL },
- { "comment", rbac::RBAC_PERM_COMMAND_TICKET_BUG_COMMENT, true, &HandleTicketCommentCommand<BugTicket>, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_TICKET_BUG_DELETE, true, &HandleTicketDeleteByIdCommand<BugTicket>, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_TICKET_BUG_LIST, true, &HandleTicketListCommand<BugTicket>, "", NULL },
- { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_UNASSIGN, true, &HandleTicketUnAssignCommand<BugTicket>, "", NULL },
- { "view", rbac::RBAC_PERM_COMMAND_TICKET_BUG_VIEW, true, &HandleTicketGetByIdCommand<BugTicket>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "assign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_ASSIGN, true, &HandleTicketAssignToCommand<BugTicket>, "" },
+ { "close", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSE, true, &HandleTicketCloseByIdCommand<BugTicket>, "" },
+ { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_BUG_CLOSEDLIST, true, &HandleTicketListClosedCommand<BugTicket>, "" },
+ { "comment", rbac::RBAC_PERM_COMMAND_TICKET_BUG_COMMENT, true, &HandleTicketCommentCommand<BugTicket>, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_TICKET_BUG_DELETE, true, &HandleTicketDeleteByIdCommand<BugTicket>, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_TICKET_BUG_LIST, true, &HandleTicketListCommand<BugTicket>, "" },
+ { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_BUG_UNASSIGN, true, &HandleTicketUnAssignCommand<BugTicket>, "" },
+ { "view", rbac::RBAC_PERM_COMMAND_TICKET_BUG_VIEW, true, &HandleTicketGetByIdCommand<BugTicket>, "" },
};
- static ChatCommand ticketComplaintCommandTable[] =
+ static std::vector<ChatCommand> ticketComplaintCommandTable =
{
- { "assign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_ASSIGN, true, &HandleTicketAssignToCommand<ComplaintTicket>, "", NULL },
- { "close", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSE, true, &HandleTicketCloseByIdCommand<ComplaintTicket>, "", NULL },
- { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSEDLIST, true, &HandleTicketListClosedCommand<ComplaintTicket>, "", NULL },
- { "comment", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_COMMENT, true, &HandleTicketCommentCommand<ComplaintTicket>, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_DELETE, true, &HandleTicketDeleteByIdCommand<ComplaintTicket>, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_LIST, true, &HandleTicketListCommand<ComplaintTicket>, "", NULL },
- { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_UNASSIGN, true, &HandleTicketUnAssignCommand<ComplaintTicket>, "", NULL },
- { "view", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_VIEW, true, &HandleTicketGetByIdCommand<ComplaintTicket>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "assign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_ASSIGN, true, &HandleTicketAssignToCommand<ComplaintTicket>, "" },
+ { "close", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSE, true, &HandleTicketCloseByIdCommand<ComplaintTicket>, "" },
+ { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_CLOSEDLIST, true, &HandleTicketListClosedCommand<ComplaintTicket>, "" },
+ { "comment", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_COMMENT, true, &HandleTicketCommentCommand<ComplaintTicket>, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_DELETE, true, &HandleTicketDeleteByIdCommand<ComplaintTicket>, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_LIST, true, &HandleTicketListCommand<ComplaintTicket>, "" },
+ { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_UNASSIGN, true, &HandleTicketUnAssignCommand<ComplaintTicket>, "" },
+ { "view", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT_VIEW, true, &HandleTicketGetByIdCommand<ComplaintTicket>, "" },
};
- static ChatCommand ticketSuggestionCommandTable[] =
+ static std::vector<ChatCommand> ticketSuggestionCommandTable =
{
- { "assign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_ASSIGN, true, &HandleTicketAssignToCommand<SuggestionTicket>, "", NULL },
- { "close", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSE, true, &HandleTicketCloseByIdCommand<SuggestionTicket>, "", NULL },
- { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSEDLIST, true, &HandleTicketListClosedCommand<SuggestionTicket>, "", NULL },
- { "comment", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_COMMENT, true, &HandleTicketCommentCommand<SuggestionTicket>, "", NULL },
- { "delete", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_DELETE, true, &HandleTicketDeleteByIdCommand<SuggestionTicket>, "", NULL },
- { "list", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_LIST, true, &HandleTicketListCommand<SuggestionTicket>, "", NULL },
- { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_UNASSIGN, true, &HandleTicketUnAssignCommand<SuggestionTicket>, "", NULL },
- { "view", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_VIEW, true, &HandleTicketGetByIdCommand<SuggestionTicket>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "assign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_ASSIGN, true, &HandleTicketAssignToCommand<SuggestionTicket>, "" },
+ { "close", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSE, true, &HandleTicketCloseByIdCommand<SuggestionTicket>, "" },
+ { "closedlist", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_CLOSEDLIST, true, &HandleTicketListClosedCommand<SuggestionTicket>, "" },
+ { "comment", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_COMMENT, true, &HandleTicketCommentCommand<SuggestionTicket>, "" },
+ { "delete", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_DELETE, true, &HandleTicketDeleteByIdCommand<SuggestionTicket>, "" },
+ { "list", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_LIST, true, &HandleTicketListCommand<SuggestionTicket>, "" },
+ { "unassign", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_UNASSIGN, true, &HandleTicketUnAssignCommand<SuggestionTicket>, "" },
+ { "view", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION_VIEW, true, &HandleTicketGetByIdCommand<SuggestionTicket>, "" },
};
- static ChatCommand ticketResetCommandTable[] =
+ static std::vector<ChatCommand> ticketResetCommandTable =
{
- { "all", rbac::RBAC_PERM_COMMAND_TICKET_RESET_ALL, true, &HandleTicketResetAllCommand, "", NULL },
- { "bug", rbac::RBAC_PERM_COMMAND_TICKET_RESET_BUG, true, &HandleTicketResetCommand<BugTicket>, "", NULL },
- { "complaint", rbac::RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT, true, &HandleTicketResetCommand<ComplaintTicket>, "", NULL },
- { "suggestion", rbac::RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION, true, &HandleTicketResetCommand<SuggestionTicket>, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "all", rbac::RBAC_PERM_COMMAND_TICKET_RESET_ALL, true, &HandleTicketResetAllCommand, "" },
+ { "bug", rbac::RBAC_PERM_COMMAND_TICKET_RESET_BUG, true, &HandleTicketResetCommand<BugTicket>, "" },
+ { "complaint", rbac::RBAC_PERM_COMMAND_TICKET_RESET_COMPLAINT, true, &HandleTicketResetCommand<ComplaintTicket>, "" },
+ { "suggestion", rbac::RBAC_PERM_COMMAND_TICKET_RESET_SUGGESTION, true, &HandleTicketResetCommand<SuggestionTicket>, "" },
};
- static ChatCommand ticketCommandTable[] =
+ static std::vector<ChatCommand> ticketCommandTable =
{
{ "bug", rbac::RBAC_PERM_COMMAND_TICKET_BUG, true, NULL, "", ticketBugCommandTable },
{ "complaint", rbac::RBAC_PERM_COMMAND_TICKET_COMPLAINT, true, NULL, "", ticketComplaintCommandTable },
{ "reset", rbac::RBAC_PERM_COMMAND_TICKET_RESET, true, NULL, "", ticketResetCommandTable },
{ "suggestion", rbac::RBAC_PERM_COMMAND_TICKET_SUGGESTION, true, NULL, "", ticketSuggestionCommandTable },
- { "togglesystem", rbac::RBAC_PERM_COMMAND_TICKET_TOGGLESYSTEM, true, &HandleToggleGMTicketSystem, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "togglesystem", rbac::RBAC_PERM_COMMAND_TICKET_TOGGLESYSTEM, true, &HandleToggleGMTicketSystem, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "ticket", rbac::RBAC_PERM_COMMAND_TICKET, false, NULL, "", ticketCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_titles.cpp b/src/server/scripts/Commands/cs_titles.cpp
index 74df7266e57..f2303311b03 100644
--- a/src/server/scripts/Commands/cs_titles.cpp
+++ b/src/server/scripts/Commands/cs_titles.cpp
@@ -33,25 +33,22 @@ class titles_commandscript : public CommandScript
public:
titles_commandscript() : CommandScript("titles_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand titlesSetCommandTable[] =
+ static std::vector<ChatCommand> titlesSetCommandTable =
{
- { "mask", rbac::RBAC_PERM_COMMAND_TITLES_SET_MASK, false, &HandleTitlesSetMaskCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "mask", rbac::RBAC_PERM_COMMAND_TITLES_SET_MASK, false, &HandleTitlesSetMaskCommand, "" },
};
- static ChatCommand titlesCommandTable[] =
+ static std::vector<ChatCommand> titlesCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_TITLES_ADD, false, &HandleTitlesAddCommand, "", NULL },
- { "current", rbac::RBAC_PERM_COMMAND_TITLES_CURRENT, false, &HandleTitlesCurrentCommand, "", NULL },
- { "remove", rbac::RBAC_PERM_COMMAND_TITLES_REMOVE, false, &HandleTitlesRemoveCommand, "", NULL },
+ { "add", rbac::RBAC_PERM_COMMAND_TITLES_ADD, false, &HandleTitlesAddCommand, "" },
+ { "current", rbac::RBAC_PERM_COMMAND_TITLES_CURRENT, false, &HandleTitlesCurrentCommand, "" },
+ { "remove", rbac::RBAC_PERM_COMMAND_TITLES_REMOVE, false, &HandleTitlesRemoveCommand, "" },
{ "set", rbac::RBAC_PERM_COMMAND_TITLES_SET, false, NULL, "", titlesSetCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "titles", rbac::RBAC_PERM_COMMAND_TITLES, false, NULL, "", titlesCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp
index 358b6fff085..5c4776fe7ec 100644
--- a/src/server/scripts/Commands/cs_wp.cpp
+++ b/src/server/scripts/Commands/cs_wp.cpp
@@ -34,23 +34,21 @@ class wp_commandscript : public CommandScript
public:
wp_commandscript() : CommandScript("wp_commandscript") { }
- ChatCommand* GetCommands() const override
+ std::vector<ChatCommand> GetCommands() const override
{
- static ChatCommand wpCommandTable[] =
+ static std::vector<ChatCommand> wpCommandTable =
{
- { "add", rbac::RBAC_PERM_COMMAND_WP_ADD, false, &HandleWpAddCommand, "", NULL },
- { "event", rbac::RBAC_PERM_COMMAND_WP_EVENT, false, &HandleWpEventCommand, "", NULL },
- { "load", rbac::RBAC_PERM_COMMAND_WP_LOAD, false, &HandleWpLoadCommand, "", NULL },
- { "modify", rbac::RBAC_PERM_COMMAND_WP_MODIFY, false, &HandleWpModifyCommand, "", NULL },
- { "unload", rbac::RBAC_PERM_COMMAND_WP_UNLOAD, false, &HandleWpUnLoadCommand, "", NULL },
- { "reload", rbac::RBAC_PERM_COMMAND_WP_RELOAD, false, &HandleWpReloadCommand, "", NULL },
- { "show", rbac::RBAC_PERM_COMMAND_WP_SHOW, false, &HandleWpShowCommand, "", NULL },
- { NULL, 0, false, NULL, "", NULL }
+ { "add", rbac::RBAC_PERM_COMMAND_WP_ADD, false, &HandleWpAddCommand, "" },
+ { "event", rbac::RBAC_PERM_COMMAND_WP_EVENT, false, &HandleWpEventCommand, "" },
+ { "load", rbac::RBAC_PERM_COMMAND_WP_LOAD, false, &HandleWpLoadCommand, "" },
+ { "modify", rbac::RBAC_PERM_COMMAND_WP_MODIFY, false, &HandleWpModifyCommand, "" },
+ { "unload", rbac::RBAC_PERM_COMMAND_WP_UNLOAD, false, &HandleWpUnLoadCommand, "" },
+ { "reload", rbac::RBAC_PERM_COMMAND_WP_RELOAD, false, &HandleWpReloadCommand, "" },
+ { "show", rbac::RBAC_PERM_COMMAND_WP_SHOW, false, &HandleWpShowCommand, "" },
};
- static ChatCommand commandTable[] =
+ static std::vector<ChatCommand> commandTable =
{
{ "wp", rbac::RBAC_PERM_COMMAND_WP, false, NULL, "", wpCommandTable },
- { NULL, 0, false, NULL, "", NULL }
};
return commandTable;
}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
deleted file mode 100644
index c2261785782..00000000000
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2008-2015 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 "ScriptMgr.h"
-#include "ScriptedCreature.h"
-
-enum Spells
-{
- SPELL_SHADOWBOLT = 17228,
- SPELL_CURSEOFTONGUES = 15470,
- SPELL_CURSEOFWEAKNESS = 17227,
- SPELL_DEMONARMOR = 11735,
- SPELL_ENVELOPINGWEB = 15471
-};
-
-enum Events
-{
- EVENT_SHADOWBOLT = 1,
- EVENT_CURSE_OF_TONGUES = 2,
- EVENT_CURSE_OF_WEAKNESS = 3,
- EVENT_DEMON_ARMOR = 4,
- EVENT_ENVELOPING_WEB = 5
-};
-
-class boss_anubshiah : public CreatureScript
-{
- public:
- boss_anubshiah() : CreatureScript("boss_anubshiah") { }
-
- struct boss_anubshiahAI : public ScriptedAI
- {
- boss_anubshiahAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- _events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- _events.ScheduleEvent(EVENT_SHADOWBOLT, 7000);
- _events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 24000);
- _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 12000);
- _events.ScheduleEvent(EVENT_DEMON_ARMOR, 3000);
- _events.ScheduleEvent(EVENT_ENVELOPING_WEB, 16000);
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_SHADOWBOLT:
- DoCast(me, SPELL_SHADOWBOLT);
- _events.ScheduleEvent(EVENT_SHADOWBOLT, 7000);
- break;
- case EVENT_CURSE_OF_TONGUES:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_CURSEOFTONGUES);
- _events.ScheduleEvent(EVENT_CURSE_OF_TONGUES, 18000);
- break;
- case EVENT_CURSE_OF_WEAKNESS:
- DoCastVictim(SPELL_CURSEOFWEAKNESS);
- _events.ScheduleEvent(EVENT_CURSE_OF_WEAKNESS, 45000);
- break;
- case EVENT_DEMON_ARMOR:
- DoCast(me, SPELL_DEMONARMOR);
- _events.ScheduleEvent(EVENT_DEMON_ARMOR, 300000);
- break;
- case EVENT_ENVELOPING_WEB:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_ENVELOPINGWEB);
- _events.ScheduleEvent(EVENT_ENVELOPING_WEB, 12000);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_anubshiahAI(creature);
- }
-};
-
-void AddSC_boss_anubshiah()
-{
- new boss_anubshiah();
-}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
deleted file mode 100644
index 83702ffb16d..00000000000
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2008-2015 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 "ScriptMgr.h"
-#include "ScriptedCreature.h"
-
-enum Spells
-{
- SPELL_WHIRLWIND = 15589,
- SPELL_MORTALSTRIKE = 24573
-};
-
-enum Events
-{
- EVENT_WHIRLWIND = 1,
- EVENT_MORTALSTRIKE = 2
-};
-
-class boss_gorosh_the_dervish : public CreatureScript
-{
- public:
- boss_gorosh_the_dervish() : CreatureScript("boss_gorosh_the_dervish") { }
-
- struct boss_gorosh_the_dervishAI : public ScriptedAI
- {
- boss_gorosh_the_dervishAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- _events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- _events.ScheduleEvent(EVENT_WHIRLWIND, 12000);
- _events.ScheduleEvent(EVENT_MORTALSTRIKE, 22000);
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_WHIRLWIND:
- DoCast(me, SPELL_WHIRLWIND);
- _events.ScheduleEvent(EVENT_WHIRLWIND, 15000);
- break;
- case EVENT_MORTALSTRIKE:
- DoCastVictim(SPELL_MORTALSTRIKE);
- _events.ScheduleEvent(EVENT_MORTALSTRIKE, 15000);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_gorosh_the_dervishAI(creature);
- }
-};
-
-void AddSC_boss_gorosh_the_dervish()
-{
- new boss_gorosh_the_dervish();
-}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
deleted file mode 100644
index 44dbbe3f4c2..00000000000
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2008-2015 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 "ScriptMgr.h"
-#include "ScriptedCreature.h"
-
-enum Grizzle
-{
- SPELL_GROUNDTREMOR = 6524,
- SPELL_FRENZY = 28371,
- EMOTE_FRENZY_KILL = 0
-};
-
-enum Events
-{
- EVENT_GROUNDTREMOR = 1,
- EVENT_FRENZY = 2
-};
-
-enum Phases
-{
- PHASE_ONE = 1,
- PHASE_TWO = 2
-};
-
-class boss_grizzle : public CreatureScript
-{
- public:
- boss_grizzle() : CreatureScript("boss_grizzle") { }
-
- struct boss_grizzleAI : public ScriptedAI
- {
- boss_grizzleAI(Creature* creature) : ScriptedAI(creature) { }
-
- void Reset() override
- {
- _events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- _events.SetPhase(PHASE_ONE);
- _events.ScheduleEvent(EVENT_GROUNDTREMOR, 12000);
- }
-
- void DamageTaken(Unit* /*attacker*/, uint32& damage) override
- {
- if (me->HealthBelowPctDamaged(50, damage) && _events.IsInPhase(PHASE_ONE))
- {
- _events.SetPhase(PHASE_TWO);
- _events.ScheduleEvent(EVENT_FRENZY, 0, 0, PHASE_TWO);
- }
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
-
- _events.Update(diff);
-
- while (uint32 eventId = _events.ExecuteEvent())
- {
- switch (eventId)
- {
- case EVENT_GROUNDTREMOR:
- DoCastVictim(SPELL_GROUNDTREMOR);
- _events.ScheduleEvent(EVENT_GROUNDTREMOR, 8000);
- break;
- case EVENT_FRENZY:
- DoCast(me, SPELL_FRENZY);
- Talk(EMOTE_FRENZY_KILL);
- _events.ScheduleEvent(EVENT_FRENZY, 15000, 0, PHASE_TWO);
- break;
- default:
- break;
- }
- }
-
- DoMeleeAttackIfReady();
- }
-
- private:
- EventMap _events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new boss_grizzleAI(creature);
- }
-};
-
-void AddSC_boss_grizzle()
-{
- new boss_grizzle();
-}
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h
index c79a57d0746..12798833a3f 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/blackwing_lair.h
@@ -25,14 +25,18 @@ uint32 const EncounterCount = 8;
enum BWLEncounter
{
- BOSS_RAZORGORE = 0,
- BOSS_VAELASTRAZ = 1,
- BOSS_BROODLORD = 2,
- BOSS_FIREMAW = 3,
- BOSS_EBONROC = 4,
- BOSS_FLAMEGOR = 5,
- BOSS_CHROMAGGUS = 6,
- BOSS_NEFARIAN = 7
+ // Encounter States/Boss GUIDs
+ DATA_RAZORGORE_THE_UNTAMED = 0,
+ DATA_VAELASTRAZ_THE_CORRUPT = 1,
+ DATA_BROODLORD_LASHLAYER = 2,
+ DATA_FIREMAW = 3,
+ DATA_EBONROC = 4,
+ DATA_FLAMEGOR = 5,
+ DATA_CHROMAGGUS = 6,
+ DATA_NEFARIAN = 7,
+
+ // Additional Data
+ DATA_LORD_VICTOR_NEFARIUS = 8
};
enum CreatureIds
@@ -44,7 +48,7 @@ enum CreatureIds
NPC_BLACKWING_WARLOCK = 12459,
NPC_VAELASTRAZ = 13020,
NPC_BROODLORD = 12017,
- NPC_FIRENAW = 11983,
+ NPC_FIREMAW = 11983,
NPC_EBONROC = 14601,
NPC_FLAMEGOR = 11981,
NPC_CHROMAGGUS = 14020,
@@ -52,17 +56,14 @@ enum CreatureIds
NPC_NEFARIAN = 11583
};
-enum BWLData64
+enum GameObjectIds
{
- DATA_RAZORGORE_THE_UNTAMED = 1,
- DATA_VAELASTRAZ_THE_CORRUPT,
- DATA_BROODLORD_LASHLAYER,
- DATA_FIRENAW,
- DATA_EBONROC,
- DATA_FLAMEGOR,
- DATA_CHROMAGGUS,
- DATA_LORD_VICTOR_NEFARIUS,
- DATA_NEFARIAN
+ GO_BLACK_DRAGON_EGG = 177807,
+ GO_BOSSGATE01 = 175946,
+ GO_DRAKE_RIDER_PORTCULLIS = 175185,
+ GO_ALTERAC_VALLEY_GATE = 180424,
+ GO_GATE = 185483,
+ GO_VACCUUM_EXIT_GATE = 181125
};
enum BWLEvents
@@ -79,4 +80,4 @@ enum BWLMisc
DATA_EGG_EVENT
};
-#endif \ No newline at end of file
+#endif
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp
index 2609cf5fdf8..5ba933005ec 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_broodlord_lashlayer.cpp
@@ -50,16 +50,10 @@ public:
struct boss_broodlordAI : public BossAI
{
- boss_broodlordAI(Creature* creature) : BossAI(creature, BOSS_BROODLORD) { }
+ boss_broodlordAI(Creature* creature) : BossAI(creature, DATA_BROODLORD_LASHLAYER) { }
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_VAELASTRAZ) != DONE)
- {
- EnterEvadeMode();
- return;
- }
-
_EnterCombat();
Talk(SAY_AGGRO);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
index 61d6c052cdf..9a49b96e68e 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_chromaggus.cpp
@@ -71,7 +71,7 @@ public:
struct boss_chromaggusAI : public BossAI
{
- boss_chromaggusAI(Creature* creature) : BossAI(creature, BOSS_CHROMAGGUS)
+ boss_chromaggusAI(Creature* creature) : BossAI(creature, DATA_CHROMAGGUS)
{
Initialize();
@@ -193,11 +193,6 @@ public:
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_FLAMEGOR) != DONE)
- {
- EnterEvadeMode();
- return;
- }
_EnterCombat();
events.ScheduleEvent(EVENT_SHIMMER, 0);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
index 8bd3ae0ebce..7a7e30f7913 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_ebonroc.cpp
@@ -41,15 +41,10 @@ public:
struct boss_ebonrocAI : public BossAI
{
- boss_ebonrocAI(Creature* creature) : BossAI(creature, BOSS_EBONROC) { }
+ boss_ebonrocAI(Creature* creature) : BossAI(creature, DATA_EBONROC) { }
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_BROODLORD) != DONE)
- {
- EnterEvadeMode();
- return;
- }
_EnterCombat();
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
index e41153796e5..3dcdbfe01df 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_firemaw.cpp
@@ -41,15 +41,10 @@ public:
struct boss_firemawAI : public BossAI
{
- boss_firemawAI(Creature* creature) : BossAI(creature, BOSS_FIREMAW) { }
+ boss_firemawAI(Creature* creature) : BossAI(creature, DATA_FIREMAW) { }
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_BROODLORD) != DONE)
- {
- EnterEvadeMode();
- return;
- }
_EnterCombat();
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
index 011c695b61f..20e69211da2 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_flamegor.cpp
@@ -46,15 +46,10 @@ public:
struct boss_flamegorAI : public BossAI
{
- boss_flamegorAI(Creature* creature) : BossAI(creature, BOSS_FLAMEGOR) { }
+ boss_flamegorAI(Creature* creature) : BossAI(creature, DATA_FLAMEGOR) { }
void EnterCombat(Unit* /*who*/) override
{
- if (instance->GetBossState(BOSS_BROODLORD) != DONE)
- {
- EnterEvadeMode();
- return;
- }
_EnterCombat();
events.ScheduleEvent(EVENT_SHADOWFLAME, urand(10000, 20000));
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
index 94d8c2f9c2e..cbb1447c261 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp
@@ -166,7 +166,7 @@ public:
struct boss_victor_nefariusAI : public BossAI
{
- boss_victor_nefariusAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN)
+ boss_victor_nefariusAI(Creature* creature) : BossAI(creature, DATA_NEFARIAN)
{
Initialize();
}
@@ -393,7 +393,7 @@ public:
struct boss_nefarianAI : public BossAI
{
- boss_nefarianAI(Creature* creature) : BossAI(creature, BOSS_NEFARIAN)
+ boss_nefarianAI(Creature* creature) : BossAI(creature, DATA_NEFARIAN)
{
Initialize();
}
@@ -457,7 +457,7 @@ public:
{
if (canDespawn && DespawnTimer <= diff)
{
- instance->SetBossState(BOSS_NEFARIAN, FAIL);
+ instance->SetBossState(DATA_NEFARIAN, FAIL);
std::list<Creature*> constructList;
me->GetCreatureListWithEntryInGrid(constructList, NPC_BONE_CONSTRUCT, 500.0f);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
index 8d660fc17d1..1d66964ce6b 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_razorgore.cpp
@@ -68,7 +68,7 @@ public:
struct boss_razorgoreAI : public BossAI
{
- boss_razorgoreAI(Creature* creature) : BossAI(creature, BOSS_RAZORGORE)
+ boss_razorgoreAI(Creature* creature) : BossAI(creature, DATA_RAZORGORE_THE_UNTAMED)
{
Initialize();
}
@@ -175,7 +175,7 @@ public:
{
if (InstanceScript* instance = go->GetInstanceScript())
if (instance->GetData(DATA_EGG_EVENT) != DONE)
- if (Creature* razor = ObjectAccessor::GetCreature(*go, instance->GetGuidData(DATA_RAZORGORE_THE_UNTAMED)))
+ if (Creature* razor = instance->GetCreature(DATA_RAZORGORE_THE_UNTAMED))
{
razor->Attack(player, true);
player->CastSpell(razor, SPELL_MINDCONTROL);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
index 827cc34d1a9..cb1306c3ea8 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_vaelastrasz.cpp
@@ -68,7 +68,7 @@ public:
struct boss_vaelAI : public BossAI
{
- boss_vaelAI(Creature* creature) : BossAI(creature, BOSS_VAELASTRAZ)
+ boss_vaelAI(Creature* creature) : BossAI(creature, DATA_VAELASTRAZ_THE_CORRUPT)
{
Initialize();
creature->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
index b8843afef98..9ba255991c0 100644
--- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
+++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp
@@ -15,23 +15,36 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "ScriptMgr.h"
+#include "Player.h"
#include "ScriptedCreature.h"
-#include "PassiveAI.h"
+#include "ScriptMgr.h"
#include "blackwing_lair.h"
-#include "Player.h"
-/*
-Blackwing Lair Encounter:
-1 - boss_razorgore.cpp
-2 - boss_vaelastrasz.cpp
-3 - boss_broodlord_lashlayer.cpp
-4 - boss_firemaw.cpp
-5 - boss_ebonroc.cpp
-6 - boss_flamegor.cpp
-7 - boss_chromaggus.cpp
-8 - boss_nefarian.cpp
-*/
+DoorData const doorData[] =
+{
+ { GO_BOSSGATE01, DATA_RAZORGORE_THE_UNTAMED, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_DRAKE_RIDER_PORTCULLIS, DATA_VAELASTRAZ_THE_CORRUPT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_ALTERAC_VALLEY_GATE, DATA_BROODLORD_LASHLAYER, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_GATE, DATA_FIREMAW, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_GATE, DATA_EBONROC, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_GATE, DATA_FLAMEGOR, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_VACCUUM_EXIT_GATE, DATA_CHROMAGGUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
+};
+
+ObjectData const creatureData[] =
+{
+ { NPC_RAZORGORE, DATA_RAZORGORE_THE_UNTAMED },
+ { NPC_VAELASTRAZ, DATA_VAELASTRAZ_THE_CORRUPT },
+ { NPC_BROODLORD, DATA_BROODLORD_LASHLAYER },
+ { NPC_FIREMAW, DATA_FIREMAW },
+ { NPC_EBONROC, DATA_EBONROC },
+ { NPC_FLAMEGOR, DATA_FLAMEGOR },
+ { NPC_CHROMAGGUS, DATA_CHROMAGGUS },
+ { NPC_NEFARIAN, DATA_NEFARIAN },
+ { NPC_VICTOR_NEFARIUS, DATA_LORD_VICTOR_NEFARIUS },
+ { 0, 0 } // END
+};
Position const SummonPosition[8] =
{
@@ -57,92 +70,84 @@ public:
instance_blackwing_lair_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
+ LoadObjectData(creatureData, nullptr);
+
// Razorgore
EggCount = 0;
EggEvent = 0;
- SetBossNumber(EncounterCount);
}
void OnCreatureCreate(Creature* creature) override
{
+ InstanceScript::OnCreatureCreate(creature);
+
switch (creature->GetEntry())
{
- case NPC_RAZORGORE:
- RazorgoreTheUntamedGUID = creature->GetGUID();
- break;
case NPC_BLACKWING_DRAGON:
case NPC_BLACKWING_TASKMASTER:
case NPC_BLACKWING_LEGIONAIRE:
case NPC_BLACKWING_WARLOCK:
- if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
+ if (Creature* razor = GetCreature(DATA_RAZORGORE_THE_UNTAMED))
razor->AI()->JustSummoned(creature);
break;
- case NPC_VAELASTRAZ:
- VaelastraszTheCorruptGUID = creature->GetGUID();
- break;
- case NPC_BROODLORD:
- BroodlordLashlayerGUID = creature->GetGUID();
- break;
- case NPC_FIRENAW:
- FiremawGUID = creature->GetGUID();
- break;
- case NPC_EBONROC:
- EbonrocGUID = creature->GetGUID();
- break;
- case NPC_FLAMEGOR:
- FlamegorGUID = creature->GetGUID();
- break;
- case NPC_CHROMAGGUS:
- ChromaggusGUID = creature->GetGUID();
- break;
- case NPC_VICTOR_NEFARIUS:
- LordVictorNefariusGUID = creature->GetGUID();
- break;
- case NPC_NEFARIAN:
- NefarianGUID = creature->GetGUID();
+ default:
break;
}
}
void OnGameObjectCreate(GameObject* go) override
{
- switch (go->GetEntry())
+ InstanceScript::OnGameObjectCreate(go);
+
+ if (go->GetEntry() == GO_BLACK_DRAGON_EGG)
{
- case 177807: // Egg
- if (GetBossState(BOSS_FIREMAW) == DONE)
- go->SetLootState(GO_JUST_DEACTIVATED);
- else
- EggList.push_back(go->GetGUID());
- break;
- case 175946: // Door
- RazorgoreDoorGUID = go->GetGUID();
- HandleGameObject(ObjectGuid::Empty, GetBossState(BOSS_RAZORGORE) == DONE, go);
- break;
- case 175185: // Door
- VaelastraszDoorGUID = go->GetGUID();
- HandleGameObject(ObjectGuid::Empty, GetBossState(BOSS_VAELASTRAZ) == DONE, go);
- break;
- case 180424: // Door
- BroodlordDoorGUID = go->GetGUID();
- HandleGameObject(ObjectGuid::Empty, GetBossState(BOSS_BROODLORD) == DONE, go);
- break;
- case 185483: // Door
- ChrommagusDoorGUID = go->GetGUID();
- HandleGameObject(ObjectGuid::Empty, GetBossState(BOSS_FIREMAW) == DONE && GetBossState(BOSS_EBONROC) == DONE && GetBossState(BOSS_FLAMEGOR) == DONE, go);
- break;
- case 181125: // Door
- NefarianDoorGUID = go->GetGUID();
- HandleGameObject(ObjectGuid::Empty, GetBossState(BOSS_CHROMAGGUS) == DONE, go);
- break;
+ if (GetBossState(DATA_FIREMAW) == DONE)
+ go->SetPhaseMask(2, true);
+ else
+ EggList.push_back(go->GetGUID());
}
}
void OnGameObjectRemove(GameObject* go) override
{
- if (go->GetEntry() == 177807) // Egg
+ InstanceScript::OnGameObjectRemove(go);
+
+ if (go->GetEntry() == GO_BLACK_DRAGON_EGG)
EggList.remove(go->GetGUID());
}
+ bool CheckRequiredBosses(uint32 bossId, Player const* player /*= nullptr*/) const override
+ {
+ if (_SkipCheckRequiredBosses(player))
+ return true;
+
+ switch (bossId)
+ {
+ case DATA_BROODLORD_LASHLAYER:
+ if (GetBossState(DATA_VAELASTRAZ_THE_CORRUPT) != DONE)
+ return false;
+ break;
+ case DATA_FIREMAW:
+ case DATA_EBONROC:
+ case DATA_FLAMEGOR:
+ if (GetBossState(DATA_BROODLORD_LASHLAYER) != DONE)
+ return false;
+ break;
+ case DATA_CHROMAGGUS:
+ if (GetBossState(DATA_FIREMAW) != DONE
+ || GetBossState(DATA_EBONROC) != DONE
+ || GetBossState(DATA_FLAMEGOR) != DONE)
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ return true;
+ }
+
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
@@ -150,40 +155,25 @@ public:
switch (type)
{
- case BOSS_RAZORGORE:
- HandleGameObject(RazorgoreDoorGUID, state == DONE);
+ case DATA_RAZORGORE_THE_UNTAMED:
if (state == DONE)
{
for (GuidList::const_iterator itr = EggList.begin(); itr != EggList.end(); ++itr)
- if (GameObject* egg = instance->GetGameObject((*itr)))
+ if (GameObject* egg = instance->GetGameObject(*itr))
egg->SetLootState(GO_JUST_DEACTIVATED);
}
SetData(DATA_EGG_EVENT, NOT_STARTED);
break;
- case BOSS_VAELASTRAZ:
- HandleGameObject(VaelastraszDoorGUID, state == DONE);
- break;
- case BOSS_BROODLORD:
- HandleGameObject(BroodlordDoorGUID, state == DONE);
- break;
- case BOSS_FIREMAW:
- case BOSS_EBONROC:
- case BOSS_FLAMEGOR:
- HandleGameObject(ChrommagusDoorGUID, GetBossState(BOSS_FIREMAW) == DONE && GetBossState(BOSS_EBONROC) == DONE && GetBossState(BOSS_FLAMEGOR) == DONE);
- break;
- case BOSS_CHROMAGGUS:
- HandleGameObject(NefarianDoorGUID, state == DONE);
- break;
- case BOSS_NEFARIAN:
+ case DATA_NEFARIAN:
switch (state)
{
case NOT_STARTED:
- if (Creature* nefarian = instance->GetCreature(NefarianGUID))
+ if (Creature* nefarian = GetCreature(DATA_NEFARIAN))
nefarian->DespawnOrUnsummon();
break;
case FAIL:
- _events.ScheduleEvent(EVENT_RESPAWN_NEFARIUS, 15*IN_MILLISECONDS*MINUTE);
- SetBossState(BOSS_NEFARIAN, NOT_STARTED);
+ _events.ScheduleEvent(EVENT_RESPAWN_NEFARIUS, 15 * IN_MILLISECONDS * MINUTE);
+ SetBossState(DATA_NEFARIAN, NOT_STARTED);
break;
default:
break;
@@ -193,24 +183,6 @@ public:
return true;
}
- ObjectGuid GetGuidData(uint32 id) const override
- {
- switch (id)
- {
- case DATA_RAZORGORE_THE_UNTAMED: return RazorgoreTheUntamedGUID;
- case DATA_VAELASTRAZ_THE_CORRUPT: return VaelastraszTheCorruptGUID;
- case DATA_BROODLORD_LASHLAYER: return BroodlordLashlayerGUID;
- case DATA_FIRENAW: return FiremawGUID;
- case DATA_EBONROC: return EbonrocGUID;
- case DATA_FLAMEGOR: return FlamegorGUID;
- case DATA_CHROMAGGUS: return ChromaggusGUID;
- case DATA_LORD_VICTOR_NEFARIUS: return LordVictorNefariusGUID;
- case DATA_NEFARIAN: return NefarianGUID;
- }
-
- return ObjectGuid::Empty;
- }
-
void SetData(uint32 type, uint32 data) override
{
if (type == DATA_EGG_EVENT)
@@ -218,7 +190,7 @@ public:
switch (data)
{
case IN_PROGRESS:
- _events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45*IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_RAZOR_SPAWN, 45 * IN_MILLISECONDS);
EggEvent = data;
EggCount = 0;
break;
@@ -230,13 +202,13 @@ public:
case SPECIAL:
if (++EggCount == 15)
{
- if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
+ if (Creature* razor = GetCreature(DATA_RAZORGORE_THE_UNTAMED))
{
SetData(DATA_EGG_EVENT, DONE);
razor->RemoveAurasDueToSpell(42013); // MindControl
DoRemoveAurasDueToSpellOnPlayers(42013);
}
- _events.ScheduleEvent(EVENT_RAZOR_PHASE_TWO, IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_RAZOR_PHASE_TWO, 1 * IN_MILLISECONDS);
_events.CancelEvent(EVENT_RAZOR_SPAWN);
}
if (EggEvent == NOT_STARTED)
@@ -249,8 +221,8 @@ public:
void OnUnitDeath(Unit* unit) override
{
//! HACK, needed because of buggy CreatureAI after charm
- if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(BOSS_RAZORGORE) != DONE)
- SetBossState(BOSS_RAZORGORE, DONE);
+ if (unit->GetEntry() == NPC_RAZORGORE && GetBossState(DATA_RAZORGORE_THE_UNTAMED) != DONE)
+ SetBossState(DATA_RAZORGORE_THE_UNTAMED, DONE);
}
void Update(uint32 diff) override
@@ -268,15 +240,15 @@ public:
for (uint8 i = urand(2, 5); i > 0 ; --i)
if (Creature* summon = instance->SummonCreature(Entry[urand(0, 4)], SummonPosition[urand(0, 7)]))
summon->SetInCombatWithZone();
- _events.ScheduleEvent(EVENT_RAZOR_SPAWN, urand(12, 17)*IN_MILLISECONDS);
+ _events.ScheduleEvent(EVENT_RAZOR_SPAWN, urand(12, 17) * IN_MILLISECONDS);
break;
case EVENT_RAZOR_PHASE_TWO:
_events.CancelEvent(EVENT_RAZOR_SPAWN);
- if (Creature* razor = instance->GetCreature(RazorgoreTheUntamedGUID))
+ if (Creature* razor = GetCreature(DATA_RAZORGORE_THE_UNTAMED))
razor->AI()->DoAction(ACTION_PHASE_TWO);
break;
case EVENT_RESPAWN_NEFARIUS:
- if (Creature* nefarius = instance->GetCreature(LordVictorNefariusGUID))
+ if (Creature* nefarius = GetCreature(DATA_LORD_VICTOR_NEFARIUS))
{
nefarius->SetPhaseMask(1, true);
nefarius->setActive(true);
@@ -291,34 +263,11 @@ public:
protected:
// Misc
EventMap _events;
+
// Razorgore
uint8 EggCount;
uint32 EggEvent;
- ObjectGuid RazorgoreTheUntamedGUID;
- ObjectGuid RazorgoreDoorGUID;
GuidList EggList;
-
- // Vaelastrasz the Corrupt
- ObjectGuid VaelastraszTheCorruptGUID;
- ObjectGuid VaelastraszDoorGUID;
-
- // Broodlord Lashlayer
- ObjectGuid BroodlordLashlayerGUID;
- ObjectGuid BroodlordDoorGUID;
-
- // 3 Dragons
- ObjectGuid FiremawGUID;
- ObjectGuid EbonrocGUID;
- ObjectGuid FlamegorGUID;
- ObjectGuid ChrommagusDoorGUID;
-
- // Chormaggus
- ObjectGuid ChromaggusGUID;
- ObjectGuid NefarianDoorGUID;
-
- // Nefarian
- ObjectGuid LordVictorNefariusGUID;
- ObjectGuid NefarianGUID;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt
index 754f0173c97..f3ba8f8d470 100644
--- a/src/server/scripts/EasternKingdoms/CMakeLists.txt
+++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt
@@ -29,12 +29,9 @@ set(scripts_STAT_SRCS
EasternKingdoms/BlackrockMountain/BlackrockCaverns/instance_blackrock_caverns.cpp
EasternKingdoms/BlackrockMountain/BlackrockCaverns/blackrock_caverns.h
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_high_interrogator_gerstahn.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_gorosh_the_dervish.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/blackrock_depths.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_anubshiah.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_tomb_of_seven.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_general_angerforge.cpp
- EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_grizzle.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_ambassador_flamelash.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/instance_blackrock_depths.cpp
EasternKingdoms/BlackrockMountain/BlackrockDepths/boss_moira_bronzebeard.cpp
diff --git a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
index 87dadd44dd7..c1470d3bc47 100644
--- a/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
+++ b/src/server/scripts/EasternKingdoms/Gnomeregan/gnomeregan.cpp
@@ -361,7 +361,7 @@ public:
}
}
- void UpdateEscortAI(const uint32 uiDiff) override
+ void UpdateEscortAI(uint32 uiDiff) override
{
if (uiPhase)
{
diff --git a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
index 9b290852dc2..44d48e3f0bb 100644
--- a/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
+++ b/src/server/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -93,11 +93,6 @@ class npc_unworthy_initiate : public CreatureScript
public:
npc_unworthy_initiate() : CreatureScript("npc_unworthy_initiate") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_unworthy_initiateAI(creature);
- }
-
struct npc_unworthy_initiateAI : public ScriptedAI
{
npc_unworthy_initiateAI(Creature* creature) : ScriptedAI(creature)
@@ -156,7 +151,7 @@ public:
me->CastSpell(me, SPELL_DK_INITIATE_VISUAL, true);
if (Player* starter = ObjectAccessor::GetPlayer(*me, playerGUID))
- sCreatureTextMgr->SendChat(me, SAY_EVENT_ATTACK, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, starter);
+ Talk(SAY_EVENT_ATTACK, starter);
phase = PHASE_TO_ATTACK;
}
@@ -286,6 +281,11 @@ public:
}
}
};
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_unworthy_initiateAI(creature);
+ }
};
class npc_unworthy_initiate_anchor : public CreatureScript
@@ -460,6 +460,7 @@ enum Spells_DKI
//SPELL_DUEL_TRIGGERED = 52990,
SPELL_DUEL_VICTORY = 52994,
SPELL_DUEL_FLAG = 52991,
+ SPELL_GROVEL = 7267,
};
enum Says_VBM
@@ -497,8 +498,6 @@ public:
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15);
- sCreatureTextMgr->SendChat(creature, SAY_DUEL, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, player);
-
player->CastSpell(creature, SPELL_DUEL, false);
player->CastSpell(player, SPELL_DUEL_FLAG, true);
}
@@ -521,11 +520,6 @@ public:
return true;
}
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_death_knight_initiateAI(creature);
- }
-
struct npc_death_knight_initiateAI : public CombatAI
{
npc_death_knight_initiateAI(Creature* creature) : CombatAI(creature)
@@ -560,6 +554,7 @@ public:
if (!m_bIsDuelInProgress && pSpell->Id == SPELL_DUEL)
{
m_uiDuelerGUID = pCaster->GetGUID();
+ Talk(SAY_DUEL, pCaster);
m_bIsDuelInProgress = true;
}
}
@@ -580,7 +575,7 @@ public:
pDoneBy->AttackStop();
me->CastSpell(pDoneBy, SPELL_DUEL_VICTORY, true);
lose = true;
- me->CastSpell(me, 7267, true);
+ me->CastSpell(me, SPELL_GROVEL, true);
me->RestoreFaction();
}
}
@@ -610,13 +605,13 @@ public:
{
if (lose)
{
- if (!me->HasAura(7267))
+ if (!me->HasAura(SPELL_GROVEL))
EnterEvadeMode();
return;
}
else if (me->GetVictim() && me->EnsureVictim()->GetTypeId() == TYPEID_PLAYER && me->EnsureVictim()->HealthBelowPct(10))
{
- me->EnsureVictim()->CastSpell(me->GetVictim(), 7267, true); // beg
+ me->EnsureVictim()->CastSpell(me->GetVictim(), SPELL_GROVEL, true); // beg
me->EnsureVictim()->RemoveGameObject(SPELL_DUEL_FLAG, true);
EnterEvadeMode();
return;
@@ -629,6 +624,10 @@ public:
}
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_death_knight_initiateAI(creature);
+ }
};
/*######
@@ -732,13 +731,19 @@ class npc_dark_rider_of_acherus : public CreatureScript
## npc_salanar_the_horseman
######*/
-enum Spells_Salanar
+enum SalanarTheHorseman
{
- SPELL_REALM_OF_SHADOWS = 52693,
+ GOSSIP_SALANAR_MENU = 9739,
+ GOSSIP_SALANAR_OPTION = 0,
+ SALANAR_SAY = 0,
+ QUEST_INTO_REALM_OF_SHADOWS = 12687,
+ NPC_DARK_RIDER_OF_ACHERUS = 28654,
+ NPC_SALANAR_IN_REALM_OF_SHADOWS = 28788,
SPELL_EFFECT_STOLEN_HORSE = 52263,
SPELL_DELIVER_STOLEN_HORSE = 52264,
SPELL_CALL_DARK_RIDER = 52266,
- SPELL_EFFECT_OVERTAKE = 52349
+ SPELL_EFFECT_OVERTAKE = 52349,
+ SPELL_REALM_OF_SHADOWS = 52693
};
class npc_salanar_the_horseman : public CreatureScript
@@ -746,15 +751,19 @@ class npc_salanar_the_horseman : public CreatureScript
public:
npc_salanar_the_horseman() : CreatureScript("npc_salanar_the_horseman") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_salanar_the_horsemanAI(creature);
- }
-
struct npc_salanar_the_horsemanAI : public ScriptedAI
{
npc_salanar_the_horsemanAI(Creature* creature) : ScriptedAI(creature) { }
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == GOSSIP_SALANAR_MENU && gossipListId == GOSSIP_SALANAR_OPTION)
+ {
+ player->CastSpell(player, SPELL_REALM_OF_SHADOWS, true);
+ player->PlayerTalkClass->SendCloseGossip();
+ }
+ }
+
void SpellHit(Unit* caster, const SpellInfo* spell) override
{
if (spell->Id == SPELL_DELIVER_STOLEN_HORSE)
@@ -769,7 +778,7 @@ public:
caster->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
caster->setFaction(35);
DoCast(caster, SPELL_CALL_DARK_RIDER, true);
- if (Creature* Dark_Rider = me->FindNearestCreature(28654, 15))
+ if (Creature* Dark_Rider = me->FindNearestCreature(NPC_DARK_RIDER_OF_ACHERUS, 15))
ENSURE_AI(npc_dark_rider_of_acherus::npc_dark_rider_of_acherusAI, Dark_Rider->AI())->InitDespawnHorse(caster);
}
}
@@ -787,10 +796,11 @@ public:
{
if (Player* player = charmer->ToPlayer())
{
- // for quest Into the Realm of Shadows(12687)
- if (me->GetEntry() == 28788 && player->GetQuestStatus(12687) == QUEST_STATUS_INCOMPLETE)
+ // for quest Into the Realm of Shadows(QUEST_INTO_REALM_OF_SHADOWS)
+ if (me->GetEntry() == NPC_SALANAR_IN_REALM_OF_SHADOWS && player->GetQuestStatus(QUEST_INTO_REALM_OF_SHADOWS) == QUEST_STATUS_INCOMPLETE)
{
- player->GroupEventHappens(12687, me);
+ player->GroupEventHappens(QUEST_INTO_REALM_OF_SHADOWS, me);
+ Talk(SALANAR_SAY);
charmer->RemoveAurasDueToSpell(SPELL_EFFECT_OVERTAKE);
if (Creature* creature = who->ToCreature())
{
@@ -799,14 +809,17 @@ public:
}
}
- if (player->HasAura(SPELL_REALM_OF_SHADOWS))
- player->RemoveAurasDueToSpell(SPELL_REALM_OF_SHADOWS);
+ player->RemoveAurasDueToSpell(SPELL_REALM_OF_SHADOWS);
}
}
}
}
};
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_salanar_the_horsemanAI(creature);
+ }
};
/*######
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
index 15280bc7848..29002460b2a 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp
@@ -41,14 +41,17 @@ enum Says
enum Spells
{
- SPELL_GROUND_TREMOR = 6524,
- SPELL_ARCHAEDAS_AWAKEN = 10347,
- SPELL_BOSS_OBJECT_VISUAL = 11206,
- SPELL_BOSS_AGGRO = 10340,
- SPELL_SUB_BOSS_AGGRO = 11568,
- SPELL_AWAKEN_VAULT_WALKER = 10258,
- SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252,
- SPELL_SELF_DESTRUCT = 9874
+ SPELL_GROUND_TREMOR = 6524,
+ SPELL_ARCHAEDAS_AWAKEN = 10347,
+ SPELL_BOSS_OBJECT_VISUAL = 11206,
+ SPELL_BOSS_AGGRO = 10340,
+ SPELL_SUB_BOSS_AGGRO = 11568,
+ SPELL_AWAKEN_VAULT_WALKER = 10258,
+ SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252,
+ SPELL_SELF_DESTRUCT = 9874,
+ SPELL_FREEZE_ANIM = 16245,
+ SPELL_MINION_FREEZE_ANIM = 10255
+
};
class boss_archaedas : public CreatureScript
@@ -96,6 +99,7 @@ class boss_archaedas : public CreatureScript
me->setFaction(35);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ me->AddAura(SPELL_FREEZE_ANIM, me);
}
void ActivateMinion(ObjectGuid uiGuid, bool flag)
@@ -109,6 +113,7 @@ class boss_archaedas : public CreatureScript
minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
minion->setFaction(14);
+ minion->RemoveAura(SPELL_MINION_FREEZE_ANIM);
}
}
@@ -258,6 +263,7 @@ class npc_archaedas_minions : public CreatureScript
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAuras();
+ me->AddAura(SPELL_MINION_FREEZE_ANIM, me);
}
void EnterCombat(Unit* /*who*/) override
@@ -297,7 +303,7 @@ class npc_archaedas_minions : public CreatureScript
{
bWakingUp = false;
bAmIAwake = true;
- // AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID
+ AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID
return; // dont want to continue until we finish the AttackStart method
}
@@ -346,6 +352,7 @@ class npc_stonekeepers : public CreatureScript
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
me->RemoveAllAuras();
+ me->AddAura(SPELL_MINION_FREEZE_ANIM, me);
}
void EnterCombat(Unit* /*who*/) override
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp
index de899c04e1a..7f0faa138ec 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp
@@ -28,10 +28,9 @@ EndScriptData */
enum Ironaya
{
- SAY_AGGRO = 0,
SPELL_ARCINGSMASH = 8374,
SPELL_KNOCKAWAY = 10101,
- SPELL_WSTOMP = 11876,
+ SPELL_WSTOMP = 11876
};
class boss_ironaya : public CreatureScript
@@ -66,10 +65,7 @@ class boss_ironaya : public CreatureScript
Initialize();
}
- void EnterCombat(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
- }
+ void EnterCombat(Unit* /*who*/) override { }
void UpdateAI(uint32 uiDiff) override
{
diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
index 9d33d41af62..ee198356359 100644
--- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
+++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp
@@ -18,7 +18,7 @@
/* ScriptData
SDName: instance_uldaman
-SD%Complete: 99
+SD%Complete: 80%
SDComment: Need some cosmetics updates when archeadas door are closing (Guardians Waypoints).
SDCategory: Uldaman
EndScriptData */
@@ -26,11 +26,14 @@ EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "uldaman.h"
+#include "CreatureAI.h"
enum Spells
{
SPELL_ARCHAEDAS_AWAKEN = 10347,
SPELL_AWAKEN_VAULT_WALKER = 10258,
+ SPELL_FREEZE_ANIM = 16245,
+ SPELL_MINION_FREEZE_ANIM = 10255
};
enum Events
@@ -38,6 +41,13 @@ enum Events
EVENT_SUB_BOSS_AGGRO = 2228
};
+enum IronayaTalk
+{
+ SAY_AGGRO = 0
+};
+
+const Position IronayaPoint = { -231.228f, 246.6135f, -49.01617f, 0.0f };
+
class instance_uldaman : public InstanceMapScript
{
public:
@@ -136,9 +146,9 @@ class instance_uldaman : public InstanceMapScript
{
creature->setFaction(35);
creature->RemoveAllAuras();
- //creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_ANIMATION_FROZEN);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ creature->AddAura(SPELL_MINION_FREEZE_ANIM, creature);
}
void SetDoor(ObjectGuid guid, bool open)
@@ -171,6 +181,8 @@ class instance_uldaman : public InstanceMapScript
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
target->setFaction(14);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
+
return; // only want the first one we find
}
// if we get this far than all four are dead so open the door
@@ -190,11 +202,13 @@ class instance_uldaman : public InstanceMapScript
Creature* target = instance->GetCreature(*i);
if (!target || !target->IsAlive() || target->getFaction() == 14)
continue;
- archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
- target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
target->setFaction(14);
+ target->RemoveAura(SPELL_MINION_FREEZE_ANIM);
+ archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true);
+ target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true);
+
return; // only want the first one we find
}
}
@@ -241,6 +255,7 @@ class instance_uldaman : public InstanceMapScript
if (ObjectAccessor::GetUnit(*archaedas, target))
{
+ archaedas->RemoveAura(SPELL_FREEZE_ANIM);
archaedas->CastSpell(archaedas, SPELL_ARCHAEDAS_AWAKEN, false);
whoWokeuiArchaedasGUID = target;
}
@@ -255,6 +270,12 @@ class instance_uldaman : public InstanceMapScript
ironaya->setFaction(415);
ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+
+ ironaya->GetMotionMaster()->Clear();
+ ironaya->GetMotionMaster()->MovePoint(0, IronayaPoint);
+ ironaya->SetHomePosition(IronayaPoint);
+
+ ironaya->AI()->Talk(SAY_AGGRO);
}
void RespawnMinions()
diff --git a/src/server/scripts/Kalimdor/zone_the_barrens.cpp b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
index 1c9d5cf2c62..978fc6d96fc 100644
--- a/src/server/scripts/Kalimdor/zone_the_barrens.cpp
+++ b/src/server/scripts/Kalimdor/zone_the_barrens.cpp
@@ -607,7 +607,7 @@ public:
summoned->AI()->AttackStart(me);
}
- void UpdateEscortAI(const uint32 Diff) override
+ void UpdateEscortAI(uint32 Diff) override
{
if (!UpdateVictim())
{
diff --git a/src/server/scripts/Kalimdor/zone_winterspring.cpp b/src/server/scripts/Kalimdor/zone_winterspring.cpp
index b287e5e9a91..067f36afad6 100644
--- a/src/server/scripts/Kalimdor/zone_winterspring.cpp
+++ b/src/server/scripts/Kalimdor/zone_winterspring.cpp
@@ -568,7 +568,7 @@ public:
}
- void UpdateEscortAI(const uint32 diff) override
+ void UpdateEscortAI(uint32 diff) override
{
DialogueUpdate(diff);
diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
index eb6230fabfc..eb004505bab 100644
--- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
+++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp
@@ -263,7 +263,7 @@ class npc_onyx_flamecaller : public CreatureScript
}
}
- void UpdateEscortAI(uint32 const diff) override
+ void UpdateEscortAI(uint32 diff) override
{
if (!UpdateVictim())
return;
diff --git a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
index 5111247b84c..4438c4ab199 100644
--- a/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
+++ b/src/server/scripts/Northrend/Gundrak/instance_gundrak.cpp
@@ -18,7 +18,6 @@
#include "InstanceScript.h"
#include "Player.h"
#include "ScriptMgr.h"
-#include "WorldSession.h"
#include "gundrak.h"
#include "EventMap.h"
@@ -191,7 +190,7 @@ class instance_gundrak : public InstanceMapScript
bool CheckRequiredBosses(uint32 bossId, Player const* player = nullptr) const override
{
- if (player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))
+ if (_SkipCheckRequiredBosses(player))
return true;
switch (bossId)
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 c832efabbe7..6a7c6a1fd5c 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
@@ -203,7 +203,7 @@ class boss_blood_queen_lana_thel : public CreatureScript
{
instance->SetData(DATA_BLOOD_QUICKENING_STATE, DONE);
if (Player* player = killer->ToPlayer())
- player->RewardPlayerAndGroupAtEvent(NPC_INFILTRATOR_MINCHAR_BQ, player);
+ player->RewardPlayerAndGroupAtEvent(Is25ManRaid() ? NPC_INFILTRATOR_MINCHAR_BQ_25 : NPC_INFILTRATOR_MINCHAR_BQ, player);
if (Creature* minchar = me->FindNearestCreature(NPC_INFILTRATOR_MINCHAR_BQ, 200.0f))
{
minchar->SetUInt32Value(UNIT_NPC_EMOTESTATE, 0);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
index 943be27943d..365e0a1588d 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_deathbringer_saurfang.cpp
@@ -203,6 +203,9 @@ enum Misc
{
DATA_MADE_A_MESS = 45374613, // 4537, 4613 are achievement IDs
FACTION_SCOURGE = 974,
+
+ GOSSIP_MENU_MURADIN_BRONZEBEARD = 10934,
+ GOSSIP_MENU_HIGH_OVERLORD_SAURFANG = 10952
};
enum MovePoints
@@ -634,6 +637,15 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
_events.Reset();
}
+ void sGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
+ {
+ if (menuId == GOSSIP_MENU_HIGH_OVERLORD_SAURFANG)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ DoAction(ACTION_START_EVENT);
+ }
+ }
+
void DoAction(int32 action) override
{
switch (action)
@@ -798,28 +810,6 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
std::list<Creature*> _guardList;
};
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE)
- {
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "We are ready to go, High Overlord. The Lich King must fall!", 631, -ACTION_START_EVENT);
- player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
- }
-
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- player->CLOSE_GOSSIP_MENU();
- if (action == -ACTION_START_EVENT)
- creature->AI()->DoAction(ACTION_START_EVENT);
-
- return true;
- }
-
CreatureAI* GetAI(Creature* creature) const override
{
return GetIcecrownCitadelAI<npc_high_overlord_saurfangAI>(creature);
@@ -843,6 +833,15 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
_events.Reset();
}
+ void sGossipSelect(Player* player, uint32 menuId, uint32 /*gossipListId*/) override
+ {
+ if (menuId == GOSSIP_MENU_MURADIN_BRONZEBEARD)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ DoAction(ACTION_START_EVENT);
+ }
+ }
+
void DoAction(int32 action) override
{
switch (action)
@@ -946,28 +945,6 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
std::list<Creature*> _guardList;
};
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetBossState(DATA_DEATHBRINGER_SAURFANG) != DONE)
- {
- player->ADD_GOSSIP_ITEM(0, "Let it begin...", 631, -ACTION_START_EVENT + 1);
- player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
- }
-
- return true;
- }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- player->CLOSE_GOSSIP_MENU();
- if (action == -ACTION_START_EVENT + 1)
- creature->AI()->DoAction(ACTION_START_EVENT);
-
- return true;
- }
-
CreatureAI* GetAI(Creature* creature) const override
{
return GetIcecrownCitadelAI<npc_muradin_bronzebeard_iccAI>(creature);
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
index c04d53079c5..97ad45542d0 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp
@@ -309,7 +309,7 @@ class boss_valithria_dreamwalker : public CreatureScript
{
me->SetHealth(_spawnHealth);
me->SetReactState(REACT_PASSIVE);
- me->LoadCreaturesAddon(true);
+ me->LoadCreaturesAddon();
// immune to percent heals
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_OBS_MOD_HEALTH, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL_PCT, true);
@@ -1072,7 +1072,7 @@ class npc_dream_cloud : public CreatureScript
_events.Reset();
_events.ScheduleEvent(EVENT_CHECK_PLAYER, 1000);
me->SetCorpseDelay(0); // remove corpse immediately
- me->LoadCreaturesAddon(true);
+ me->LoadCreaturesAddon();
}
void UpdateAI(uint32 diff) override
@@ -1336,7 +1336,7 @@ class spell_dreamwalker_summon_dream_portal : public SpellScriptLoader
if (!GetHitUnit())
return;
- uint32 spellId = RAND<uint32>(71301, 72220, 72223, 72225);
+ uint32 spellId = RAND(71301, 72220, 72223, 72225);
GetHitUnit()->CastSpell(GetHitUnit(), spellId, true);
}
@@ -1367,7 +1367,7 @@ class spell_dreamwalker_summon_nightmare_portal : public SpellScriptLoader
if (!GetHitUnit())
return;
- uint32 spellId = RAND<uint32>(71977, 72481, 72482, 72483);
+ uint32 spellId = RAND(71977, 72481, 72482, 72483);
GetHitUnit()->CastSpell(GetHitUnit(), spellId, true);
}
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index 30b797bf98d..8676b6c0506 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1140,7 +1140,7 @@ class npc_crok_scourgebane : public CreatureScript
}
}
- void UpdateEscortAI(uint32 const diff) override
+ void UpdateEscortAI(uint32 diff) override
{
if (_wipeCheckTimer <= diff)
_wipeCheckTimer = 0;
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
index 091190b6b4e..e739f5a5036 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.h
@@ -155,6 +155,7 @@ enum CreaturesIds
NPC_ALCHEMIST_ADRIANNA = 38501,
NPC_ALRIN_THE_AGILE = 38551,
NPC_INFILTRATOR_MINCHAR_BQ = 38558,
+ NPC_INFILTRATOR_MINCHAR_BQ_25 = 39123,
NPC_MINCHAR_BEAM_STALKER = 38557,
NPC_VALITHRIA_DREAMWALKER_QUEST = 38589,
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
index d38d630f775..555ed40e805 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp
@@ -17,7 +17,6 @@
#include "AccountMgr.h"
#include "InstanceScript.h"
-#include "Map.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "PoolMgr.h"
@@ -26,7 +25,6 @@
#include "Transport.h"
#include "TransportMgr.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "icecrown_citadel.h"
enum EventIds
@@ -1118,7 +1116,7 @@ class instance_icecrown_citadel : public InstanceMapScript
bool CheckRequiredBosses(uint32 bossId, Player const* player = nullptr) const override
{
- if (player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))
+ if (_SkipCheckRequiredBosses(player))
return true;
switch (bossId)
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
index 28d181a990e..998d519c7fe 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_anubrekhan.cpp
@@ -17,39 +17,61 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "Player.h"
#include "naxxramas.h"
-enum Says
+enum AnubSays
{
SAY_AGGRO = 0,
SAY_GREET = 1,
- SAY_SLAY = 2
+ SAY_SLAY = 2,
+
+ EMOTE_LOCUST = 3
};
-Position const GuardSummonPos = {3333.72f, -3476.30f, 287.1f, 6.2801f};
+enum GuardSays
+{
+ EMOTE_FRENZY = 0,
+ EMOTE_SPAWN = 1,
+ EMOTE_SCARAB = 2
+};
enum Events
{
- EVENT_IMPALE = 1,
- EVENT_LOCUST,
- EVENT_SPAWN_GUARDIAN_NORMAL,
- EVENT_BERSERK
+ EVENT_IMPALE = 1, // Cast Impale on a random target
+ EVENT_LOCUST, // Begin channeling Locust Swarm
+ EVENT_LOCUST_ENDS, // Locust swarm dissipates
+ EVENT_SPAWN_GUARD, // 10-man only - crypt guard has delayed spawn; also used for the locust swarm crypt guard in both modes
+ EVENT_SCARABS, // spawn corpse scarabs
+ EVENT_BERSERK // Berserk
};
enum Spells
{
- SPELL_IMPALE = 28783,
- SPELL_LOCUST_SWARM = 28785,
+ SPELL_IMPALE = 28783, // 25-man: 56090
+ SPELL_LOCUST_SWARM = 28785, // 25-man: 54021
SPELL_SUMMON_CORPSE_SCARABS_PLR = 29105, // This spawns 5 corpse scarabs on top of player
SPELL_SUMMON_CORPSE_SCARABS_MOB = 28864, // This spawns 10 corpse scarabs on top of dead guards
SPELL_BERSERK = 27680
};
+enum SpawnGroups
+{
+ GROUP_INITIAL_25M = 1,
+ GROUP_SINGLE_SPAWN = 2
+};
+
enum Misc
{
ACHIEV_TIMED_START_EVENT = 9891
};
+enum Phases
+{
+ PHASE_NORMAL = 1,
+ PHASE_SWARM
+};
+
class boss_anubrekhan : public CreatureScript
{
public:
@@ -62,46 +84,64 @@ public:
struct boss_anubrekhanAI : public BossAI
{
- boss_anubrekhanAI(Creature* creature) : BossAI(creature, BOSS_ANUBREKHAN)
+ boss_anubrekhanAI(Creature* creature) : BossAI(creature, BOSS_ANUBREKHAN) { }
+
+ void SummonGuards()
{
- Initialize();
+ if (Is25ManRaid())
+ me->SummonCreatureGroup(GROUP_INITIAL_25M);
}
- void Initialize()
+ void InitializeAI() override
{
- hasTaunted = false;
+ if (!me->isDead())
+ {
+ Reset();
+ SummonGuards();
+ }
}
- bool hasTaunted;
-
void Reset() override
{
_Reset();
+ guardCorpses.clear();
+ }
- Initialize();
+ void JustReachedHome() override
+ {
+ _JustReachedHome();
+ SummonGuards();
+ }
- if (GetDifficulty() == DIFFICULTY_25_N)
- {
- Position pos;
+ void JustSummoned(Creature* summon) override
+ {
+ BossAI::JustSummoned(summon);
+
+ if (me->IsInCombat())
+ if (summon->GetEntry() == NPC_CRYPT_GUARD)
+ summon->AI()->Talk(EMOTE_SPAWN, me);
+ }
- // respawn guard using home position,
- // otherwise, after a wipe, they respawn where boss was at wipe moment.
- pos = me->GetHomePosition();
- pos.m_positionY -= 10.0f;
- me->SummonCreature(NPC_CRYPT_GUARD, pos, TEMPSUMMON_CORPSE_DESPAWN);
+ void SummonedCreatureDies(Creature* summon, Unit* killer) override
+ {
+ BossAI::SummonedCreatureDies(summon, killer);
- pos = me->GetHomePosition();
- pos.m_positionY += 10.0f;
- me->SummonCreature(NPC_CRYPT_GUARD, pos, TEMPSUMMON_CORPSE_DESPAWN);
- }
+ if (summon->GetEntry() == NPC_CRYPT_GUARD)
+ guardCorpses.insert(summon->GetGUID());
+ }
+
+ void SummonedCreatureDespawn(Creature* summon) override
+ {
+ BossAI::SummonedCreatureDespawn(summon);
+
+ if (summon->GetEntry() == NPC_CRYPT_GUARD)
+ guardCorpses.erase(summon->GetGUID());
}
void KilledUnit(Unit* victim) override
{
- /// Force the player to spawn corpse scarabs via spell, @todo Check percent chance for scarabs, 20% at the moment
- if (!(rand32() % 5))
- if (victim->GetTypeId() == TYPEID_PLAYER)
- victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCARABS_PLR, true, NULL, NULL, me->GetGUID());
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ victim->CastSpell(victim, SPELL_SUMMON_CORPSE_SCARABS_PLR, true, nullptr, nullptr, me->GetGUID());
Talk(SAY_SLAY);
}
@@ -113,37 +153,22 @@ public:
// start achievement timer (kill Maexna within 20 min)
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_TIMED_START_EVENT);
}
+
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_IMPALE, urand(10000, 20000));
- events.ScheduleEvent(EVENT_LOCUST, 90000);
- events.ScheduleEvent(EVENT_BERSERK, 600000);
-
- if (GetDifficulty() == DIFFICULTY_10_N)
- events.ScheduleEvent(EVENT_SPAWN_GUARDIAN_NORMAL, urand(15000, 20000));
- }
- void MoveInLineOfSight(Unit* who) override
- {
- if (!hasTaunted && me->IsWithinDistInMap(who, 60.0f) && who->GetTypeId() == TYPEID_PLAYER)
- {
- Talk(SAY_GREET);
- hasTaunted = true;
- }
- ScriptedAI::MoveInLineOfSight(who);
- }
-
- void SummonedCreatureDespawn(Creature* summon) override
- {
- BossAI::SummonedCreatureDespawn(summon);
-
- // check if it is an actual killed guard
- if (!me->IsAlive() || summon->IsAlive() || summon->GetEntry() != NPC_CRYPT_GUARD)
- return;
+ summons.DoZoneInCombat();
+
+ events.SetPhase(PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_LOCUST, urand(80,120) * IN_MILLISECONDS, 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_BERSERK, 10 * MINUTE * IN_MILLISECONDS);
- summon->CastSpell(summon, SPELL_SUMMON_CORPSE_SCARABS_MOB, true, NULL, NULL, me->GetGUID());
+ if (!Is25ManRaid())
+ events.ScheduleEvent(EVENT_SPAWN_GUARD, urand(15, 20) * IN_MILLISECONDS);
}
void UpdateAI(uint32 diff) override
@@ -158,22 +183,43 @@ public:
switch (eventId)
{
case EVENT_IMPALE:
- //Cast Impale on a random target
- //Do NOT cast it when we are afflicted by locust swarm
- if (!me->HasAura(SPELL_LOCUST_SWARM))
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_IMPALE);
- events.ScheduleEvent(EVENT_IMPALE, urand(10000, 20000));
+ if (events.GetTimeUntilEvent(EVENT_LOCUST) < 5 * IN_MILLISECONDS) break; // don't chain impale tank -> locust swarm
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ DoCast(target, SPELL_IMPALE);
+ else
+ EnterEvadeMode();
+
+ events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ break;
+ case EVENT_SCARABS:
+ events.ScheduleEvent(EVENT_SCARABS, urand(40 * IN_MILLISECONDS, 60 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+
+ if (!guardCorpses.empty())
+ {
+ if (Creature* creatureTarget = ObjectAccessor::GetCreature(*me, Trinity::Containers::SelectRandomContainerElement(guardCorpses)))
+ {
+ creatureTarget->CastSpell(creatureTarget, SPELL_SUMMON_CORPSE_SCARABS_MOB, true, nullptr, nullptr, me->GetGUID());
+ creatureTarget->AI()->Talk(EMOTE_SCARAB);
+ creatureTarget->DespawnOrUnsummon();
+ }
+ }
break;
case EVENT_LOCUST:
- /// @todo Add Text
+ Talk(EMOTE_LOCUST);
DoCast(me, SPELL_LOCUST_SWARM);
- DoSummon(NPC_CRYPT_GUARD, GuardSummonPos, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ events.ScheduleEvent(EVENT_SPAWN_GUARD, 3 * IN_MILLISECONDS);
+
+ events.ScheduleEvent(EVENT_LOCUST_ENDS, RAID_MODE(19, 23) * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_LOCUST, 90000);
+ events.SetPhase(PHASE_SWARM);
+ break;
+ case EVENT_LOCUST_ENDS:
+ events.ScheduleEvent(EVENT_IMPALE, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ events.ScheduleEvent(EVENT_SCARABS, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS), 0, PHASE_NORMAL);
+ events.SetPhase(PHASE_NORMAL);
break;
- case EVENT_SPAWN_GUARDIAN_NORMAL:
- /// @todo Add Text
- DoSummon(NPC_CRYPT_GUARD, GuardSummonPos, 0, TEMPSUMMON_CORPSE_DESPAWN);
+ case EVENT_SPAWN_GUARD:
+ me->SummonCreatureGroup(GROUP_SINGLE_SPAWN);
break;
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
@@ -182,13 +228,37 @@ public:
}
}
- DoMeleeAttackIfReady();
+ if (events.IsInPhase(PHASE_NORMAL))
+ DoMeleeAttackIfReady();
}
+ private:
+ GuidSet guardCorpses;
};
};
+class at_anubrekhan_entrance : public AreaTriggerScript
+{
+ public:
+ at_anubrekhan_entrance() : AreaTriggerScript("at_anubrekhan_entrance") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/, bool /*entered*/) override
+ {
+ InstanceScript* instance = player->GetInstanceScript();
+ if (!instance || instance->GetData(DATA_HAD_ANUBREKHAN_GREET) || instance->GetBossState(BOSS_ANUBREKHAN) != NOT_STARTED)
+ return true;
+
+ if (Creature* anub = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_ANUBREKHAN)))
+ anub->AI()->Talk(SAY_GREET);
+ instance->SetData(DATA_HAD_ANUBREKHAN_GREET, 1u);
+
+ return true;
+ }
+};
+
void AddSC_boss_anubrekhan()
{
new boss_anubrekhan();
+
+ new at_anubrekhan_entrance();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
index a90b72b6842..78720964518 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_faerlina.cpp
@@ -18,14 +18,20 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "naxxramas.h"
+#include "Player.h"
+#include "SpellAuras.h"
#include "SpellInfo.h"
enum Yells
{
- SAY_GREET = 0,
- SAY_AGGRO = 1,
- SAY_SLAY = 2,
- SAY_DEATH = 3
+ SAY_GREET = 0,
+ SAY_AGGRO = 1,
+ SAY_SLAY = 2,
+ SAY_DEATH = 3,
+
+ EMOTE_WIDOW_EMBRACE = 4,
+ EMOTE_FRENZY = 5
+
};
enum Spells
@@ -33,7 +39,9 @@ enum Spells
SPELL_POISON_BOLT_VOLLEY = 28796,
SPELL_RAIN_OF_FIRE = 28794,
SPELL_FRENZY = 28798,
- SPELL_WIDOWS_EMBRACE = 28732
+ SPELL_WIDOWS_EMBRACE = 28732,
+
+ SPELL_ADD_FIREBALL = 54095 // 25-man: 54096
};
#define SPELL_WIDOWS_EMBRACE_HELPER RAID_MODE<uint32>(28732, 54097)
@@ -45,6 +53,12 @@ enum Events
EVENT_FRENZY = 3
};
+enum SummonGroups
+{
+ SUMMON_GROUP_WORSHIPPERS = 1,
+ SUMMON_GROUP_FOLLOWERS = 2
+};
+
enum Misc
{
DATA_FRENZY_DISPELS = 1
@@ -57,39 +71,46 @@ class boss_faerlina : public CreatureScript
struct boss_faerlinaAI : public BossAI
{
- boss_faerlinaAI(Creature* creature) : BossAI(creature, BOSS_FAERLINA),
- _frenzyDispels(0), _introDone(false), _delayFrenzy(false)
+ boss_faerlinaAI(Creature* creature) : BossAI(creature, BOSS_FAERLINA), _frenzyDispels(0) { }
+
+ void SummonAdds()
{
+ me->SummonCreatureGroup(SUMMON_GROUP_WORSHIPPERS);
+ if (Is25ManRaid())
+ me->SummonCreatureGroup(SUMMON_GROUP_FOLLOWERS);
}
+ void InitializeAI() override
+ {
+ if (!me->isDead())
+ {
+ Reset();
+ SummonAdds();
+ }
+ }
+
+ void JustReachedHome() override
+ {
+ _JustReachedHome();
+ SummonAdds();
+ }
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
Talk(SAY_AGGRO);
- events.ScheduleEvent(EVENT_POISON, urand(10000, 15000));
- events.ScheduleEvent(EVENT_FIRE, urand(6000, 18000));
- events.ScheduleEvent(EVENT_FRENZY, urand(60000, 80000));
+ summons.DoZoneInCombat();
+ events.ScheduleEvent(EVENT_POISON, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FIRE, urand(6 * IN_MILLISECONDS, 18 * IN_MILLISECONDS));
+ events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS));
}
void Reset() override
{
_Reset();
- _delayFrenzy = false;
_frenzyDispels = 0;
}
- void MoveInLineOfSight(Unit* who) override
- {
- if (!_introDone && who->GetTypeId() == TYPEID_PLAYER)
- {
- Talk(SAY_GREET);
- _introDone = true;
- }
-
- BossAI::MoveInLineOfSight(who);
- }
-
void KilledUnit(Unit* /*victim*/) override
{
if (!urand(0, 2))
@@ -106,9 +127,8 @@ class boss_faerlina : public CreatureScript
{
if (spell->Id == SPELL_WIDOWS_EMBRACE_HELPER)
{
- /// @todo Add Text
++_frenzyDispels;
- _delayFrenzy = true;
+ Talk(EMOTE_WIDOW_EMBRACE, caster);
me->Kill(caster);
}
}
@@ -126,12 +146,6 @@ class boss_faerlina : public CreatureScript
if (!UpdateVictim())
return;
- if (_delayFrenzy && !me->HasAura(SPELL_WIDOWS_EMBRACE_HELPER))
- {
- _delayFrenzy = false;
- DoCast(me, SPELL_FRENZY, true);
- }
-
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
@@ -152,13 +166,14 @@ class boss_faerlina : public CreatureScript
events.ScheduleEvent(EVENT_FIRE, urand(6000, 18000));
break;
case EVENT_FRENZY:
- /// @todo Add Text
- if (!me->HasAura(SPELL_WIDOWS_EMBRACE_HELPER))
- DoCast(me, SPELL_FRENZY);
+ if (Aura* widowsEmbrace = me->GetAura(SPELL_WIDOWS_EMBRACE_HELPER))
+ events.ScheduleEvent(EVENT_FRENZY, widowsEmbrace->GetDuration()+1 * IN_MILLISECONDS);
else
- _delayFrenzy = true;
-
- events.ScheduleEvent(EVENT_FRENZY, urand(60000, 80000));
+ {
+ DoCast(SPELL_FRENZY);
+ Talk(EMOTE_FRENZY);
+ events.ScheduleEvent(EVENT_FRENZY, urand(60 * IN_MILLISECONDS, 80 * IN_MILLISECONDS));
+ }
break;
}
}
@@ -168,8 +183,6 @@ class boss_faerlina : public CreatureScript
private:
uint32 _frenzyDispels;
- bool _introDone;
- bool _delayFrenzy;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -192,19 +205,36 @@ class npc_faerlina_add : public CreatureScript
void Reset() override
{
- if (GetDifficulty() == DIFFICULTY_10_N) {
+ if (!Is25ManRaid()) {
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_BIND, true);
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true);
}
}
+ void EnterCombat(Unit* /*who*/) override
+ {
+ if (Creature* faerlina = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FAERLINA)))
+ faerlina->AI()->DoZoneInCombat(nullptr, 250.0f);
+ }
+
void JustDied(Unit* /*killer*/) override
{
- if (_instance && GetDifficulty() == DIFFICULTY_10_N)
+ if (!Is25ManRaid())
if (Creature* faerlina = ObjectAccessor::GetCreature(*me, _instance->GetGuidData(DATA_FAERLINA)))
DoCast(faerlina, SPELL_WIDOWS_EMBRACE);
}
+ void UpdateAI(uint32 /*diff*/) override
+ {
+ if (!UpdateVictim())
+ return;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
+
+ DoCastVictim(SPELL_ADD_FIREBALL);
+ DoMeleeAttackIfReady(); // this will only happen if the fireball cast fails for some reason
+ }
+
private:
InstanceScript* const _instance;
};
@@ -226,9 +256,29 @@ class achievement_momma_said_knock_you_out : public AchievementCriteriaScript
}
};
+class at_faerlina_entrance : public AreaTriggerScript
+{
+ public:
+ at_faerlina_entrance() : AreaTriggerScript("at_faerlina_entrance") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*areaTrigger*/, bool /*entered*/) override
+ {
+ InstanceScript* instance = player->GetInstanceScript();
+ if (!instance || instance->GetData(DATA_HAD_FAERLINA_GREET) || instance->GetBossState(BOSS_FAERLINA) != NOT_STARTED)
+ return true;
+
+ if (Creature* faerlina = ObjectAccessor::GetCreature(*player, instance->GetGuidData(DATA_FAERLINA)))
+ faerlina->AI()->Talk(SAY_GREET);
+ instance->SetData(DATA_HAD_FAERLINA_GREET, 1u);
+
+ return true;
+ }
+};
+
void AddSC_boss_faerlina()
{
new boss_faerlina();
new npc_faerlina_add();
+ new at_faerlina_entrance();
new achievement_momma_said_knock_you_out();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
index 3d7c128c8dd..5248c48029c 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_heigan.cpp
@@ -21,36 +21,42 @@
#include "naxxramas.h"
#include "Player.h"
-enum Heigan
+enum Spells
{
- SPELL_DECREPIT_FEVER = 29998, // 25-man: 55011
- SPELL_SPELL_DISRUPTION = 29310,
- SPELL_PLAGUE_CLOUD = 29350,
-
- SAY_AGGRO = 0,
- SAY_SLAY = 1,
- SAY_TAUNT = 2,
- SAY_DEATH = 3
+ SPELL_DECREPIT_FEVER = 29998, // 25-man: 55011
+ SPELL_SPELL_DISRUPTION = 29310,
+ SPELL_PLAGUE_CLOUD = 29350,
+ SPELL_TELEPORT_SELF = 30211,
+};
+
+enum Yells
+{
+ SAY_AGGRO = 0,
+ SAY_SLAY = 1,
+ SAY_TAUNT = 2,
+ SAY_DEATH = 3,
+
+ EMOTE_DANCE = 4,
+ EMOTE_DANCE_END = 5,
};
enum Events
{
- EVENT_NONE,
- EVENT_DISRUPT,
+ EVENT_DISRUPT = 1,
EVENT_FEVER,
EVENT_ERUPT,
- EVENT_PHASE,
+ EVENT_DANCE,
+ EVENT_DANCE_END
};
enum Phases
{
PHASE_FIGHT = 1,
- PHASE_DANCE,
+ PHASE_DANCE
};
enum Misc
{
- ACTION_SAFETY_DANCE_FAIL = 1,
DATA_SAFETY_DANCE = 19962139
};
@@ -66,39 +72,25 @@ public:
struct boss_heiganAI : public BossAI
{
- boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN)
+ boss_heiganAI(Creature* creature) : BossAI(creature, BOSS_HEIGAN), eruptSection(0), eruptDirection(false), safetyDance(false) { }
+
+ void Reset() override
{
- eruptSection = 0;
- eruptDirection = false;
- safetyDance = false;
- phase = PHASE_FIGHT;
+ me->SetReactState(REACT_AGGRESSIVE);
+ _Reset();
}
- uint32 eruptSection;
- bool eruptDirection;
- bool safetyDance;
- Phases phase;
-
void KilledUnit(Unit* who) override
{
- if (!(rand32() % 5))
- Talk(SAY_SLAY);
+ Talk(SAY_SLAY);
+
if (who->GetTypeId() == TYPEID_PLAYER)
safetyDance = false;
}
- void SetData(uint32 id, uint32 data) override
- {
- if (id == DATA_SAFETY_DANCE)
- safetyDance = data ? true : false;
- }
-
uint32 GetData(uint32 type) const override
{
- if (type == DATA_SAFETY_DANCE)
- return safetyDance ? 1 : 0;
-
- return 0;
+ return (type == DATA_SAFETY_DANCE && safetyDance) ? 1u : 0u;
}
void JustDied(Unit* /*killer*/) override
@@ -111,35 +103,14 @@ public:
{
_EnterCombat();
Talk(SAY_AGGRO);
- EnterPhase(PHASE_FIGHT);
- safetyDance = true;
- }
-
- void EnterPhase(Phases newPhase)
- {
- phase = newPhase;
- events.Reset();
+
eruptSection = 3;
- if (phase == PHASE_FIGHT)
- {
- events.ScheduleEvent(EVENT_DISRUPT, urand(10000, 25000));
- events.ScheduleEvent(EVENT_FEVER, urand(15000, 20000));
- events.ScheduleEvent(EVENT_PHASE, 90000);
- events.ScheduleEvent(EVENT_ERUPT, 15000);
- me->GetMotionMaster()->MoveChase(me->GetVictim());
- }
- else
- {
- float x, y, z, o;
- me->GetHomePosition(x, y, z, o);
- me->NearTeleportTo(x, y, z, o - (float(M_PI) / 2));
- me->GetMotionMaster()->Clear();
- me->GetMotionMaster()->MoveIdle();
- me->SetTarget(ObjectGuid::Empty);
- DoCastAOE(SPELL_PLAGUE_CLOUD);
- events.ScheduleEvent(EVENT_PHASE, 45000);
- events.ScheduleEvent(EVENT_ERUPT, 8000);
- }
+ events.ScheduleEvent(EVENT_DISRUPT, urand(15 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_FEVER, urand(10 * IN_MILLISECONDS, 20 * IN_MILLISECONDS), 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+
+ safetyDance = true;
}
void UpdateAI(uint32 diff) override
@@ -155,15 +126,36 @@ public:
{
case EVENT_DISRUPT:
DoCastAOE(SPELL_SPELL_DISRUPTION);
- events.ScheduleEvent(EVENT_DISRUPT, urand(5000, 10000));
+ events.ScheduleEvent(EVENT_DISRUPT, 11 * IN_MILLISECONDS);
break;
case EVENT_FEVER:
DoCastAOE(SPELL_DECREPIT_FEVER);
- events.ScheduleEvent(EVENT_FEVER, urand(20000, 25000));
+ events.ScheduleEvent(EVENT_FEVER, urand(20 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
+ break;
+ case EVENT_DANCE:
+ events.SetPhase(PHASE_DANCE);
+ Talk(SAY_TAUNT);
+ Talk(EMOTE_DANCE);
+ eruptSection = 3;
+ me->SetReactState(REACT_PASSIVE);
+ me->AttackStop();
+ me->StopMoving();
+ DoCast(SPELL_TELEPORT_SELF);
+ DoCastAOE(SPELL_PLAGUE_CLOUD);
+ events.ScheduleEvent(EVENT_DANCE_END, 45 * IN_MILLISECONDS, 0, PHASE_DANCE);
+ events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS);
break;
- case EVENT_PHASE:
- /// @todo Add missing texts for both phase switches
- EnterPhase(phase == PHASE_FIGHT ? PHASE_DANCE : PHASE_FIGHT);
+ case EVENT_DANCE_END:
+ events.SetPhase(PHASE_FIGHT);
+ Talk(EMOTE_DANCE_END);
+ eruptSection = 3;
+ events.ScheduleEvent(EVENT_DISRUPT, urand(10, 25) * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_FEVER, urand(15, 20) * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_DANCE, 90 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ events.ScheduleEvent(EVENT_ERUPT, 15 * IN_MILLISECONDS, 0, PHASE_FIGHT);
+ me->CastStop();
+ me->SetReactState(REACT_AGGRESSIVE);
+ DoZoneInCombat();
break;
case EVENT_ERUPT:
instance->SetData(DATA_HEIGAN_ERUPT, eruptSection);
@@ -176,13 +168,22 @@ public:
eruptDirection ? ++eruptSection : --eruptSection;
- events.ScheduleEvent(EVENT_ERUPT, phase == PHASE_FIGHT ? 10000 : 3000);
+ if (events.IsInPhase(PHASE_DANCE))
+ events.ScheduleEvent(EVENT_ERUPT, 3 * IN_MILLISECONDS, 0, PHASE_DANCE);
+ else
+ events.ScheduleEvent(EVENT_ERUPT, 10 * IN_MILLISECONDS, 0, PHASE_FIGHT);
break;
}
}
DoMeleeAttackIfReady();
}
+
+ private:
+ uint32 eruptSection;
+ bool eruptDirection;
+
+ bool safetyDance; // is achievement still possible? (= no player deaths yet)
};
};
@@ -205,7 +206,7 @@ class spell_heigan_eruption : public SpellScriptLoader
if (GetHitDamage() >= int32(GetHitPlayer()->GetHealth()))
if (InstanceScript* instance = caster->GetInstanceScript())
if (Creature* Heigan = ObjectAccessor::GetCreature(*caster, instance->GetGuidData(DATA_HEIGAN)))
- Heigan->AI()->SetData(DATA_SAFETY_DANCE, 0);
+ Heigan->AI()->KilledUnit(GetHitPlayer());
}
void Register() override
@@ -223,9 +224,7 @@ class spell_heigan_eruption : public SpellScriptLoader
class achievement_safety_dance : public AchievementCriteriaScript
{
public:
- achievement_safety_dance() : AchievementCriteriaScript("achievement_safety_dance")
- {
- }
+ achievement_safety_dance() : AchievementCriteriaScript("achievement_safety_dance") { }
bool OnCheck(Player* /*player*/, Unit* target) override
{
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
index 33fb43b6bbc..494c173f5fc 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_loatheb.cpp
@@ -27,7 +27,10 @@ enum Spells
SPELL_WARN_NECROTIC_AURA = 59481,
SPELL_SUMMON_SPORE = 29234,
SPELL_DEATHBLOOM = 29865,
- SPELL_INEVITABLE_DOOM = 29204
+ SPELL_INEVITABLE_DOOM = 29204,
+ SPELL_FUNGAL_CREEP = 29232,
+
+ SPELL_DEATHBLOOM_FINAL_DAMAGE = 55594,
};
enum Texts
@@ -72,29 +75,35 @@ class boss_loatheb : public CreatureScript
void Reset() override
{
_Reset();
+ instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_FUNGAL_CREEP);
Initialize();
}
void EnterCombat(Unit* /*who*/) override
{
_EnterCombat();
- events.ScheduleEvent(EVENT_NECROTIC_AURA, 17000);
- events.ScheduleEvent(EVENT_DEATHBLOOM, 5000);
- events.ScheduleEvent(EVENT_SPORE, IsHeroic() ? 18000 : 36000);
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 120000);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA, 17 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_DEATHBLOOM, 5 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 2 * MINUTE * IN_MILLISECONDS);
}
- void SummonedCreatureDies(Creature* /*summon*/, Unit* /*killer*/) override
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
{
_sporeLoserData = false;
+ summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true);
}
- uint32 GetData(uint32 id) const override
+ void SummonedCreatureDespawn(Creature* summon) override
{
- if (id != DATA_ACHIEVEMENT_SPORE_LOSER)
- return 0;
+ summons.Despawn(summon);
+ if (summon->IsAlive())
+ summon->CastSpell(summon,SPELL_FUNGAL_CREEP,true);
+ }
- return uint32(_sporeLoserData);
+ uint32 GetData(uint32 id) const override
+ {
+ return (_sporeLoserData && id == DATA_ACHIEVEMENT_SPORE_LOSER) ? 1u : 0u;
}
void UpdateAI(uint32 diff) override
@@ -111,21 +120,29 @@ class boss_loatheb : public CreatureScript
case EVENT_NECROTIC_AURA:
DoCastAOE(SPELL_NECROTIC_AURA);
DoCast(me, SPELL_WARN_NECROTIC_AURA);
- events.ScheduleEvent(EVENT_NECROTIC_AURA, 20000);
- events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14000);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA, 20 * IN_MILLISECONDS);
+ events.ScheduleEvent(EVENT_NECROTIC_AURA_FADING, 14 * IN_MILLISECONDS);
break;
case EVENT_DEATHBLOOM:
DoCastAOE(SPELL_DEATHBLOOM);
- events.ScheduleEvent(EVENT_DEATHBLOOM, 30000);
+ events.ScheduleEvent(EVENT_DEATHBLOOM, 30 * IN_MILLISECONDS);
break;
case EVENT_INEVITABLE_DOOM:
_doomCounter++;
DoCastAOE(SPELL_INEVITABLE_DOOM);
- events.ScheduleEvent(EVENT_INEVITABLE_DOOM, std::max(120000 - _doomCounter * 15000, 15000)); // needs to be confirmed
+ if (_doomCounter > 6)
+ {
+ if (_doomCounter & 1) // odd
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 14 * IN_MILLISECONDS);
+ else
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 17 * IN_MILLISECONDS);
+ }
+ else
+ events.ScheduleEvent(EVENT_INEVITABLE_DOOM, 30 * IN_MILLISECONDS);
break;
case EVENT_SPORE:
DoCast(me, SPELL_SUMMON_SPORE, false);
- events.ScheduleEvent(EVENT_SPORE, IsHeroic() ? 18000 : 36000);
+ events.ScheduleEvent(EVENT_SPORE, RAID_MODE(36,18) * IN_MILLISECONDS);
break;
case EVENT_NECROTIC_AURA_FADING:
Talk(SAY_NECROTIC_AURA_FADING);
@@ -203,9 +220,46 @@ class spell_loatheb_necrotic_aura_warning : public SpellScriptLoader
}
};
+class spell_loatheb_deathbloom : public SpellScriptLoader
+{
+ public:
+ spell_loatheb_deathbloom() : SpellScriptLoader("spell_loatheb_deathbloom") { }
+
+ class spell_loatheb_deathbloom_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_loatheb_deathbloom_AuraScript);
+
+ bool Validate(SpellInfo const* /*spell*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_DEATHBLOOM_FINAL_DAMAGE))
+ return false;
+ return true;
+ }
+
+ void AfterRemove(AuraEffect const* eff, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
+ return;
+
+ GetTarget()->CastSpell(nullptr, SPELL_DEATHBLOOM_FINAL_DAMAGE, true, nullptr, eff, GetCasterGUID());
+ }
+
+ void Register() override
+ {
+ AfterEffectRemove += AuraEffectRemoveFn(spell_loatheb_deathbloom_AuraScript::AfterRemove, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_loatheb_deathbloom_AuraScript();
+ }
+};
+
void AddSC_boss_loatheb()
{
new boss_loatheb();
new achievement_spore_loser();
new spell_loatheb_necrotic_aura_warning();
+ new spell_loatheb_deathbloom();
}
diff --git a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
index 57ea9eaf8c8..5f9ca92aaf4 100644
--- a/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/boss_noth.cpp
@@ -19,51 +19,58 @@
#include "ScriptedCreature.h"
#include "naxxramas.h"
-enum Noth
+enum Phases
{
- SAY_AGGRO = 0,
- SAY_SUMMON = 1,
- SAY_SLAY = 2,
- SAY_DEATH = 3,
-
- SOUND_DEATH = 8848,
-
- SPELL_CURSE_PLAGUEBRINGER = 29213, // 25-man: 54835
- SPELL_CRIPPLE = 29212, // 25-man: 54814
- SPELL_TELEPORT = 29216,
-
- NPC_WARRIOR = 16984,
- NPC_CHAMPION = 16983,
- NPC_GUARDIAN = 16981
+ PHASE_NONE,
+ PHASE_GROUND,
+ PHASE_BALCONY
};
-#define SPELL_BLINK RAND(29208, 29209, 29210, 29211)
+enum Events
+{
+ EVENT_CURSE = 1, // curse of the plaguebringer
+ EVENT_BLINK, // blink (25m only)
+ EVENT_WARRIOR, // summon warriors during ground phase
+ EVENT_BALCONY, // become untargetable and begin balcony phase
+ EVENT_BALCONY_TELEPORT, // actually teleport to balcony, this is slightly delayed
+ EVENT_WAVE, // spawn wave during balcony phase
+ EVENT_GROUND, // end balcony phase and teleport to ground
+ EVENT_GROUND_ATTACKABLE // become attackable and aggressive again at start of ground phase, once again slightly delayed to prevent motionmaster weirdness
+};
-// Teleport position of Noth on his balcony
-Position const Teleport = { 2631.370f, -3529.680f, 274.040f, 6.277f };
+enum Talk
+{
+ SAY_AGGRO = 0,
+ SAY_SUMMON = 1,
+ SAY_SLAY = 2,
+ SAY_DEATH = 3,
-#define MAX_SUMMON_POS 5
+ EMOTE_SUMMON = 4, // ground phase
+ EMOTE_SUMMON_WAVE = 5, // balcony phase
+ EMOTE_TELEPORT_1 = 6, // ground to balcony
+ EMOTE_TELEPORT_2 = 7 // balcony to ground
+};
-Position const SummonPos[MAX_SUMMON_POS] =
+enum Spells
{
- { 2728.12f, -3544.43f, 261.91f, 6.04f },
- { 2729.05f, -3544.47f, 261.91f, 5.58f },
- { 2728.24f, -3465.08f, 264.20f, 3.56f },
- { 2704.11f, -3456.81f, 265.53f, 4.51f },
- { 2663.56f, -3464.43f, 262.66f, 5.20f }
+ SPELL_CURSE = 29213, // 25-man: 54835
+ SPELL_CRIPPLE = 29212, // 25-man: 54814
+
+ SPELL_TELEPORT = 29216, // ground to balcony
+ SPELL_TELEPORT_BACK = 29231 // balcony to ground
};
-enum Events
+enum Adds
{
- EVENT_NONE,
- EVENT_BERSERK,
- EVENT_CURSE,
- EVENT_BLINK,
- EVENT_WARRIOR,
- EVENT_BALCONY,
- EVENT_WAVE,
- EVENT_GROUND
+ N_WARRIOR_SPELLS = 3,
+ N_CHAMPION_SPELLS = 6,
+ N_GUARDIAN_SPELLS = 3
};
+const uint32 SummonWarriorSpells[N_WARRIOR_SPELLS] = { 29247, 29248, 29249 };
+const uint32 SummonChampionSpells[N_CHAMPION_SPELLS] = { 29238, 29255, 29257, 29258, 29262, 29267 };
+const uint32 SummonGuardianSpells[N_GUARDIAN_SPELLS] = { 29239, 29256, 29268 };
+
+#define SPELL_BLINK RAND(29208, 29209, 29210, 29211)
class boss_noth : public CreatureScript
{
@@ -72,16 +79,38 @@ public:
struct boss_nothAI : public BossAI
{
- boss_nothAI(Creature* creature) : BossAI(creature, BOSS_NOTH)
+ boss_nothAI(Creature* creature) : BossAI(creature, BOSS_NOTH), balconyCount(0), justBlinked(false)
{
- balconyCount = 0;
- waveCount = 0;
+ std::copy(SummonWarriorSpells, SummonWarriorSpells + N_WARRIOR_SPELLS, _SummonWarriorSpells);
+ std::copy(SummonChampionSpells, SummonChampionSpells + N_CHAMPION_SPELLS, _SummonChampionSpells);
+ std::copy(SummonGuardianSpells, SummonGuardianSpells + N_GUARDIAN_SPELLS, _SummonGuardianSpells);
+
+ events.SetPhase(PHASE_NONE);
+ }
+
+ void EnterEvadeMode() override
+ {
+ Reset(); // teleport back first
+ _EnterEvadeMode();
}
void Reset() override
{
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ if (!me->IsAlive())
+ return;
+
+ // in case we reset during balcony phase
+ if (events.IsInPhase(PHASE_BALCONY))
+ {
+ DoCastAOE(SPELL_TELEPORT_BACK);
+ me->SetReactState(REACT_AGGRESSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+ }
+
+ balconyCount = 0;
+ events.SetPhase(PHASE_NONE);
+ justBlinked = false;
+
_Reset();
}
@@ -89,31 +118,44 @@ public:
{
_EnterCombat();
Talk(SAY_AGGRO);
- balconyCount = 0;
EnterPhaseGround();
}
void EnterPhaseGround()
{
- me->SetReactState(REACT_AGGRESSIVE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ events.SetPhase(PHASE_GROUND);
+
DoZoneInCombat();
if (me->getThreatManager().isThreatListEmpty())
- EnterEvadeMode();
+ Reset();
else
{
- events.ScheduleEvent(EVENT_BALCONY, 110000);
- events.ScheduleEvent(EVENT_CURSE, 10000 + rand32() % 15000);
- events.ScheduleEvent(EVENT_WARRIOR, 30000);
+ uint8 secondsGround;
+ switch (balconyCount)
+ {
+ case 0:
+ secondsGround = 90;
+ break;
+ case 1:
+ secondsGround = 110;
+ break;
+ case 2:
+ default:
+ secondsGround = 180;
+ }
+ events.ScheduleEvent(EVENT_GROUND_ATTACKABLE, 2 * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_BALCONY, secondsGround * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_CURSE, urand(10,25) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ events.ScheduleEvent(EVENT_WARRIOR, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND);
if (GetDifficulty() == DIFFICULTY_25_N)
- events.ScheduleEvent(EVENT_BLINK, urand(20000, 40000));
+ events.ScheduleEvent(EVENT_BLINK, urand(20,30) * IN_MILLISECONDS, 0, PHASE_GROUND);
}
}
- void KilledUnit(Unit* /*victim*/) override
+ void KilledUnit(Unit* victim) override
{
- if (!(rand32() % 5))
+ if(victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
@@ -121,7 +163,7 @@ public:
{
summons.Summon(summon);
summon->setActive(true);
- summon->AI()->DoZoneInCombat();
+ summon->AI()->DoZoneInCombat(nullptr, 250.0f); // specify range to cover entire room - default 50yd is not enough
}
void JustDied(Unit* /*killer*/) override
@@ -130,10 +172,35 @@ public:
Talk(SAY_DEATH);
}
- void SummonUndead(uint32 entry, uint32 num)
+ void DamageTaken(Unit* /*who*/, uint32& damage) override // prevent noth from somehow dying in the balcony phase
{
- for (uint32 i = 0; i < num; ++i)
- me->SummonCreature(entry, SummonPos[rand32() % MAX_SUMMON_POS], TEMPSUMMON_CORPSE_DESPAWN, 60000);
+ if (!events.IsInPhase(PHASE_BALCONY))
+ return;
+ if (damage < me->GetHealth())
+ return;
+
+ me->SetHealth(1u);
+ damage = 0u;
+ }
+
+ void HandleSummon(uint32* spellsList, const uint8 nSpells, uint8 num)
+ { // this ensures we do not spawn two mobs using the same spell (<=> in the same position) if we can help it
+ while (num)
+ for (uint8 it = 0; it < nSpells && num; ++it)
+ {
+ num--;
+ uint8 selected = urand(it, nSpells - 1);
+ DoCastAOE(spellsList[selected]);
+ if (selected != it) // shuffle the selected into the part of the array that is no longer being searched
+ std::swap(spellsList[selected], spellsList[it]);
+ }
+ }
+
+ void CastSummon(uint8 nWarrior, uint8 nChampion, uint8 nGuardian)
+ {
+ HandleSummon(_SummonWarriorSpells, N_WARRIOR_SPELLS, nWarrior);
+ HandleSummon(_SummonChampionSpells, N_CHAMPION_SPELLS, nChampion);
+ HandleSummon(_SummonGuardianSpells, N_GUARDIAN_SPELLS, nGuardian);
}
void UpdateAI(uint32 diff) override
@@ -151,72 +218,115 @@ public:
switch (eventId)
{
case EVENT_CURSE:
- DoCastAOE(SPELL_CURSE_PLAGUEBRINGER);
- events.ScheduleEvent(EVENT_CURSE, urand(50000, 60000));
- return;
+ {
+ DoCastAOE(SPELL_CURSE);
+ events.ScheduleEvent(EVENT_CURSE, urand(50, 70) * IN_MILLISECONDS, 0, PHASE_GROUND);
+ break;
+ }
case EVENT_WARRIOR:
Talk(SAY_SUMMON);
- SummonUndead(NPC_WARRIOR, RAID_MODE(2, 3));
- events.ScheduleEvent(EVENT_WARRIOR, 30000);
- return;
+ Talk(EMOTE_SUMMON);
+
+ CastSummon(RAID_MODE(2, 3), 0, 0);
+
+ events.ScheduleEvent(EVENT_WARRIOR, 40 * IN_MILLISECONDS, 0, PHASE_GROUND);
+ break;
case EVENT_BLINK:
DoCastAOE(SPELL_CRIPPLE, true);
DoCastAOE(SPELL_BLINK);
DoResetThreat();
- events.ScheduleEvent(EVENT_BLINK, 40000);
- return;
+ justBlinked = true;
+
+ events.ScheduleEvent(EVENT_BLINK, 40000, 0, PHASE_GROUND);
+ break;
case EVENT_BALCONY:
+ events.SetPhase(PHASE_BALCONY);
me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
me->AttackStop();
+ me->StopMoving();
me->RemoveAllAuras();
- me->NearTeleportTo(Teleport.GetPositionX(), Teleport.GetPositionY(), Teleport.GetPositionZ(), Teleport.GetOrientation());
- events.Reset();
- events.ScheduleEvent(EVENT_WAVE, urand(2000, 5000));
- waveCount = 0;
- return;
+
+ events.ScheduleEvent(EVENT_BALCONY_TELEPORT, 3 * IN_MILLISECONDS, 0, PHASE_BALCONY);
+ events.ScheduleEvent(EVENT_WAVE, urand(5 * IN_MILLISECONDS, 8 * IN_MILLISECONDS), 0, PHASE_BALCONY);
+
+ uint8 secondsBalcony;
+ switch (balconyCount)
+ {
+ case 0:
+ secondsBalcony = 70;
+ break;
+ case 1:
+ secondsBalcony = 97;
+ break;
+ case 2:
+ default:
+ secondsBalcony = 120;
+ break;
+ }
+ events.ScheduleEvent(EVENT_GROUND, secondsBalcony * IN_MILLISECONDS, 0, PHASE_BALCONY);
+ break;
+ case EVENT_BALCONY_TELEPORT:
+ Talk(EMOTE_TELEPORT_1);
+ DoCastAOE(SPELL_TELEPORT);
+ break;
case EVENT_WAVE:
- Talk(SAY_SUMMON);
+ Talk(EMOTE_SUMMON_WAVE);
switch (balconyCount)
{
case 0:
- SummonUndead(NPC_CHAMPION, RAID_MODE(2, 4));
+ CastSummon(0, RAID_MODE(2, 4), 0);
break;
case 1:
- SummonUndead(NPC_CHAMPION, RAID_MODE(1, 2));
- SummonUndead(NPC_GUARDIAN, RAID_MODE(1, 2));
+ CastSummon(0, RAID_MODE(1, 2), RAID_MODE(1, 2));
break;
case 2:
- SummonUndead(NPC_GUARDIAN, RAID_MODE(2, 4));
+ CastSummon(0, 0, RAID_MODE(2, 4));
break;
default:
- SummonUndead(NPC_CHAMPION, RAID_MODE(5, 10));
- SummonUndead(NPC_GUARDIAN, RAID_MODE(5, 10));
+ CastSummon(0, RAID_MODE(5, 10), RAID_MODE(5, 10));
break;
}
- ++waveCount;
- events.ScheduleEvent(waveCount < 2 ? EVENT_WAVE : EVENT_GROUND, urand(30000, 45000));
- return;
+ events.ScheduleEvent(EVENT_WAVE, urand(30, 45) * IN_MILLISECONDS, 0, PHASE_BALCONY);
+ break;
case EVENT_GROUND:
- {
++balconyCount;
- float x, y, z, o;
- me->GetHomePosition(x, y, z, o);
- me->NearTeleportTo(x, y, z, o);
- events.ScheduleEvent(EVENT_BALCONY, 110000);
+
+ DoCastAOE(SPELL_TELEPORT_BACK);
+ Talk(EMOTE_TELEPORT_2);
+
EnterPhaseGround();
- return;
- }
+ break;
+ case EVENT_GROUND_ATTACKABLE:
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
+ me->SetReactState(REACT_AGGRESSIVE);
+ break;
}
}
- if (me->HasReactState(REACT_AGGRESSIVE))
- DoMeleeAttackIfReady();
+ if (events.IsInPhase(PHASE_GROUND))
+ {
+ /* workaround for movechase breaking after blinking
+ without this noth would just stand there unless his current target moves */
+ if (justBlinked && me->GetVictim() && !me->IsWithinMeleeRange(me->EnsureVictim()))
+ {
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveChase(me->EnsureVictim());
+ justBlinked = false;
+ }
+ else
+ DoMeleeAttackIfReady();
+ }
}
private:
- uint32 waveCount;
uint32 balconyCount;
+
+ bool justBlinked;
+
+ uint32 _SummonWarriorSpells[N_WARRIOR_SPELLS];
+ uint32 _SummonChampionSpells[N_CHAMPION_SPELLS];
+ uint32 _SummonGuardianSpells[N_GUARDIAN_SPELLS];
};
CreatureAI* GetAI(Creature* creature) const override
diff --git a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
index 493fb7cfe9d..f0348c408b1 100644
--- a/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
+++ b/src/server/scripts/Northrend/Naxxramas/instance_naxxramas.cpp
@@ -60,7 +60,6 @@ DoorData const doorData[] =
MinionData const minionData[] =
{
- { NPC_FOLLOWER_WORSHIPPER, BOSS_FAERLINA },
{ NPC_DK_UNDERSTUDY, BOSS_RAZUVIOUS },
{ NPC_SIR, BOSS_HORSEMEN },
{ NPC_THANE, BOSS_HORSEMEN },
@@ -78,12 +77,13 @@ ObjectData const objectData[] =
{ 0, 0, }
};
-float const HeiganPos[2] = { 2796.0f, -3707.0f };
+// from P2 teleport spell stored target
+float const HeiganPos[2] = { 2793.86f, -3707.38f };
float const HeiganEruptionSlope[3] =
{
- (-3685.0f - HeiganPos[1]) / (2724.0f - HeiganPos[0]),
- (-3647.0f - HeiganPos[1]) / (2749.0f - HeiganPos[0]),
- (-3637.0f - HeiganPos[1]) / (2771.0f - HeiganPos[0])
+ (-3703.303223f - HeiganPos[1]) / (2777.494141f - HeiganPos[0]), // between right center and far right
+ (-3696.948242f - HeiganPos[1]) / (2785.624268f - HeiganPos[0]), // between left and right halves
+ (-3691.880615f - HeiganPos[1]) / (2790.280029f - HeiganPos[0]) // between far left and left center
};
// 0 H x
@@ -125,6 +125,8 @@ class instance_naxxramas : public InstanceMapScript
minHorsemenDiedTime = 0;
maxHorsemenDiedTime = 0;
AbominationCount = 0;
+ hadAnubRekhanGreet = false;
+ hadFaerlinaGreet = false;
CurrentWingTaunt = SAY_KELTHUZAD_FIRST_WING_TAUNT;
playerDied = 0;
@@ -134,6 +136,9 @@ class instance_naxxramas : public InstanceMapScript
{
switch (creature->GetEntry())
{
+ case NPC_ANUBREKHAN:
+ AnubRekhanGUID = creature->GetGUID();
+ break;
case NPC_FAERLINA:
FaerlinaGUID = creature->GetGUID();
break;
@@ -246,7 +251,6 @@ class instance_naxxramas : public InstanceMapScript
if (go->GetGOInfo()->displayId == 6785 || go->GetGOInfo()->displayId == 1287)
{
uint32 section = GetEruptionSection(go->GetPositionX(), go->GetPositionY());
-
HeiganEruptionGUID[section].erase(go->GetGUID());
return;
}
@@ -319,6 +323,14 @@ class instance_naxxramas : public InstanceMapScript
case DATA_ABOMINATION_KILLED:
AbominationCount = value;
break;
+ case DATA_HAD_ANUBREKHAN_GREET:
+ hadAnubRekhanGreet = (value == 1u);
+ break;
+ case DATA_HAD_FAERLINA_GREET:
+ hadFaerlinaGreet = (value == 1u);
+ break;
+ default:
+ break;
}
}
@@ -328,6 +340,10 @@ class instance_naxxramas : public InstanceMapScript
{
case DATA_ABOMINATION_KILLED:
return AbominationCount;
+ case DATA_HAD_ANUBREKHAN_GREET:
+ return (uint32)hadAnubRekhanGreet;
+ case DATA_HAD_FAERLINA_GREET:
+ return (uint32)hadFaerlinaGreet;
default:
break;
}
@@ -339,6 +355,8 @@ class instance_naxxramas : public InstanceMapScript
{
switch (id)
{
+ case DATA_ANUBREKHAN:
+ return AnubRekhanGUID;
case DATA_FAERLINA:
return FaerlinaGUID;
case DATA_THANE:
@@ -552,7 +570,7 @@ class instance_naxxramas : public InstanceMapScript
// This Function is called in CheckAchievementCriteriaMeet and CheckAchievementCriteriaMeet is called before SetBossState(bossId, DONE),
// so to check if all bosses are done the checker must exclude 1 boss, the last done, if there is at most 1 encouter in progress when is
// called this function then all bosses are done. The one boss that check is the boss that calls this function, so it is dead.
- bool AreAllEncoutersDone()
+ bool AreAllEncountersDone()
{
uint32 numBossAlive = 0;
for (uint32 i = 0; i < EncounterCount; ++i)
@@ -589,7 +607,7 @@ class instance_naxxramas : public InstanceMapScript
case 13239: // Loatheb
case 13240: // Thaddius
case 7617: // Kel'Thuzad
- if (AreAllEncoutersDone() && !playerDied)
+ if (AreAllEncountersDone() && !playerDied)
return true;
return false;
}
@@ -599,6 +617,8 @@ class instance_naxxramas : public InstanceMapScript
protected:
/* The Arachnid Quarter */
+ // Anub'rekhan
+ ObjectGuid AnubRekhanGUID;
// Grand Widow Faerlina
ObjectGuid FaerlinaGUID;
@@ -635,6 +655,8 @@ class instance_naxxramas : public InstanceMapScript
ObjectGuid KelthuzadDoorGUID;
ObjectGuid LichKingGUID;
uint8 AbominationCount;
+ bool hadAnubRekhanGreet;
+ bool hadFaerlinaGreet;
uint8 CurrentWingTaunt;
/* The Immortal / The Undying */
diff --git a/src/server/scripts/Northrend/Naxxramas/naxxramas.h b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
index 459903c4c86..6289b707411 100644
--- a/src/server/scripts/Northrend/Naxxramas/naxxramas.h
+++ b/src/server/scripts/Northrend/Naxxramas/naxxramas.h
@@ -46,6 +46,9 @@ enum Data
DATA_HEIGAN_ERUPT,
DATA_GOTHIK_GATE,
DATA_SAPPHIRON_BIRTH,
+ DATA_HAD_ANUBREKHAN_GREET,
+
+ DATA_HAD_FAERLINA_GREET,
DATA_HORSEMEN0,
DATA_HORSEMEN1,
@@ -61,6 +64,7 @@ enum Data
enum Data64
{
+ DATA_ANUBREKHAN,
DATA_FAERLINA,
DATA_THANE,
DATA_LADY,
@@ -81,6 +85,7 @@ enum Data64
enum CreaturesIds
{
+ NPC_ANUBREKHAN = 15956,
NPC_FAERLINA = 15953,
NPC_THANE = 16064,
NPC_LADY = 16065,
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
index 6233c7e8953..86dbe6c16fb 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp
@@ -437,7 +437,7 @@ public:
return 0;
}
- void UpdateEscortAI(const uint32 uiDiff) override
+ void UpdateEscortAI(uint32 uiDiff) override
{
if (uiPhaseTimer <= uiDiff)
{
diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
index c67e31c4cc0..227b9c208cc 100644
--- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
+++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp
@@ -18,7 +18,6 @@
#include "InstanceScript.h"
#include "Player.h"
#include "ScriptMgr.h"
-#include "WorldSession.h"
#include "halls_of_stone.h"
DoorData const doorData[] =
@@ -172,7 +171,7 @@ class instance_halls_of_stone : public InstanceMapScript
bool CheckRequiredBosses(uint32 bossId, Player const* player = nullptr) const override
{
- if (player && player->GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_INSTANCE_REQUIRED_BOSSES))
+ if (_SkipCheckRequiredBosses(player))
return true;
switch (bossId)
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 566c311955c..21066528fef 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp
@@ -97,9 +97,6 @@ enum Creatures
NPC_MIMIRON_TARGET_BEACON = 33369,
NPC_HODIR_TARGET_BEACON = 33108,
NPC_FREYA_TARGET_BEACON = 33366,
- NPC_LOREKEEPER = 33686, // Hard mode starter
- NPC_BRANZ_BRONZBEARD = 33579,
- NPC_DELORAH = 33701,
NPC_ULDUAR_GAUNTLET_GENERATOR = 33571, // Trigger tied to towers
};
@@ -1167,9 +1164,49 @@ class npc_freya_ward_summon : public CreatureScript
}
};
-//npc lore keeper
-#define GOSSIP_ITEM_1 "Activate secondary defensive systems"
-#define GOSSIP_ITEM_2 "Confirmed"
+enum BrannBronzebeardGossips
+{
+ GOSSIP_MENU_BRANN_BRONZEBEARD = 10355,
+ GOSSIP_OPTION_BRANN_BRONZEBEARD = 0
+};
+
+class npc_brann_bronzebeard_ulduar_intro : public CreatureScript
+{
+ public:
+ npc_brann_bronzebeard_ulduar_intro() : CreatureScript("npc_brann_bronzebeard_ulduar_intro") { }
+
+ struct npc_brann_bronzebeard_ulduar_introAI : public ScriptedAI
+ {
+ npc_brann_bronzebeard_ulduar_introAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
+
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == GOSSIP_MENU_BRANN_BRONZEBEARD && gossipListId == GOSSIP_OPTION_BRANN_BRONZEBEARD)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ if (Creature* loreKeeper = _instance->GetCreature(DATA_LORE_KEEPER_OF_NORGANNON))
+ loreKeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ }
+ }
+
+ private:
+ InstanceScript* _instance;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetUlduarAI<npc_brann_bronzebeard_ulduar_introAI>(creature);
+ }
+};
+
+enum LoreKeeperGossips
+{
+ GOSSIP_MENU_LORE_KEEPER = 10477,
+ GOSSIP_OPTION_LORE_KEEPER = 0
+};
class npc_lorekeeper : public CreatureScript
{
@@ -1180,6 +1217,7 @@ class npc_lorekeeper : public CreatureScript
{
npc_lorekeeperAI(Creature* creature) : ScriptedAI(creature)
{
+ _instance = creature->GetInstanceScript();
}
void DoAction(int32 action) override
@@ -1187,66 +1225,42 @@ class npc_lorekeeper : public CreatureScript
// Start encounter
if (action == ACTION_SPAWN_VEHICLES)
{
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_SIEGE, PosSiege[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_CHOPPER, PosChopper[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- for (int32 i = 0; i < RAID_MODE(2, 5); ++i)
+ for (uint8 i = 0; i < RAID_MODE(2, 5); ++i)
DoSummon(VEHICLE_DEMOLISHER, PosDemolisher[i], 3000, TEMPSUMMON_CORPSE_TIMED_DESPAWN);
- return;
}
}
- };
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->CLOSE_GOSSIP_MENU();
- InstanceScript* instance = creature->GetInstanceScript();
- if (!instance)
- return true;
- switch (action)
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
{
- case GOSSIP_ACTION_INFO_DEF+1:
- player->PrepareGossipMenu(creature);
- instance->instance->LoadGrid(364, -16); //make sure leviathan is loaded
+ if (menuId == GOSSIP_MENU_LORE_KEEPER && gossipListId == GOSSIP_OPTION_LORE_KEEPER)
+ {
+ player->PlayerTalkClass->SendCloseGossip();
+ _instance->instance->LoadGrid(364, -16); // make sure leviathan is loaded
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- if (Creature* leviathan = instance->instance->GetCreature(instance->GetGuidData(BOSS_LEVIATHAN)))
+ if (Creature* leviathan = _instance->instance->GetCreature(_instance->GetGuidData(BOSS_LEVIATHAN)))
{
leviathan->AI()->DoAction(ACTION_START_HARD_MODE);
- creature->SetVisible(false);
- creature->AI()->DoAction(ACTION_SPAWN_VEHICLES); // spawn the vehicles
- if (Creature* Delorah = creature->FindNearestCreature(NPC_DELORAH, 1000, true))
+ me->SetVisible(false);
+ DoAction(ACTION_SPAWN_VEHICLES); // spawn the vehicles
+ if (Creature* delorah = _instance->GetCreature(DATA_DELLORAH))
{
- if (Creature* Branz = creature->FindNearestCreature(NPC_BRANZ_BRONZBEARD, 1000, true))
+ if (Creature* brann = _instance->GetCreature(DATA_BRANN_BRONZEBEARD_INTRO))
{
- Delorah->GetMotionMaster()->MovePoint(0, Branz->GetPositionX()-4, Branz->GetPositionY(), Branz->GetPositionZ());
- /// @todo Delorah->AI()->Talk(xxxx, Branz); when reached at branz
+ delorah->GetMotionMaster()->MovePoint(0, brann->GetPositionX() - 4, brann->GetPositionY(), brann->GetPositionZ());
+ /// @todo delorah->AI()->Talk(xxxx, brann->GetGUID()); when reached at branz
}
}
}
- break;
+ }
}
- return true;
- }
-
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- InstanceScript* instance = creature->GetInstanceScript();
- if (instance && instance->GetData(BOSS_LEVIATHAN) != DONE && player)
- {
- player->PrepareGossipMenu(creature);
-
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- }
- return true;
- }
+ private:
+ InstanceScript* _instance;
+ };
CreatureAI* GetAI(Creature* creature) const override
{
@@ -1254,56 +1268,6 @@ class npc_lorekeeper : public CreatureScript
}
};
-//enable hardmode
-////npc_brann_bronzebeard this requires more work involving area triggers. if reached this guy speaks through his radio..
-//#define GOSSIP_ITEM_1 "xxxxx"
-//#define GOSSIP_ITEM_2 "xxxxx"
-//
-/*
-class npc_brann_bronzebeard : public CreatureScript
-{
-public:
- npc_brann_bronzebeard() : CreatureScript("npc_brann_bronzebeard") { }
-
- //bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action) override
- //{
- // player->PlayerTalkClass->ClearMenus();
- // switch (action)
- // {
- // case GOSSIP_ACTION_INFO_DEF+1:
- // if (player)
- // {
- // player->PrepareGossipMenu(creature);
- //
- // player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- // player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- // }
- // break;
- // case GOSSIP_ACTION_INFO_DEF+2:
- // if (player)
- // player->CLOSE_GOSSIP_MENU();
- // if (Creature* Lorekeeper = creature->FindNearestCreature(NPC_LOREKEEPER, 1000, true)) //lore keeper of lorgannon
- // Lorekeeper->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- // break;
- // }
- // return true;
- //}
- //bool OnGossipHello(Player* player, Creature* creature) override
- //{
- // InstanceScript* instance = creature->GetInstanceScript();
- // if (instance && instance->GetData(BOSS_LEVIATHAN) !=DONE)
- // {
- // player->PrepareGossipMenu(creature);
- //
- // player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- // player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
- // }
- // return true;
- //}
- //
-}
-*/
-
class go_ulduar_tower : public GameObjectScript
{
public:
@@ -1836,8 +1800,8 @@ void AddSC_boss_flame_leviathan()
new npc_hodirs_fury();
new npc_freyas_ward();
new npc_freya_ward_summon();
+ new npc_brann_bronzebeard_ulduar_intro();
new npc_lorekeeper();
- // new npc_brann_bronzebeard();
new go_ulduar_tower();
new achievement_three_car_garage_demolisher();
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
index 282e3ac8d2d..ebd53edc673 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/instance_ulduar.cpp
@@ -54,6 +54,15 @@ MinionData const minionData[] =
{ 0, 0, }
};
+ObjectData const creatureData[] =
+{
+ { NPC_BRANN_BRONZEBEARD_INTRO, DATA_BRANN_BRONZEBEARD_INTRO },
+ { NPC_LORE_KEEPER_OF_NORGANNON, DATA_LORE_KEEPER_OF_NORGANNON },
+ { NPC_HIGH_EXPLORER_DELLORAH, DATA_DELLORAH },
+ { NPC_BRONZEBEARD_RADIO, DATA_BRONZEBEARD_RADIO },
+ { 0, 0, }
+};
+
class instance_ulduar : public InstanceMapScript
{
public:
@@ -68,6 +77,7 @@ class instance_ulduar : public InstanceMapScript
LoadDoorData(doorData);
LoadMinionData(minionData);
+ LoadObjectData(creatureData, nullptr);
_algalonTimer = 61;
_maxArmorItemLevel = 0;
@@ -420,6 +430,8 @@ class instance_ulduar : public InstanceMapScript
algalon->AI()->JustSummoned(creature);
break;
}
+
+ InstanceScript::OnCreatureCreate(creature);
}
void OnCreatureRemove(Creature* creature) override
@@ -446,6 +458,8 @@ class instance_ulduar : public InstanceMapScript
default:
break;
}
+
+ InstanceScript::OnCreatureRemove(creature);
}
void OnGameObjectCreate(GameObject* gameObject) override
diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
index 9f640c410ef..834ab32864f 100644
--- a/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
+++ b/src/server/scripts/Northrend/Ulduar/Ulduar/ulduar.h
@@ -80,6 +80,23 @@ enum UlduarNPCs
NPC_YOGG_SARON = 33288,
NPC_ALGALON = 32871,
+ // Flame Leviathan
+ NPC_ULDUAR_COLOSSUS = 33237,
+ NPC_BRANN_BRONZEBEARD_INTRO = 33579,
+ NPC_BRANN_BRONZEBEARD_FLYING_MACHINE = 34119,
+ NPC_BRANN_S_FLYING_MACHINE = 34120,
+ NPC_ARCHMAGE_PENTARUS = 33624,
+ NPC_ARCHMAGE_RHYDIAN = 33696,
+ NPC_LORE_KEEPER_OF_NORGANNON = 33686,
+ NPC_HIGH_EXPLORER_DELLORAH = 33701,
+ NPC_BRONZEBEARD_RADIO = 34054,
+ NPC_FLAME_LEVIATHAN = 33113,
+ NPC_FLAME_LEVIATHAN_SEAT = 33114,
+ NPC_FLAME_LEVIATHAN_TURRET = 33139,
+ NPC_LEVIATHAN_DEFENSE_TURRET = 33142,
+ NPC_OVERLOAD_CONTROL_DEVICE = 33143,
+ NPC_ORBITAL_SUPPORT = 34286,
+
// Mimiron
NPC_LEVIATHAN_MKII = 33432,
NPC_VX_001 = 33651,
@@ -382,6 +399,12 @@ enum UlduarData
DATA_UNIVERSE_GLOBE,
DATA_ALGALON_TRAPDOOR,
DATA_BRANN_BRONZEBEARD_ALG,
+
+ // Misc
+ DATA_BRANN_BRONZEBEARD_INTRO,
+ DATA_LORE_KEEPER_OF_NORGANNON,
+ DATA_DELLORAH,
+ DATA_BRONZEBEARD_RADIO
};
enum UlduarWorldStates
diff --git a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
index dc923e534b0..d3868b8df9c 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_cyanigosa.cpp
@@ -16,11 +16,13 @@
*/
#include "ScriptMgr.h"
+#include "SpellScript.h"
#include "ScriptedCreature.h"
#include "violet_hold.h"
enum Spells
{
+ SPELL_SUMMON_PLAYER = 21150,
SPELL_ARCANE_VACUUM = 58694,
SPELL_BLIZZARD = 58693,
SPELL_MANA_DESTRUCTION = 59374,
@@ -42,119 +44,91 @@ enum Yells
class boss_cyanigosa : public CreatureScript
{
-public:
- boss_cyanigosa() : CreatureScript("boss_cyanigosa") { }
-
- struct boss_cyanigosaAI : public BossAI
- {
- boss_cyanigosaAI(Creature* creature) : BossAI(creature, DATA_CYANIGOSA)
- {
- Initialize();
- }
-
- void Initialize()
- {
- uiArcaneVacuumTimer = 10000;
- uiBlizzardTimer = 15000;
- uiManaDestructionTimer = 30000;
- uiTailSweepTimer = 20000;
- uiUncontrollableEnergyTimer = 25000;
- }
-
- uint32 uiArcaneVacuumTimer;
- uint32 uiBlizzardTimer;
- uint32 uiManaDestructionTimer;
- uint32 uiTailSweepTimer;
- uint32 uiUncontrollableEnergyTimer;
+ public:
+ boss_cyanigosa() : CreatureScript("boss_cyanigosa") { }
- void Reset() override
+ struct boss_cyanigosaAI : public BossAI
{
- Initialize();
- BossAI::Reset();
- }
+ boss_cyanigosaAI(Creature* creature) : BossAI(creature, DATA_CYANIGOSA) { }
- void EnterCombat(Unit* who) override
- {
- BossAI::EnterCombat(who);
- Talk(SAY_AGGRO);
- }
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ Talk(SAY_AGGRO);
+ }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- void UpdateAI(uint32 diff) override
- {
- if (instance->GetData(DATA_REMOVE_NPC) == 1)
+ void JustDied(Unit* killer) override
{
- me->DespawnOrUnsummon();
- instance->SetData(DATA_REMOVE_NPC, 0);
+ BossAI::JustDied(killer);
+ Talk(SAY_DEATH);
}
- if (!UpdateVictim())
- return;
+ void MoveInLineOfSight(Unit* /*who*/) override { }
- if (uiArcaneVacuumTimer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCastAOE(SPELL_ARCANE_VACUUM);
- uiArcaneVacuumTimer = 10000;
- } else uiArcaneVacuumTimer -= diff;
+ if (!UpdateVictim())
+ return;
- if (uiBlizzardTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_BLIZZARD);
- uiBlizzardTimer = 15000;
- } else uiBlizzardTimer -= diff;
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
+ }
- if (uiTailSweepTimer <= diff)
+ void ScheduleTasks() override
{
- DoCastVictim(SPELL_TAIL_SWEEP);
- uiTailSweepTimer = 20000;
- } else uiTailSweepTimer -= diff;
+ scheduler.Schedule(Seconds(10), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_ARCANE_VACUUM);
+ task.Repeat();
+ });
- if (uiUncontrollableEnergyTimer <= diff)
- {
- DoCastVictim(SPELL_UNCONTROLLABLE_ENERGY);
- uiUncontrollableEnergyTimer = 25000;
- } else uiUncontrollableEnergyTimer -= diff;
+ scheduler.Schedule(Seconds(15), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true))
+ DoCast(target, SPELL_BLIZZARD);
+ task.Repeat();
+ });
- if (IsHeroic())
- {
- if (uiManaDestructionTimer <= diff)
+ scheduler.Schedule(Seconds(20), [this](TaskContext task)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_MANA_DESTRUCTION);
- uiManaDestructionTimer = 30000;
- } else uiManaDestructionTimer -= diff;
- }
+ DoCastVictim(SPELL_TAIL_SWEEP);
+ task.Repeat();
+ });
- DoMeleeAttackIfReady();
- }
+ scheduler.Schedule(Seconds(25), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_UNCONTROLLABLE_ENERGY);
+ task.Repeat();
+ });
- void JustDied(Unit* killer) override
- {
- BossAI::JustDied(killer);
- Talk(SAY_DEATH);
- }
+ if (IsHeroic())
+ {
+ scheduler.Schedule(Seconds(30), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
+ DoCast(target, SPELL_MANA_DESTRUCTION);
+ task.Repeat();
+ });
+ }
+ }
+ };
- void KilledUnit(Unit* victim) override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
+ return GetVioletHoldAI<boss_cyanigosaAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_cyanigosaAI>(creature);
- }
};
class achievement_defenseless : public AchievementCriteriaScript
{
public:
- achievement_defenseless() : AchievementCriteriaScript("achievement_defenseless")
- {
- }
+ achievement_defenseless() : AchievementCriteriaScript("achievement_defenseless") { }
bool OnCheck(Player* /*player*/, Unit* target) override
{
@@ -165,10 +139,40 @@ class achievement_defenseless : public AchievementCriteriaScript
if (!instance)
return false;
- if (!instance->GetData(DATA_DEFENSELESS))
- return false;
+ return instance->GetData(DATA_DEFENSELESS) != 0;
+ }
+};
+
+class spell_cyanigosa_arcane_vacuum : public SpellScriptLoader
+{
+ public:
+ spell_cyanigosa_arcane_vacuum() : SpellScriptLoader("spell_cyanigosa_arcane_vacuum") { }
- return true;
+ class spell_cyanigosa_arcane_vacuum_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_cyanigosa_arcane_vacuum_SpellScript);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SUMMON_PLAYER))
+ return false;
+ return true;
+ }
+
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_SUMMON_PLAYER, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_cyanigosa_arcane_vacuum_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
+
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_cyanigosa_arcane_vacuum_SpellScript();
}
};
@@ -176,4 +180,5 @@ void AddSC_boss_cyanigosa()
{
new boss_cyanigosa();
new achievement_defenseless();
+ new spell_cyanigosa_arcane_vacuum();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
index 8ead8ab559e..cc27bf52118 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_erekem.cpp
@@ -41,269 +41,210 @@ enum Yells
SAY_BOTH_ADDS_KILLED = 5
};
-enum ErekemEvents
-{
- EVENT_EARTH_SHIELD = 1,
- EVENT_CHAIN_HEAL,
- EVENT_BLOODLUST,
- EVENT_LIGHTNING_BOLT,
- EVENT_EARTH_SHOCK,
- EVENT_WINDFURY,
- EVENT_STORMSTRIKE
-};
-
class boss_erekem : public CreatureScript
{
-public:
- boss_erekem() : CreatureScript("boss_erekem") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_erekemAI>(creature);
- }
-
- struct boss_erekemAI : public ScriptedAI
- {
- boss_erekemAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- phase = 0;
- breakBondsCd = 0;
- }
+ public:
+ boss_erekem() : CreatureScript("boss_erekem") { }
- void Reset() override
+ struct boss_erekemAI : public BossAI
{
- Initialize();
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
-
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ boss_erekemAI(Creature* creature) : BossAI(creature, DATA_EREKEM)
{
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
- pGuard1->DespawnOrUnsummon();
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- pGuard2->DespawnOrUnsummon();
+ Initialize();
}
- else
+
+ void Initialize()
{
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
- {
- if (!pGuard1->IsAlive())
- pGuard1->Respawn();
- }
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- {
- if (!pGuard2->IsAlive())
- pGuard2->Respawn();
- }
+ _phase = 0;
}
- events.Reset();
- }
-
- void JustReachedHome() override
- {
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
- pGuard1->Respawn();
+ void Reset() override
+ {
+ Initialize();
+ BossAI::Reset();
+ me->SetCanDualWield(false);
+ }
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- pGuard2->Respawn();
- }
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ Talk(SAY_AGGRO);
+ DoCast(me, SPELL_EARTH_SHIELD);
+ }
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type == EFFECT_MOTION_TYPE && pointId == POINT_INTRO)
+ me->SetFacingTo(4.921828f);
+ }
- if (me->Attack(who, true))
+ void JustReachedHome() override
{
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_EREKEM);
+ }
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
- {
- pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- if (!pGuard1->GetVictim() && pGuard1->AI())
- pGuard1->AI()->AttackStart(who);
- }
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- {
- pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- if (!pGuard2->GetVictim() && pGuard2->AI())
- pGuard2->AI()->AttackStart(who);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
}
- }
- void EnterCombat(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
- DoCast(me, SPELL_EARTH_SHIELD);
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+ Talk(SAY_DEATH);
+ }
- if (GameObject* door = instance->GetGameObject(DATA_EREKEM_CELL))
- if (door->GetGoState() == GO_STATE_READY)
+ bool CheckGuardAuras(Creature* guard) const
+ {
+ static uint32 const MechanicImmunityList =
+ (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);
+
+ static std::list<AuraType> const AuraImmunityList =
{
- EnterEvadeMode();
- return;
- }
+ SPELL_AURA_MOD_STUN,
+ SPELL_AURA_MOD_DECREASE_SPEED,
+ SPELL_AURA_MOD_ROOT,
+ SPELL_AURA_MOD_CONFUSE,
+ SPELL_AURA_MOD_FEAR
+ };
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ if (guard->HasAuraWithMechanic(MechanicImmunityList))
+ return true;
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_NPC);
-
- events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
- events.ScheduleEvent(EVENT_BLOODLUST, 15000);
- events.ScheduleEvent(EVENT_CHAIN_HEAL, 10000);
- events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2000);
- }
+ for (AuraType type : AuraImmunityList)
+ if (guard->HasAuraType(type))
+ return true;
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- {
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
+ return false;
}
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
+
+ bool CheckGuardAlive() const
{
- instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 13);
- }
- }
+ for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
+ {
+ if (Creature* guard = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i)))
+ if (guard->IsAlive())
+ return true;
+ }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
+ return false;
+ }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ Unit* GetChainHealTarget() const
+ {
+ if (HealthBelowPct(85))
+ return me;
- if (phase == 0)
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
{
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- {
- if (!pGuard1->IsAlive() && !pGuard2->IsAlive())
- {
- phase = 1;
- DoCastVictim(SPELL_STORMSTRIKE);
- DoCast(SPELL_WINDFURY);
- events.Reset();
- events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(2000, 8000));
- events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
- events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
- }
- }
+ if (Creature* guard = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i)))
+ if (guard->IsAlive() && !guard->HealthAbovePct(75))
+ return guard;
}
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ return nullptr;
+ }
- if (breakBondsCd <= 0)
+ void UpdateAI(uint32 diff) override
{
- if (Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1)))
+ if (!UpdateVictim())
+ return;
+
+ if (_phase == 0 && !CheckGuardAlive())
{
- if (Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2)))
- {
- if (pGuard1->IsAlive())
- {
- if (pGuard1->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard1->HasAuraType(SPELL_AURA_MOD_ROOT)
- || pGuard1->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard1->HasAuraType(SPELL_AURA_MOD_PACIFY)
- || pGuard1->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
- {
- DoCast(SPELL_BREAK_BONDS);
- breakBondsCd = 10000;
- return;
- }
- }
- if (pGuard2->IsAlive())
- {
- if (pGuard2->HasAuraType(SPELL_AURA_MOD_STUN) || pGuard2->HasAuraType(SPELL_AURA_MOD_ROOT)
- || pGuard2->HasAuraType(SPELL_AURA_MOD_CONFUSE) || pGuard2->HasAuraType(SPELL_AURA_MOD_PACIFY)
- || pGuard2->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
- {
- DoCast(SPELL_BREAK_BONDS);
- breakBondsCd = 10000;
- return;
- }
- }
- }
+ _phase = 1;
+ me->SetCanDualWield(true);
+ DoCast(me, SPELL_WINDFURY, true);
}
+
+ scheduler.Update(diff, [this]
+ {
+ if (_phase == 1)
+ DoSpellAttackIfReady(SPELL_STORMSTRIKE);
+ else
+ DoMeleeAttackIfReady();
+ });
}
- else
- breakBondsCd -= diff;
- switch (events.ExecuteEvent())
+ void ScheduleTasks() override
{
- case EVENT_EARTH_SHIELD:
+ scheduler.Schedule(Seconds(20), [this](TaskContext task)
+ {
if (Unit* ally = DoSelectLowestHpFriendly(30.0f))
DoCast(ally, SPELL_EARTH_SHIELD);
- events.ScheduleEvent(EVENT_EARTH_SHIELD, 20000);
- break;
- case EVENT_BLOODLUST:
+
+ task.Repeat(Seconds(20));
+ });
+
+ scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
DoCast(SPELL_BLOODLUST);
- events.ScheduleEvent(EVENT_BLOODLUST, urand(35000, 45000));
- break;
- case EVENT_LIGHTNING_BOLT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ task.Repeat(Seconds(35), Seconds(45));
+ });
+
+ scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f))
DoCast(target, SPELL_LIGHTNING_BOLT);
- events.ScheduleEvent(EVENT_LIGHTNING_BOLT, 2500);
- break;
- case EVENT_CHAIN_HEAL:
+
+ task.Repeat(Milliseconds(2500));
+ });
+
+ scheduler.Schedule(Seconds(10), [this](TaskContext task)
+ {
if (Unit* ally = DoSelectLowestHpFriendly(40.0f))
DoCast(ally, SPELL_CHAIN_HEAL);
+
+ if (!CheckGuardAlive())
+ task.Repeat(Seconds(3));
+ else
+ task.Repeat(Seconds(8), Seconds(11));
+ });
+
+ scheduler.Schedule(Seconds(2), Seconds(8), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_EARTH_SHOCK);
+ task.Repeat(Seconds(8), Seconds(13));
+ });
+
+ scheduler.Schedule(Seconds(0), [this](TaskContext task)
+ {
+ for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
{
- Creature* pGuard1 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_1));
- Creature* pGuard2 = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_EREKEM_GUARD_2));
- events.ScheduleEvent(EVENT_CHAIN_HEAL, ((pGuard1 && !pGuard1->IsAlive()) || (pGuard2 && !pGuard2->IsAlive()) ? 3000 : 8000 + rand() % 3000));
+ Creature* guard = ObjectAccessor::GetCreature(*me, instance->GetGuidData(i));
+
+ if (guard && guard->IsAlive() && CheckGuardAuras(guard))
+ {
+ DoCastAOE(SPELL_BREAK_BONDS);
+ task.Repeat(Seconds(10));
+ return;
+ }
}
- break;
- case EVENT_EARTH_SHOCK:
- DoCastVictim(SPELL_EARTH_SHOCK);
- events.ScheduleEvent(EVENT_EARTH_SHOCK, urand(8000, 13000));
- break;
- case EVENT_WINDFURY:
- DoCast(SPELL_WINDFURY);
- events.ScheduleEvent(EVENT_WINDFURY, urand(1500, 2000));
- break;
- case EVENT_STORMSTRIKE:
- DoCastVictim(SPELL_STORMSTRIKE);
- events.ScheduleEvent(EVENT_STORMSTRIKE, urand(1500, 2000));
- break;
- default:
- break;
+ task.Repeat(Milliseconds(500));
+ });
}
- DoMeleeAttackIfReady();
- }
+ private:
+ uint8 _phase;
+ };
- private:
- EventMap events;
- InstanceScript* instance;
- uint8 phase;
- int32 breakBondsCd;
- };
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<boss_erekemAI>(creature);
+ }
};
enum GuardSpells
@@ -315,85 +256,61 @@ enum GuardSpells
class npc_erekem_guard : public CreatureScript
{
-public:
- npc_erekem_guard() : CreatureScript("npc_erekem_guard") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_erekem_guardAI>(creature);
- }
+ public:
+ npc_erekem_guard() : CreatureScript("npc_erekem_guard") { }
- struct npc_erekem_guardAI : public ScriptedAI
- {
- npc_erekem_guardAI(Creature* creature) : ScriptedAI(creature)
+ struct npc_erekem_guardAI : public ScriptedAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ npc_erekem_guardAI(Creature* creature) : ScriptedAI(creature) { }
- void Initialize()
- {
- uiStrikeTimer = urand(4000, 8000);
- uiHowlingScreechTimer = urand(8000, 13000);
- uiGushingWoundTimer = urand(1000, 3000);
- }
+ void Reset() override
+ {
+ scheduler.CancelAll();
+ }
- uint32 uiGushingWoundTimer;
- uint32 uiHowlingScreechTimer;
- uint32 uiStrikeTimer;
+ void EnterCombat(Unit* /*who*/) override
+ {
+ DoZoneInCombat();
+ }
- InstanceScript* instance;
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- void Reset() override
- {
- Initialize();
+ scheduler.Update(diff,
+ std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
+ }
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC);
- }
+ void ScheduledTasks()
+ {
+ scheduler.Schedule(Seconds(4), Seconds(8), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_STRIKE);
+ task.Repeat(Seconds(4), Seconds(8));
+ });
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ scheduler.Schedule(Seconds(8), Seconds(13), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_HOWLING_SCREECH);
+ task.Repeat(Seconds(8), Seconds(13));
+ });
- if (me->Attack(who, true))
- {
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ scheduler.Schedule(Seconds(1), Seconds(3), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_GUSHING_WOUND);
+ task.Repeat(Seconds(7), Seconds(12));
+ });
}
- }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ private:
+ TaskScheduler scheduler;
+ };
- void UpdateAI(uint32 diff) override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (!UpdateVictim())
- return;
-
- DoMeleeAttackIfReady();
-
- if (uiStrikeTimer <= diff)
- {
- DoCastVictim(SPELL_STRIKE);
- uiStrikeTimer = urand(4000, 8000);
- } else uiStrikeTimer -= diff;
-
- if (uiHowlingScreechTimer <= diff)
- {
- DoCastVictim(SPELL_HOWLING_SCREECH);
- uiHowlingScreechTimer = urand(8000, 13000);
- } else uiHowlingScreechTimer -= diff;
-
- if (uiGushingWoundTimer <= diff)
- {
- DoCastVictim(SPELL_GUSHING_WOUND);
- uiGushingWoundTimer = urand(7000, 12000);
- } else uiGushingWoundTimer -= diff;
+ return GetVioletHoldAI<npc_erekem_guardAI>(creature);
}
- };
};
void AddSC_boss_erekem()
diff --git a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
index caf1392ea38..3c29cc1123c 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_ichoron.cpp
@@ -17,26 +17,32 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
+#include "SpellAuraEffects.h"
+#include "SpellScript.h"
#include "violet_hold.h"
enum Spells
{
- SPELL_DRAINED = 59820,
- SPELL_FRENZY = 54312,
- SPELL_PROTECTIVE_BUBBLE = 54306,
SPELL_WATER_BLAST = 54237,
SPELL_WATER_BOLT_VOLLEY = 54241,
- SPELL_SPLASH = 59516,
+ SPELL_SPLATTER = 54259,
+ SPELL_PROTECTIVE_BUBBLE = 54306,
+ SPELL_FRENZY = 54312,
SPELL_BURST = 54379,
- SPELL_WATER_GLOBULE = 54268,
- SPELL_MERGE = 54269,
- SPELL_WATER_GLOBULE_VISUAL = 54260
-};
+ SPELL_DRAINED = 59820,
+ SPELL_THREAT_PROC = 61732,
+ SPELL_SHRINK = 54297,
-enum IchoronCreatures
-{
- NPC_ICHOR_GLOBULE = 29321,
- NPC_ICHORON_SUMMON_TARGET = 29326
+ SPELL_WATER_GLOBULE_SUMMON_1 = 54258,
+ SPELL_WATER_GLOBULE_SUMMON_2 = 54264,
+ SPELL_WATER_GLOBULE_SUMMON_3 = 54265,
+ SPELL_WATER_GLOBULE_SUMMON_4 = 54266,
+ SPELL_WATER_GLOBULE_SUMMON_5 = 54267,
+ SPELL_WATER_GLOBULE_TRANSFORM = 54268,
+ SPELL_WATER_GLOBULE_VISUAL = 54260,
+
+ SPELL_MERGE = 54269,
+ SPELL_SPLASH = 59516
};
enum Yells
@@ -47,483 +53,412 @@ enum Yells
SAY_SPAWN = 3,
SAY_ENRAGE = 4,
SAY_SHATTER = 5,
- SAY_BUBBLE = 6
+ SAY_BUBBLE = 6,
+ EMOTE_SHATTER = 7
};
enum Actions
{
- ACTION_WATER_ELEMENT_HIT = 1
-};
-
-enum IchoronEvents
-{
- EVENT_WATER_BLAST = 1,
- EVENT_WATER_BOLT_VOLLEY
-};
-
-enum GlobuleEvents
-{
- EVENT_GLOBULE_MOVE = 1
+ ACTION_WATER_GLOBULE_HIT = 1,
+ ACTION_PROTECTIVE_BUBBLE_SHATTERED = 2,
+ ACTION_DRAINED = 3
};
enum Misc
{
- DATA_GLOBULE_PATH = 0,
DATA_DEHYDRATION = 1
};
-
-#define MAX_GLOBULE_PATHS 10
-
-Position const globulePaths[MAX_GLOBULE_PATHS] =
-{
- // first target
- { 1861.357f, 804.039f, 44.008f, 6.268f },
- { 1869.375f, 803.976f, 38.781f, 0.009f },
- // second target
- { 1888.063f, 763.488f, 47.667f, 1.744f },
- { 1882.865f, 776.385f, 38.824f, 1.882f },
- // third target
- { 1935.140f, 817.752f, 52.181f, 1.885f },
- { 1916.642f, 826.337f, 39.139f, 2.851f },
- // fourth target
- { 1930.257f, 833.053f, 46.906f, 4.579f },
- { 1916.642f, 826.337f, 39.139f, 2.851f },
- // fifth target
- { 1878.248f, 841.883f, 43.334f, 4.717f },
- { 1879.438f, 834.443f, 38.699f, 4.831f }
-};
-
class boss_ichoron : public CreatureScript
{
-public:
- boss_ichoron() : CreatureScript("boss_ichoron") { }
+ public:
+ boss_ichoron() : CreatureScript("boss_ichoron") { }
- struct boss_ichoronAI : public ScriptedAI
- {
- boss_ichoronAI(Creature* creature) : ScriptedAI(creature), m_waterElements(creature)
+ struct boss_ichoronAI : public BossAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ boss_ichoronAI(Creature* creature) : BossAI(creature, DATA_ICHORON)
+ {
+ Initialize();
- void Initialize()
- {
- bIsExploded = false;
- bIsFrenzy = false;
- bIsDrained = false;
- dehydration = true;
- drainedTimer = 50;
- burstTimer = 15000;
- }
+ /// for some reason ichoron can't walk back to it's water basin on evade
+ me->AddUnitState(UNIT_STATE_IGNORE_PATHFINDING);
+ }
- void Reset() override
- {
- Initialize();
+ void Initialize()
+ {
+ _isFrenzy = false;
+ _dehydration = true;
+ }
- events.Reset();
- me->SetVisible(true);
- DespawnWaterElements();
+ void Reset() override
+ {
+ Initialize();
+ BossAI::Reset();
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- }
+ DoCast(me, SPELL_THREAT_PROC, true);
+ }
- void EnterCombat(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ Talk(SAY_AGGRO);
+ }
- DoCast(me, SPELL_PROTECTIVE_BUBBLE);
+ void JustReachedHome() override
+ {
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_ICHORON);
+ }
- if (GameObject* door = instance->GetGameObject(DATA_ICHORON_CELL))
- if (door->GetGoState() == GO_STATE_READY)
+ void DoAction(int32 actionId) override
+ {
+ switch (actionId)
{
- EnterEvadeMode();
- return;
- }
+ case ACTION_WATER_GLOBULE_HIT:
+ if (!me->IsAlive())
+ break;
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ me->ModifyHealth(int32(me->CountPctFromMaxHealth(3)));
+ _dehydration = false;
+ break;
+ case ACTION_PROTECTIVE_BUBBLE_SHATTERED:
+ {
+ Talk(SAY_SHATTER);
+ Talk(EMOTE_SHATTER);
- events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
- events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
- }
+ DoCastAOE(SPELL_SPLATTER, true);
+ DoCastAOE(SPELL_BURST, true);
+ DoCast(me, SPELL_DRAINED, true);
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ uint32 damage = me->CountPctFromMaxHealth(30);
+ me->LowerPlayerDamageReq(damage);
+ me->ModifyHealth(-std::min<int32>(damage, me->GetHealth() - 1));
- if (me->Attack(who, true))
- {
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ scheduler.DelayAll(Seconds(15));
+ break;
+ }
+ case ACTION_DRAINED:
+ if (HealthAbovePct(30))
+ {
+ Talk(SAY_BUBBLE);
+ DoCast(me, SPELL_PROTECTIVE_BUBBLE, true);
+ }
+ break;
+ default:
+ break;
+ }
}
- }
- void DoAction(int32 param) override
- {
- if (!me->IsAlive())
- return;
+ uint32 GetData(uint32 type) const override
+ {
+ if (type == DATA_DEHYDRATION)
+ return _dehydration ? 1 : 0;
+ return 0;
+ }
- switch (param)
+ void KilledUnit(Unit* victim) override
{
- case ACTION_WATER_ELEMENT_HIT:
- {
- if (bIsExploded)
- DoExplodeCompleted();
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- me->SetHealth(me->GetHealth() + me->CountPctFromMaxHealth(3));
- dehydration = false;
- }
- break;
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+ Talk(SAY_DEATH);
}
- }
- void DespawnWaterElements()
- {
- m_waterElements.DespawnAll();
- }
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
- // call when explode shall stop.
- // either when "hit" by a bubble, or when there is no bubble left.
- void DoExplodeCompleted()
- {
- bIsExploded = false;
- bIsDrained = false;
+ if (summon->GetEntry() == NPC_ICHOR_GLOBULE)
+ DoCast(summon, SPELL_WATER_GLOBULE_VISUAL);
+ }
- if (!HealthBelowPct(25))
+ void SummonedCreatureDespawn(Creature* summon) override
{
- Talk(SAY_BUBBLE);
- DoCast(me, SPELL_PROTECTIVE_BUBBLE, true);
+ BossAI::SummonedCreatureDespawn(summon);
+
+ if (summons.empty())
+ me->RemoveAurasDueToSpell(SPELL_DRAINED, ObjectGuid::Empty, 0, AURA_REMOVE_BY_EXPIRE);
}
- me->SetVisible(true);
- me->GetMotionMaster()->MoveChase(me->GetVictim());
- }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- uint32 GetData(uint32 type) const override
- {
- if (type == DATA_DEHYDRATION)
- return dehydration ? 1 : 0;
+ if (!_isFrenzy && HealthBelowPct(25) && !me->HasAura(SPELL_DRAINED))
+ {
+ Talk(SAY_ENRAGE);
+ DoCast(me, SPELL_FRENZY, true);
+ _isFrenzy = true;
+ }
- return 0;
- }
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
+ }
- void MoveInLineOfSight(Unit* who) override
- {
- if (!who->ToCreature())
- return;
+ void ScheduleTasks() override
+ {
+ scheduler.Async([this]
+ {
+ DoCast(me, SPELL_SHRINK);
+ DoCast(me, SPELL_PROTECTIVE_BUBBLE);
+ });
- if (who->GetEntry() != NPC_ICHOR_GLOBULE)
- return;
+ scheduler.Schedule(Seconds(10), Seconds(15), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_WATER_BOLT_VOLLEY);
+ task.Repeat(Seconds(10), Seconds(15));
+ });
- if (!me->IsWithinDist(who, 4.0f, false))
- return;
+ scheduler.Schedule(Seconds(6), Seconds(9), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f))
+ DoCast(target, SPELL_WATER_BLAST);
+ task.Repeat(Seconds(6), Seconds(9));
+ });
+ }
- if (who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
- return;
+ private:
+ bool _isFrenzy;
+ bool _dehydration;
+ };
- who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- who->CastSpell(who, SPELL_MERGE);
- DoAction(ACTION_WATER_ELEMENT_HIT);
- who->ToCreature()->DespawnOrUnsummon(1000);
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<boss_ichoronAI>(creature);
}
+};
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
+class npc_ichor_globule : public CreatureScript
+{
+ public:
+ npc_ichor_globule() : CreatureScript("npc_ichor_globule") { }
- if (bIsExploded)
+ struct npc_ichor_globuleAI : public ScriptedAI
+ {
+ npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature)
{
- bIsExploded = false;
- me->SetVisible(true);
+ _instance = creature->GetInstanceScript();
+ creature->SetReactState(REACT_PASSIVE);
}
- DespawnWaterElements();
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- {
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
- }
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
+ void SpellHit(Unit* caster, SpellInfo const* spellInfo) override
{
- instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 13);
+ if (spellInfo->Id == SPELL_WATER_GLOBULE_VISUAL)
+ {
+ DoCast(me, SPELL_WATER_GLOBULE_TRANSFORM);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ me->GetMotionMaster()->MoveFollow(caster, 0.0f, 0.0f);
+ }
}
- }
- void JustSummoned(Creature* summoned) override
- {
- summoned->SetSpeed(MOVE_RUN, 0.3f);
- m_waterElements.Summon(summoned);
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != FOLLOW_MOTION_TYPE)
+ return;
- instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
- }
+ if (_instance->GetObjectGuid(DATA_ICHORON).GetCounter() != id)
+ return;
- void SummonedCreatureDespawn(Creature* summoned) override
- {
- m_waterElements.Despawn(summoned);
+ me->CastSpell(me, SPELL_MERGE);
+ me->DespawnOrUnsummon(1);
+ }
- if (m_waterElements.empty() && bIsExploded)
+ // on retail spell casted on a creature's death are not casted after death but keeping mob at 1 health, casting it and then letting the mob die.
+ // this feature should be still implemented
+ void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
- me->RemoveAllAuras();
- DoExplodeCompleted();
+ if (damage >= me->GetHealth())
+ DoCastAOE(SPELL_SPLASH);
}
- instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
- }
+ void UpdateAI(uint32 /*diff*/) override { }
+
+ private:
+ InstanceScript* _instance;
+ };
- void KilledUnit(Unit* victim) override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
+ return GetVioletHoldAI<npc_ichor_globuleAI>(creature);
}
+};
+
+// 59820 - Drained
+class spell_ichoron_drained : public SpellScriptLoader
+{
+ public:
+ spell_ichoron_drained() : SpellScriptLoader("spell_ichoron_drained") { }
- void UpdateAI(uint32 diff) override
+ class spell_ichoron_drained_AuraScript : public AuraScript
{
- if (!UpdateVictim())
- return;
+ PrepareAuraScript(spell_ichoron_drained_AuraScript);
- if (!bIsFrenzy && HealthBelowPct(25) && !bIsExploded)
+ bool Load() override
{
- Talk(SAY_ENRAGE);
- DoCast(me, SPELL_FRENZY, true);
- bIsFrenzy = true;
+ return GetOwner()->GetEntry() == NPC_ICHORON || GetOwner()->GetEntry() == NPC_DUMMY_ICHORON;
}
- if (!bIsFrenzy)
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (!bIsExploded)
- {
- if (!me->HasAura(SPELL_PROTECTIVE_BUBBLE))
- {
- bIsExploded = true;
- Talk(SAY_SHATTER);
- DoCast(SPELL_BURST);
- me->RemoveAllAuras();
- burstTimer = 15000;
+ GetTarget()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_31);
+ GetTarget()->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ }
- std::list<Creature*> summonTargets;
- GetCreatureListWithEntryInGrid(summonTargets, me, NPC_ICHORON_SUMMON_TARGET, 200.0f);
- std::list<Creature*>::iterator itr = summonTargets.begin();
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_UNK_31);
+ GetTarget()->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- for (uint8 i = 0; i < MAX_GLOBULE_PATHS; i++)
- {
- std::advance(itr, urand(0, summonTargets.size() - 1)); // I take a random minion in the list
- Position targetPos = (*itr)->GetRandomNearPosition(10.0f);
- itr = summonTargets.begin();
- TempSummon* globule = me->SummonCreature(NPC_ICHOR_GLOBULE, targetPos, TEMPSUMMON_CORPSE_DESPAWN);
- DoCast(globule, SPELL_WATER_GLOBULE_VISUAL);
-
- float minDistance = 1000.0f;
- uint8 nextPath = 0;
- // I move the globules to next position. the 10 positions are in couples, defined in globulePaths, so i have to increase by 2.
- for (uint8 gpath = 0; gpath < MAX_GLOBULE_PATHS; gpath += 2)
- {
- if (globule->GetDistance(globulePaths[gpath]) < minDistance)
- {
- minDistance = globule->GetDistance(globulePaths[gpath]);
- nextPath = gpath;
- }
- }
-
- globule->GetAI()->SetData(DATA_GLOBULE_PATH, nextPath);
- }
- return;
- }
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ if (GetTarget()->IsAIEnabled)
+ GetTarget()->GetAI()->DoAction(ACTION_DRAINED);
+ }
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_ichoron_drained_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_ichoron_drained_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
- events.Update(diff);
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_ichoron_drained_AuraScript();
+ }
+};
- switch (events.ExecuteEvent())
- {
- case EVENT_WATER_BLAST:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_WATER_BLAST);
- events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
- break;
- case EVENT_WATER_BOLT_VOLLEY:
- DoCast(SPELL_WATER_BOLT_VOLLEY);
- events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
- break;
- }
+// 54269 - Merge
+class spell_ichoron_merge : public SpellScriptLoader
+{
+ public:
+ spell_ichoron_merge() : SpellScriptLoader("spell_ichoron_merge") { }
- DoMeleeAttackIfReady();
- }
- else if (!bIsDrained)
- {
- if (drainedTimer <= 0)
- {
- bIsDrained = true;
- drainedTimer = 50;
- uint32 damage = me->CountPctFromMaxHealth(30);
- if (me->GetHealth() < damage)
- me->SetHealth(me->CountPctFromMaxHealth(1));
- else
- {
- me->SetHealth(me->GetHealth() - damage);
- me->LowerPlayerDamageReq(damage);
- }
- DoCast(SPELL_DRAINED);
- me->SetVisible(false);
- me->AttackStop();
- }
- else
- drainedTimer -= diff;
- }
- else if (bIsDrained)
- {
- if (burstTimer <= 0)
- {
- DoExplodeCompleted();
- }
- else
- burstTimer -= diff;
- }
- }
- else
- {
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ class spell_ichoron_merge_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_ichoron_merge_SpellScript);
- events.Update(diff);
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_SHRINK))
+ return false;
+ return true;
+ }
- switch (events.ExecuteEvent())
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Creature* target = GetHitCreature())
{
- case EVENT_WATER_BLAST:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_WATER_BLAST);
- events.ScheduleEvent(EVENT_WATER_BLAST, urand(6000, 9000));
- break;
- case EVENT_WATER_BOLT_VOLLEY:
- DoCast(SPELL_WATER_BOLT_VOLLEY);
- events.ScheduleEvent(EVENT_WATER_BOLT_VOLLEY, urand(10000, 15000));
- break;
+ if (Aura* aura = target->GetAura(SPELL_SHRINK))
+ aura->ModStackAmount(-1);
+
+ target->AI()->DoAction(ACTION_WATER_GLOBULE_HIT);
}
+ }
- DoMeleeAttackIfReady();
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_ichoron_merge_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
- }
+ };
- private:
- InstanceScript* instance;
- SummonList m_waterElements;
- EventMap events;
- bool bIsExploded;
- bool bIsFrenzy;
- bool bIsDrained;
- bool dehydration;
- int32 drainedTimer;
- int32 burstTimer;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_ichoronAI>(creature);
- }
+ SpellScript* GetSpellScript() const override
+ {
+ return new spell_ichoron_merge_SpellScript();
+ }
};
-class npc_ichor_globule : public CreatureScript
+// 54306 - Protective Bubble
+class spell_ichoron_protective_bubble : public SpellScriptLoader
{
-public:
- npc_ichor_globule() : CreatureScript("npc_ichor_globule") { }
+ public:
+ spell_ichoron_protective_bubble() : SpellScriptLoader("spell_ichoron_protective_bubble") { }
- struct npc_ichor_globuleAI : public ScriptedAI
- {
- npc_ichor_globuleAI(Creature* creature) : ScriptedAI(creature)
+ class spell_ichoron_protective_bubble_AuraScript : public AuraScript
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ PrepareAuraScript(spell_ichoron_protective_bubble_AuraScript);
- void Initialize()
- {
- pathId = 0;
- }
+ bool Load() override
+ {
+ return GetOwner()->GetEntry() == NPC_ICHORON || GetOwner()->GetEntry() == NPC_DUMMY_ICHORON;
+ }
- void Reset() override
- {
- Initialize();
- events.Reset();
- DoCast(SPELL_WATER_GLOBULE);
- me->SetReactState(REACT_PASSIVE);
- }
+ void HandleShatter(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ //if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL)
+ if (GetAura()->GetCharges() <= 1)
+ if (GetTarget()->IsAIEnabled)
+ GetTarget()->GetAI()->DoAction(ACTION_PROTECTIVE_BUBBLE_SHATTERED);
+ }
- void SetData(uint32 id, uint32 data) override
- {
- if (id == DATA_GLOBULE_PATH)
+ void Register() override
{
- pathId = data;
- me->GetMotionMaster()->MovePoint(0, globulePaths[pathId]);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_ichoron_protective_bubble_AuraScript::HandleShatter, EFFECT_0, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, AURA_EFFECT_HANDLE_REAL);
}
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_ichoron_protective_bubble_AuraScript();
}
+};
- void MovementInform(uint32 type, uint32 id) override
+// 54259 - Splatter
+class spell_ichoron_splatter : public SpellScriptLoader
+{
+ public:
+ spell_ichoron_splatter() : SpellScriptLoader("spell_ichoron_splatter") { }
+
+ class spell_ichoron_splatter_AuraScript : public AuraScript
{
- if (type != POINT_MOTION_TYPE)
- return;
+ PrepareAuraScript(spell_ichoron_splatter_AuraScript);
- switch (id)
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- case 0:
- me->GetMotionMaster()->Clear();
- events.ScheduleEvent(EVENT_GLOBULE_MOVE, 500);
- break;
- case 1:
- me->GetMotionMaster()->Clear();
- if (Creature* ichoron = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_ICHORON)))
- me->GetMotionMaster()->MoveFollow(ichoron, 0.0f, 0.0f);
- break;
+ if (!sSpellMgr->GetSpellInfo(SPELL_WATER_GLOBULE_SUMMON_1)
+ || !sSpellMgr->GetSpellInfo(SPELL_WATER_GLOBULE_SUMMON_2)
+ || !sSpellMgr->GetSpellInfo(SPELL_WATER_GLOBULE_SUMMON_3)
+ || !sSpellMgr->GetSpellInfo(SPELL_WATER_GLOBULE_SUMMON_4)
+ || !sSpellMgr->GetSpellInfo(SPELL_WATER_GLOBULE_SUMMON_5)
+ || !sSpellMgr->GetSpellInfo(SPELL_SHRINK))
+ return false;
+ return true;
}
- }
- // on retail spell casted on a creature's death are not casted after death but keeping mob at 1 health, casting it and then letting the mob die.
- // this feature should be still implemented
- void DamageTaken(Unit* /*attacker*/, uint32 &damage) override
- {
- int32 actualHp = me->GetHealth();
- actualHp -= damage;
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
+ {
+ PreventDefaultAction();
+ GetTarget()->CastSpell(GetTarget(), RAND(SPELL_WATER_GLOBULE_SUMMON_1, SPELL_WATER_GLOBULE_SUMMON_2, SPELL_WATER_GLOBULE_SUMMON_3, SPELL_WATER_GLOBULE_SUMMON_4, SPELL_WATER_GLOBULE_SUMMON_5), true);
+ }
- if (actualHp <= 0)
- DoCast(SPELL_SPLASH);
- }
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
+ if (Aura* aura = GetTarget()->GetAura(SPELL_SHRINK))
+ aura->ModStackAmount(10);
+ }
- void UpdateAI(uint32 diff) override
- {
- events.Update(diff);
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_ichoron_splatter_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_ichoron_splatter_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
- if (events.ExecuteEvent() == EVENT_GLOBULE_MOVE)
- me->GetMotionMaster()->MovePoint(1, globulePaths[pathId + 1]);
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_ichoron_splatter_AuraScript();
}
-
- private:
- InstanceScript* instance;
- EventMap events;
- uint8 pathId;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_ichor_globuleAI>(creature);
- }
};
class achievement_dehydration : public AchievementCriteriaScript
{
public:
- achievement_dehydration() : AchievementCriteriaScript("achievement_dehydration")
- {
- }
+ achievement_dehydration() : AchievementCriteriaScript("achievement_dehydration") { }
bool OnCheck(Player* /*player*/, Unit* target) override
{
@@ -542,5 +477,9 @@ void AddSC_boss_ichoron()
{
new boss_ichoron();
new npc_ichor_globule();
+ new spell_ichoron_drained();
+ new spell_ichoron_merge();
+ new spell_ichoron_protective_bubble();
+ new spell_ichoron_splatter();
new achievement_dehydration();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
index 8b77b512ca4..c3b617f8199 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_lavanthor.cpp
@@ -27,130 +27,82 @@ enum Spells
SPELL_LAVA_BURN = 54249
};
-enum LavanthorEvents
-{
- EVENT_CAUTERIZING_FLAMES = 1,
- EVENT_FIREBOLT,
- EVENT_FLAME_BREATH,
- EVENT_LAVA_BURN
-};
-
class boss_lavanthor : public CreatureScript
{
-public:
- boss_lavanthor() : CreatureScript("boss_lavanthor") { }
+ public:
+ boss_lavanthor() : CreatureScript("boss_lavanthor") { }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_lavanthorAI>(creature);
- }
-
- struct boss_lavanthorAI : public ScriptedAI
- {
- boss_lavanthorAI(Creature* creature) : ScriptedAI(creature)
+ struct boss_lavanthorAI : public BossAI
{
- instance = creature->GetInstanceScript();
- }
+ boss_lavanthorAI(Creature* creature) : BossAI(creature, DATA_LAVANTHOR) { }
- void Reset() override
- {
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
-
- events.Reset();
- }
-
- void EnterCombat(Unit* /*who*/) override
- {
- if (GameObject* door = instance->GetGameObject(DATA_LAVANTHOR_CELL))
- if (door->GetGoState() == GO_STATE_READY)
- {
- EnterEvadeMode();
- return;
- }
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
-
- events.ScheduleEvent(EVENT_FIREBOLT, 1000);
- events.ScheduleEvent(EVENT_FLAME_BREATH, 5000);
- events.ScheduleEvent(EVENT_LAVA_BURN, 10000);
- if (IsHeroic())
- events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, 3000);
- }
+ void Reset() override
+ {
+ BossAI::Reset();
+ }
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ }
- if (me->Attack(who, true))
+ void JustReachedHome() override
{
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_LAVANTHOR);
}
- }
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+ }
- events.Update(diff);
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
+ }
- switch (events.ExecuteEvent())
+ void ScheduleTasks() override
{
- case EVENT_FIREBOLT:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ scheduler.Schedule(Seconds(1), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
DoCast(target, SPELL_FIREBOLT);
- events.ScheduleEvent(EVENT_FIREBOLT, urand(5000, 13000));
- break;
- case EVENT_FLAME_BREATH:
- DoCast(SPELL_FLAME_BREATH);
- events.ScheduleEvent(EVENT_FLAME_BREATH, urand(10000, 15000));
- break;
- case EVENT_LAVA_BURN:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ task.Repeat(Seconds(5), Seconds(13));
+ });
+
+ scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_FLAME_BREATH);
+ task.Repeat(Seconds(10), Seconds(15));
+ });
+
+ scheduler.Schedule(Seconds(10), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f))
DoCast(target, SPELL_LAVA_BURN);
- events.ScheduleEvent(EVENT_LAVA_BURN, urand(15000, 23000));
- break;
- case EVENT_CAUTERIZING_FLAMES:
- DoCast(SPELL_CAUTERIZING_FLAMES);
- events.ScheduleEvent(EVENT_CAUTERIZING_FLAMES, urand(10000, 16000));
- break;
- default:
- break;
- }
+ task.Repeat(Seconds(15), Seconds(23));
+ });
- DoMeleeAttackIfReady();
- }
+ if (IsHeroic())
+ {
+ scheduler.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_CAUTERIZING_FLAMES);
+ task.Repeat(Seconds(10), Seconds(16));
+ });
+ }
+ }
+ };
- void JustDied(Unit* /*killer*/) override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- {
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
- }
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- {
- instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 13);
- }
+ return GetVioletHoldAI<boss_lavanthorAI>(creature);
}
-
- private:
- EventMap events;
- InstanceScript* instance;
- };
};
void AddSC_boss_lavanthor()
diff --git a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
index ee89faac3a4..4c5c0373b8c 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_moragg.cpp
@@ -25,8 +25,10 @@ enum Spells
{
SPELL_CORROSIVE_SALIVA = 54527,
SPELL_OPTIC_LINK = 54396,
- SPELL_RAY_OF_PAIN = 54438, // NYI missing spelldifficulty
- SPELL_RAY_OF_SUFFERING = 54442, // NYI missing spelldifficulty
+ SPELL_RAY_OF_PAIN = 54438,
+ SPELL_RAY_OF_PAIN_H = 59523,
+ SPELL_RAY_OF_SUFFERING = 54442,
+ SPELL_RAY_OF_SUFFERING_H = 59524,
// Visual
SPELL_OPTIC_LINK_LEVEL_1 = 54393,
@@ -34,191 +36,107 @@ enum Spells
SPELL_OPTIC_LINK_LEVEL_3 = 54395
};
-enum MoraggEvents
-{
- EVENT_CORROSIVE_SALIVA = 1,
- EVENT_OPTIC_LINK
-};
-
class boss_moragg : public CreatureScript
{
-public:
- boss_moragg() : CreatureScript("boss_moragg") { }
-
- struct boss_moraggAI : public ScriptedAI
- {
- boss_moraggAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
-
- void Reset() override
- {
- events.Reset();
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- }
+ public:
+ boss_moragg() : CreatureScript("boss_moragg") { }
- void EnterCombat(Unit* /*who*/) override
+ struct boss_moraggAI : public BossAI
{
- if (GameObject* door = instance->GetGameObject(DATA_MORAGG_CELL))
- if (door->GetGoState() == GO_STATE_READY)
- {
- EnterEvadeMode();
- return;
- }
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
-
- me->SetInCombatWithZone();
-
- DoCast(SPELL_RAY_OF_PAIN);
- DoCast(SPELL_RAY_OF_SUFFERING);
- events.ScheduleEvent(EVENT_OPTIC_LINK, 15000);
- events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 5000);
- }
-
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ boss_moraggAI(Creature* creature) : BossAI(creature, DATA_MORAGG) { }
- if (me->Attack(who, true))
+ void Reset() override
{
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ BossAI::Reset();
}
- }
-
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- switch (events.ExecuteEvent())
+ void EnterCombat(Unit* who) override
{
- case EVENT_OPTIC_LINK:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_OPTIC_LINK);
- events.ScheduleEvent(EVENT_OPTIC_LINK, 25000);
- break;
- case EVENT_CORROSIVE_SALIVA:
- DoCastVictim(SPELL_CORROSIVE_SALIVA);
- events.ScheduleEvent(EVENT_CORROSIVE_SALIVA, 10000);
- break;
- default:
- break;
+ BossAI::EnterCombat(who);
}
- DoMeleeAttackIfReady();
- }
-
- void JustDied(Unit* /*killer*/) override
- {
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
+ void JustReachedHome() override
{
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_MORAGG);
}
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
+
+ void JustDied(Unit* killer) override
{
- instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 13);
+ BossAI::JustDied(killer);
}
- }
-
- private:
- EventMap events;
- InstanceScript* instance;
- };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_moraggAI>(creature);
- }
-};
-
-class spell_moragg_ray_of_suffering : public SpellScriptLoader
-{
-public:
- spell_moragg_ray_of_suffering() : SpellScriptLoader("spell_moragg_ray_of_suffering") { }
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- class spell_moragg_ray_of_suffering_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_moragg_ray_of_suffering_AuraScript);
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
+ }
- void OnPeriodic(AuraEffect const* aurEff)
- {
- PreventDefaultAction();
- std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
- if (!players.empty())
+ void ScheduleTasks() override
{
- std::list<HostileReference*>::iterator itr = players.begin();
- std::advance(itr, urand(0, players.size() - 1));
+ scheduler.Async([this]
+ {
+ DoCast(me, DUNGEON_MODE(SPELL_RAY_OF_PAIN, SPELL_RAY_OF_PAIN_H));
+ DoCast(me, DUNGEON_MODE(SPELL_RAY_OF_SUFFERING, SPELL_RAY_OF_SUFFERING_H));
+ });
+
+ scheduler.Schedule(Seconds(15), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
+ DoCast(target, SPELL_OPTIC_LINK);
+ task.Repeat(Seconds(25));
+ });
- uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell;
- GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
+ scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_CORROSIVE_SALIVA);
+ task.Repeat(Seconds(10));
+ });
}
- }
+ };
- void Register() override
+ CreatureAI* GetAI(Creature* creature) const override
{
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_suffering_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ return GetVioletHoldAI<boss_moraggAI>(creature);
}
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_moragg_ray_of_suffering_AuraScript();
- }
};
-class spell_moragg_ray_of_pain : public SpellScriptLoader
+class spell_moragg_ray : public SpellScriptLoader
{
-public:
- spell_moragg_ray_of_pain() : SpellScriptLoader("spell_moragg_ray_of_pain") { }
+ public:
+ spell_moragg_ray() : SpellScriptLoader("spell_moragg_ray") { }
- class spell_moragg_ray_of_pain_AuraScript : public AuraScript
- {
- PrepareAuraScript(spell_moragg_ray_of_pain_AuraScript);
-
- void OnPeriodic(AuraEffect const* aurEff)
+ class spell_moragg_ray_AuraScript : public AuraScript
{
- PreventDefaultAction();
- std::list<HostileReference*> players = GetTarget()->getThreatManager().getThreatList();
- if (!players.empty())
+ PrepareAuraScript(spell_moragg_ray_AuraScript);
+
+ void OnPeriodic(AuraEffect const* aurEff)
{
- std::list<HostileReference*>::iterator itr = players.begin();
- std::advance(itr, urand(0, players.size() - 1));
+ PreventDefaultAction();
+
+ if (!GetTarget()->IsAIEnabled)
+ return;
- uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell;
- GetTarget()->CastCustomSpell(triggerSpell, SPELLVALUE_MAX_TARGETS, 1, (*itr)->getTarget(), TRIGGERED_FULL_MASK, NULL, aurEff);
+ if (Unit* target = GetTarget()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true))
+ {
+ uint32 triggerSpell = aurEff->GetSpellEffectInfo()->TriggerSpell;
+ GetTarget()->CastSpell(target, triggerSpell, TRIGGERED_FULL_MASK, nullptr, aurEff);
+ }
}
- }
- void Register() override
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
{
- OnEffectPeriodic += AuraEffectPeriodicFn(spell_moragg_ray_of_pain_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ return new spell_moragg_ray_AuraScript();
}
- };
-
- AuraScript* GetAuraScript() const override
- {
- return new spell_moragg_ray_of_pain_AuraScript();
- }
};
class spell_moragg_optic_link : public SpellScriptLoader
@@ -232,30 +150,15 @@ public:
void OnPeriodic(AuraEffect const* aurEff)
{
- switch (aurEff->GetTickNumber()) // Different visual based on tick
+ if (Unit* caster = GetCaster())
{
- case 1:
- case 2:
- case 3:
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- break;
- case 4:
- case 5:
- case 6:
- case 7:
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- break;
- case 8:
- case 9:
- case 10:
- case 11:
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_1, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_2, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- GetTarget()->CastCustomSpell(SPELL_OPTIC_LINK_LEVEL_3, SPELLVALUE_MAX_TARGETS, 1, (Unit*)NULL, TRIGGERED_FULL_MASK, NULL, aurEff);
- break;
- default:
- break;
+ if (aurEff->GetTickNumber() >= 8)
+ caster->CastSpell(GetTarget(), SPELL_OPTIC_LINK_LEVEL_3, TRIGGERED_FULL_MASK, nullptr, aurEff);
+
+ if (aurEff->GetTickNumber() >= 4)
+ caster->CastSpell(GetTarget(), SPELL_OPTIC_LINK_LEVEL_2, TRIGGERED_FULL_MASK, nullptr, aurEff);
+
+ caster->CastSpell(GetTarget(), SPELL_OPTIC_LINK_LEVEL_1, TRIGGERED_FULL_MASK, nullptr, aurEff);
}
}
@@ -293,7 +196,6 @@ public:
void AddSC_boss_moragg()
{
new boss_moragg();
- new spell_moragg_ray_of_suffering();
- new spell_moragg_ray_of_pain();
+ new spell_moragg_ray();
new spell_moragg_optic_link();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
index fe0f161cc27..62fcda47c9b 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_xevozz.cpp
@@ -22,50 +22,53 @@
#include "Player.h"
#include "violet_hold.h"
+/*
+ * TODO:
+ * - Implement Ethereal Summon Target
+ */
+
enum Spells
{
SPELL_ARCANE_BARRAGE_VOLLEY = 54202,
SPELL_ARCANE_BUFFET = 54226,
- SPELL_SUMMON_ETHEREAL_SPHERE_1 = 54102,
- SPELL_SUMMON_ETHEREAL_SPHERE_2 = 61337,
- SPELL_SUMMON_ETHEREAL_SPHERE_3 = 54138
+ SPELL_SUMMON_TARGET_VISUAL = 54111
};
+static uint32 const EtherealSphereCount = 3;
+static uint32 const EtherealSphereSummonSpells[EtherealSphereCount] = { 54102, 54137, 54138 };
+static uint32 const EtherealSphereHeroicSummonSpells[EtherealSphereCount] = { 54102, 54137, 54138 };
+
enum NPCs
{
NPC_ETHEREAL_SPHERE = 29271,
- NPC_ETHEREAL_SPHERE2 = 32582
+ NPC_ETHEREAL_SPHERE2 = 32582,
+ NPC_ETHEREAL_SUMMON_TARGET = 29276
};
enum CreatureSpells
{
SPELL_ARCANE_POWER = 54160,
H_SPELL_ARCANE_POWER = 59474,
+ SPELL_MAGIC_PULL = 50770,
SPELL_SUMMON_PLAYERS = 54164,
SPELL_POWER_BALL_VISUAL = 54141,
- SPELL_POWER_BALL_DAMAGE_TRIGGER = 54207
+ SPELL_POWER_BALL_DAMAGE_TRIGGER = 54207,
+ SPELL_POWER_BALL_DAMAGE_TRIGGER_H = 59476
};
enum Yells
{
+ // Xevozz
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_DEATH = 2,
SAY_SPAWN = 3,
SAY_CHARGED = 4,
SAY_REPEAT_SUMMON = 5,
- SAY_SUMMON_ENERGY = 6
-};
+ SAY_SUMMON_ENERGY = 6,
-enum XevozzEvents
-{
- EVENT_ARCANE_BARRAGE = 1,
- EVENT_ARCANE_BUFFET,
- EVENT_SUMMON_SPHERE,
- EVENT_SUMMON_SPHERE_2,
- EVENT_RANGE_CHECK,
- EVENT_SUMMON_PLAYERS,
- EVENT_DESPAWN_SPHERE
+ // Ethereal Sphere
+ SAY_ETHEREAL_SPHERE_SUMMON = 0
};
enum SphereActions
@@ -75,319 +78,210 @@ enum SphereActions
class boss_xevozz : public CreatureScript
{
-public:
- boss_xevozz() : CreatureScript("boss_xevozz") { }
-
- struct boss_xevozzAI : public ScriptedAI
- {
- boss_xevozzAI(Creature* creature) : ScriptedAI(creature)
- {
- instance = creature->GetInstanceScript();
- }
+ public:
+ boss_xevozz() : CreatureScript("boss_xevozz") { }
- void Reset() override
+ struct boss_xevozzAI : public BossAI
{
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
+ boss_xevozzAI(Creature* creature) : BossAI(creature, DATA_XEVOZZ) { }
- DespawnSphere();
- events.Reset();
- }
+ void Reset() override
+ {
+ BossAI::Reset();
+ }
- void DespawnSphere()
- {
- std::list<Creature*> assistList;
- GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE, 150.0f);
- GetCreatureListWithEntryInGrid(assistList, me, NPC_ETHEREAL_SPHERE2, 150.0f);
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ Talk(SAY_AGGRO);
+ }
- if (assistList.empty())
- return;
+ void JustReachedHome() override
+ {
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_XEVOZZ);
+ }
- for (std::list<Creature*>::const_iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
+ void JustSummoned(Creature* summon) override
{
- if (Creature* pSphere = *iter)
- pSphere->Kill(pSphere, false);
+ BossAI::JustSummoned(summon);
+ summon->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f);
}
- }
- void JustSummoned(Creature* summoned) override
- {
- summoned->SetSpeed(MOVE_RUN, 0.5f);
- summoned->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f);
- }
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+ Talk(SAY_DEATH);
+ }
- if (me->Attack(who, true))
+ void SpellHit(Unit* /*who*/, SpellInfo const* spell) override
{
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ if (spell->Id == SPELL_ARCANE_POWER || spell->Id == H_SPELL_ARCANE_POWER)
+ Talk(SAY_SUMMON_ENERGY);
}
- }
- void EnterCombat(Unit* /*who*/) override
- {
- if (GameObject* door = instance->GetGameObject(DATA_XEVOZZ_CELL))
- if (door->GetGoState() == GO_STATE_READY)
- {
- EnterEvadeMode();
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
return;
- }
-
- Talk(SAY_AGGRO);
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetBossState(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
-
- events.ScheduleEvent(EVENT_SUMMON_SPHERE, 5000);
- events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
- events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(10000, 11000));
- }
- void JustDied(Unit* /*killer*/) override
- {
- Talk(SAY_DEATH);
-
- DespawnSphere();
-
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- {
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
}
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
+
+ void ScheduleTasks() override
{
- instance->SetBossState(DATA_2ND_BOSS_EVENT, NOT_STARTED);
- instance->SetData(DATA_WAVE_COUNT, 13);
- }
- }
+ scheduler.Schedule(Seconds(8), Seconds(10), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_ARCANE_BARRAGE_VOLLEY);
+ task.Repeat(Seconds(8), Seconds(10));
+ });
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
+ scheduler.Schedule(Seconds(10), Seconds(11), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.0f, true))
+ DoCast(target, SPELL_ARCANE_BUFFET);
+ task.Repeat(Seconds(15), Seconds(20));
+ });
- void SpellHit(Unit* who, const SpellInfo* spell) override
- {
- if (!who->ToCreature())
- return;
+ scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ Talk(SAY_REPEAT_SUMMON);
- if ((spell->Id == SPELL_ARCANE_POWER) || (spell->Id == H_SPELL_ARCANE_POWER))
- Talk(SAY_SUMMON_ENERGY);
- }
+ std::list<uint8> summonSpells = { 0, 1, 2 };
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ uint8 spell = Trinity::Containers::SelectRandomContainerElement(summonSpells);
+ DoCast(me, EtherealSphereSummonSpells[spell]);
+ summonSpells.remove(spell);
- events.Update(diff);
+ if (IsHeroic())
+ {
+ spell = Trinity::Containers::SelectRandomContainerElement(summonSpells);
+ task.Schedule(Milliseconds(2500), [this, spell](TaskContext /*task*/)
+ {
+ DoCast(me, EtherealSphereHeroicSummonSpells[spell]);
+ });
+ }
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ task.Schedule(Seconds(33), Seconds(35), [this](TaskContext /*task*/)
+ {
+ DummyEntryCheckPredicate pred;
+ summons.DoAction(ACTION_SUMMON, pred);
+ });
- switch (events.ExecuteEvent())
- {
- case EVENT_ARCANE_BARRAGE:
- DoCast(SPELL_ARCANE_BARRAGE_VOLLEY);
- events.ScheduleEvent(EVENT_ARCANE_BARRAGE, urand(8000, 10000));
- break;
- case EVENT_ARCANE_BUFFET:
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_ARCANE_BUFFET);
- events.ScheduleEvent(EVENT_ARCANE_BUFFET, urand(15000, 20000));
- break;
- case EVENT_SUMMON_SPHERE:
- Talk(SAY_REPEAT_SUMMON);
- DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_1);
- if (IsHeroic())
- events.ScheduleEvent(EVENT_SUMMON_SPHERE_2, 2500);
- events.ScheduleEvent(EVENT_SUMMON_PLAYERS, urand(33000, 35000));
- events.ScheduleEvent(EVENT_SUMMON_SPHERE, urand(45000, 47000));
- break;
- case EVENT_SUMMON_SPHERE_2:
- Talk(SAY_REPEAT_SUMMON);
- DoCast(SPELL_SUMMON_ETHEREAL_SPHERE_2);
- break;
- case EVENT_SUMMON_PLAYERS:
- {
- Creature* sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE, 150.0f);
- if (!sphere)
- sphere = me->FindNearestCreature(NPC_ETHEREAL_SPHERE2, 150.0f);
- if (sphere)
- sphere->GetAI()->DoAction(ACTION_SUMMON);
- break;
- }
- default:
- break;
+ task.Repeat(Seconds(45), Seconds(47));
+ });
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<boss_xevozzAI>(creature);
}
-
- private:
- InstanceScript* instance;
- EventMap events;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_xevozzAI>(creature);
- }
};
class npc_ethereal_sphere : public CreatureScript
{
-public:
- npc_ethereal_sphere() : CreatureScript("npc_ethereal_sphere") { }
+ public:
+ npc_ethereal_sphere() : CreatureScript("npc_ethereal_sphere") { }
- struct npc_ethereal_sphereAI : public ScriptedAI
- {
- npc_ethereal_sphereAI(Creature* creature) : ScriptedAI(creature)
+ struct npc_ethereal_sphereAI : public ScriptedAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ npc_ethereal_sphereAI(Creature* creature) : ScriptedAI(creature)
+ {
+ instance = creature->GetInstanceScript();
+ }
- void Initialize()
- {
- arcanePower = false;
- }
+ void Reset() override
+ {
+ scheduler.CancelAll();
+ ScheduledTasks();
- void Reset() override
- {
- Initialize();
- events.Reset();
- DoCast(SPELL_POWER_BALL_VISUAL);
- DoCast(SPELL_POWER_BALL_DAMAGE_TRIGGER);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
- me->setFaction(16);
- events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 40000);
- events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
- }
+ DoCast(me, SPELL_POWER_BALL_VISUAL);
+ DoCast(me, DUNGEON_MODE(SPELL_POWER_BALL_DAMAGE_TRIGGER, SPELL_POWER_BALL_DAMAGE_TRIGGER_H));
- void DoAction(int32 action) override
- {
- if (action == ACTION_SUMMON)
- DoCast(SPELL_SUMMON_PLAYERS);
- }
+ me->DespawnOrUnsummon(40000);
+ }
- void UpdateAI(uint32 diff) override
- {
- events.Update(diff);
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_SUMMON)
+ {
+ Talk(SAY_ETHEREAL_SPHERE_SUMMON);
+ DoCastAOE(SPELL_SUMMON_PLAYERS);
+ }
+ }
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
+ void UpdateAI(uint32 diff) override
+ {
+ scheduler.Update(diff);
+ }
- switch (events.ExecuteEvent())
+ void ScheduledTasks()
{
- case EVENT_RANGE_CHECK:
- if (Creature* xevozz = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_XEVOZZ)))
+ scheduler.Schedule(Seconds(1), [this](TaskContext task)
+ {
+ if (Creature* xevozz = instance->GetCreature(DATA_XEVOZZ))
{
- if (me->IsWithinDist(xevozz, 3.0f) && !arcanePower)
+ if (me->IsWithinDist(xevozz, 3.0f))
{
- DoCast(SPELL_ARCANE_POWER);
- arcanePower = true;
- events.ScheduleEvent(EVENT_DESPAWN_SPHERE, 8000);
+ DoCastAOE(SPELL_ARCANE_POWER);
+ me->DespawnOrUnsummon(8000);
+ return;
}
}
- events.ScheduleEvent(EVENT_RANGE_CHECK, 1000);
- break;
- case EVENT_DESPAWN_SPHERE:
- me->DespawnOrUnsummon();
- break;
+ task.Repeat();
+ });
}
- }
- private:
- InstanceScript* instance;
- EventMap events;
- bool arcanePower;
- };
+ private:
+ InstanceScript* instance;
+ TaskScheduler scheduler;
+ };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_ethereal_sphereAI>(creature);
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_ethereal_sphereAI>(creature);
+ }
};
class spell_xevozz_summon_players : public SpellScriptLoader
{
-public:
- spell_xevozz_summon_players() : SpellScriptLoader("spell_xevozz_summon_players") { }
-
- class spell_xevozz_summon_players_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_xevozz_summon_players_SpellScript);
+ public:
+ spell_xevozz_summon_players() : SpellScriptLoader("spell_xevozz_summon_players") { }
- void HandleScript(SpellEffIndex /*effIndex*/)
+ class spell_xevozz_summon_players_SpellScript : public SpellScript
{
- Unit* target = GetHitUnit();
+ PrepareSpellScript(spell_xevozz_summon_players_SpellScript);
- if (target)
+ bool Validate(SpellInfo const* /*spellInfo*/) override
{
- Position pos = GetOriginalCaster()->GetPosition();
-
- target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
+ if (!sSpellMgr->GetSpellInfo(SPELL_MAGIC_PULL))
+ return false;
+ return true;
}
- }
-
- void Register() override
- {
- OnEffectHitTarget += SpellEffectFn(spell_xevozz_summon_players_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
- }
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_xevozz_summon_players_SpellScript();
- }
-};
-
-class spell_xevozz_summon_ethereal_sphere : public SpellScriptLoader
-{
-public:
- spell_xevozz_summon_ethereal_sphere() : SpellScriptLoader("spell_xevozz_summon_ethereal_sphere") { }
-
- class spell_xevozz_summon_ethereal_sphere_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_xevozz_summon_ethereal_sphere_SpellScript);
- void HandleScript(SpellDestination& target)
- {
- Unit* caster = GetOriginalCaster();
- Position pos;
- float distance = 0.0f;
-
- while (distance < 20.0f)
+ void HandleScript(SpellEffIndex /*effIndex*/)
{
- pos = caster->GetRandomNearPosition(60.0f);
- distance = caster->GetDistance(pos);
+ GetCaster()->CastSpell(GetHitUnit(), SPELL_MAGIC_PULL, true);
}
- target.Relocate(pos);
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_xevozz_summon_players_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_DUMMY);
+ }
+ };
- void Register() override
+ SpellScript* GetSpellScript() const override
{
- OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_xevozz_summon_ethereal_sphere_SpellScript::HandleScript, EFFECT_0, TARGET_DEST_DB);
+ return new spell_xevozz_summon_players_SpellScript();
}
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_xevozz_summon_ethereal_sphere_SpellScript();
- }
};
void AddSC_boss_xevozz()
@@ -395,5 +289,4 @@ void AddSC_boss_xevozz()
new boss_xevozz();
new npc_ethereal_sphere();
new spell_xevozz_summon_players();
- new spell_xevozz_summon_ethereal_sphere();
}
diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
index 5b3f06c9e40..14d7b5fcd95 100644
--- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
+++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp
@@ -25,6 +25,10 @@ enum Spells
SPELL_SUMMON_VOID_SENTRY = 54369,
SPELL_VOID_SHIFT = 54361,
SPELL_VOID_SHIFTED = 54343,
+ SPELL_ZURAMAT_ADD = 54341,
+ SPELL_ZURAMAT_ADD_2 = 54342,
+ SPELL_ZURAMAT_ADD_DUMMY = 54351,
+ SPELL_SUMMON_VOID_SENTRY_BALL = 58650
};
enum Yells
@@ -39,188 +43,172 @@ enum Yells
enum Misc
{
+ ACTION_DESPAWN_VOID_SENTRY_BALL = 1,
DATA_VOID_DANCE = 2153
};
-enum ZuramatEvents
-{
- EVENT_VOID_SHIFT = 1,
- EVENT_SUMMON_VOID,
- EVENT_SHROUD_OF_DARKNESS
-};
-
class boss_zuramat : public CreatureScript
{
-public:
- boss_zuramat() : CreatureScript("boss_zuramat") { }
+ public:
+ boss_zuramat() : CreatureScript("boss_zuramat") { }
- struct boss_zuramatAI : public ScriptedAI
- {
- boss_zuramatAI(Creature* creature) : ScriptedAI(creature), sentries(me)
+ struct boss_zuramatAI : public BossAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ boss_zuramatAI(Creature* creature) : BossAI(creature, DATA_ZURAMAT)
+ {
+ Initialize();
+ }
- void Initialize()
- {
- voidDance = true;
- }
+ void Initialize()
+ {
+ _voidDance = true;
+ }
- void DespawnSentries()
- {
- sentries.DespawnAll();
- std::list<Creature*> sentrylist;
- GetCreatureListWithEntryInGrid(sentrylist, me, NPC_VOID_SENTRY_BALL, 200.0f);
- if (!sentrylist.empty())
- for (std::list<Creature*>::const_iterator itr = sentrylist.begin(); itr != sentrylist.end(); ++itr)
- (*itr)->DespawnOrUnsummon();
- }
+ void Reset() override
+ {
+ BossAI::Reset();
+ Initialize();
+ }
- void Reset() override
- {
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetData(DATA_1ST_BOSS_EVENT, NOT_STARTED);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetData(DATA_2ND_BOSS_EVENT, NOT_STARTED);
-
- Initialize();
- events.Reset();
- DespawnSentries();
- }
+ void EnterCombat(Unit* who) override
+ {
+ BossAI::EnterCombat(who);
+ Talk(SAY_AGGRO);
+ }
- void AttackStart(Unit* who) override
- {
- if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC) || me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE))
- return;
+ void JustReachedHome() override
+ {
+ BossAI::JustReachedHome();
+ instance->SetData(DATA_HANDLE_CELLS, DATA_ZURAMAT);
+ }
- if (me->Attack(who, true))
+ void SummonedCreatureDies(Creature* summon, Unit* /*who*/) override
{
- me->AddThreat(who, 0.0f);
- me->SetInCombatWith(who);
- who->SetInCombatWith(me);
- DoStartMovement(who);
+ if (summon->GetEntry() == NPC_VOID_SENTRY)
+ _voidDance = false;
}
- }
- void EnterCombat(Unit* /*who*/) override
- {
- if (GameObject* door = instance->GetGameObject(DATA_ZURAMAT_CELL))
- if (door->GetGoState() == GO_STATE_READY)
- {
- EnterEvadeMode();
+ void SummonedCreatureDespawn(Creature* summon) override
+ {
+ if (summon->GetEntry() == NPC_VOID_SENTRY)
+ summon->AI()->DoAction(ACTION_DESPAWN_VOID_SENTRY_BALL);
+ BossAI::SummonedCreatureDespawn(summon);
+ }
+
+ uint32 GetData(uint32 type) const override
+ {
+ if (type == DATA_VOID_DANCE)
+ return _voidDance ? 1 : 0;
+
+ return 0;
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ BossAI::JustDied(killer);
+ Talk(SAY_DEATH);
+ }
+
+ void KilledUnit(Unit* victim) override
+ {
+ if (victim->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_SLAY);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
return;
- }
- Talk(SAY_AGGRO);
+ scheduler.Update(diff,
+ std::bind(&BossAI::DoMeleeAttackIfReady, this));
+ }
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
- instance->SetBossState(DATA_1ST_BOSS_EVENT, IN_PROGRESS);
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
- instance->SetData(DATA_2ND_BOSS_EVENT, IN_PROGRESS);
+ void ScheduleTasks() override
+ {
+ scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ DoCast(me, SPELL_SUMMON_VOID_SENTRY);
+ task.Repeat(Seconds(7), Seconds(10));
+ });
- me->SetInCombatWithZone();
- events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
- events.ScheduleEvent(EVENT_VOID_SHIFT, 9000);
- events.ScheduleEvent(EVENT_SUMMON_VOID, 4000);
- }
+ scheduler.Schedule(Seconds(9), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
+ DoCast(target, SPELL_VOID_SHIFT);
+ task.Repeat(Seconds(15));
+ });
- void JustSummoned(Creature* summon) override
- {
- sentries.Summon(summon);
- }
+ scheduler.Schedule(Seconds(18), Seconds(20), [this](TaskContext task)
+ {
+ DoCast(me, SPELL_SHROUD_OF_DARKNESS);
+ task.Repeat(Seconds(18), Seconds(20));
+ });
+ }
- void SummonedCreatureDies(Creature* summoned, Unit* /*who*/) override
- {
- if (summoned->GetEntry() == NPC_VOID_SENTRY)
- voidDance = false;
- }
+ private:
+ bool _voidDance;
+ };
- uint32 GetData(uint32 type) const override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (type == DATA_VOID_DANCE)
- return voidDance ? 1 : 0;
-
- return 0;
+ return GetVioletHoldAI<boss_zuramatAI>(creature);
}
+};
- void JustDied(Unit* /*killer*/) override
+class npc_void_sentry : public CreatureScript
+{
+ public:
+ npc_void_sentry() : CreatureScript("npc_void_sentry") { }
+
+ struct npc_void_sentryAI : public ScriptedAI
{
- instance->SetData(DATA_ZURAMAT, 1);
+ npc_void_sentryAI(Creature* creature) : ScriptedAI(creature), _summons(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
- Talk(SAY_DEATH);
+ void IsSummonedBy(Unit* /*summoner*/) override
+ {
+ me->CastSpell(me, SPELL_SUMMON_VOID_SENTRY_BALL, true);
+ }
- DespawnSentries();
+ void JustSummoned(Creature* summon) override
+ {
+ _summons.Summon(summon);
+ summon->SetReactState(REACT_PASSIVE);
+ }
- if (instance->GetData(DATA_WAVE_COUNT) == 6)
+ void SummonedCreatureDespawn(Creature* summon) override
{
- instance->SetBossState(DATA_1ST_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 7);
+ _summons.Despawn(summon);
}
- else if (instance->GetData(DATA_WAVE_COUNT) == 12)
+
+ void DoAction(int32 actionId) override
{
- instance->SetBossState(DATA_2ND_BOSS_EVENT, DONE);
- instance->SetData(DATA_WAVE_COUNT, 13);
+ if (actionId == ACTION_DESPAWN_VOID_SENTRY_BALL)
+ _summons.DespawnAll();
}
- }
- void KilledUnit(Unit* victim) override
- {
- if (victim->GetTypeId() == TYPEID_PLAYER)
- Talk(SAY_SLAY);
- }
+ void JustDied(Unit* /*killer*/) override
+ {
+ DoAction(ACTION_DESPAWN_VOID_SENTRY_BALL);
+ }
- void UpdateAI(uint32 diff) override
+ private:
+ SummonList _summons;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (!UpdateVictim())
- return;
-
- events.Update(diff);
-
- if (me->HasUnitState(UNIT_STATE_CASTING))
- return;
-
- switch (events.ExecuteEvent())
- {
- case EVENT_SUMMON_VOID:
- DoCast(SPELL_SUMMON_VOID_SENTRY);
- events.ScheduleEvent(EVENT_SUMMON_VOID, urand(7000, 10000));
- break;
- case EVENT_VOID_SHIFT:
- if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(unit, SPELL_VOID_SHIFT);
- events.ScheduleEvent(EVENT_VOID_SHIFT, 15000);
- break;
- case EVENT_SHROUD_OF_DARKNESS:
- DoCast(SPELL_SHROUD_OF_DARKNESS);
- events.ScheduleEvent(EVENT_SHROUD_OF_DARKNESS, urand(18000, 20000));
- break;
- default:
- break;
- }
-
- DoMeleeAttackIfReady();
+ return GetVioletHoldAI<npc_void_sentryAI>(creature);
}
-
- private:
- InstanceScript* instance;
- EventMap events;
- SummonList sentries;
- bool voidDance;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_zuramatAI>(creature);
- }
};
class achievement_void_dance : public AchievementCriteriaScript
{
public:
- achievement_void_dance() : AchievementCriteriaScript("achievement_void_dance")
- {
- }
+ achievement_void_dance() : AchievementCriteriaScript("achievement_void_dance") { }
bool OnCheck(Player* /*player*/, Unit* target) override
{
@@ -238,5 +226,6 @@ class achievement_void_dance : public AchievementCriteriaScript
void AddSC_boss_zuramat()
{
new boss_zuramat();
+ new npc_void_sentry();
new achievement_void_dance();
}
diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
index e9c526df42e..9b51e5611ad 100644
--- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp
@@ -18,82 +18,150 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "InstanceScript.h"
+#include "WorldStatePackets.h"
#include "violet_hold.h"
#include "Player.h"
-#include "TemporarySummon.h"
-
-/* Violet Hold encounters:
-0 - First boss
-1 - Second boss
-2 - Cyanigosa*/
-
-/* Violet hold bosses:
-1 - Moragg
-2 - Erekem
-3 - Ichoron
-4 - Lavanthor
-5 - Xevozz
-6 - Zuramat
-7 - Cyanigosa */
-
-enum AzureSaboteurSpells
+
+/*
+ * TODO:
+ * - replace bosses by dummy npcs also after grid unload
+ */
+
+Position const DefenseSystemLocation = { 1888.146f, 803.382f, 58.60389f, 3.071779f }; // sniff
+
+Position const CyanigosaSpawnLocation = { 1922.109f, 804.4493f, 52.49254f, 3.176499f }; // sniff
+Position const CyanigosaJumpLocation = { 1888.32f, 804.473f, 38.3578f, 0.0f }; // sniff
+
+Position const SaboteurSpawnLocation = { 1886.251f, 803.0743f, 38.42326f, 3.211406f }; // sniff
+
+uint32 const PortalPositionsSize = 5;
+Position const PortalPositions[PortalPositionsSize] = // sniff
+{
+ { 1877.523f, 850.1788f, 45.36822f, 4.34587f }, // 0
+ { 1890.679f, 753.4202f, 48.771f, 1.675516f }, // 1
+ { 1936.09f, 803.1875f, 54.09715f, 3.054326f }, // 2
+ { 1858.243f, 770.2379f, 40.42146f, 0.9075712f }, // 3
+ { 1907.288f, 831.1111f, 40.22015f, 3.560472f } // 4
+};
+
+uint32 const PortalElitePositionsSize = 3;
+Position const PortalElitePositions[PortalElitePositionsSize] = // sniff
+{
+ { 1911.281f, 800.9722f, 39.91673f, 3.01942f }, // 5
+ { 1926.516f, 763.6616f, 52.35725f, 2.251475f }, // 6
+ { 1922.464f, 847.0699f, 48.50161f, 3.961897f } // 7
+};
+
+uint32 const PortalIntroPositionsSize = 5;
+Position const PortalIntroPositions[PortalIntroPositionsSize] = // sniff
+{
+ { 1877.51f, 850.1042f, 44.65989f, 4.782202f }, // 0 - Intro
+ { 1890.637f, 753.4705f, 48.72239f, 1.710423f }, // 1 - Intro
+ { 1936.073f, 803.1979f, 53.37491f, 3.124139f }, // 2 - Intro
+ { 1886.545f, 803.2014f, 40.40931f, 3.159046f }, // 3 - Boss 1/2
+ { 1924.096f, 804.3707f, 54.29256f, 3.228859f } // 4 - Boss 3
+};
+
+uint32 const EncouterPortalsCount = PortalPositionsSize + PortalElitePositionsSize;
+
+uint32 const MoraggPathSize = 3;
+G3D::Vector3 const MoraggPath[MoraggPathSize] = // sniff
+{
+ { 1893.895f, 728.1261f, 47.75016f },
+ { 1892.997f, 738.4987f, 47.66684f },
+ { 1889.76f, 758.1089f, 47.66684f }
+};
+
+uint32 const ErekemPathSize = 3;
+G3D::Vector3 const ErekemPath[ErekemPathSize] = // sniff
+{
+ { 1871.456f, 871.0361f, 43.41524f },
+ { 1874.948f, 859.5452f, 43.33349f },
+ { 1877.245f, 851.967f, 43.3335f }
+};
+
+uint32 const ErekemGuardLeftPathSize = 3;
+G3D::Vector3 const ErekemGuardLeftPath[ErekemGuardLeftPathSize] = // sniff
+{
+ { 1853.752f, 862.4528f, 43.41614f },
+ { 1866.931f, 854.577f, 43.3335f },
+ { 1872.973f, 850.7875f, 43.3335f }
+};
+
+uint32 const ErekemGuardRightPathSize = 3;
+G3D::Vector3 const ErekemGuardRightPath[ErekemGuardRightPathSize] = // sniff
+{
+ { 1892.418f, 872.2831f, 43.41563f },
+ { 1885.639f, 859.0245f, 43.3335f },
+ { 1882.432f, 852.2423f, 43.3335f }
+};
+
+uint32 const IchoronPathSize = 5;
+G3D::Vector3 const IchoronPath[IchoronPathSize] = // sniff
{
- SABOTEUR_SHIELD_DISRUPTION = 58291,
- SABOTEUR_SHIELD_EFFECT = 45775
+ { 1942.041f, 749.5228f, 30.95229f },
+ { 1930.571f, 762.9065f, 31.98814f },
+ { 1923.657f, 770.6718f, 34.07256f },
+ { 1910.631f, 784.4096f, 37.09015f },
+ { 1906.595f, 788.3828f, 37.99429f }
};
-enum CrystalSpells
+uint32 const LavanthorPathSize = 3;
+G3D::Vector3 const LavanthorPath[LavanthorPathSize] = // sniff
{
- SPELL_ARCANE_LIGHTNING = 57930
+ { 1844.557f, 748.7083f, 38.74205f },
+ { 1854.618f, 761.5295f, 38.65631f },
+ { 1862.17f, 773.2255f, 38.74879f }
};
-Position const PortalLocation[] =
+uint32 const XevozzPathSize = 3;
+G3D::Vector3 const XevozzPath[XevozzPathSize] = // sniff
{
- {1877.51f, 850.104f, 44.6599f, 4.7822f }, // WP 1
- {1918.37f, 853.437f, 47.1624f, 4.12294f}, // WP 2
- {1936.07f, 803.198f, 53.3749f, 3.12414f}, // WP 3
- {1927.61f, 758.436f, 51.4533f, 2.20891f}, // WP 4
- {1890.64f, 753.471f, 48.7224f, 1.71042f}, // WP 5
- {1908.31f, 809.657f, 38.7037f, 3.08701f} // WP 6
+ { 1908.417f, 845.8502f, 38.71947f },
+ { 1905.557f, 841.3157f, 38.65529f },
+ { 1899.453f, 832.533f, 38.70752f }
+};
+
+uint32 const ZuramatPathSize = 3;
+G3D::Vector3 const ZuramatPath[ZuramatPathSize] = // sniff
+{
+ { 1934.151f, 860.9463f, 47.29499f },
+ { 1927.085f, 852.1342f, 47.19214f },
+ { 1923.226f, 847.3297f, 47.15541f }
};
-Position const ArcaneSphere = {1887.060059f, 806.151001f, 61.321602f, 0.0f};
-Position const BossStartMove1 = {1894.684448f, 739.390503f, 47.668003f, 0.0f};
-Position const BossStartMove2 = {1875.173950f, 860.832703f, 43.333565f, 0.0f};
-Position const BossStartMove21 = {1858.854614f, 855.071411f, 43.333565f, 0.0f};
-Position const BossStartMove22 = {1891.926636f, 863.388977f, 43.333565f, 0.0f};
-Position const BossStartMove3 = {1916.138062f, 778.152222f, 35.772308f, 0.0f};
-Position const BossStartMove4 = {1853.618286f, 758.557617f, 38.657505f, 0.0f};
-Position const BossStartMove5 = {1906.683960f, 842.348022f, 38.637459f, 0.0f};
-Position const BossStartMove6 = {1928.207031f, 852.864441f, 47.200813f, 0.0f};
-
-Position const CyanigosasSpawnLocation = {1930.281250f, 804.407715f, 52.410946f, 3.139621f};
-Position const MiddleRoomLocation = {1892.291260f, 805.696838f, 38.438862f, 3.139621f};
-Position const MiddleRoomPortalSaboLocation = {1896.622925f, 804.854126f, 38.504772f, 3.139621f};
-
-// Cyanigosa's prefight event data
enum Yells
{
- CYANIGOSA_SAY_SPAWN = 0
+ SAY_CYANIGOSA_SPAWN = 3,
+ SAY_XEVOZZ_SPAWN = 3,
+ SAY_EREKEM_SPAWN = 3,
+ SAY_ICHORON_SPAWN = 3,
+ SAY_ZURAMAT_SPAWN = 3,
+
+ SOUND_MORAGG_SPAWN = 10112
};
enum Spells
{
- CYANIGOSA_SPELL_TRANSFORM = 58668,
- CYANIGOSA_BLUE_AURA = 47759,
+ SPELL_CYANIGOSA_TRANSFORM = 58668,
+ SPELL_CYANIGOSA_ARCANE_POWER_STATE = 49411,
+ SPELL_MORAGG_EMOTE_ROAR = 48350,
+ SPELL_LAVANTHOR_SPECIAL_UNARMED = 33334,
+ SPELL_ZURAMAT_COSMETIC_CHANNEL_OMNI = 57552
};
ObjectData const creatureData[] =
{
- { NPC_XEVOZZ, DATA_XEVOZZ },
- { NPC_LAVANTHOR, DATA_LAVANTHOR },
- { NPC_ICHORON, DATA_ICHORON },
- { NPC_ZURAMAT, DATA_ZURAMAT },
- { NPC_EREKEM, DATA_EREKEM },
- { NPC_MORAGG, DATA_MORAGG },
- { NPC_CYANIGOSA, DATA_CYANIGOSA },
- { NPC_SINCLARI, DATA_SINCLARI },
- { 0, 0 } // END
+ { NPC_XEVOZZ, DATA_XEVOZZ },
+ { NPC_LAVANTHOR, DATA_LAVANTHOR },
+ { NPC_ICHORON, DATA_ICHORON },
+ { NPC_ZURAMAT, DATA_ZURAMAT },
+ { NPC_EREKEM, DATA_EREKEM },
+ { NPC_MORAGG, DATA_MORAGG },
+ { NPC_CYANIGOSA, DATA_CYANIGOSA },
+ { NPC_SINCLARI, DATA_SINCLARI },
+ { NPC_SINCLARI_TRIGGER, DATA_SINCLARI_TRIGGER },
+ { 0, 0 } // END
};
ObjectData const gameObjectData[] =
@@ -110,598 +178,770 @@ ObjectData const gameObjectData[] =
{ 0, 0 } // END
};
+MinionData const minionData[] =
+{
+ { NPC_EREKEM_GUARD, DATA_EREKEM },
+ { 0, 0, } // END
+};
+
class instance_violet_hold : public InstanceMapScript
{
-public:
- instance_violet_hold() : InstanceMapScript("instance_violet_hold", 608) { }
+ public:
+ instance_violet_hold() : InstanceMapScript(VioletHoldScriptName, 608) { }
- struct instance_violet_hold_InstanceMapScript : public InstanceScript
- {
- instance_violet_hold_InstanceMapScript(Map* map) : InstanceScript(map)
+ struct instance_violet_hold_InstanceMapScript : public InstanceScript
{
- SetHeaders(DataHeader);
- SetBossNumber(EncounterCount);
- LoadObjectData(creatureData, gameObjectData);
-
- uiRemoveNpc = 0;
-
- uiDoorIntegrity = 100;
-
- uiWaveCount = 0;
- uiLocation = urand(0, 5);
- uiFirstBoss = 0;
- uiSecondBoss = 0;
- uiCountErekemGuards = 0;
- uiCountActivationCrystals = 0;
- uiCyanigosaEventPhase = 1;
-
- uiActivationTimer = 5000;
- uiDoorSpellTimer = 2000;
- uiCyanigosaEventTimer = 3 * IN_MILLISECONDS;
-
- bActive = false;
- bWiped = false;
- bIsDoorSpellCast = false;
- bCrystalActivated = false;
- defenseless = true;
- uiMainEventPhase = NOT_STARTED;
- zuramatDead = false;
- }
+ instance_violet_hold_InstanceMapScript(Map* map) : InstanceScript(map)
+ {
+ SetHeaders(DataHeader);
+ SetBossNumber(EncounterCount);
+ LoadObjectData(creatureData, gameObjectData);
+ LoadMinionData(minionData);
- ObjectGuid uiErekemGuard[2];
+ FirstBossId = 0;
+ SecondBossId = 0;
- ObjectGuid uiTeleportationPortal;
- ObjectGuid uiSaboteurPortal;
+ DoorIntegrity = 100;
+ WaveCount = 0;
+ EventState = NOT_STARTED;
- ObjectGuid uiActivationCrystal[4];
+ LastPortalLocation = urand(0, EncouterPortalsCount - 1);
- uint32 uiActivationTimer;
- uint32 uiCyanigosaEventTimer;
- uint32 uiDoorSpellTimer;
+ Defenseless = true;
+ }
- GuidSet trashMobs; // to kill with crystal
+ void OnCreatureCreate(Creature* creature) override
+ {
+ InstanceScript::OnCreatureCreate(creature);
- uint8 uiWaveCount;
- uint8 uiLocation;
- uint8 uiFirstBoss;
- uint8 uiSecondBoss;
- uint8 uiRemoveNpc;
+ switch (creature->GetEntry())
+ {
+ case NPC_EREKEM_GUARD:
+ for (uint8 i = 0; i < ErekemGuardCount; ++i)
+ if (ErekemGuardGUIDs[i].IsEmpty())
+ {
+ ErekemGuardGUIDs[i] = creature->GetGUID();
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- uint8 uiDoorIntegrity;
+ void OnCreatureRemove(Creature* creature) override
+ {
+ InstanceScript::OnCreatureRemove(creature);
- uint8 uiCountErekemGuards;
- uint8 uiCountActivationCrystals;
- uint8 uiCyanigosaEventPhase;
- uint8 uiMainEventPhase; // SPECIAL: pre event animations, IN_PROGRESS: event itself
+ switch (creature->GetEntry())
+ {
+ case NPC_EREKEM_GUARD:
+ for (uint8 i = 0; i < ErekemGuardCount; ++i)
+ if (ErekemGuardGUIDs[i] == creature->GetGUID())
+ {
+ ErekemGuardGUIDs[i].Clear();
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- bool bActive;
- bool bWiped;
- bool bIsDoorSpellCast;
- bool bCrystalActivated;
- bool defenseless;
- bool zuramatDead;
+ void OnGameObjectCreate(GameObject* go) override
+ {
+ InstanceScript::OnGameObjectCreate(go);
- std::list<uint8> NpcAtDoorCastingList;
+ switch (go->GetEntry())
+ {
+ case GO_ACTIVATION_CRYSTAL:
+ for (uint8 i = 0; i < ActivationCrystalCount; ++i)
+ if (ActivationCrystalGUIDs[i].IsEmpty())
+ {
+ ActivationCrystalGUIDs[i] = go->GetGUID();
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- void OnCreatureCreate(Creature* creature) override
- {
- InstanceScript::OnCreatureCreate(creature);
+ void OnGameObjectRemove(GameObject* go) override
+ {
+ InstanceScript::OnGameObjectRemove(go);
+
+ switch (go->GetEntry())
+ {
+ case GO_ACTIVATION_CRYSTAL:
+ for (uint8 i = 0; i < ActivationCrystalCount; ++i)
+ if (ActivationCrystalGUIDs[i] == go->GetGUID())
+ {
+ ActivationCrystalGUIDs[i].Clear();
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
- switch (creature->GetEntry())
+ void FillInitialWorldStates(WorldPackets::WorldState::InitWorldStates& data) override
{
- case NPC_EREKEM_GUARD:
- if (uiCountErekemGuards < 2)
- {
- uiErekemGuard[uiCountErekemGuards++] = creature->GetGUID();
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- }
- break;
- case NPC_CYANIGOSA:
- creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- break;
- default:
- break;
- case NPC_VOID_SENTRY:
- if (zuramatDead)
- {
- creature->DespawnOrUnsummon();
- zuramatDead = false;
- }
- break;
+ data.Worldstates.emplace_back(uint32(WORLD_STATE_VH_SHOW), uint32(EventState == IN_PROGRESS ? 1 : 0));
+ data.Worldstates.emplace_back(uint32(WORLD_STATE_VH_PRISON_STATE), uint32(DoorIntegrity));
+ data.Worldstates.emplace_back(uint32(WORLD_STATE_VH_WAVE_COUNT), uint32(WaveCount));
}
- /*if (creature->GetGUID() == uiFirstBoss || creature->GetGUID() == uiSecondBoss)
+ bool CheckRequiredBosses(uint32 bossId, Player const* player = nullptr) const override
{
- creature->AllLootRemovedFromCorpse();
- creature->RemoveLootMode(1);
- }*/
- }
+ if (_SkipCheckRequiredBosses(player))
+ return true;
- void OnGameObjectCreate(GameObject* go) override
- {
- InstanceScript::OnGameObjectCreate(go);
+ switch (bossId)
+ {
+ case DATA_MORAGG:
+ case DATA_EREKEM:
+ case DATA_ICHORON:
+ case DATA_LAVANTHOR:
+ case DATA_XEVOZZ:
+ case DATA_ZURAMAT:
+ /// old code used cell door state to check this
+ if (!(WaveCount == 6 && FirstBossId == bossId) && !(WaveCount == 12 && SecondBossId == bossId))
+ return false;
+ break;
+ case DATA_CYANIGOSA:
+ if (WaveCount < 18)
+ return false;
+ break;
+ default:
+ break;
+ }
- switch (go->GetEntry())
+ return true;
+ }
+
+ bool SetBossState(uint32 type, EncounterState state) override
{
- case GO_ACTIVATION_CRYSTAL:
- if (uiCountActivationCrystals < 4)
- uiActivationCrystal[uiCountActivationCrystals++] = go->GetGUID();
- break;
- default:
- break;
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
+ {
+ case DATA_1ST_BOSS:
+ if (state == DONE)
+ UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_EREKEM, nullptr);
+ break;
+ case DATA_2ND_BOSS:
+ if (state == DONE)
+ UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_MORAGG, nullptr);
+ break;
+ case DATA_CYANIGOSA:
+ if (state == DONE)
+ SetData(DATA_MAIN_EVENT_STATE, DONE);
+ break;
+ case DATA_MORAGG:
+ case DATA_EREKEM:
+ case DATA_ICHORON:
+ case DATA_LAVANTHOR:
+ case DATA_XEVOZZ:
+ case DATA_ZURAMAT:
+ // this won't work correctly because bossstate was initializd with TO_BE_DECIDED
+ if (WaveCount == 6)
+ SetBossState(DATA_1ST_BOSS, state);
+ else if (WaveCount == 12)
+ SetBossState(DATA_2ND_BOSS, state);
+
+ if (state == DONE)
+ SetData(DATA_WAVE_COUNT, WaveCount + 1);
+ break;
+ default:
+ break;
+ }
+
+ return true;
}
- }
- bool SetBossState(uint32 type, EncounterState state) override
- {
- if (!InstanceScript::SetBossState(type, state))
- return false;
+ void SetData(uint32 type, uint32 data) override
+ {
+ switch (type)
+ {
+ case DATA_WAVE_COUNT:
+ WaveCount = data;
+ if (WaveCount)
+ {
+ Scheduler.Schedule(Seconds(IsBossWave(WaveCount - 1) ? 45 : 5), [this](TaskContext /*task*/)
+ {
+ AddWave();
+ });
+ }
+ break;
+ case DATA_DOOR_INTEGRITY:
+ DoorIntegrity = data;
+ Defenseless = false;
+ DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, DoorIntegrity);
+ break;
+ case DATA_START_BOSS_ENCOUNTER:
+ switch (WaveCount)
+ {
+ case 6:
+ StartBossEncounter(FirstBossId);
+ break;
+ case 12:
+ StartBossEncounter(SecondBossId);
+ break;
+ }
+ break;
+ case DATA_MAIN_EVENT_STATE:
+ EventState = data;
+ if (data == IN_PROGRESS) // Start event
+ {
+ DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, WaveCount);
+ DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, DoorIntegrity);
+ DoUpdateWorldState(WORLD_STATE_VH_SHOW, 1);
- switch (type)
+ WaveCount = 1;
+ Scheduler.Async(std::bind(&instance_violet_hold_InstanceMapScript::AddWave, this));
+
+ for (uint8 i = 0; i < ActivationCrystalCount; ++i)
+ if (GameObject* crystal = instance->GetGameObject(ActivationCrystalGUIDs[i]))
+ crystal->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ else if (data == NOT_STARTED)
+ {
+ if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
+ {
+ mainDoor->SetGoState(GO_STATE_ACTIVE);
+ mainDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ }
+
+ DoUpdateWorldState(WORLD_STATE_VH_SHOW, 0);
+ DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, WaveCount);
+ DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, DoorIntegrity);
+
+ for (uint8 i = 0; i < ActivationCrystalCount; ++i)
+ if (GameObject* crystal = instance->GetGameObject(ActivationCrystalGUIDs[i]))
+ crystal->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+ }
+ else if (data == DONE)
+ {
+ if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
+ {
+ mainDoor->SetGoState(GO_STATE_ACTIVE);
+ mainDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
+ }
+
+ DoUpdateWorldState(WORLD_STATE_VH_SHOW, 0);
+
+ for (uint8 i = 0; i < ActivationCrystalCount; ++i)
+ if (GameObject* crystal = instance->GetGameObject(ActivationCrystalGUIDs[i]))
+ crystal->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
+
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ sinclari->AI()->DoAction(ACTION_SINCLARI_OUTRO);
+ }
+ break;
+ case DATA_HANDLE_CELLS:
+ HandleCells(data, false);
+ break;
+ }
+ }
+
+ uint32 GetData(uint32 type) const override
{
- case DATA_1ST_BOSS_EVENT:
- if (state == DONE)
- UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_EREKEM, nullptr);
- break;
- case DATA_2ND_BOSS_EVENT:
- if (state == DONE)
- UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, NPC_MORAGG, nullptr);
- break;
- case DATA_CYANIGOSA:
- if (state == DONE)
- {
- uiMainEventPhase = DONE;
- if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
- mainDoor->SetGoState(GO_STATE_ACTIVE);
- }
- break;
- default:
- break;
+ switch (type)
+ {
+ case DATA_1ST_BOSS:
+ return FirstBossId;
+ case DATA_2ND_BOSS:
+ return SecondBossId;
+ case DATA_MAIN_EVENT_STATE:
+ return EventState;
+ case DATA_WAVE_COUNT:
+ return WaveCount;
+ case DATA_DOOR_INTEGRITY:
+ return DoorIntegrity;
+ case DATA_DEFENSELESS:
+ return Defenseless ? 1 : 0;
+ default:
+ break;
+ }
+
+ return 0;
}
- return true;
- }
+ ObjectGuid GetGuidData(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_EREKEM_GUARD_1:
+ case DATA_EREKEM_GUARD_2:
+ return ErekemGuardGUIDs[type - DATA_EREKEM_GUARD_1];
+ default:
+ break;
+ }
- void SetData(uint32 type, uint32 data) override
- {
- switch (type)
+ return InstanceScript::GetGuidData(type);
+ }
+
+ void SpawnPortal()
{
- case DATA_WAVE_COUNT:
- uiWaveCount = data;
- bActive = true;
- break;
- case DATA_REMOVE_NPC:
- uiRemoveNpc = data;
- break;
- case DATA_PORTAL_LOCATION:
- uiLocation = (uint8)data;
- break;
- case DATA_DOOR_INTEGRITY:
- uiDoorIntegrity = data;
- defenseless = false;
- DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, uiDoorIntegrity);
- break;
- case DATA_NPC_PRESENCE_AT_DOOR_ADD:
- NpcAtDoorCastingList.push_back(data);
- break;
- case DATA_NPC_PRESENCE_AT_DOOR_REMOVE:
- if (!NpcAtDoorCastingList.empty())
- NpcAtDoorCastingList.pop_back();
- break;
- case DATA_MAIN_DOOR:
- if (GameObject* mainDoor = GetGameObject(type))
- mainDoor->SetGoState(GOState(data));
- break;
- case DATA_START_BOSS_ENCOUNTER:
- switch (uiWaveCount)
+ LastPortalLocation = (LastPortalLocation + urand(1, EncouterPortalsCount - 1)) % (EncouterPortalsCount);
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ {
+ if (LastPortalLocation < PortalPositionsSize)
{
- case 6:
- StartBossEncounter(uiFirstBoss);
- break;
- case 12:
- StartBossEncounter(uiSecondBoss);
- break;
+ if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalPositions[LastPortalLocation], TEMPSUMMON_CORPSE_DESPAWN))
+ portal->AI()->SetData(DATA_PORTAL_LOCATION, LastPortalLocation);
}
- break;
- case DATA_ACTIVATE_CRYSTAL:
- ActivateCrystal();
- break;
- case DATA_MAIN_EVENT_PHASE:
- uiMainEventPhase = data;
- if (data == IN_PROGRESS) // Start event
+ else
{
- if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
- mainDoor->SetGoState(GO_STATE_READY);
- uiWaveCount = 1;
- bActive = true;
- for (int i = 0; i < 4; ++i)
- if (GameObject* crystal = instance->GetGameObject(uiActivationCrystal[i]))
- crystal->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
- uiRemoveNpc = 0; // might not have been reset after a wipe on a boss.
+ if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL_ELITE, PortalElitePositions[LastPortalLocation - PortalPositionsSize], TEMPSUMMON_CORPSE_DESPAWN))
+ portal->AI()->SetData(DATA_PORTAL_LOCATION, LastPortalLocation);
}
- break;
- case DATA_ZURAMAT:
- zuramatDead = true;
- break;
+ }
}
- }
- void SetGuidData(uint32 type, ObjectGuid data) override
- {
- switch (type)
+ void HandleCells(uint8 bossId, bool open = true)
{
- case DATA_ADD_TRASH_MOB:
- trashMobs.insert(data);
- break;
- case DATA_DEL_TRASH_MOB:
- trashMobs.erase(data);
- break;
+ switch (bossId)
+ {
+ case DATA_MORAGG:
+ HandleGameObject(GetObjectGuid(DATA_MORAGG_CELL), open);
+ break;
+ case DATA_EREKEM:
+ HandleGameObject(GetObjectGuid(DATA_EREKEM_CELL), open);
+ HandleGameObject(GetObjectGuid(DATA_EREKEM_LEFT_GUARD_CELL), open);
+ HandleGameObject(GetObjectGuid(DATA_EREKEM_RIGHT_GUARD_CELL), open);
+ break;
+ case DATA_ICHORON:
+ HandleGameObject(GetObjectGuid(DATA_ICHORON_CELL), open);
+ break;
+ case DATA_LAVANTHOR:
+ HandleGameObject(GetObjectGuid(DATA_LAVANTHOR_CELL), open);
+ break;
+ case DATA_XEVOZZ:
+ HandleGameObject(GetObjectGuid(DATA_XEVOZZ_CELL), open);
+ break;
+ case DATA_ZURAMAT:
+ HandleGameObject(GetObjectGuid(DATA_ZURAMAT_CELL), open);
+ break;
+ default:
+ break;
+ }
}
- }
- uint32 GetData(uint32 type) const override
- {
- switch (type)
+ void StartBossEncounter(uint8 bossId)
{
- case DATA_WAVE_COUNT: return uiWaveCount;
- case DATA_REMOVE_NPC: return uiRemoveNpc;
- case DATA_PORTAL_LOCATION: return uiLocation;
- case DATA_DOOR_INTEGRITY: return uiDoorIntegrity;
- case DATA_NPC_PRESENCE_AT_DOOR: return NpcAtDoorCastingList.size();
- case DATA_FIRST_BOSS: return uiFirstBoss;
- case DATA_SECOND_BOSS: return uiSecondBoss;
- case DATA_MAIN_EVENT_PHASE: return uiMainEventPhase;
- case DATA_DEFENSELESS: return defenseless ? 1 : 0;
- }
+ switch (bossId)
+ {
+ case DATA_MORAGG:
+ Scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
+ if (Creature* moragg = GetCreature(DATA_MORAGG))
+ {
+ moragg->PlayDirectSound(SOUND_MORAGG_SPAWN);
+ moragg->CastSpell(moragg, SPELL_MORAGG_EMOTE_ROAR);
+ }
+
+ task.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ if (Creature* moragg = GetCreature(DATA_MORAGG))
+ moragg->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, MoraggPath, MoraggPathSize, true);
+
+ task.Schedule(Seconds(8), [this](TaskContext /*task*/)
+ {
+ if (Creature* moragg = GetCreature(DATA_MORAGG))
+ {
+ moragg->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ moragg->AI()->DoZoneInCombat(moragg, 200.0f);
+ }
+ });
+ });
+ });
+ break;
+ case DATA_EREKEM:
+ Scheduler.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ if (Creature* erekem = GetCreature(DATA_EREKEM))
+ erekem->AI()->Talk(SAY_EREKEM_SPAWN);
+
+ task.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ if (Creature* erekem = GetCreature(DATA_EREKEM))
+ erekem->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, ErekemPath, ErekemPathSize, true);
+
+ if (Creature* guard = instance->GetCreature(GetGuidData(DATA_EREKEM_GUARD_1)))
+ guard->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, ErekemGuardLeftPath, ErekemGuardLeftPathSize, true);
+ if (Creature* guard = instance->GetCreature(GetGuidData(DATA_EREKEM_GUARD_2)))
+ guard->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, ErekemGuardRightPath, ErekemGuardRightPathSize, true);
+
+ task.Schedule(Seconds(6), [this](TaskContext task)
+ {
+ if (Creature* erekem = GetCreature(DATA_EREKEM))
+ erekem->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+
+ task.Schedule(Seconds(1), [this](TaskContext /*task*/)
+ {
+ for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
+ {
+ if (Creature* guard = instance->GetCreature(GetGuidData(i)))
+ guard->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ }
+
+ if (Creature* erekem = GetCreature(DATA_EREKEM))
+ {
+ erekem->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ erekem->AI()->DoZoneInCombat(erekem, 200.0f);
+ }
+ });
+ });
+ });
+ });
+ break;
+ case DATA_ICHORON:
+ Scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
+ if (Creature* ichoron = GetCreature(DATA_ICHORON))
+ ichoron->AI()->Talk(SAY_ICHORON_SPAWN);
+
+ task.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ if (Creature* ichoron = GetCreature(DATA_ICHORON))
+ ichoron->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, IchoronPath, IchoronPathSize, true);
+
+ task.Schedule(Seconds(14), [this](TaskContext /*task*/)
+ {
+ if (Creature* ichoron = GetCreature(DATA_ICHORON))
+ {
+ ichoron->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ ichoron->AI()->DoZoneInCombat(ichoron, 200.0f);
+ }
+ });
+ });
+ });
+ break;
+ case DATA_LAVANTHOR:
+ Scheduler.Schedule(Seconds(1), [this](TaskContext task)
+ {
+ if (Creature* lavanthor = GetCreature(DATA_LAVANTHOR))
+ lavanthor->CastSpell(lavanthor, SPELL_LAVANTHOR_SPECIAL_UNARMED);
+
+ task.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ if (Creature* lavanthor = GetCreature(DATA_LAVANTHOR))
+ lavanthor->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, LavanthorPath, LavanthorPathSize, true);
+
+ task.Schedule(Seconds(8), [this](TaskContext /*task*/)
+ {
+ if (Creature* lavanthor = GetCreature(DATA_LAVANTHOR))
+ {
+ lavanthor->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ lavanthor->AI()->DoZoneInCombat(lavanthor, 200.0f);
+ }
+ });
+ });
+ });
+ break;
+ case DATA_XEVOZZ:
+ Scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
+ if (Creature* xevozz = GetCreature(DATA_XEVOZZ))
+ xevozz->AI()->Talk(SAY_XEVOZZ_SPAWN);
+
+ task.Schedule(Seconds(3), [this](TaskContext task)
+ {
+ if (Creature* xevozz = GetCreature(DATA_XEVOZZ))
+ xevozz->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
+
+ task.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (Creature* xevozz = GetCreature(DATA_XEVOZZ))
+ xevozz->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, XevozzPath, XevozzPathSize, true);
+
+ task.Schedule(Seconds(4), [this](TaskContext /*task*/)
+ {
+ if (Creature* xevozz = GetCreature(DATA_XEVOZZ))
+ {
+ xevozz->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ xevozz->AI()->DoZoneInCombat(xevozz, 200.0f);
+ }
+ });
+ });
+ });
+ });
+ break;
+ case DATA_ZURAMAT:
+ Scheduler.Schedule(Seconds(2), [this](TaskContext task)
+ {
+ if (Creature* zuramat = GetCreature(DATA_ZURAMAT))
+ {
+ zuramat->CastSpell(zuramat, SPELL_ZURAMAT_COSMETIC_CHANNEL_OMNI);
+ zuramat->AI()->Talk(SAY_ZURAMAT_SPAWN);
+ }
+
+ task.Schedule(Seconds(6), [this](TaskContext task)
+ {
+ if (Creature* zuramat = GetCreature(DATA_ZURAMAT))
+ zuramat->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, ZuramatPath, ZuramatPathSize, true);
+
+ task.Schedule(Seconds(4), [this](TaskContext /*task*/)
+ {
+ if (Creature* zuramat = GetCreature(DATA_ZURAMAT))
+ {
+ zuramat->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ zuramat->AI()->DoZoneInCombat(zuramat, 200.0f);
+ }
+ });
+ });
+ });
+ break;
+ default:
+ return;
+ }
- return 0;
- }
+ HandleCells(bossId);
+ }
- ObjectGuid GetGuidData(uint32 type) const override
- {
- switch (type)
+ void ResetBossEncounter(uint8 bossId)
{
- case DATA_EREKEM_GUARD_1: return uiErekemGuard[0];
- case DATA_EREKEM_GUARD_2: return uiErekemGuard[1];
- case DATA_TELEPORTATION_PORTAL: return uiTeleportationPortal;
- case DATA_SABOTEUR_PORTAL: return uiSaboteurPortal;
- }
+ if (bossId < DATA_CYANIGOSA || bossId > DATA_ZURAMAT)
+ return;
- return InstanceScript::GetGuidData(type);
- }
+ Creature* boss = GetCreature(bossId);
+ if (!boss)
+ return;
- void SpawnPortal()
- {
- SetData(DATA_PORTAL_LOCATION, (GetData(DATA_PORTAL_LOCATION) + urand(1, 5))%6);
- if (Creature* sinclari = GetCreature(DATA_SINCLARI))
- if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalLocation[GetData(DATA_PORTAL_LOCATION)], TEMPSUMMON_CORPSE_DESPAWN))
- uiTeleportationPortal = portal->GetGUID();
- }
+ switch (bossId)
+ {
+ case DATA_CYANIGOSA:
+ boss->DespawnOrUnsummon();
+ break;
+ case DATA_EREKEM:
+ for (uint32 i = DATA_EREKEM_GUARD_1; i <= DATA_EREKEM_GUARD_2; ++i)
+ {
+ if (Creature* guard = instance->GetCreature(GetGuidData(i)))
+ {
+ if (guard->isDead())
+ guard->Respawn();
- void StartBossEncounter(uint8 uiBoss, bool bForceRespawn = true)
- {
- Creature* boss = nullptr;
+ if (GetBossState(bossId) == DONE)
+ UpdateKilledBoss(guard);
- switch (uiBoss)
- {
- case BOSS_MORAGG:
- HandleGameObject(GetObjectGuid(DATA_MORAGG_CELL), bForceRespawn);
- boss = GetCreature(DATA_MORAGG);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove1);
- break;
- case BOSS_EREKEM:
- HandleGameObject(GetObjectGuid(DATA_EREKEM_CELL), bForceRespawn);
- HandleGameObject(GetObjectGuid(DATA_EREKEM_LEFT_GUARD_CELL), bForceRespawn);
- HandleGameObject(GetObjectGuid(DATA_EREKEM_RIGHT_GUARD_CELL), bForceRespawn);
-
- boss = GetCreature(DATA_EREKEM);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove2);
-
- if (Creature* pGuard1 = instance->GetCreature(uiErekemGuard[0]))
- {
- if (bForceRespawn)
+ guard->GetMotionMaster()->MoveTargetedHome();
+ guard->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ }
+ }
+ // no break
+ default:
+ if (boss->isDead())
{
- pGuard1->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NON_ATTACKABLE);
- pGuard1->GetMotionMaster()->MovePoint(0, BossStartMove21);
+ // respawn and update to a placeholder npc to avoid be looted again
+ boss->Respawn();
+ UpdateKilledBoss(boss);
}
- else
- pGuard1->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- }
- if (Creature* pGuard2 = instance->GetCreature(uiErekemGuard[1]))
- {
- if (bForceRespawn)
+ boss->GetMotionMaster()->MoveTargetedHome();
+ boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ break;
+ }
+ }
+
+ void AddWave()
+ {
+ DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, WaveCount);
+
+ switch (WaveCount)
+ {
+ case 6:
+ if (FirstBossId == 0)
+ FirstBossId = urand(DATA_MORAGG, DATA_ZURAMAT);
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
{
- pGuard2->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- pGuard2->GetMotionMaster()->MovePoint(0, BossStartMove22);
+ sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL_INTRO, PortalIntroPositions[3], TEMPSUMMON_TIMED_DESPAWN, 3000);
+ sinclari->SummonCreature(NPC_SABOTEOUR, SaboteurSpawnLocation, TEMPSUMMON_DEAD_DESPAWN);
}
- else
- pGuard2->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- }
- break;
- case BOSS_ICHORON:
- HandleGameObject(GetObjectGuid(DATA_ICHORON_CELL), bForceRespawn);
- boss = GetCreature(DATA_ICHORON);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove3);
- break;
- case BOSS_LAVANTHOR:
- HandleGameObject(GetObjectGuid(DATA_LAVANTHOR_CELL), bForceRespawn);
- boss = GetCreature(DATA_LAVANTHOR);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove4);
- break;
- case BOSS_XEVOZZ:
- HandleGameObject(GetObjectGuid(DATA_XEVOZZ_CELL), bForceRespawn);
- boss = GetCreature(DATA_XEVOZZ);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove5);
- break;
- case BOSS_ZURAMAT:
- HandleGameObject(GetObjectGuid(DATA_ZURAMAT_CELL), bForceRespawn);
- boss = GetCreature(DATA_ZURAMAT);
- if (boss)
- boss->GetMotionMaster()->MovePoint(0, BossStartMove6);
- break;
+ break;
+ case 12:
+ if (SecondBossId == 0)
+ do
+ {
+ SecondBossId = urand(DATA_MORAGG, DATA_ZURAMAT);
+ } while (SecondBossId == FirstBossId);
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ {
+ sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL_INTRO, PortalIntroPositions[3], TEMPSUMMON_TIMED_DESPAWN, 3000);
+ sinclari->SummonCreature(NPC_SABOTEOUR, SaboteurSpawnLocation, TEMPSUMMON_DEAD_DESPAWN);
+ }
+ break;
+ case 18:
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ {
+ sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL_INTRO, PortalIntroPositions[4], TEMPSUMMON_TIMED_DESPAWN, 6000);
+ if (Creature* cyanigosa = sinclari->SummonCreature(NPC_CYANIGOSA, CyanigosaSpawnLocation, TEMPSUMMON_DEAD_DESPAWN))
+ cyanigosa->CastSpell(cyanigosa, SPELL_CYANIGOSA_ARCANE_POWER_STATE, true);
+ ScheduleCyanigosaIntro();
+ }
+ break;
+ default:
+ SpawnPortal();
+ break;
+ }
}
- // generic boss state changes
- if (boss)
+ void WriteSaveDataMore(std::ostringstream& data) override
{
- boss->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- boss->SetReactState(REACT_AGGRESSIVE);
+ data << FirstBossId << ' ' << SecondBossId;
+ }
+
+ void ReadSaveDataMore(std::istringstream& data) override
+ {
+ data >> FirstBossId;
+ data >> SecondBossId;
+ }
- if (!bForceRespawn)
+ bool CheckWipe() const
+ {
+ Map::PlayerList const& players = instance->GetPlayers();
+ for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
- if (boss->isDead())
- {
- // respawn but avoid to be looted again
- boss->Respawn();
- boss->RemoveLootMode(1);
- }
- else
- boss->GetMotionMaster()->MoveTargetedHome();
+ Player* player = itr->GetSource();
+ if (player->IsGameMaster())
+ continue;
- boss->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- uiWaveCount = 0;
+ if (player->IsAlive())
+ return false;
}
- }
- }
- void AddWave()
- {
- DoUpdateWorldState(WORLD_STATE_VH, 1);
- DoUpdateWorldState(WORLD_STATE_VH_WAVE_COUNT, uiWaveCount);
+ return true;
+ }
- switch (uiWaveCount)
+ void UpdateKilledBoss(Creature* boss)
{
- case 6:
- if (uiFirstBoss == 0)
- uiFirstBoss = urand(1, 6);
- if (Creature* sinclari = GetCreature(DATA_SINCLARI))
- {
- if (Creature* portal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
- uiSaboteurPortal = portal->GetGUID();
- if (Creature* azureSaboteur = sinclari->SummonCreature(NPC_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
- azureSaboteur->CastSpell(azureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
- }
- break;
- case 12:
- if (uiSecondBoss == 0)
- do
- {
- uiSecondBoss = urand(1, 6);
- } while (uiSecondBoss == uiFirstBoss);
- if (Creature* sinclari = GetCreature(DATA_SINCLARI))
- {
- if (Creature* pPortal = sinclari->SummonCreature(NPC_TELEPORTATION_PORTAL, MiddleRoomPortalSaboLocation, TEMPSUMMON_CORPSE_DESPAWN))
- uiSaboteurPortal = pPortal->GetGUID();
- if (Creature* pAzureSaboteur = sinclari->SummonCreature(NPC_SABOTEOUR, MiddleRoomLocation, TEMPSUMMON_DEAD_DESPAWN))
- pAzureSaboteur->CastSpell(pAzureSaboteur, SABOTEUR_SHIELD_EFFECT, false);
- }
- break;
- case 18:
- if (Creature* sinclari = GetCreature(DATA_SINCLARI))
- sinclari->SummonCreature(NPC_CYANIGOSA, CyanigosasSpawnLocation, TEMPSUMMON_DEAD_DESPAWN);
- break;
- case 1:
+ switch (boss->GetEntry())
{
- if (GameObject* mainDoor = GetGameObject(DATA_MAIN_DOOR))
- mainDoor->SetGoState(GO_STATE_READY);
- DoUpdateWorldState(WORLD_STATE_VH_PRISON_STATE, 100);
- // no break
+ case NPC_XEVOZZ:
+ boss->UpdateEntry(NPC_DUMMY_XEVOZZ);
+ break;
+ case NPC_LAVANTHOR:
+ boss->UpdateEntry(NPC_DUMMY_LAVANTHOR);
+ break;
+ case NPC_ICHORON:
+ boss->UpdateEntry(NPC_DUMMY_ICHORON);
+ break;
+ case NPC_ZURAMAT:
+ boss->UpdateEntry(NPC_DUMMY_ZURAMAT);
+ break;
+ case NPC_EREKEM:
+ boss->UpdateEntry(NPC_DUMMY_EREKEM);
+ break;
+ case NPC_MORAGG:
+ boss->UpdateEntry(NPC_DUMMY_MORAGG);
+ break;
+ case NPC_EREKEM_GUARD:
+ boss->UpdateEntry(NPC_DUMMY_EREKEM_GUARD);
+ break;
+ default:
+ break;
}
- default:
- SpawnPortal();
- break;
}
- }
- void WriteSaveDataMore(std::ostringstream& data) override
- {
- data << uiFirstBoss << ' ' << uiSecondBoss;
- }
+ void Update(uint32 diff) override
+ {
+ if (!instance->HavePlayers())
+ return;
- void ReadSaveDataMore(std::istringstream& data) override
- {
- data >> uiFirstBoss;
- data >> uiSecondBoss;
- }
+ // if main event is in progress and players have wiped then reset instance
+ if ((EventState == IN_PROGRESS && CheckWipe()) || EventState == FAIL)
+ {
+ ResetBossEncounter(FirstBossId);
+ ResetBossEncounter(SecondBossId);
+ ResetBossEncounter(DATA_CYANIGOSA);
- bool CheckWipe()
- {
- Map::PlayerList const &players = instance->GetPlayers();
- for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
- {
- Player* player = itr->GetSource();
- if (player->IsGameMaster())
- continue;
+ WaveCount = 0;
+ DoorIntegrity = 100;
+ Defenseless = true;
+ SetData(DATA_MAIN_EVENT_STATE, NOT_STARTED);
- if (player->IsAlive())
- return false;
- }
+ Scheduler.CancelAll();
- zuramatDead = false;
- return true;
- }
+ if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ sinclari->AI()->EnterEvadeMode();
+ }
- void Update(uint32 diff) override
- {
- if (!instance->HavePlayers())
- return;
+ Scheduler.Update(diff);
- // portals should spawn if other portal is dead and doors are closed
- if (bActive && uiMainEventPhase == IN_PROGRESS)
- {
- if (uiActivationTimer < diff)
+ if (EventState == IN_PROGRESS)
{
- AddWave();
- bActive = false;
- // 1 minute waiting time after each boss fight
- uiActivationTimer = (uiWaveCount == 6 || uiWaveCount == 12) ? 60000 : 5000;
- } else uiActivationTimer -= diff;
+ // if door is destroyed, event is failed
+ if (!GetData(DATA_DOOR_INTEGRITY))
+ EventState = FAIL;
+ }
}
- // if main event is in progress and players have wiped then reset instance
- if (uiMainEventPhase == IN_PROGRESS && CheckWipe())
+ void ScheduleCyanigosaIntro()
{
- SetData(DATA_REMOVE_NPC, 1);
- StartBossEncounter(uiFirstBoss, false);
- StartBossEncounter(uiSecondBoss, false);
-
- SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE);
- SetData(DATA_WAVE_COUNT, 0);
- uiMainEventPhase = NOT_STARTED;
- uiActivationTimer = 5000;
-
- for (int i = 0; i < 4; ++i)
- if (GameObject* crystal = instance->GetGameObject(uiActivationCrystal[i]))
- crystal->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
-
- if (Creature* sinclari = GetCreature(DATA_SINCLARI))
+ Scheduler.Schedule(Seconds(2), [this](TaskContext task)
{
- sinclari->SetVisible(true);
+ if (Creature* cyanigosa = GetCreature(DATA_CYANIGOSA))
+ cyanigosa->AI()->Talk(SAY_CYANIGOSA_SPAWN);
- std::list<Creature*> GuardList;
- sinclari->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
- if (!GuardList.empty())
+ task.Schedule(Seconds(6), [this](TaskContext task)
{
- for (Creature* guard : GuardList)
+ if (Creature* cyanigosa = GetCreature(DATA_CYANIGOSA))
+ cyanigosa->GetMotionMaster()->MoveJump(CyanigosaJumpLocation, 10.0f, 27.44744f);
+
+ task.Schedule(Seconds(7), [this](TaskContext /*task*/)
{
- guard->SetVisible(true);
- guard->SetReactState(REACT_AGGRESSIVE);
- guard->GetMotionMaster()->MovePoint(1, guard->GetHomePosition());
- }
- }
- sinclari->GetMotionMaster()->MovePoint(1, sinclari->GetHomePosition());
- sinclari->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
- }
+ if (Creature* cyanigosa = GetCreature(DATA_CYANIGOSA))
+ {
+ cyanigosa->RemoveAurasDueToSpell(SPELL_CYANIGOSA_ARCANE_POWER_STATE);
+ cyanigosa->CastSpell(cyanigosa, SPELL_CYANIGOSA_TRANSFORM, true);
+ cyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
+ }
+ });
+ });
+ });
}
- // Cyanigosa is spawned but not tranformed, prefight event
- Creature* cyanigosa = GetCreature(DATA_CYANIGOSA);
- if (cyanigosa && !cyanigosa->HasAura(CYANIGOSA_SPELL_TRANSFORM))
+ void ProcessEvent(WorldObject* /*go*/, uint32 eventId) override
{
- if (uiCyanigosaEventTimer <= diff)
+ if (eventId == EVENT_ACTIVATE_CRYSTAL)
{
- switch (uiCyanigosaEventPhase)
- {
- case 1:
- cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false);
- cyanigosa->AI()->Talk(CYANIGOSA_SAY_SPAWN);
- uiCyanigosaEventTimer = 7*IN_MILLISECONDS;
- ++uiCyanigosaEventPhase;
- break;
- case 2:
- cyanigosa->GetMotionMaster()->MoveJump(MiddleRoomLocation.GetPositionX(), MiddleRoomLocation.GetPositionY(), MiddleRoomLocation.GetPositionZ(), 10.0f, 20.0f);
- cyanigosa->CastSpell(cyanigosa, CYANIGOSA_BLUE_AURA, false);
- uiCyanigosaEventTimer = 7*IN_MILLISECONDS;
- ++uiCyanigosaEventPhase;
- break;
- case 3:
- cyanigosa->RemoveAurasDueToSpell(CYANIGOSA_BLUE_AURA);
- cyanigosa->CastSpell(cyanigosa, CYANIGOSA_SPELL_TRANSFORM, 0);
- cyanigosa->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- cyanigosa->SetReactState(REACT_AGGRESSIVE);
- uiCyanigosaEventTimer = 2*IN_MILLISECONDS;
- ++uiCyanigosaEventPhase;
- break;
- case 4:
- uiCyanigosaEventPhase = 0;
- break;
- }
- } else uiCyanigosaEventTimer -= diff;
+ instance->SummonCreature(NPC_DEFENSE_SYSTEM, DefenseSystemLocation);
+ Defenseless = false;
+ }
}
- // if there are NPCs in front of the prison door, which are casting the door seal spell and doors are active
- if (GetData(DATA_NPC_PRESENCE_AT_DOOR) && uiMainEventPhase == IN_PROGRESS)
+ static bool IsBossWave(uint8 wave)
{
- // if door integrity is > 0 then decrase it's integrity state
- if (GetData(DATA_DOOR_INTEGRITY))
- {
- if (uiDoorSpellTimer < diff)
- {
- SetData(DATA_DOOR_INTEGRITY, GetData(DATA_DOOR_INTEGRITY)-1);
- uiDoorSpellTimer =2000;
- } else uiDoorSpellTimer -= diff;
- }
- // else set door state to active (means door will open and group have failed to sustain mob invasion on the door)
- else
- {
- SetData(DATA_MAIN_DOOR, GO_STATE_ACTIVE);
- uiMainEventPhase = FAIL;
- }
+ return wave && ((wave % 6) == 0);
}
- }
- void ActivateCrystal()
- {
- // just to make things easier we'll get the gameobject from the map
- GameObject* invoker = instance->GetGameObject(uiActivationCrystal[0]);
- if (!invoker)
- return;
+ protected:
+ TaskScheduler Scheduler;
- SpellInfo const* spellInfoLightning = sSpellMgr->GetSpellInfo(SPELL_ARCANE_LIGHTNING);
- if (!spellInfoLightning)
- return;
+ static uint8 const ErekemGuardCount = 2;
+ ObjectGuid ErekemGuardGUIDs[ErekemGuardCount];
- // the orb
- TempSummon* trigger = invoker->SummonCreature(NPC_DEFENSE_SYSTEM, ArcaneSphere, TEMPSUMMON_MANUAL_DESPAWN, 0);
- if (!trigger)
- return;
+ static uint8 const ActivationCrystalCount = 5;
+ ObjectGuid ActivationCrystalGUIDs[ActivationCrystalCount];
- // visuals
- trigger->CastSpell(trigger, spellInfoLightning, true, 0, 0, trigger->GetGUID());
+ uint32 FirstBossId;
+ uint32 SecondBossId;
- // Kill all mobs registered with SetGuidData(ADD_TRASH_MOB)
- for (GuidSet::const_iterator itr = trashMobs.begin(); itr != trashMobs.end();)
- {
- Creature* creature = instance->GetCreature(*itr);
- // Increment the iterator before killing the creature because the kill will remove itr from trashMobs
- ++itr;
- if (creature && creature->IsAlive())
- trigger->Kill(creature);
- }
- }
+ uint8 DoorIntegrity;
+ uint8 WaveCount;
+ uint8 EventState;
+ uint8 LastPortalLocation;
+
+ bool Defenseless;
+ };
- void ProcessEvent(WorldObject* /*go*/, uint32 uiEventId) override
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
- switch (uiEventId)
- {
- case EVENT_ACTIVATE_CRYSTAL:
- bCrystalActivated = true; // Activation by player's will throw event signal
- ActivateCrystal();
- break;
- }
+ return new instance_violet_hold_InstanceMapScript(map);
}
- };
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const override
- {
- return new instance_violet_hold_InstanceMapScript(map);
- }
};
void AddSC_instance_violet_hold()
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
index b05da4b994c..fdb4c4dc3fc 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.cpp
@@ -15,36 +15,41 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "ScriptedEscortAI.h"
-#include "violet_hold.h"
-#include "Player.h"
-#include "SpellAuras.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
+#include "violet_hold.h"
-#define GOSSIP_START_EVENT "Get your people to safety, we'll keep the Blue Dragonflight's forces at bay."
-#define GOSSIP_ITEM_1 "Activate the crystals when we get in trouble, right"
-#define GOSSIP_I_WANT_IN "I'm not fighting, so send me in now!"
-#define SAY_EVENT_LOCK "I'm locking the door. Good luck, and thank you for doing this."
-#define SPAWN_TIME 20000
+/*
+ * TODO:
+ * - add missing trash emotes
+ */
-enum PortalCreatures
+enum PortalCreatureIds
{
NPC_AZURE_INVADER_1 = 30661,
- NPC_AZURE_INVADER_2 = 30961,
NPC_AZURE_SPELLBREAKER_1 = 30662,
- NPC_AZURE_SPELLBREAKER_2 = 30962,
NPC_AZURE_BINDER_1 = 30663,
- NPC_AZURE_BINDER_2 = 30918,
NPC_AZURE_MAGE_SLAYER_1 = 30664,
+ NPC_VETERAN_MAGE_HUNTER = 30665,
+ NPC_AZURE_CAPTAIN_1 = 30666,
+ NPC_AZURE_SORCEROR_1 = 30667,
+ NPC_AZURE_RAIDER_1 = 30668,
+
+ NPC_AZURE_BINDER_2 = 30918,
+ NPC_AZURE_INVADER_2 = 30961,
+ NPC_AZURE_SPELLBREAKER_2 = 30962,
NPC_AZURE_MAGE_SLAYER_2 = 30963,
- NPC_AZURE_CAPTAIN = 30666,
- NPC_AZURE_SORCEROR = 30667,
- NPC_AZURE_RAIDER = 30668,
- NPC_AZURE_STALKER = 32191
+ NPC_AZURE_BINDER_3 = 31007,
+ NPC_AZURE_INVADER_3 = 31008,
+ NPC_AZURE_SPELLBREAKER_3 = 31009,
+ NPC_AZURE_MAGE_SLAYER_3 = 31010,
+ NPC_AZURE_RAIDER_2 = 31118,
+ NPC_AZURE_STALKER_1 = 32191
};
enum AzureInvaderSpells
@@ -103,8 +108,8 @@ enum AzureStalkerSpells
enum AzureSaboteurSpells
{
- SABOTEUR_SHIELD_DISRUPTION = 58291,
- SABOTEUR_SHIELD_EFFECT = 45775
+ SPELL_SHIELD_DISRUPTION = 58291,
+ SPELL_TELEPORT_VISUAL = 51347
};
enum TrashDoorSpell
@@ -112,19 +117,45 @@ enum TrashDoorSpell
SPELL_DESTROY_DOOR_SEAL = 58040
};
-enum Spells
+enum DefenseSystemSpells
+{
+ SPELL_ARCANE_LIGHTNING_DAMAGE = 57912,
+ SPELL_ARCANE_LIGHTNING_INSTAKILL = 58152,
+ SPELL_ARCANE_LIGHTNING_DUMMY = 57930
+};
+
+enum MiscSpells
+{
+ SPELL_PORTAL_PERIODIC = 58008,
+ SPELL_PORTAL_CHANNEL = 58012,
+ SPELL_CRYSTAL_ACTIVATION = 57804,
+
+ SPELL_TELEPORT_PLAYER = 62138,
+ SPELL_TELEPORT_PLAYER_EFFECT = 62139
+};
+
+enum MiscData
{
- SPELL_PORTAL_CHANNEL = 58012,
- SPELL_CRYSTAL_ACTIVATION = 57804, // visual effect
- SPELL_ARCANE_SPHERE_PASSIVE = 44263
+ DATA_PORTAL_PERIODIC_TICK = 1
};
enum Sinclari
{
- SAY_SINCLARI_1 = 0
+ // Sinclari
+ SAY_SINCLARI_INTRO_1 = 0,
+ SAY_SINCLARI_INTRO_2 = 1,
+ SAY_SINCLARI_OUTRO = 2,
+
+ GOSSIP_MENU_START_ENCOUNTER = 9998,
+ GOSSIP_MENU_SEND_ME_IN = 10275,
+
+ // Sinclari Trigger
+ SAY_SINCLARI_ELITE_SQUAD = 0,
+ SAY_SINCLARI_PORTAL_GUARDIAN = 1,
+ SAY_SINCLARI_PORTAL_KEEPER = 2
};
-float FirstPortalWPs [6][3] =
+G3D::Vector3 const FirstPortalWPs[6] =
{
{1877.670288f, 842.280273f, 43.333591f},
{1877.338867f, 834.615356f, 38.762287f},
@@ -135,7 +166,7 @@ float FirstPortalWPs [6][3] =
//{1825.736084f, 807.305847f, 44.363785f}
};
-float SecondPortalFirstWPs [9][3] =
+G3D::Vector3 const SecondPortalFirstWPs[9] =
{
{1902.561401f, 853.334656f, 47.106117f},
{1895.486084f, 855.376404f, 44.334591f},
@@ -149,7 +180,7 @@ float SecondPortalFirstWPs [9][3] =
//{1825.736084f, 807.305847f, 44.363785f}
};
-float SecondPortalSecondWPs [8][3] =
+G3D::Vector3 const SecondPortalSecondWPs[8] =
{
{1929.392212f, 837.614990f, 47.136166f},
{1928.290649f, 824.750427f, 45.474411f},
@@ -162,7 +193,7 @@ float SecondPortalSecondWPs [8][3] =
//{1825.736084f, 807.305847f, 44.363785f}
};
-float ThirdPortalWPs [8][3] =
+G3D::Vector3 const ThirdPortalWPs[8] =
{
{1934.049438f, 815.778503f, 52.408699f},
{1928.290649f, 824.750427f, 45.474411f},
@@ -175,7 +206,7 @@ float ThirdPortalWPs [8][3] =
//{1825.736084f, 807.305847f, 44.363785f}
};
-float FourthPortalWPs [9][3] =
+G3D::Vector3 const FourthPortalWPs[9] =
{
{1921.658447f, 761.657043f, 50.866741f},
{1910.559814f, 755.780457f, 47.701447f},
@@ -189,7 +220,7 @@ float FourthPortalWPs [9][3] =
//{1827.100342f, 801.605957f, 44.363358f}
};
-float FifthPortalWPs [6][3] =
+G3D::Vector3 const FifthPortalWPs[6] =
{
{1887.398804f, 763.633240f, 47.666851f},
{1879.020386f, 775.396973f, 38.705990f},
@@ -200,7 +231,7 @@ float FifthPortalWPs [6][3] =
//{1827.100342f, 801.605957f, 44.363358f}
};
-float SixthPoralWPs [4][3] =
+G3D::Vector3 const SixthPoralWPs[4] =
{
{1888.861084f, 805.074768f, 38.375790f},
{1869.793823f, 804.135804f, 38.647018f},
@@ -209,1308 +240,1188 @@ float SixthPoralWPs [4][3] =
//{1826.889648f, 803.929993f, 44.363239f}
};
-const float SaboteurFinalPos1[3][3] =
+G3D::Vector3 const DefaultPortalWPs[1] =
{
- {1892.502319f, 777.410767f, 38.630402f},
- {1891.165161f, 762.969421f, 47.666920f},
- {1893.168091f, 740.919189f, 47.666920f}
+ { 1843.567017f, 804.288208f, 44.139091f }
};
-const float SaboteurFinalPos2[3][3] =
+
+uint32 const SaboteurMoraggPathSize = 5;
+G3D::Vector3 const SaboteurMoraggPath[SaboteurMoraggPathSize] = // sniff
{
- {1882.242676f, 834.818726f, 38.646786f},
- {1879.220825f, 842.224854f, 43.333641f},
- {1873.842896f, 863.892456f, 43.333641f}
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1885.71f, 799.8929f, 38.37241f },
+ { 1889.505f, 762.3288f, 47.66684f },
+ { 1894.542f, 742.1829f, 47.66684f },
+ { 1894.603f, 739.9231f, 47.66684f },
};
-const float SaboteurFinalPos3[2][3] =
+
+uint32 const SaboteurErekemPathSize = 5;
+G3D::Vector3 const SaboteurErekemPath[SaboteurErekemPathSize] = // sniff
{
- {1904.298340f, 792.400391f, 38.646782f},
- {1935.716919f, 758.437073f, 30.627895f}
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1881.047f, 829.6866f, 38.64856f },
+ { 1877.585f, 844.6685f, 38.49014f },
+ { 1876.085f, 851.6685f, 42.99014f },
+ { 1873.747f, 864.1373f, 43.33349f }
};
-const float SaboteurFinalPos4[3] =
+
+uint32 const SaboteurIchoronPathSize = 3;
+G3D::Vector3 const SaboteurIchoronPath[SaboteurIchoronPathSize] = // sniff
{
- 1855.006104f, 760.641724f, 38.655266f
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1888.672f, 801.2348f, 38.42305f },
+ { 1901.987f, 793.3254f, 38.65126f }
};
-const float SaboteurFinalPos5[3] =
+
+uint32 const SaboteurLavanthorPathSize = 3;
+G3D::Vector3 const SaboteurLavanthorPath[SaboteurLavanthorPathSize] = // sniff
{
- 1906.667358f, 841.705566f, 38.637894f
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1867.925f, 778.8035f, 38.64702f },
+ { 1853.304f, 759.0161f, 38.65761f }
};
-const float SaboteurFinalPos6[5][3] =
-{
- {1911.437012f, 821.289246f, 38.684128f},
- {1920.734009f, 822.978027f, 41.525414f},
- {1928.262939f, 830.836609f, 44.668266f},
- {1929.338989f, 837.593933f, 47.137596f},
- {1931.063354f, 848.468445f, 47.190434f}
- };
-
-const Position PortalLocation[] =
+
+uint32 const SaboteurXevozzPathSize = 4;
+G3D::Vector3 const SaboteurXevozzPath[SaboteurXevozzPathSize] = // sniff
{
- { 1877.51f, 850.104f, 44.6599f, 4.7822f }, // WP 1
- { 1936.07f, 803.198f, 53.3749f, 3.12414f }, // WP 3
- { 1890.64f, 753.471f, 48.7224f, 1.71042f }, // WP 5
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1889.096f, 810.0487f, 38.43871f },
+ { 1896.547f, 823.5473f, 38.72863f },
+ { 1906.666f, 842.3111f, 38.63351f }
};
-#define MAX_PRE_EVENT_PORTAL 3
+uint32 const SaboteurZuramatPathSize = 7;
+G3D::Vector3 const SaboteurZuramatPath[SaboteurZuramatPathSize] = // sniff
+{
+ { 1886.251f, 803.0743f, 38.42326f },
+ { 1889.69f, 807.0032f, 38.39914f },
+ { 1906.91f, 818.2574f, 38.86596f },
+ { 1929.03f, 824.2713f, 46.09165f },
+ { 1928.441f, 842.8891f, 47.15078f },
+ { 1927.454f, 851.6091f, 47.19094f },
+ { 1927.947f, 852.2986f, 47.19637f }
+};
-ObjectGuid preEventPortalGUID[MAX_PRE_EVENT_PORTAL] = { ObjectGuid::Empty };
+Position const SinclariPositions[] = // sniff
+{
+ { 1829.142f, 798.219f, 44.36212f, 0.122173f }, // 0 - Crystal
+ { 1820.12f, 803.916f, 44.36466f, 0.0f }, // 1 - Outside
+ { 1816.185f, 804.0629f, 44.44799f, 3.176499f }, // 2 - Second Spawn Point
+ { 1827.886f, 804.0555f, 44.36467f, 0.0f } // 3 - Outro
+};
-const Position MovePosition = { 1806.955566f, 803.851807f, 44.363323f, 0.0f };
-const Position playerTeleportPosition = { 1830.531006f, 803.939758f, 44.340508f, 6.281611f };
-const Position sinclariOutsidePosition = { 1820.429810f, 804.066040f, 44.363998f, 0.0f };
-const Position sinclariCrystalPosition = { 1828.868286f, 798.468811f, 44.363998f, 3.890467f };
+Position const GuardsMovePosition = { 1802.099f, 803.7724f, 44.36466f, 0.0f }; // sniff
class npc_sinclari_vh : public CreatureScript
{
-public:
- npc_sinclari_vh() : CreatureScript("npc_sinclari_vh") { }
-
- bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
- {
- player->PlayerTalkClass->ClearMenus();
- switch (action)
- {
- case GOSSIP_ACTION_INFO_DEF+1:
- player->CLOSE_GOSSIP_MENU();
- ENSURE_AI(npc_sinclari_vh::npc_sinclariAI, creature->AI())->uiPhase = 1;
- if (InstanceScript* instance = creature->GetInstanceScript())
- instance->SetData(DATA_MAIN_EVENT_PHASE, SPECIAL);
- break;
- case GOSSIP_ACTION_INFO_DEF+2:
- player->SEND_GOSSIP_MENU(13854, creature->GetGUID());
- break;
- case GOSSIP_ACTION_INFO_DEF+3:
- player->NearTeleportTo(playerTeleportPosition.GetPositionX(), playerTeleportPosition.GetPositionY(), playerTeleportPosition.GetPositionZ(), playerTeleportPosition.GetOrientation(), true);
- player->CLOSE_GOSSIP_MENU();
- break;
- }
- return true;
- }
+ public:
+ npc_sinclari_vh() : CreatureScript("npc_sinclari_vh") { }
- bool OnGossipHello(Player* player, Creature* creature) override
- {
- if (InstanceScript* instance = creature->GetInstanceScript())
+ bool OnGossipHello(Player* player, Creature* creature) override
{
- switch (instance->GetData(DATA_MAIN_EVENT_PHASE))
+ // override default gossip
+ if (InstanceScript* instance = creature->GetInstanceScript())
{
- case NOT_STARTED:
- case FAIL: // Allow to start event if not started or wiped
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_START_EVENT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
- player->SEND_GOSSIP_MENU(13853, creature->GetGUID());
- break;
- case IN_PROGRESS: // Allow to teleport inside if event is in progress
- player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_I_WANT_IN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
- player->SEND_GOSSIP_MENU(13853, creature->GetGUID());
- break;
- default:
- player->SEND_GOSSIP_MENU(13910, creature->GetGUID());
+ switch (instance->GetData(DATA_MAIN_EVENT_STATE))
+ {
+ case IN_PROGRESS:
+ player->PrepareGossipMenu(creature, GOSSIP_MENU_SEND_ME_IN, true);
+ player->SendPreparedGossip(creature);
+ return true;
+ case DONE:
+ return true; // NYI
+ case NOT_STARTED:
+ case FAIL:
+ default:
+ break;
+ }
}
- }
- return true;
- }
- struct npc_sinclariAI : public ScriptedAI
- {
- npc_sinclariAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
+ // load default gossip
+ return false;
}
- void Initialize()
+ struct npc_sinclariAI : public ScriptedAI
{
- uiPhase = 0;
- uiTimer = 0;
- }
+ npc_sinclariAI(Creature* creature) : ScriptedAI(creature), _summons(creature)
+ {
+ _instance = creature->GetInstanceScript();
+ }
- InstanceScript* instance;
+ void Reset() override
+ {
+ _summons.DespawnAll();
+ for (uint8 i = 0; i < PortalIntroCount; ++i)
+ if (Creature* summon = me->SummonCreature(NPC_TELEPORTATION_PORTAL_INTRO, PortalIntroPositions[i], TEMPSUMMON_MANUAL_DESPAWN))
+ summon->AI()->SetData(DATA_PORTAL_LOCATION, i);
- uint8 uiPhase;
- uint32 uiTimer;
+ me->SetVisible(true);
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
- void Reset() override
- {
- Initialize();
+ std::list<Creature*> guardList;
+ me->GetCreatureListWithEntryInGrid(guardList, NPC_VIOLET_HOLD_GUARD, 100.0f);
+ for (Creature* guard : guardList)
+ {
+ guard->Respawn(true);
+ guard->SetVisible(true);
+ guard->SetReactState(REACT_AGGRESSIVE);
+ guard->AI()->EnterEvadeMode();
+ }
+ }
- me->SetReactState(REACT_AGGRESSIVE);
- for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
- if (TempSummon* summon = me->SummonCreature(NPC_TELEPORTATION_PORTAL, PortalLocation[i], TEMPSUMMON_MANUAL_DESPAWN))
- preEventPortalGUID[i] = summon->GetGUID();
+ void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override
+ {
+ if (menuId == GOSSIP_MENU_START_ENCOUNTER && gossipListId == 0)
+ {
+ me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ _instance->SetData(DATA_MAIN_EVENT_STATE, SPECIAL);
+ ScheduleIntro();
+ player->PlayerTalkClass->SendCloseGossip();
+ }
+ else if (menuId == GOSSIP_MENU_SEND_ME_IN && gossipListId == 0)
+ {
+ me->CastSpell(player, SPELL_TELEPORT_PLAYER, true);
+ player->PlayerTalkClass->SendCloseGossip();
+ }
+ }
- std::list<Creature*> GuardList;
- me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
- if (!GuardList.empty())
+ void DoAction(int32 actionId) override
{
- for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ if (actionId == ACTION_SINCLARI_OUTRO)
{
- if (Creature* pGuard = *itr)
- {
- pGuard->DisappearAndDie();
- pGuard->Respawn();
- pGuard->SetVisible(true);
- pGuard->SetReactState(REACT_AGGRESSIVE);
- }
+ me->SetVisible(true);
+ ScheduleOutro();
}
}
- }
- void UpdateAI(uint32 uiDiff) override
- {
- if (uiPhase)
+ void UpdateAI(uint32 diff) override
{
- if (uiTimer <= uiDiff)
+ _scheduler.Update(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void ScheduleIntro()
+ {
+ _scheduler.Schedule(Seconds(1), [this](TaskContext task)
{
- switch (uiPhase)
+ switch (task.GetRepeatCounter())
{
- case 1:
+ case 0:
me->SetWalk(true);
- me->GetMotionMaster()->MovePoint(0, sinclariCrystalPosition);
- uiTimer = 1000;
- uiPhase = 6;
+ me->GetMotionMaster()->MovePoint(0, SinclariPositions[0]);
+ task.Repeat(Seconds(1));
break;
- case 2:
- {
- me->SetFacingTo(me->GetOrientation() - 3.14f);
- Talk(SAY_SINCLARI_1);
- uiTimer = 1500;
- uiPhase = 7;
+ case 1:
+ me->HandleEmoteCommand(EMOTE_ONESHOT_USE_STANDING);
+ me->GetMap()->SummonCreature(NPC_DEFENSE_SYSTEM, DefenseSystemLocation);
+ task.Repeat(Seconds(3));
break;
- }
- case 3:
- {
- std::list<Creature*> GuardList;
- me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
- if (!GuardList.empty())
- for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
+ case 2:
+ me->SetFacingTo(SinclariPositions[0].GetOrientation());
+ Talk(SAY_SINCLARI_INTRO_1);
+
+ task.Schedule(Seconds(1), [this](TaskContext /*task*/)
+ {
+ std::list<Creature*> guardList;
+ me->GetCreatureListWithEntryInGrid(guardList, NPC_VIOLET_HOLD_GUARD, 100.0f);
+ for (Creature* guard : guardList)
{
- if (Creature* pGuard = *itr)
- {
- pGuard->SetVisible(false);
- }
+ guard->SetReactState(REACT_PASSIVE);
+ guard->SetWalk(false);
+ guard->GetMotionMaster()->MovePoint(0, GuardsMovePosition);
}
- uiTimer = 2000;
- uiPhase = 4;
+ });
+
+ task.Repeat(Seconds(2));
+ break;
+ case 3:
+ me->GetMotionMaster()->MovePoint(0, SinclariPositions[1]);
+ _summons.DespawnAll();
+ task.Repeat(Seconds(5));
break;
- }
case 4:
- me->GetMotionMaster()->MovePoint(0, sinclariOutsidePosition);
- uiTimer = 4000;
- uiPhase = 5;
+ me->SetFacingTo(SinclariPositions[1].GetOrientation());
+
+ task.Schedule(Seconds(1), [this](TaskContext /*task*/)
+ {
+ std::list<Creature*> guardList;
+ me->GetCreatureListWithEntryInGrid(guardList, NPC_VIOLET_HOLD_GUARD, 100.0f);
+ for (Creature* guard : guardList)
+ guard->SetVisible(false);
+ });
+
+ task.Repeat(Seconds(6));
break;
case 5:
- me->SetFacingTo(0.006673f);
- me->Say(SAY_EVENT_LOCK, LANG_UNIVERSAL, me); // need to change to db say
- me->SetReactState(REACT_PASSIVE);
- uiTimer = 3000;
- uiPhase = 8;
+ Talk(SAY_SINCLARI_INTRO_2);
+ task.Repeat(Seconds(4));
break;
case 6:
- me->GetMotionMaster()->MovementExpired();
- me->HandleEmoteCommand(EMOTE_STATE_USE_STANDING);
- uiTimer = 2000;
- uiPhase = 2;
+ me->HandleEmoteCommand(EMOTE_ONESHOT_TALK_NO_SHEATHE);
+ task.Repeat(Seconds(1));
break;
case 7:
- {
- std::list<Creature*> creatures;
- GetCreatureListWithEntryInGrid(creatures, me, NPC_TELEPORTATION_PORTAL, 200.0f);
- GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_BINDER_1, 200.0f);
- GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_MAGE_SLAYER_1, 200.0f);
- GetCreatureListWithEntryInGrid(creatures, me, NPC_AZURE_INVADER_1, 200.0f);
- DoCast(SPELL_CRYSTAL_ACTIVATION);
- if (!creatures.empty())
+ if (GameObject* mainDoor = _instance->GetGameObject(DATA_MAIN_DOOR))
{
- for (std::list<Creature*>::iterator itr = creatures.begin(); itr != creatures.end(); ++itr)
- (*itr)->DisappearAndDie();
+ mainDoor->SetGoState(GO_STATE_READY);
+ mainDoor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
}
- uiTimer = 500;
- uiPhase = 9;
- }
- break;
+ task.Repeat(Seconds(5));
+ break;
case 8:
- instance->SetData(DATA_MAIN_EVENT_PHASE, IN_PROGRESS);
- uiTimer = 0;
- uiPhase = 0;
+ me->SetVisible(false);
+ task.Repeat(Seconds(1));
break;
case 9:
- {
- std::list<Creature*> GuardList;
- me->GetCreatureListWithEntryInGrid(GuardList, NPC_VIOLET_HOLD_GUARD, 40.0f);
- if (!GuardList.empty())
- for (std::list<Creature*>::const_iterator itr = GuardList.begin(); itr != GuardList.end(); ++itr)
- {
- if (Creature* pGuard = *itr)
- {
- pGuard->SetReactState(REACT_PASSIVE);
- pGuard->SetWalk(false);
- pGuard->GetMotionMaster()->MovePoint(0, MovePosition);
- }
- }
- uiTimer = 4000;
- uiPhase = 3;
- }
- break;
+ _instance->SetData(DATA_MAIN_EVENT_STATE, IN_PROGRESS);
+ // [1] GUID: Full: 0xF1300077C202E6DD Type: Creature Entry: 30658 Low: 190173
+ break;
+ default:
+ break;
}
- }
- else uiTimer -= uiDiff;
+ });
}
- if (!UpdateVictim())
- return;
+ void ScheduleOutro()
+ {
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ Talk(SAY_SINCLARI_OUTRO);
+ me->GetMotionMaster()->MovePoint(0, SinclariPositions[3]);
- DoMeleeAttackIfReady();
- }
- };
+ task.Schedule(Seconds(10), [this](TaskContext /*task*/)
+ {
+ me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
+ });
+ });
+ }
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_sinclariAI>(creature);
- }
-};
+ void JustSummoned(Creature* summon) override
+ {
+ ScriptedAI::JustSummoned(summon);
+ _summons.Summon(summon);
+ }
-class npc_azure_saboteur : public CreatureScript
-{
-public:
- npc_azure_saboteur() : CreatureScript("npc_azure_saboteur") { }
+ void SummonedCreatureDespawn(Creature* summon) override
+ {
+ _summons.Despawn(summon);
+ ScriptedAI::SummonedCreatureDespawn(summon);
+ }
- struct npc_azure_saboteurAI : public npc_escortAI
- {
- npc_azure_saboteurAI(Creature* creature) : npc_escortAI(creature)
- {
- instance = creature->GetInstanceScript();
- bHasGotMovingPoints = false;
- uiBoss = 0;
- Reset();
- }
+ private:
+ InstanceScript* _instance;
+ TaskScheduler _scheduler;
- InstanceScript* instance;
- bool bHasGotMovingPoints;
- uint32 uiBoss;
+ SummonList _summons;
+ };
- void Reset() override
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (!uiBoss)
- uiBoss = instance->GetData(DATA_WAVE_COUNT) == 6 ? instance->GetData(DATA_FIRST_BOSS) : instance->GetData(DATA_SECOND_BOSS);
- me->SetReactState(REACT_PASSIVE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_NON_ATTACKABLE);
- me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
+ return GetVioletHoldAI<npc_sinclariAI>(creature);
}
+};
- void WaypointReached(uint32 waypointId) override
- {
- switch (uiBoss)
- {
- case 1:
- if (waypointId == 2)
- FinishPointReached();
- break;
- case 2:
- if (waypointId == 2)
- FinishPointReached();
- break;
- case 3:
- if (waypointId == 1)
- FinishPointReached();
- break;
- case 4:
- if (waypointId == 0)
- FinishPointReached();
- break;
- case 5:
- if (waypointId == 0)
- FinishPointReached();
- break;
- case 6:
- if (waypointId == 4)
- FinishPointReached();
- break;
- }
- }
+class npc_azure_saboteur : public CreatureScript
+{
+ public:
+ npc_azure_saboteur() : CreatureScript("npc_azure_saboteur") { }
- void UpdateAI(uint32 diff) override
+ struct npc_azure_saboteurAI : public ScriptedAI
{
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
- me->CastStop();
+ npc_azure_saboteurAI(Creature* creature) : ScriptedAI(creature)
+ {
+ _instance = creature->GetInstanceScript();
- npc_escortAI::UpdateAI(diff);
+ if (_instance->GetData(DATA_WAVE_COUNT) == 6)
+ _bossId = _instance->GetData(DATA_1ST_BOSS);
+ else
+ _bossId = _instance->GetData(DATA_2ND_BOSS);
+ }
- if (!bHasGotMovingPoints)
+ void StartMovement()
{
- bHasGotMovingPoints = true;
- switch (uiBoss)
+ uint32 pathSize = 0;
+ G3D::Vector3 const* path = nullptr;
+
+ switch (_bossId)
{
- case 1:
- for (int i=0;i<3;i++)
- AddWaypoint(i, SaboteurFinalPos1[i][0], SaboteurFinalPos1[i][1], SaboteurFinalPos1[i][2], 0);
- me->SetHomePosition(SaboteurFinalPos1[2][0], SaboteurFinalPos1[2][1], SaboteurFinalPos1[2][2], 4.762346f);
+ case DATA_MORAGG:
+ pathSize = SaboteurMoraggPathSize;
+ path = SaboteurMoraggPath;
break;
- case 2:
- for (int i=0;i<3;i++)
- AddWaypoint(i, SaboteurFinalPos2[i][0], SaboteurFinalPos2[i][1], SaboteurFinalPos2[i][2], 0);
- me->SetHomePosition(SaboteurFinalPos2[2][0], SaboteurFinalPos2[2][1], SaboteurFinalPos2[2][2], 1.862674f);
+ case DATA_EREKEM:
+ pathSize = SaboteurErekemPathSize;
+ path = SaboteurErekemPath;
break;
- case 3:
- for (int i=0;i<2;i++)
- AddWaypoint(i, SaboteurFinalPos3[i][0], SaboteurFinalPos3[i][1], SaboteurFinalPos3[i][2], 0);
- me->SetHomePosition(SaboteurFinalPos3[1][0], SaboteurFinalPos3[1][1], SaboteurFinalPos3[1][2], 5.500638f);
+ case DATA_ICHORON:
+ pathSize = SaboteurIchoronPathSize;
+ path = SaboteurIchoronPath;
break;
- case 4:
- AddWaypoint(0, SaboteurFinalPos4[0], SaboteurFinalPos4[1], SaboteurFinalPos4[2], 0);
- me->SetHomePosition(SaboteurFinalPos4[0], SaboteurFinalPos4[1], SaboteurFinalPos4[2], 3.991108f);
+ case DATA_LAVANTHOR:
+ pathSize = SaboteurLavanthorPathSize;
+ path = SaboteurLavanthorPath;
break;
- case 5:
- AddWaypoint(0, SaboteurFinalPos5[0], SaboteurFinalPos5[1], SaboteurFinalPos5[2], 0);
- me->SetHomePosition(SaboteurFinalPos5[0], SaboteurFinalPos5[1], SaboteurFinalPos5[2], 1.100841f);
+ case DATA_XEVOZZ:
+ pathSize = SaboteurXevozzPathSize;
+ path = SaboteurXevozzPath;
break;
- case 6:
- for (int i=0;i<5;i++)
- AddWaypoint(i, SaboteurFinalPos6[i][0], SaboteurFinalPos6[i][1], SaboteurFinalPos6[i][2], 0);
- me->SetHomePosition(SaboteurFinalPos6[4][0], SaboteurFinalPos6[4][1], SaboteurFinalPos6[4][2], 0.983031f);
+ case DATA_ZURAMAT:
+ pathSize = SaboteurZuramatPathSize;
+ path = SaboteurZuramatPath;
break;
}
- SetDespawnAtEnd(false);
- Start(true, true);
+ if (path)
+ me->GetMotionMaster()->MoveSmoothPath(POINT_INTRO, path, pathSize, false);
+ }
+
+ void Reset() override
+ {
+ _scheduler.CancelAll();
+ _scheduler.Schedule(Seconds(2), [this](TaskContext /*task*/)
+ {
+ StartMovement();
+ });
+ }
+
+ void MovementInform(uint32 type, uint32 pointId) override
+ {
+ if (type == EFFECT_MOTION_TYPE && pointId == POINT_INTRO)
+ {
+ _scheduler.Schedule(Seconds(0), [this](TaskContext task)
+ {
+ me->CastSpell(me, SPELL_SHIELD_DISRUPTION, false);
+
+ if (task.GetRepeatCounter() < 2)
+ task.Repeat(Seconds(1));
+ else
+ {
+ task.Schedule(Seconds(2), [this](TaskContext /*task*/)
+ {
+ _instance->SetData(DATA_START_BOSS_ENCOUNTER, 1);
+ me->CastSpell(me, SPELL_TELEPORT_VISUAL, false);
+ me->DespawnOrUnsummon(1000);
+ });
+ }
+ });
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
}
- }
- void FinishPointReached()
+ private:
+ InstanceScript* _instance;
+ TaskScheduler _scheduler;
+
+ uint32 _bossId;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
{
- me->CastSpell(me, SABOTEUR_SHIELD_DISRUPTION, false);
- me->DisappearAndDie();
- if (Creature* pSaboPort = ObjectAccessor::GetCreature((*me), instance->GetGuidData(DATA_SABOTEUR_PORTAL)))
- pSaboPort->DisappearAndDie();
- instance->SetData(DATA_START_BOSS_ENCOUNTER, 1);
+ return GetVioletHoldAI<npc_azure_saboteurAI>(creature);
}
- };
+};
- CreatureAI* GetAI(Creature* creature) const override
+struct npc_violet_hold_teleportation_portal_commonAI : public ScriptedAI
+{
+ npc_violet_hold_teleportation_portal_commonAI(Creature* creature) : ScriptedAI(creature), _summons(me)
{
- return GetInstanceAI<npc_azure_saboteurAI>(creature);
+ _instance = creature->GetInstanceScript();
+ _portalLocation = 0;
}
-};
-class npc_teleportation_portal_vh : public CreatureScript
-{
-public:
- npc_teleportation_portal_vh() : CreatureScript("npc_teleportation_portal_vh") { }
+ void InitializeAI() override
+ {
+ ScriptedAI::InitializeAI();
+ ScheduleTasks();
+ }
- struct npc_teleportation_portalAI : public ScriptedAI
+ void SetData(uint32 type, uint32 data) override
{
- npc_teleportation_portalAI(Creature* creature) : ScriptedAI(creature), listOfMobs(me)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- uiTypeOfMobsPortal = urand(0, 1); // 0 - elite mobs 1 - portal guardian or portal keeper with regular mobs
+ if (type == DATA_PORTAL_LOCATION)
+ _portalLocation = uint8(data);
+ }
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
- uiTypeOfMobsPortal = 2;
- }
+ void MoveInLineOfSight(Unit* /*who*/) override { }
- void Initialize()
- {
- uiSpawnTimer = 10000;
- bPortalGuardianOrKeeperOrEliteSpawn = false;
- }
+ void EnterCombat(Unit* /*who*/) override { }
- uint32 uiSpawnTimer;
- bool bPortalGuardianOrKeeperOrEliteSpawn;
- uint8 uiTypeOfMobsPortal;
+ void JustSummoned(Creature* summon) override
+ {
+ _summons.Summon(summon);
+ summon->AI()->SetData(DATA_PORTAL_LOCATION, _portalLocation);
+ }
- SummonList listOfMobs;
+ void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
+ {
+ _summons.Despawn(summon);
+ }
- InstanceScript* instance;
+ virtual void ScheduleTasks() { }
- void Reset() override
- {
- Initialize();
- }
+ void UpdateAI(uint32 diff) override
+ {
+ _scheduler.Update(diff);
+ }
- void EnterCombat(Unit* /*who*/) override { }
+protected:
+ InstanceScript* _instance;
+ SummonList _summons;
+ TaskScheduler _scheduler;
+ uint8 _portalLocation;
+};
- void MoveInLineOfSight(Unit* /*who*/) override { }
+class npc_violet_hold_teleportation_portal : public CreatureScript
+{
+ public:
+ npc_violet_hold_teleportation_portal() : CreatureScript("npc_violet_hold_teleportation_portal") { }
- void UpdateAI(uint32 diff) override
+ struct npc_violet_hold_teleportation_portalAI : public npc_violet_hold_teleportation_portal_commonAI
{
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ npc_violet_hold_teleportation_portalAI(Creature* creature) : npc_violet_hold_teleportation_portal_commonAI(creature)
{
- if (instance->GetData(DATA_REMOVE_NPC) == 1)
- {
- me->DespawnOrUnsummon();
- instance->SetData(DATA_REMOVE_NPC, 0);
- }
}
- uint8 uiWaveCount = instance->GetData(DATA_WAVE_COUNT);
- if ((uiWaveCount == 6) || (uiWaveCount == 12)) //Don't spawn mobs on boss encounters
- return;
+ void InitializeAI() override
+ {
+ npc_violet_hold_teleportation_portal_commonAI::InitializeAI();
+ me->CastSpell(me, SPELL_PORTAL_PERIODIC, true);
+ }
- switch (uiTypeOfMobsPortal)
+ void SetData(uint32 type, uint32 data) override
{
- // spawn elite mobs and then set portals visibility to make it look like it dissapeard
- case 0:
- if (!bPortalGuardianOrKeeperOrEliteSpawn)
+ npc_violet_hold_teleportation_portal_commonAI::SetData(type, data);
+
+ if (type == DATA_PORTAL_PERIODIC_TICK)
+ {
+ if (data == 1)
{
- if (uiSpawnTimer <= diff)
+ uint32 entry = RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER);
+ if (Creature* portalKeeper = DoSummon(entry, me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN))
+ me->CastSpell(portalKeeper, SPELL_PORTAL_CHANNEL, false);
+
+ if (Creature* sinclariTrigger = _instance->GetCreature(DATA_SINCLARI_TRIGGER))
{
- bPortalGuardianOrKeeperOrEliteSpawn = true;
- uint8 k = uiWaveCount < 12 ? 2 : 3;
- for (uint8 i = 0; i < k; ++i)
- {
- uint32 entry = RAND(NPC_AZURE_CAPTAIN, NPC_AZURE_RAIDER, NPC_AZURE_STALKER, NPC_AZURE_SORCEROR);
- DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
- }
- me->SetVisible(false);
- } else uiSpawnTimer -= diff;
+ if (entry == NPC_PORTAL_GUARDIAN)
+ sinclariTrigger->AI()->Talk(SAY_SINCLARI_PORTAL_GUARDIAN);
+ else if (entry == NPC_PORTAL_KEEPER)
+ sinclariTrigger->AI()->Talk(SAY_SINCLARI_PORTAL_KEEPER);
+ }
}
else
{
- // if all spawned elites have died kill portal
- if (listOfMobs.empty())
+ uint8 k = _instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4;
+ while (k--)
{
- me->Kill(me, false);
- me->RemoveCorpse();
+ uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_INVADER_2, NPC_AZURE_SPELLBREAKER_1, NPC_AZURE_SPELLBREAKER_2, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_MAGE_SLAYER_2, NPC_AZURE_BINDER_1, NPC_AZURE_BINDER_2);
+ DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
}
}
- break;
- // spawn portal guardian or portal keeper with regular mobs
- case 1:
- if (uiSpawnTimer <= diff)
- {
- if (bPortalGuardianOrKeeperOrEliteSpawn)
- {
- uint8 k = instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4;
- for (uint8 i = 0; i < k; ++i)
- {
- uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_INVADER_2, NPC_AZURE_SPELLBREAKER_1, NPC_AZURE_SPELLBREAKER_2, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_MAGE_SLAYER_2, NPC_AZURE_BINDER_1, NPC_AZURE_BINDER_2);
- DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
- }
- }
- else
- {
- bPortalGuardianOrKeeperOrEliteSpawn = true;
- uint32 entry = RAND(NPC_PORTAL_GUARDIAN, NPC_PORTAL_KEEPER);
- if (Creature* pPortalKeeper = DoSummon(entry, me, 2.0f, 0, TEMPSUMMON_DEAD_DESPAWN))
- me->CastSpell(pPortalKeeper, SPELL_PORTAL_CHANNEL, false);
- }
- uiSpawnTimer = SPAWN_TIME;
- } else uiSpawnTimer -= diff;
+ }
+ }
- if (bPortalGuardianOrKeeperOrEliteSpawn && !me->IsNonMeleeSpellCast(false))
+ void SummonedCreatureDies(Creature* summon, Unit* killer) override
+ {
+ npc_violet_hold_teleportation_portal_commonAI::SummonedCreatureDies(summon, killer);
+
+ if (summon->GetEntry() == NPC_PORTAL_GUARDIAN || summon->GetEntry() == NPC_PORTAL_KEEPER)
+ {
+ _instance->SetData(DATA_WAVE_COUNT, _instance->GetData(DATA_WAVE_COUNT) + 1);
+ me->DespawnOrUnsummon();
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_violet_hold_teleportation_portalAI>(creature);
+ }
+};
+
+class npc_violet_hold_teleportation_portal_elite : public CreatureScript
+{
+ public:
+ npc_violet_hold_teleportation_portal_elite() : CreatureScript("npc_violet_hold_teleportation_portal_elite") { }
+
+ struct npc_violet_hold_teleportation_portal_eliteAI : public npc_violet_hold_teleportation_portal_commonAI
+ {
+ npc_violet_hold_teleportation_portal_eliteAI(Creature* creature) : npc_violet_hold_teleportation_portal_commonAI(creature)
+ {
+ }
+
+ void ScheduleTasks() override
+ {
+ _scheduler.Schedule(Seconds(15), [this](TaskContext task)
+ {
+ uint8 k = _instance->GetData(DATA_WAVE_COUNT) < 12 ? 3 : 4;
+ while (k--)
{
- me->Kill(me, false);
- me->RemoveCorpse();
+ uint32 entry = RAND(NPC_AZURE_CAPTAIN_1, NPC_AZURE_RAIDER_1, NPC_AZURE_STALKER_1, NPC_AZURE_SORCEROR_1);
+ DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
}
- break;
- case 2: // Pre-event
- if (uiSpawnTimer <= diff)
+
+ if (Creature* sinclariTrigger = _instance->GetCreature(DATA_SINCLARI_TRIGGER))
+ sinclariTrigger->AI()->Talk(SAY_SINCLARI_ELITE_SQUAD);
+
+ task.Schedule(Seconds(1), [this](TaskContext /*task*/)
{
- uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_BINDER_1);
- DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
- uiSpawnTimer = SPAWN_TIME;
- } else uiSpawnTimer -= diff;
- break;
+ me->SetVisible(false);
+ });
+ });
}
- }
- void JustDied(Unit* /*killer*/) override
+ void SummonedCreatureDies(Creature* summon, Unit* killer) override
+ {
+ npc_violet_hold_teleportation_portal_commonAI::SummonedCreatureDies(summon, killer);
+
+ if (_summons.empty())
+ {
+ _instance->SetData(DATA_WAVE_COUNT, _instance->GetData(DATA_WAVE_COUNT) + 1);
+ me->DespawnOrUnsummon();
+ }
+ }
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
{
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
- instance->SetData(DATA_WAVE_COUNT, instance->GetData(DATA_WAVE_COUNT) + 1);
+ return GetVioletHoldAI<npc_violet_hold_teleportation_portal_eliteAI>(creature);
}
+};
+
+class npc_violet_hold_teleportation_portal_intro : public CreatureScript
+{
+ public:
+ npc_violet_hold_teleportation_portal_intro() : CreatureScript("npc_violet_hold_teleportation_portal_intro") { }
- void JustSummoned(Creature* summoned) override
+ struct npc_violet_hold_teleportation_portal_introAI : public npc_violet_hold_teleportation_portal_commonAI
{
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ npc_violet_hold_teleportation_portal_introAI(Creature* creature) : npc_violet_hold_teleportation_portal_commonAI(creature)
{
- listOfMobs.Summon(summoned);
- instance->SetGuidData(DATA_ADD_TRASH_MOB, summoned->GetGUID());
}
- }
- void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) override
- {
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == IN_PROGRESS)
+ void ScheduleTasks() override
{
- listOfMobs.Despawn(summoned);
- instance->SetGuidData(DATA_DEL_TRASH_MOB, summoned->GetGUID());
+ if (_instance->GetData(DATA_MAIN_EVENT_STATE) != NOT_STARTED)
+ return;
+
+ _scheduler.Schedule(Seconds(15), [this](TaskContext task)
+ {
+ uint32 entry = RAND(NPC_AZURE_INVADER_1, NPC_AZURE_MAGE_SLAYER_1, NPC_AZURE_BINDER_1);
+ DoSummon(entry, me, 2.0f, 20000, TEMPSUMMON_DEAD_DESPAWN);
+
+ task.Repeat();
+ });
}
- }
- };
+ };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_teleportation_portalAI>(creature);
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_violet_hold_teleportation_portal_introAI>(creature);
+ }
};
struct violet_hold_trashAI : public npc_escortAI
{
violet_hold_trashAI(Creature* creature) : npc_escortAI(creature)
{
- instance = creature->GetInstanceScript();
- bHasGotMovingPoints = false;
+ _instance = creature->GetInstanceScript();
+ _lastWaypointId = 0;
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) == NOT_STARTED)
- {
- if (Creature* portal = me->FindNearestCreature(NPC_TELEPORTATION_PORTAL, 10.0f))
- {
- ObjectGuid portalGUID = portal->GetGUID();
- for (uint8 i = 0; i < MAX_PRE_EVENT_PORTAL; i++)
- if (portalGUID == preEventPortalGUID[i])
- portalLocationID = i * 2;
- }
- }
- else
+ SetDespawnAtEnd(false);
+
+ _scheduler.SetValidator([this]
{
- portalLocationID = instance->GetData(DATA_PORTAL_LOCATION);
- Reset();
- }
+ return !me->HasUnitState(UNIT_STATE_CASTING);
+ });
}
- public:
- InstanceScript* instance;
- bool bHasGotMovingPoints;
- uint32 portalLocationID;
- uint32 secondPortalRouteID;
-
- void WaypointReached(uint32 waypointId) override
+ void Reset() override
{
- switch (portalLocationID)
- {
- case 0:
- if (waypointId == 5)
- CreatureStartAttackDoor();
- break;
- case 1:
- if ((waypointId == 8 && secondPortalRouteID == 0) || (waypointId == 7 && secondPortalRouteID == 1))
- CreatureStartAttackDoor();
- break;
- case 2:
- if (waypointId == 7)
- CreatureStartAttackDoor();
- break;
- case 3:
- if (waypointId == 8)
- CreatureStartAttackDoor();
- break;
- case 4:
- if (waypointId == 5)
- CreatureStartAttackDoor();
- break;
- case 5:
- if (waypointId == 3)
- CreatureStartAttackDoor();
- break;
- }
+ _scheduler.CancelAll();
}
- void UpdateAI(uint32 diff) override
+ void SetData(uint32 type, uint32 data) override
{
- if (instance->GetData(DATA_MAIN_EVENT_PHASE) != IN_PROGRESS)
- me->CastStop();
-
- if (!bHasGotMovingPoints)
+ if (type == DATA_PORTAL_LOCATION)
{
- bHasGotMovingPoints = true;
- switch (portalLocationID)
+ G3D::Vector3 const* path = nullptr;
+
+ switch (data)
{
case 0:
- for (int i=0;i<6;i++)
- AddWaypoint(i, FirstPortalWPs[i][0]+irand(-1, 1), FirstPortalWPs[i][1]+irand(-1, 1), FirstPortalWPs[i][2]+irand(-1, 1), 0);
- me->SetHomePosition(FirstPortalWPs[5][0], FirstPortalWPs[5][1], FirstPortalWPs[5][2], 3.149439f);
+ _lastWaypointId = 5;
+ path = FirstPortalWPs;
break;
- case 1:
- secondPortalRouteID = urand(0, 1);
- switch (secondPortalRouteID)
+ case 7:
+ switch (urand(0, 1))
{
case 0:
- for (int i=0;i<9;i++)
- AddWaypoint(i, SecondPortalFirstWPs[i][0]+irand(-1, 1), SecondPortalFirstWPs[i][1]+irand(-1, 1), SecondPortalFirstWPs[i][2], 0);
- me->SetHomePosition(SecondPortalFirstWPs[8][0]+irand(-1, 1), SecondPortalFirstWPs[8][1]+irand(-1, 1), SecondPortalFirstWPs[8][2]+irand(-1, 1), 3.149439f);
+ _lastWaypointId = 8;
+ path = SecondPortalFirstWPs;
break;
case 1:
- for (int i=0;i<8;i++)
- AddWaypoint(i, SecondPortalSecondWPs[i][0]+irand(-1, 1), SecondPortalSecondWPs[i][1]+irand(-1, 1), SecondPortalSecondWPs[i][2], 0);
- me->SetHomePosition(SecondPortalSecondWPs[7][0], SecondPortalSecondWPs[7][1], SecondPortalSecondWPs[7][2], 3.149439f);
+ _lastWaypointId = 7;
+ path = SecondPortalSecondWPs;
break;
}
break;
case 2:
- for (int i=0;i<8;i++)
- AddWaypoint(i, ThirdPortalWPs[i][0]+irand(-1, 1), ThirdPortalWPs[i][1]+irand(-1, 1), ThirdPortalWPs[i][2], 0);
- me->SetHomePosition(ThirdPortalWPs[7][0], ThirdPortalWPs[7][1], ThirdPortalWPs[7][2], 3.149439f);
+ _lastWaypointId = 7;
+ path = ThirdPortalWPs;
break;
- case 3:
- for (int i=0;i<9;i++)
- AddWaypoint(i, FourthPortalWPs[i][0]+irand(-1, 1), FourthPortalWPs[i][1]+irand(-1, 1), FourthPortalWPs[i][2], 0);
- me->SetHomePosition(FourthPortalWPs[8][0], FourthPortalWPs[8][1], FourthPortalWPs[8][2], 3.149439f);
+ case 6:
+ _lastWaypointId = 8;
+ path = FourthPortalWPs;
break;
- case 4:
- for (int i=0;i<6;i++)
- AddWaypoint(i, FifthPortalWPs[i][0]+irand(-1, 1), FifthPortalWPs[i][1]+irand(-1, 1), FifthPortalWPs[i][2], 0);
- me->SetHomePosition(FifthPortalWPs[5][0], FifthPortalWPs[5][1], FifthPortalWPs[5][2], 3.149439f);
+ case 1:
+ _lastWaypointId = 5;
+ path = FifthPortalWPs;
break;
case 5:
- for (int i=0;i<4;i++)
- AddWaypoint(i, SixthPoralWPs[i][0]+irand(-1, 1), SixthPoralWPs[i][1]+irand(-1, 1), SixthPoralWPs[i][2], 0);
- me->SetHomePosition(SixthPoralWPs[3][0], SixthPoralWPs[3][1], SixthPoralWPs[3][2], 3.149439f);
+ _lastWaypointId = 3;
+ path = SixthPoralWPs;
break;
+ default:
+ _lastWaypointId = 0;
+ path = DefaultPortalWPs;
+ break;
+ }
+
+ if (path)
+ {
+ for (uint32 i = 0; i <= _lastWaypointId; i++)
+ AddWaypoint(i, path[i].x + irand(-1, 1), path[i].y + irand(-1, 1), path[i].z, 0);
+ me->SetHomePosition(path[_lastWaypointId].x, path[_lastWaypointId].y, path[_lastWaypointId].z, float(M_PI));
}
- SetDespawnAtEnd(false);
+
Start(true, true);
}
-
- npc_escortAI::UpdateAI(diff);
}
- void JustDied(Unit* /*killer*/) override
+ void WaypointReached(uint32 waypointId) override
{
- instance->SetData(DATA_NPC_PRESENCE_AT_DOOR_REMOVE, 1);
+ if (waypointId == _lastWaypointId)
+ CreatureStartAttackDoor();
}
- void CreatureStartAttackDoor()
+ void EnterCombat(Unit* who) override
{
- me->SetReactState(REACT_PASSIVE);
- DoCast(SPELL_DESTROY_DOOR_SEAL);
- instance->SetData(DATA_NPC_PRESENCE_AT_DOOR_ADD, 1);
+ npc_escortAI::EnterCombat(who);
+ ScheduledTasks();
}
-};
-
-class npc_azure_invader : public CreatureScript
-{
-public:
- npc_azure_invader() : CreatureScript("npc_azure_invader") { }
- struct npc_azure_invaderAI : public violet_hold_trashAI
+ void UpdateEscortAI(uint32 diff) override
{
- npc_azure_invaderAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ if (_instance->GetData(DATA_MAIN_EVENT_STATE) != IN_PROGRESS)
+ me->CastStop();
- void Initialize()
- {
- uiCleaveTimer = 5000;
- uiImpaleTimer = 4000;
- uiBrutalStrikeTimer = 5000;
- uiSunderArmorTimer = 4000;
- }
+ if (!UpdateVictim())
+ return;
- uint32 uiCleaveTimer;
- uint32 uiImpaleTimer;
- uint32 uiBrutalStrikeTimer;
- uint32 uiSunderArmorTimer;
+ _scheduler.Update(diff,
+ std::bind(&npc_escortAI::DoMeleeAttackIfReady, this));
+ }
- void Reset() override
- {
- Initialize();
- }
+ virtual void ScheduledTasks() { }
- void UpdateAI(uint32 diff) override
- {
- violet_hold_trashAI::UpdateAI(diff);
+ void CreatureStartAttackDoor()
+ {
+ me->SetReactState(REACT_DEFENSIVE);
+ DoCastAOE(SPELL_DESTROY_DOOR_SEAL);
+ }
- if (!UpdateVictim())
- return;
+protected:
+ InstanceScript* _instance;
+ TaskScheduler _scheduler;
- if (me->GetEntry() == NPC_AZURE_INVADER_1)
- {
- if (uiCleaveTimer <= diff)
- {
- DoCastVictim(SPELL_CLEAVE);
- uiCleaveTimer = 5000;
- } else uiCleaveTimer -= diff;
+ uint32 _lastWaypointId;
+};
- if (uiImpaleTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_IMPALE);
- uiImpaleTimer = 4000;
- } else uiImpaleTimer -= diff;
- }
+class npc_azure_invader : public CreatureScript
+{
+ public:
+ npc_azure_invader() : CreatureScript("npc_azure_invader") { }
- if (me->GetEntry() == NPC_AZURE_INVADER_2)
+ struct npc_azure_invaderAI : public violet_hold_trashAI
+ {
+ npc_azure_invaderAI(Creature* creature) : violet_hold_trashAI(creature) { }
+
+ void ScheduledTasks() override
{
- if (uiBrutalStrikeTimer <= diff)
+ if (me->GetEntry() == NPC_AZURE_INVADER_1)
{
- DoCastVictim(SPELL_BRUTAL_STRIKE);
- uiBrutalStrikeTimer = 5000;
- } else uiBrutalStrikeTimer -= diff;
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_CLEAVE);
+ task.Repeat();
+ });
- if (uiSunderArmorTimer <= diff)
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_IMPALE);
+ task.Repeat();
+ });
+ }
+ else if (me->GetEntry() == NPC_AZURE_INVADER_2)
{
- DoCastVictim(SPELL_SUNDER_ARMOR);
- uiSunderArmorTimer = urand(8000, 10000);
- } else uiSunderArmorTimer -= diff;
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_BRUTAL_STRIKE);
+ task.Repeat();
+ });
- DoMeleeAttackIfReady();
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_SUNDER_ARMOR);
+ task.Repeat(Seconds(8), Seconds(10));
+ });
+ }
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_invaderAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_invaderAI>(creature);
- }
};
class npc_azure_binder : public CreatureScript
{
-public:
- npc_azure_binder() : CreatureScript("npc_azure_binder") { }
-
- struct npc_azure_binderAI : public violet_hold_trashAI
- {
- npc_azure_binderAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- uiArcaneExplosionTimer = 5000;
- uiArcainBarrageTimer = 4000;
- uiFrostNovaTimer = 5000;
- uiFrostboltTimer = 4000;
- }
-
- uint32 uiArcaneExplosionTimer;
- uint32 uiArcainBarrageTimer;
- uint32 uiFrostNovaTimer;
- uint32 uiFrostboltTimer;
-
- void Reset() override
- {
- Initialize();
- }
+ public:
+ npc_azure_binder() : CreatureScript("npc_azure_binder") { }
- void UpdateAI(uint32 diff) override
+ struct npc_azure_binderAI : public violet_hold_trashAI
{
- violet_hold_trashAI::UpdateAI(diff);
+ npc_azure_binderAI(Creature* creature) : violet_hold_trashAI(creature) { }
- if (!UpdateVictim())
- return;
-
- if (me->GetEntry() == NPC_AZURE_BINDER_1)
+ void ScheduledTasks() override
{
- if (uiArcaneExplosionTimer <= diff)
- {
- DoCast(SPELL_ARCANE_EXPLOSION);
- uiArcaneExplosionTimer = 5000;
- } else uiArcaneExplosionTimer -= diff;
-
- if (uiArcainBarrageTimer <= diff)
+ if (me->GetEntry() == NPC_AZURE_BINDER_1)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_ARCANE_BARRAGE);
- uiArcainBarrageTimer = 6000;
- } else uiArcainBarrageTimer -= diff;
- }
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_ARCANE_EXPLOSION);
+ task.Repeat();
+ });
- if (me->GetEntry() == NPC_AZURE_BINDER_2)
- {
- if (uiFrostNovaTimer <= diff)
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_ARCANE_BARRAGE);
+ task.Repeat(Seconds(6));
+ });
+ }
+ else if (me->GetEntry() == NPC_AZURE_BINDER_2)
{
- DoCast(SPELL_FROST_NOVA);
- uiFrostNovaTimer = 5000;
- } else uiFrostNovaTimer -= diff;
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_FROST_NOVA);
+ task.Repeat();
+ });
- if (uiFrostboltTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_FROSTBOLT);
- uiFrostboltTimer = 6000;
- } else uiFrostboltTimer -= diff;
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f))
+ DoCast(target, SPELL_FROSTBOLT);
+ task.Repeat(Seconds(6));
+ });
+ }
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_binderAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_binderAI>(creature);
- }
};
class npc_azure_mage_slayer : public CreatureScript
{
-public:
- npc_azure_mage_slayer() : CreatureScript("npc_azure_mage_slayer") { }
-
- struct npc_azure_mage_slayerAI : public violet_hold_trashAI
- {
- npc_azure_mage_slayerAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- uiArcaneEmpowermentTimer = 5000;
- uiSpellLockTimer = 5000;
- }
-
- uint32 uiArcaneEmpowermentTimer;
- uint32 uiSpellLockTimer;
-
- void Reset() override
- {
- Initialize();
- }
+ public:
+ npc_azure_mage_slayer() : CreatureScript("npc_azure_mage_slayer") { }
- void UpdateAI(uint32 diff) override
+ struct npc_azure_mage_slayerAI : public violet_hold_trashAI
{
- violet_hold_trashAI::UpdateAI(diff);
-
- if (!UpdateVictim())
- return;
+ npc_azure_mage_slayerAI(Creature* creature) : violet_hold_trashAI(creature) { }
- if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_1)
+ void ScheduledTasks() override
{
- if (uiArcaneEmpowermentTimer <= diff)
+ if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_1)
{
- DoCast(me, SPELL_ARCANE_EMPOWERMENT);
- uiArcaneEmpowermentTimer = 14000;
- } else uiArcaneEmpowermentTimer -= diff;
- }
-
- if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_2)
- {
- if (uiSpellLockTimer <= diff)
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCast(me, SPELL_ARCANE_EMPOWERMENT);
+ task.Repeat(Seconds(14));
+ });
+ }
+ else if (me->GetEntry() == NPC_AZURE_MAGE_SLAYER_2)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_SPELL_LOCK);
- uiSpellLockTimer = 9000;
- } else uiSpellLockTimer -= diff;
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ // wrong spellid?
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_SPELL_LOCK);
+ task.Repeat(Seconds(9));
+ });
+ }
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_mage_slayerAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_mage_slayerAI>(creature);
- }
};
class npc_azure_raider : public CreatureScript
{
-public:
- npc_azure_raider() : CreatureScript("npc_azure_raider") { }
-
- struct npc_azure_raiderAI : public violet_hold_trashAI
- {
- npc_azure_raiderAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- uiConcussionBlowTimer = 5000;
- uiMagicReflectionTimer = 8000;
- }
-
- uint32 uiConcussionBlowTimer;
- uint32 uiMagicReflectionTimer;
-
- void Reset() override
- {
- Initialize();
- }
+ public:
+ npc_azure_raider() : CreatureScript("npc_azure_raider") { }
- void UpdateAI(uint32 diff) override
+ struct npc_azure_raiderAI : public violet_hold_trashAI
{
- violet_hold_trashAI::UpdateAI(diff);
+ npc_azure_raiderAI(Creature* creature) : violet_hold_trashAI(creature) { }
- if (!UpdateVictim())
- return;
-
- if (uiConcussionBlowTimer <= diff)
+ void ScheduledTasks() override
{
- DoCastVictim(SPELL_CONCUSSION_BLOW);
- uiConcussionBlowTimer = 5000;
- } else uiConcussionBlowTimer -= diff;
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ DoCastVictim(SPELL_CONCUSSION_BLOW);
+ task.Repeat();
+ });
- if (uiMagicReflectionTimer <= diff)
- {
- DoCast(SPELL_MAGIC_REFLECTION);
- uiMagicReflectionTimer = urand(10000, 15000);
- } else uiMagicReflectionTimer -= diff;
+ _scheduler.Schedule(Seconds(8), [this](TaskContext task)
+ {
+ DoCast(me, SPELL_MAGIC_REFLECTION);
+ task.Repeat(Seconds(10), Seconds(15));
+ });
+ }
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_raiderAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_raiderAI>(creature);
- }
};
class npc_azure_stalker : public CreatureScript
{
-public:
- npc_azure_stalker() : CreatureScript("npc_azure_stalker") { }
-
- struct npc_azure_stalkerAI : public violet_hold_trashAI
- {
- npc_azure_stalkerAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
-
- void Initialize()
- {
- _backstabTimer = 1300;
- _tacticalBlinkTimer = 8000;
- _tacticalBlinkCast = false;
- }
-
- void Reset() override
- {
- Initialize();
- }
+ public:
+ npc_azure_stalker() : CreatureScript("npc_azure_stalker") { }
- void UpdateAI(uint32 diff) override
+ struct npc_azure_stalkerAI : public violet_hold_trashAI
{
- violet_hold_trashAI::UpdateAI(diff);
-
- if (!UpdateVictim())
- return;
+ npc_azure_stalkerAI(Creature* creature) : violet_hold_trashAI(creature) { }
- if (!_tacticalBlinkCast)
+ void ScheduledTasks() override
{
- if (_tacticalBlinkTimer <= diff)
+ _scheduler.Schedule(Seconds(8), [this](TaskContext task)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true))
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f))
DoCast(target, SPELL_TACTICAL_BLINK);
- _tacticalBlinkTimer = 6000;
- _tacticalBlinkCast = true;
- } else _tacticalBlinkTimer -= diff;
- }
- else
- {
- if (_backstabTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 10, true))
- DoCast(target, SPELL_BACKSTAB);
- _tacticalBlinkCast = false;
- _backstabTimer =1300;
- } else _backstabTimer -= diff;
+ task.Schedule(Milliseconds(1300), [this](TaskContext /*task*/)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_NEAREST, 0, 5.0f))
+ DoCast(target, SPELL_BACKSTAB);
+ });
+
+ task.Repeat();
+ });
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_stalkerAI>(creature);
}
-
- private:
- uint32 _backstabTimer;
- uint32 _tacticalBlinkTimer;
- bool _tacticalBlinkCast;
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_stalkerAI>(creature);
- }
};
class npc_azure_spellbreaker : public CreatureScript
{
-public:
- npc_azure_spellbreaker() : CreatureScript("npc_azure_spellbreaker") { }
+ public:
+ npc_azure_spellbreaker() : CreatureScript("npc_azure_spellbreaker") { }
- struct npc_azure_spellbreakerAI : public violet_hold_trashAI
- {
- npc_azure_spellbreakerAI(Creature* creature) : violet_hold_trashAI(creature)
+ struct npc_azure_spellbreakerAI : public violet_hold_trashAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ npc_azure_spellbreakerAI(Creature* creature) : violet_hold_trashAI(creature) { }
- void Initialize()
- {
- uiArcaneBlastTimer = 5000;
- uiSlowTimer = 4000;
- uiChainsOfIceTimer = 5000;
- uiConeOfColdTimer = 4000;
- }
+ void ScheduledTasks() override
+ {
+ if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_1)
+ {
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_ARCANE_BLAST);
+ task.Repeat(Seconds(6));
+ });
- uint32 uiArcaneBlastTimer;
- uint32 uiSlowTimer;
- uint32 uiChainsOfIceTimer;
- uint32 uiConeOfColdTimer;
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_SLOW);
+ task.Repeat(Seconds(5));
+ });
+ }
+ else if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_2)
+ {
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
+ DoCast(target, SPELL_CHAINS_OF_ICE);
+ task.Repeat(Seconds(7));
+ });
- void Reset() override
- {
- Initialize();
- }
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ DoCast(me, SPELL_CONE_OF_COLD);
+ task.Repeat(Seconds(5));
+ });
+ }
+ }
+ };
- void UpdateAI(uint32 diff) override
+ CreatureAI* GetAI(Creature* creature) const override
{
- violet_hold_trashAI::UpdateAI(diff);
-
- if (!UpdateVictim())
- return;
+ return GetVioletHoldAI<npc_azure_spellbreakerAI>(creature);
+ }
+};
- if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_1)
- {
- if (uiArcaneBlastTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_ARCANE_BLAST);
- uiArcaneBlastTimer = 6000;
- } else uiArcaneBlastTimer -= diff;
+class npc_azure_captain : public CreatureScript
+{
+ public:
+ npc_azure_captain() : CreatureScript("npc_azure_captain") { }
- if (uiSlowTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_SLOW);
- uiSlowTimer = 5000;
- } else uiSlowTimer -= diff;
- }
+ struct npc_azure_captainAI : public violet_hold_trashAI
+ {
+ npc_azure_captainAI(Creature* creature) : violet_hold_trashAI(creature) { }
- if (me->GetEntry() == NPC_AZURE_SPELLBREAKER_2)
+ void ScheduledTasks() override
{
- if (uiChainsOfIceTimer <= diff)
+ _scheduler.Schedule(Seconds(5), [this](TaskContext task)
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_CHAINS_OF_ICE);
- uiChainsOfIceTimer = 7000;
- } else uiChainsOfIceTimer -= diff;
+ DoCastVictim(SPELL_MORTAL_STRIKE);
+ task.Repeat();
+ });
- if (uiConeOfColdTimer <= diff)
+ _scheduler.Schedule(Seconds(8), [this](TaskContext task)
{
- DoCast(SPELL_CONE_OF_COLD);
- uiConeOfColdTimer = 5000;
- } else uiConeOfColdTimer -= diff;
+ DoCast(me, SPELL_WHIRLWIND_OF_STEEL);
+ task.Repeat();
+ });
}
+ };
- DoMeleeAttackIfReady();
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetVioletHoldAI<npc_azure_captainAI>(creature);
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_spellbreakerAI>(creature);
- }
};
-class npc_azure_captain : public CreatureScript
+class npc_azure_sorceror : public CreatureScript
{
-public:
- npc_azure_captain() : CreatureScript("npc_azure_captain") { }
+ public:
+ npc_azure_sorceror() : CreatureScript("npc_azure_sorceror") { }
- struct npc_azure_captainAI : public violet_hold_trashAI
- {
- npc_azure_captainAI(Creature* creature) : violet_hold_trashAI(creature)
+ struct npc_azure_sorcerorAI : public violet_hold_trashAI
{
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ npc_azure_sorcerorAI(Creature* creature) : violet_hold_trashAI(creature) { }
- void Initialize()
- {
- uiMortalStrikeTimer = 5000;
- uiWhirlwindTimer = 8000;
- }
+ void ScheduledTasks() override
+ {
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 35.0f))
+ DoCast(target, SPELL_ARCANE_STREAM);
+ task.Repeat(Seconds(5), Seconds(10));
+ });
- uint32 uiMortalStrikeTimer;
- uint32 uiWhirlwindTimer;
+ _scheduler.Schedule(Seconds(), Seconds(), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_MANA_DETONATION);
+ task.Repeat(Seconds(2), Seconds(6));
+ });
+ }
+ };
- void Reset() override
+ CreatureAI* GetAI(Creature* creature) const override
{
- Initialize();
+ return GetVioletHoldAI<npc_azure_sorcerorAI>(creature);
}
+};
+
+class npc_violet_hold_defense_system : public CreatureScript
+{
+ public:
+ npc_violet_hold_defense_system() : CreatureScript("npc_violet_hold_defense_system") { }
- void UpdateAI(uint32 diff) override
+ struct npc_violet_hold_defense_systemAI : public ScriptedAI
{
- violet_hold_trashAI::UpdateAI(diff);
+ npc_violet_hold_defense_systemAI(Creature* creature) : ScriptedAI(creature) { }
- if (!UpdateVictim())
- return;
+ void Reset() override
+ {
+ ScheduledTasks();
+ me->DespawnOrUnsummon(7000);
+ }
- if (uiMortalStrikeTimer <= diff)
+ void ScheduledTasks()
{
- DoCastVictim(SPELL_MORTAL_STRIKE);
- uiMortalStrikeTimer = 5000;
- } else uiMortalStrikeTimer -= diff;
+ _scheduler.Schedule(Seconds(4), [this](TaskContext task)
+ {
+ DoCastAOE(SPELL_ARCANE_LIGHTNING_DAMAGE);
+ DoCastAOE(SPELL_ARCANE_LIGHTNING_DUMMY);
+ if (task.GetRepeatCounter() == 2)
+ DoCastAOE(SPELL_ARCANE_LIGHTNING_INSTAKILL);
+ else
+ task.Repeat(Seconds(1));
+ });
+ }
- if (uiWhirlwindTimer <= diff)
+ void UpdateAI(uint32 diff) override
{
- DoCast(me, SPELL_WHIRLWIND_OF_STEEL);
- uiWhirlwindTimer = 8000;
- } else uiWhirlwindTimer -= diff;
+ _scheduler.Update(diff);
+ }
- DoMeleeAttackIfReady();
- }
- };
+ private:
+ TaskScheduler _scheduler;
+ };
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_captainAI>(creature);
- }
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_violet_hold_defense_systemAI(creature);
+ }
};
-class npc_azure_sorceror : public CreatureScript
+class go_activation_crystal : public GameObjectScript
{
-public:
- npc_azure_sorceror() : CreatureScript("npc_azure_sorceror") { }
-
- struct npc_azure_sorcerorAI : public violet_hold_trashAI
- {
- npc_azure_sorcerorAI(Creature* creature) : violet_hold_trashAI(creature)
- {
- Initialize();
- instance = creature->GetInstanceScript();
- }
+ public:
+ go_activation_crystal() : GameObjectScript("go_activation_crystal") { }
- void Initialize()
+ bool OnGossipHello(Player* player, GameObject* /*go*/) override
{
- uiArcaneStreamTimer = 4000;
- uiArcaneStreamTimerStartingValueHolder = uiArcaneStreamTimer;
- uiManaDetonationTimer = 5000;
+ player->CastSpell(player, SPELL_CRYSTAL_ACTIVATION, true);
+ return false;
}
+};
- uint32 uiArcaneStreamTimer;
- uint32 uiArcaneStreamTimerStartingValueHolder;
- uint32 uiManaDetonationTimer;
-
- void Reset() override
- {
- Initialize();
- }
+// 58040 - Destroy Door Seal
+class spell_violet_hold_destroy_door_seal : public SpellScriptLoader
+{
+ public:
+ spell_violet_hold_destroy_door_seal() : SpellScriptLoader("spell_violet_hold_destroy_door_seal") { }
- void UpdateAI(uint32 diff) override
+ class spell_violet_hold_destroy_door_seal_AuraScript : public AuraScript
{
- violet_hold_trashAI::UpdateAI(diff);
+ PrepareAuraScript(spell_violet_hold_destroy_door_seal_AuraScript);
- if (!UpdateVictim())
- return;
-
- if (uiArcaneStreamTimer <= diff)
+ bool Load() override
{
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_ARCANE_STREAM);
- uiArcaneStreamTimer = urand(0, 5000)+5000;
- uiArcaneStreamTimerStartingValueHolder = uiArcaneStreamTimer;
- } else uiArcaneStreamTimer -= diff;
+ _instance = GetUnitOwner()->GetInstanceScript();
+ return _instance != nullptr;
+ }
- if (uiManaDetonationTimer <= diff && uiArcaneStreamTimer >=1500 && uiArcaneStreamTimer <= uiArcaneStreamTimerStartingValueHolder/2)
+ void PeriodicTick(AuraEffect const* /*aurEff*/)
{
- DoCast(SPELL_MANA_DETONATION);
- uiManaDetonationTimer = urand(2000, 6000);
- } else uiManaDetonationTimer -= diff;
-
- DoMeleeAttackIfReady();
- }
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<npc_azure_sorcerorAI>(creature);
- }
-};
+ PreventDefaultAction();
+ if (uint32 integrity = _instance->GetData(DATA_DOOR_INTEGRITY))
+ _instance->SetData(DATA_DOOR_INTEGRITY, integrity - 1);
+ }
-class npc_violet_hold_arcane_sphere : public CreatureScript
-{
-public:
- npc_violet_hold_arcane_sphere() : CreatureScript("npc_violet_hold_arcane_sphere") { }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_violet_hold_destroy_door_seal_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
- struct npc_violet_hold_arcane_sphereAI : public ScriptedAI
- {
- npc_violet_hold_arcane_sphereAI(Creature* creature) : ScriptedAI(creature)
- {
- Initialize();
- }
+ private:
+ InstanceScript* _instance = nullptr;
+ };
- void Initialize()
+ AuraScript* GetAuraScript() const override
{
- DespawnTimer = 3000;
+ return new spell_violet_hold_destroy_door_seal_AuraScript();
}
+};
- uint32 DespawnTimer;
+// 58008 - Portal Periodic
+class spell_violet_hold_portal_periodic : public SpellScriptLoader
+{
+ public:
+ spell_violet_hold_portal_periodic() : SpellScriptLoader("spell_violet_hold_portal_periodic") { }
- void Reset() override
+ class spell_violet_hold_portal_periodic_AuraScript : public AuraScript
{
- Initialize();
+ PrepareAuraScript(spell_violet_hold_portal_periodic_AuraScript);
- me->SetDisableGravity(true);
- DoCast(me, SPELL_ARCANE_SPHERE_PASSIVE, true);
- }
+ void PeriodicTick(AuraEffect const* aurEff)
+ {
+ PreventDefaultAction();
+ if (GetTarget()->IsAIEnabled)
+ GetTarget()->GetAI()->SetData(DATA_PORTAL_PERIODIC_TICK, aurEff->GetTickNumber());
+ }
- void EnterCombat(Unit * /*who*/) override { }
+ void Register() override
+ {
+ OnEffectPeriodic += AuraEffectPeriodicFn(spell_violet_hold_portal_periodic_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
+ }
+ };
- void UpdateAI(uint32 diff) override
+ AuraScript* GetAuraScript() const override
{
- if (DespawnTimer <= diff)
- me->Kill(me);
- else
- DespawnTimer -= diff;
+ return new spell_violet_hold_portal_periodic_AuraScript();
}
- };
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_violet_hold_arcane_sphereAI(creature);
- }
};
-class go_activation_crystal : public GameObjectScript
+// 62138 - Teleport to Inside Violet Hold
+class spell_violet_hold_teleport_player : public SpellScriptLoader
{
-public:
- go_activation_crystal() : GameObjectScript("go_activation_crystal") { }
+ public:
+ spell_violet_hold_teleport_player() : SpellScriptLoader("spell_violet_hold_teleport_player") { }
- bool OnGossipHello(Player * /*player*/, GameObject* go) override
- {
- go->EventInform(EVENT_ACTIVATE_CRYSTAL);
- return false;
- }
-};
+ class spell_violet_hold_teleport_player_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_violet_hold_teleport_player_SpellScript);
-class spell_crystal_activation : public SpellScriptLoader
-{
-public:
- spell_crystal_activation() : SpellScriptLoader("spell_crystal_activation") { }
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ if (!sSpellMgr->GetSpellInfo(SPELL_TELEPORT_PLAYER_EFFECT))
+ return false;
+ return true;
+ }
- class spell_crystal_activation_SpellScript : public SpellScript
- {
- PrepareSpellScript(spell_crystal_activation_SpellScript);
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->CastSpell(target, SPELL_TELEPORT_PLAYER_EFFECT, true);
+ }
- void HandleSendEvent(SpellEffIndex effIndex)
- {
- if (GetHitUnit()->GetEntry() == NPC_VIOLET_HOLD_GUARD)
- PreventHitDefaultEffect(effIndex);
- }
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_violet_hold_teleport_player_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
- void Register() override
+ SpellScript* GetSpellScript() const override
{
- OnEffectHitTarget += SpellEffectFn(spell_crystal_activation_SpellScript::HandleSendEvent, EFFECT_0, SPELL_EFFECT_SEND_EVENT);
+ return new spell_violet_hold_teleport_player_SpellScript();
}
- };
-
- SpellScript* GetSpellScript() const override
- {
- return new spell_crystal_activation_SpellScript();
- }
};
void AddSC_violet_hold()
{
new npc_sinclari_vh();
- new npc_teleportation_portal_vh();
+ new npc_violet_hold_teleportation_portal();
+ new npc_violet_hold_teleportation_portal_elite();
+ new npc_violet_hold_teleportation_portal_intro();
new npc_azure_invader();
new npc_azure_spellbreaker();
new npc_azure_binder();
@@ -1520,7 +1431,9 @@ void AddSC_violet_hold()
new npc_azure_raider();
new npc_azure_stalker();
new npc_azure_saboteur();
- new npc_violet_hold_arcane_sphere();
+ new npc_violet_hold_defense_system();
new go_activation_crystal();
- new spell_crystal_activation();
+ new spell_violet_hold_destroy_door_seal();
+ new spell_violet_hold_portal_periodic();
+ new spell_violet_hold_teleport_player();
}
diff --git a/src/server/scripts/Northrend/VioletHold/violet_hold.h b/src/server/scripts/Northrend/VioletHold/violet_hold.h
index 2bd90672024..113a3c46ea0 100644
--- a/src/server/scripts/Northrend/VioletHold/violet_hold.h
+++ b/src/server/scripts/Northrend/VioletHold/violet_hold.h
@@ -15,44 +15,56 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef DEF_VIOLET_HOLD_H
-#define DEF_VIOLET_HOLD_H
+#ifndef VIOLET_HOLD_H_
+#define VIOLET_HOLD_H_
+#define VioletHoldScriptName "instance_violet_hold"
#define DataHeader "VH"
-uint32 const EncounterCount = 3;
+uint32 const EncounterCount = 3 + 6;
+
+// Defined in instance_violet_hold.cpp
+extern Position const DefenseSystemLocation;
+uint8 const PortalIntroCount = 3;
+extern Position const PortalIntroPositions[];
+
+/*
+ * Violet hold bosses:
+ *
+ * 1 - Moragg
+ * 2 - Erekem
+ * 3 - Ichoron
+ * 4 - Lavanthor
+ * 5 - Xevozz
+ * 6 - Zuramat
+ * 7 - Cyanigosa
+ */
enum Data
{
// Main encounters
- DATA_1ST_BOSS_EVENT,
- DATA_2ND_BOSS_EVENT,
- DATA_CYANIGOSA,
+ DATA_1ST_BOSS = 0,
+ DATA_2ND_BOSS = 1,
+ DATA_CYANIGOSA = 2,
+ // Bosses
+ DATA_MORAGG = 3,
+ DATA_EREKEM = 4,
+ DATA_ICHORON = 5,
+ DATA_LAVANTHOR = 6,
+ DATA_XEVOZZ = 7,
+ DATA_ZURAMAT = 8,
// Misc
+ DATA_MAIN_EVENT_STATE,
DATA_WAVE_COUNT,
- DATA_REMOVE_NPC,
- DATA_PORTAL_LOCATION,
DATA_DOOR_INTEGRITY,
- DATA_NPC_PRESENCE_AT_DOOR,
- DATA_NPC_PRESENCE_AT_DOOR_ADD,
- DATA_NPC_PRESENCE_AT_DOOR_REMOVE,
+ DATA_PORTAL_LOCATION,
DATA_START_BOSS_ENCOUNTER,
- DATA_FIRST_BOSS,
- DATA_SECOND_BOSS,
- DATA_ACTIVATE_CRYSTAL,
- DATA_MAIN_EVENT_PHASE,
DATA_DEFENSELESS,
// Bosses
- DATA_MORAGG,
- DATA_EREKEM,
DATA_EREKEM_GUARD_1,
DATA_EREKEM_GUARD_2,
- DATA_ICHORON,
- DATA_LAVANTHOR,
- DATA_XEVOZZ,
- DATA_ZURAMAT,
// Cells
DATA_MORAGG_CELL,
@@ -67,43 +79,43 @@ enum Data
// Misc
DATA_MAIN_DOOR,
DATA_SINCLARI,
- DATA_TELEPORTATION_PORTAL,
- DATA_SABOTEUR_PORTAL,
- DATA_ADD_TRASH_MOB,
- DATA_DEL_TRASH_MOB
-};
-
-enum Bosses
-{
- BOSS_NONE, // 0 used as marker for not yet randomized
- BOSS_MORAGG,
- BOSS_EREKEM,
- BOSS_ICHORON,
- BOSS_LAVANTHOR,
- BOSS_XEVOZZ,
- BOSS_ZURAMAT,
- BOSS_CYANIGOSA
+ DATA_SINCLARI_TRIGGER,
+ DATA_HANDLE_CELLS
};
enum CreaturesIds
{
- NPC_TELEPORTATION_PORTAL = 31011,
+ NPC_TELEPORTATION_PORTAL = 30679,
+ NPC_TELEPORTATION_PORTAL_ELITE = 32174,
+ NPC_TELEPORTATION_PORTAL_INTRO = 31011,
NPC_PORTAL_GUARDIAN = 30660,
NPC_PORTAL_KEEPER = 30695,
NPC_XEVOZZ = 29266,
NPC_LAVANTHOR = 29312,
NPC_ICHORON = 29313,
+ NPC_ICHOR_GLOBULE = 29321,
+ NPC_ICHORON_SUMMON_TARGET = 29326,
NPC_ZURAMAT = 29314,
+ NPC_VOID_SENTRY = 29364,
+ NPC_VOID_SENTRY_BALL = 29365,
NPC_EREKEM = 29315,
NPC_EREKEM_GUARD = 29395,
NPC_MORAGG = 29316,
+
+ NPC_DUMMY_XEVOZZ = 32231,
+ NPC_DUMMY_LAVANTHOR = 32237,
+ NPC_DUMMY_ICHORON = 32234,
+ NPC_DUMMY_ZURAMAT = 32230,
+ NPC_DUMMY_EREKEM = 32226,
+ NPC_DUMMY_EREKEM_GUARD = 32228,
+ NPC_DUMMY_MORAGG = 32235,
+
NPC_CYANIGOSA = 31134,
NPC_SINCLARI = 30658,
+ NPC_SINCLARI_TRIGGER = 32204,
NPC_SABOTEOUR = 31079,
NPC_VIOLET_HOLD_GUARD = 30659,
- NPC_DEFENSE_SYSTEM = 30837,
- NPC_VOID_SENTRY = 29364,
- NPC_VOID_SENTRY_BALL = 29365
+ NPC_DEFENSE_SYSTEM = 30837
};
enum GameObjectIds
@@ -117,13 +129,13 @@ enum GameObjectIds
GO_EREKEM_GUARD_1_DOOR = 191563,
GO_EREKEM_GUARD_2_DOOR = 191562,
GO_MORAGG_DOOR = 191606,
- GO_INTRO_ACTIVATION_CRYSTAL = 193615,
- GO_ACTIVATION_CRYSTAL = 193611
+ GO_ACTIVATION_CRYSTAL = 193611,
+ GO_INTRO_ACTIVATION_CRYSTAL = 193615
};
enum WorldStateIds
{
- WORLD_STATE_VH = 3816,
+ WORLD_STATE_VH_SHOW = 3816,
WORLD_STATE_VH_PRISON_STATE = 3815,
WORLD_STATE_VH_WAVE_COUNT = 3810,
};
@@ -133,4 +145,16 @@ enum Events
EVENT_ACTIVATE_CRYSTAL = 20001
};
-#endif
+enum InstanceMisc
+{
+ ACTION_SINCLARI_OUTRO = 1,
+ POINT_INTRO = 1
+};
+
+template<class AI>
+inline AI* GetVioletHoldAI(Creature* creature)
+{
+ return GetInstanceAI<AI>(creature, VioletHoldScriptName);
+}
+
+#endif // VIOLET_HOLD_H_
diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp
index 74614ae7c13..511ddcff5fa 100644
--- a/src/server/scripts/Northrend/zone_borean_tundra.cpp
+++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp
@@ -593,12 +593,13 @@ public:
switch (IntroPhase)
{
case 1:
- Talk(SAY_START_1);
+ if (Player* player = GetPlayerForEscort())
+ Talk(SAY_START_1, player);
IntroPhase = 2;
IntroTimer = 7500;
break;
case 2:
- Talk(SAY_END_1);
+ Talk(SAY_START_2);
IntroPhase = 3;
IntroTimer = 7500;
break;
@@ -608,12 +609,13 @@ public:
IntroTimer = 0;
break;
case 4:
- Talk(SAY_START_2);
+ Talk(SAY_END_1);
IntroPhase = 5;
IntroTimer = 8000;
break;
case 5:
- Talk(SAY_END_2);
+ if (Player* player = GetPlayerForEscort())
+ Talk(SAY_END_2, player);
IntroPhase = 6;
IntroTimer = 2500;
break;
@@ -1816,7 +1818,7 @@ public:
player->FailQuest(QUEST_GET_ME_OUTA_HERE);
}
- void UpdateEscortAI(const uint32 /*diff*/) override
+ void UpdateEscortAI(uint32 /*diff*/) override
{
if (GetAttack() && UpdateVictim())
{
diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp
index fe72a2cedf7..ba69a1385d5 100644
--- a/src/server/scripts/Northrend/zone_howling_fjord.cpp
+++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp
@@ -98,7 +98,7 @@ public:
player->FailQuest(QUEST_TRAIL_OF_FIRE);
}
- void UpdateEscortAI(const uint32 diff) override
+ void UpdateEscortAI(uint32 diff) override
{
if (HealthBelowPct(75))
{
diff --git a/src/server/scripts/Northrend/zone_sholazar_basin.cpp b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
index 1e998b78c03..e0c7e4b57a7 100644
--- a/src/server/scripts/Northrend/zone_sholazar_basin.cpp
+++ b/src/server/scripts/Northrend/zone_sholazar_basin.cpp
@@ -621,17 +621,17 @@ public:
enum MiscLifewarden
{
- NPC_PRESENCE = 28563, // Freya's Presence
- NPC_SABOTEUR = 28538, // Cultist Saboteur
- NPC_SERVANT = 28320, // Servant of Freya
+ NPC_PRESENCE = 28563, // Freya's Presence
+ NPC_SABOTEUR = 28538, // Cultist Saboteur
+ NPC_SERVANT = 28320, // Servant of Freya
- WHISPER_ACTIVATE = 0,
+ WHISPER_ACTIVATE = 0,
- SPELL_FREYA_DUMMY = 51318,
- SPELL_LIFEFORCE = 51395,
- SPELL_FREYA_DUMMY_TRIGGER = 51335,
- SPELL_LASHER_EMERGE = 48195,
- SPELL_WILD_GROWTH = 52948,
+ SPELL_FREYA_DUMMY = 51318,
+ SPELL_LIFEFORCE = 51395,
+ SPELL_FREYA_DUMMY_TRIGGER = 51335,
+ SPELL_LASHER_EMERGE = 48195,
+ SPELL_WILD_GROWTH = 52948,
};
class spell_q12620_the_lifewarden_wrath : public SpellScriptLoader
@@ -701,25 +701,25 @@ public:
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,
+ 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
@@ -799,8 +799,6 @@ public:
wilhelm->AI()->Talk(SAY_WILHELM_HIT);
if (Player* player = shooter->ToPlayer())
player->KilledMonsterCredit(NPC_APPLE);
- apple->DespawnOrUnsummon();
-
break;
}
}
@@ -827,11 +825,11 @@ may be easily converted to SAI when they get.*/
enum SongOfWindAndWater
{
// Spells
- SPELL_DEVOUR_WIND = 52862,
- SPELL_DEVOUR_WATER = 52864,
+ SPELL_DEVOUR_WIND = 52862,
+ SPELL_DEVOUR_WATER = 52864,
// NPCs
- NPC_HAIPHOON_WATER = 28999,
- NPC_HAIPHOON_AIR = 28985
+ NPC_HAIPHOON_WATER = 28999,
+ NPC_HAIPHOON_AIR = 28985
};
class npc_haiphoon : public CreatureScript
@@ -882,7 +880,7 @@ enum ReconnaissanceFlight
VIC_SAY_6 = 6,
PLANE_EMOTE = 0,
- SPELL_ENGINE = 52255, // Engine on Fire
+ SPELL_ENGINE = 52255, // Engine on Fire
SPELL_LAND = 52226, // Land Flying Machine
SPELL_CREDIT = 53328 // Land Flying Machine Credit
diff --git a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
index 9667b4e3bb0..80cc2028cb3 100644
--- a/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
+++ b/src/server/scripts/Outland/Auchindoun/ShadowLabyrinth/boss_ambassador_hellmaw.cpp
@@ -136,7 +136,7 @@ class boss_ambassador_hellmaw : public CreatureScript
Talk(SAY_DEATH);
}
- void UpdateEscortAI(uint32 const diff) override
+ void UpdateEscortAI(uint32 diff) override
{
if (!UpdateVictim())
return;
diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
index 1657b178327..d7ba0a34939 100644
--- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
+++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp
@@ -275,8 +275,8 @@ class instance_serpent_shrine : public InstanceMapScript
if (data == DONE)
{
HandleGameObject(BridgePart[0], true);
- HandleGameObject(BridgePart[0], true);
- HandleGameObject(BridgePart[0], true);
+ HandleGameObject(BridgePart[1], true);
+ HandleGameObject(BridgePart[2], true);
}
break;
case DATA_TRASH:
diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
index 3986e50877f..8e56df071c9 100644
--- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
+++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.cpp
@@ -146,8 +146,6 @@ class boss_shattered_executioner : public CreatureScript
me->RemoveLootMode(LOOT_MODE_HARD_MODE_2);
case 1:
me->RemoveLootMode(LOOT_MODE_HARD_MODE_3);
- default:
- break;
}
}
}
diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
index d140b41a8f8..8549fe5030f 100644
--- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
+++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp
@@ -407,10 +407,483 @@ public:
}
};
+enum ExorcismSpells
+{
+ SPELL_JULES_GOES_PRONE = 39283,
+ SPELL_JULES_THREATENS_AURA = 39284,
+ SPELL_JULES_GOES_UPRIGHT = 39294,
+ SPELL_JULES_VOMITS_AURA = 39295,
+
+ SPELL_BARADAS_COMMAND = 39277,
+ SPELL_BARADA_FALTERS = 39278,
+};
+
+enum ExorcismTexts
+{
+ SAY_BARADA_1 = 0,
+ SAY_BARADA_2 = 1,
+ SAY_BARADA_3 = 2,
+ SAY_BARADA_4 = 3,
+ SAY_BARADA_5 = 4,
+ SAY_BARADA_6 = 5,
+ SAY_BARADA_7 = 6,
+ SAY_BARADA_8 = 7,
+
+ SAY_JULES_1 = 0,
+ SAY_JULES_2 = 1,
+ SAY_JULES_3 = 2,
+ SAY_JULES_4 = 3,
+ SAY_JULES_5 = 4,
+};
+
+Position const exorcismPos[11] =
+{
+ { -707.123f, 2751.686f, 101.592f, 4.577416f }, //Barada Waypoint-1 0
+ { -710.731f, 2749.075f, 101.592f, 1.513286f }, //Barada Cast position 1
+ { -710.332f, 2754.394f, 102.948f, 3.207566f }, //Jules 2
+ { -714.261f, 2747.754f, 103.391f, 0.0f }, //Jules Waypoint-1 3
+ { -713.113f, 2750.194f, 103.391f, 0.0f }, //Jules Waypoint-2 4
+ { -710.385f, 2750.896f, 103.391f, 0.0f }, //Jules Waypoint-3 5
+ { -708.309f, 2750.062f, 103.391f, 0.0f }, //Jules Waypoint-4 6
+ { -707.401f, 2747.696f, 103.391f, 0.0f }, //Jules Waypoint-5 7
+ { -708.591f, 2745.266f, 103.391f, 0.0f }, //Jules Waypoint-6 8
+ { -710.597f, 2744.035f, 103.391f, 0.0f }, //Jules Waypoint-7 9
+ { -713.089f, 2745.302f, 103.391f, 0.0f }, //Jules Waypoint-8 10
+};
+
+enum ExorcismMisc
+{
+ NPC_DARKNESS_RELEASED = 22507,
+ NPC_FOUL_PURGE = 22506,
+ NPC_COLONEL_JULES = 22432,
+
+ BARADAS_GOSSIP_MESSAGE = 10683,
+
+ QUEST_THE_EXORCISM_OF_COLONEL_JULES = 10935,
+
+ ACTION_START_EVENT = 1,
+ ACTION_JULES_HOVER = 2,
+ ACTION_JULES_FLIGHT = 3,
+ ACTION_JULES_MOVE_HOME = 4,
+};
+
+enum ExorcismEvents
+{
+ EVENT_BARADAS_TALK = 1,
+
+ //Colonel Jules
+ EVENT_SUMMON_SKULL = 1,
+};
+
+/*######
+## npc_barada
+######*/
+
+class npc_barada : public CreatureScript
+{
+public:
+ npc_barada() : CreatureScript("npc_barada") { }
+
+ struct npc_baradaAI : public ScriptedAI
+ {
+ npc_baradaAI(Creature* creature) : ScriptedAI(creature)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ step = 0;
+ }
+
+ void Reset() override
+ {
+ events.Reset();
+ Initialize();
+
+ playerGUID.Clear();
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+ }
+
+ void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
+ {
+ player->PlayerTalkClass->ClearMenus();
+ switch (gossipListId)
+ {
+ case 1:
+ player->PlayerTalkClass->SendCloseGossip();
+ me->AI()->Talk(SAY_BARADA_1);
+ me->AI()->DoAction(ACTION_START_EVENT);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_START_EVENT)
+ {
+ if (Creature* jules = me->FindNearestCreature(NPC_COLONEL_JULES, 20.0f, true))
+ {
+ julesGUID = jules->GetGUID();
+ jules->AI()->Talk(SAY_JULES_1);
+ }
+
+ me->GetMotionMaster()->MovePoint(0, exorcismPos[1]);
+ Talk(SAY_BARADA_2);
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id == 0)
+ me->GetMotionMaster()->MovePoint(1, exorcismPos[1]);
+
+ if (id == 1)
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 2000);
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ {
+ jules->AI()->DoAction(ACTION_JULES_MOVE_HOME);
+ jules->RemoveAllAuras();
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_BARADAS_TALK:
+ switch (step)
+ {
+ case 0:
+ me->SetFacingTo(1.513286f);
+
+ me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 3000);
+ step++;
+ break;
+ case 1:
+ DoCast(SPELL_BARADAS_COMMAND);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 5000);
+ step++;
+ break;
+ case 2:
+ Talk(SAY_BARADA_3);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 7000);
+ step++;
+ break;
+ case 3:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_2);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 18000);
+ step++;
+ break;
+ case 4:
+ DoCast(SPELL_BARADA_FALTERS);
+ me->HandleEmoteCommand(EMOTE_STAND_STATE_NONE);
+
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->DoAction(ACTION_JULES_HOVER);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 11000);
+ step++;
+ break;
+ case 5:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_3);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 13000);
+ step++;
+ break;
+ case 6:
+ Talk(SAY_BARADA_4);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 5000);
+ step++;
+ break;
+ case 7:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_3);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 13000);
+ step++;
+ break;
+ case 8:
+ Talk(SAY_BARADA_4);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 12000);
+ step++;
+ break;
+ case 9:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_4);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 12000);
+ step++;
+ break;
+ case 10:
+ Talk(SAY_BARADA_4);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 5000);
+ step++;
+ break;
+ case 11:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->DoAction(ACTION_JULES_FLIGHT);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 12:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_4);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 8000);
+ step++;
+ break;
+ case 13:
+ Talk(SAY_BARADA_5);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 14:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_4);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 15:
+ Talk(SAY_BARADA_6);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 16:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_5);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 17:
+ Talk(SAY_BARADA_7);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 18:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->AI()->Talk(SAY_JULES_3);
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 19:
+ Talk(SAY_BARADA_7);
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 20:
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ {
+ jules->AI()->DoAction(ACTION_JULES_MOVE_HOME);
+ jules->RemoveAura(SPELL_JULES_VOMITS_AURA);
+ }
+
+ events.ScheduleEvent(EVENT_BARADAS_TALK, 10000);
+ step++;
+ break;
+ case 21:
+ //End
+ if (Player* player = ObjectAccessor::FindPlayer(playerGUID))
+ player->KilledMonsterCredit(NPC_COLONEL_JULES, ObjectGuid::Empty);
+
+ if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID))
+ jules->RemoveAllAuras();
+
+ me->RemoveAura(SPELL_BARADAS_COMMAND);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+
+ Talk(SAY_BARADA_8);
+ me->GetMotionMaster()->MoveTargetedHome();
+ EnterEvadeMode();
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ uint8 step;
+ ObjectGuid julesGUID;
+ ObjectGuid playerGUID;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_baradaAI(creature);
+ }
+};
+
+/*######
+## npc_colonel_jules
+######*/
+
+class npc_colonel_jules : public CreatureScript
+{
+public:
+ npc_colonel_jules() : CreatureScript("npc_colonel_jules") { }
+
+ struct npc_colonel_julesAI : public ScriptedAI
+ {
+ npc_colonel_julesAI(Creature* creature) : ScriptedAI(creature), summons(me)
+ {
+ Initialize();
+ }
+
+ void Initialize()
+ {
+ circleRounds = 0;
+ point = 0;
+ }
+
+ void Reset() override
+ {
+ events.Reset();
+
+ summons.DespawnAll();
+ circleRounds = 0;
+ point = 3;
+ wpreached = false;
+ }
+
+ void DoAction(int32 action) override
+ {
+ switch (action)
+ {
+ case ACTION_JULES_HOVER:
+ me->AddAura(SPELL_JULES_GOES_PRONE, me);
+ me->AddAura(SPELL_JULES_THREATENS_AURA, me);
+
+ me->SetCanFly(true);
+ me->SetSpeed(MOVE_RUN, 0.2f);
+
+ me->SetFacingTo(3.207566f);
+ me->GetMotionMaster()->MoveJump(exorcismPos[2], 2.0f, 2.0f);
+
+ events.ScheduleEvent(EVENT_SUMMON_SKULL, 10000);
+ break;
+ case ACTION_JULES_FLIGHT:
+ circleRounds++;
+
+ me->RemoveAura(SPELL_JULES_GOES_PRONE);
+
+ me->AddAura(SPELL_JULES_GOES_UPRIGHT, me);
+ me->AddAura(SPELL_JULES_VOMITS_AURA, me);
+
+ wpreached = true;
+ me->GetMotionMaster()->MovePoint(point, exorcismPos[point]);
+ break;
+ case ACTION_JULES_MOVE_HOME:
+ wpreached = false;
+ me->SetSpeed(MOVE_RUN, 1.0f);
+ me->GetMotionMaster()->MovePoint(11, exorcismPos[2]);
+
+ events.CancelEvent(EVENT_SUMMON_SKULL);
+ break;
+ }
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ summons.Summon(summon);
+ summon->GetMotionMaster()->MoveRandom(10.0f);
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id < 10)
+ wpreached = true;
+
+ if (id == 8)
+ {
+ for (uint8 i = 0; i < circleRounds; i++)
+ DoSummon(NPC_FOUL_PURGE, exorcismPos[8]);
+ }
+
+ if (id == 10)
+ {
+ wpreached = true;
+ point = 3;
+ circleRounds++;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ if (wpreached)
+ {
+ me->GetMotionMaster()->MovePoint(point, exorcismPos[point]);
+ point++;
+ wpreached = false;
+ }
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_SUMMON_SKULL:
+ uint8 summonCount = urand(1,3);
+
+ for (uint8 i = 0; i < summonCount; i++)
+ me->SummonCreature(NPC_DARKNESS_RELEASED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 0, TEMPSUMMON_MANUAL_DESPAWN);
+
+ events.ScheduleEvent(EVENT_SUMMON_SKULL, urand(10000, 15000));
+ break;
+ }
+ }
+ }
+
+ private:
+ EventMap events;
+ SummonList summons;
+
+ uint8 circleRounds;
+ uint8 point;
+
+ bool wpreached;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_colonel_julesAI(creature);
+ }
+};
+
void AddSC_hellfire_peninsula()
{
new npc_aeranas();
new npc_ancestral_wolf();
new npc_wounded_blood_elf();
new npc_fel_guard_hound();
+ new npc_barada();
+ new npc_colonel_jules();
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 0bb61ab15bd..8a435b1d5a7 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -676,6 +676,47 @@ class spell_gen_burn_brutallus : public SpellScriptLoader
}
};
+// 48750 - Burning Depths Necrolyte Image
+class spell_gen_burning_depths_necrolyte_image : public SpellScriptLoader
+{
+ public:
+ spell_gen_burning_depths_necrolyte_image() : SpellScriptLoader("spell_gen_burning_depths_necrolyte_image") { }
+
+ class spell_gen_burning_depths_necrolyte_image_AuraScript : public AuraScript
+ {
+ PrepareAuraScript(spell_gen_burning_depths_necrolyte_image_AuraScript);
+
+ bool Validate(SpellInfo const* spellInfo) override
+ {
+ if (!sSpellMgr->GetSpellInfo(uint32(spellInfo->GetEffect(EFFECT_2)->CalcValue())))
+ return false;
+ return true;
+ }
+
+ void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ if (Unit* caster = GetCaster())
+ caster->CastSpell(GetTarget(), uint32(GetSpellInfo()->GetEffect(EFFECT_2)->CalcValue()));
+ }
+
+ void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAurasDueToSpell(uint32(GetSpellInfo()->GetEffect(EFFECT_2)->CalcValue()), GetCasterGUID());
+ }
+
+ void Register() override
+ {
+ AfterEffectApply += AuraEffectApplyFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
+ AfterEffectRemove += AuraEffectRemoveFn(spell_gen_burning_depths_necrolyte_image_AuraScript::HandleRemove, EFFECT_0, SPELL_AURA_TRANSFORM, AURA_EFFECT_HANDLE_REAL);
+ }
+ };
+
+ AuraScript* GetAuraScript() const override
+ {
+ return new spell_gen_burning_depths_necrolyte_image_AuraScript();
+ }
+};
+
enum CannibalizeSpells
{
SPELL_CANNIBALIZE_TRIGGERED = 20578
@@ -4088,6 +4129,7 @@ void AddSC_generic_spell_scripts()
new spell_gen_break_shield("spell_gen_break_shield");
new spell_gen_break_shield("spell_gen_tournament_counterattack");
new spell_gen_burn_brutallus();
+ new spell_gen_burning_depths_necrolyte_image();
new spell_gen_cannibalize();
new spell_gen_chaos_blast();
new spell_gen_clone();
diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp
new file mode 100644
index 00000000000..f08469d5bd5
--- /dev/null
+++ b/src/server/scripts/World/duel_reset.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008-2015 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 "ScriptMgr.h"
+#include "Player.h"
+
+class DuelResetScript : public PlayerScript
+{
+ public:
+ DuelResetScript() : PlayerScript("DuelResetScript") { }
+
+ // Called when a duel starts (after 3s countdown)
+ void OnDuelStart(Player* player1, Player* player2) override
+ {
+ if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS))
+ {
+ player1->GetSpellHistory()->SaveCooldownStateBeforeDuel();
+ player2->GetSpellHistory()->SaveCooldownStateBeforeDuel();
+
+ player1->RemoveArenaSpellCooldowns(true);
+ player2->RemoveArenaSpellCooldowns(true);
+ }
+ }
+
+ // Called when a duel ends
+ void OnDuelEnd(Player* winner, Player* loser, DuelCompleteType /*type*/) override
+ {
+ if (sWorld->getBoolConfig(CONFIG_RESET_DUEL_COOLDOWNS))
+ {
+ winner->RemoveArenaSpellCooldowns(true);
+ loser->RemoveArenaSpellCooldowns(true);
+
+ winner->GetSpellHistory()->RestoreCooldownStateAfterDuel();
+ loser->GetSpellHistory()->RestoreCooldownStateAfterDuel();
+ }
+ }
+};
+
+void AddSC_duel_reset()
+{
+ new DuelResetScript();
+}
+
diff --git a/src/server/scripts/World/npc_professions.cpp b/src/server/scripts/World/npc_professions.cpp
index e2ab2860796..a9261849f38 100644
--- a/src/server/scripts/World/npc_professions.cpp
+++ b/src/server/scripts/World/npc_professions.cpp
@@ -179,6 +179,52 @@ enum ProfessionSpells
};
/*###
+# specialization trainers
+###*/
+enum SpecializationTrainers
+{
+ /* Alchemy */
+ N_TRAINER_TRANSMUTE = 22427, // Zarevhi
+ N_TRAINER_ELIXIR = 19052, // Lorokeem
+ N_TRAINER_POTION = 17909, // Lauranna Thar'well
+
+ /* Blacksmithing */
+ N_TRAINER_SMITHOMNI1 = 11145, // Myolor Sunderfury
+ N_TRAINER_SMITHOMNI2 = 11176, // Krathok Moltenfist
+ N_TRAINER_WEAPON1 = 11146, // Ironus Coldsteel
+ N_TRAINER_WEAPON2 = 11178, // Borgosh Corebender
+ N_TRAINER_ARMOR1 = 5164, // Grumnus Steelshaper
+ N_TRAINER_ARMOR2 = 11177, // Okothos Ironrager
+ N_TRAINER_HAMMER = 11191, // Lilith the Lithe
+ N_TRAINER_AXE = 11192, // Kilram
+ N_TRAINER_SWORD = 11193, // Seril Scourgebane
+
+ /* Leatherworking */
+ N_TRAINER_DRAGON1 = 7866, // Peter Galen
+ N_TRAINER_DRAGON2 = 7867, // Thorkaf Dragoneye
+ N_TRAINER_ELEMENTAL1 = 7868, // Sarah Tanner
+ N_TRAINER_ELEMENTAL2 = 7869, // Brumn Winterhoof
+ N_TRAINER_TRIBAL1 = 7870, // Caryssia Moonhunter
+ N_TRAINER_TRIBAL2 = 7871, // Se'Jib
+
+ /* Tailoring */
+ N_TRAINER_SPELLFIRE = 22213, // Gidge Spellweaver
+ N_TRAINER_MOONCLOTH = 22208, // Nasmara Moonsong
+ N_TRAINER_SHADOWEAVE = 22212, // Andrion Darkspinner
+};
+
+/*###
+# specialization quests
+###*/
+enum SpecializationQuests
+{
+ /* Alchemy */
+ Q_MASTER_TRANSMUTE = 10899,
+ Q_MASTER_ELIXIR = 10902,
+ Q_MASTER_POTION = 10897,
+};
+
+/*###
# formulas to calculate unlearning cost
###*/
@@ -398,23 +444,23 @@ public:
if (player->HasSkill(SKILL_ALCHEMY) && player->GetBaseSkillValue(SKILL_ALCHEMY) >= 350 && player->getLevel() > 67)
{
- if (player->GetQuestRewardStatus(10899) || player->GetQuestRewardStatus(10902) || player->GetQuestRewardStatus(10897))
+ if (player->GetQuestRewardStatus(Q_MASTER_TRANSMUTE) || player->GetQuestRewardStatus(Q_MASTER_ELIXIR) || player->GetQuestRewardStatus(Q_MASTER_POTION))
{
switch (creature->GetEntry())
{
- case 22427: //Zarevhi
+ case N_TRAINER_TRANSMUTE: //Zarevhi
if (!HasAlchemySpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1);
if (player->HasSpell(S_TRANSMUTE))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
break;
- case 19052: //Lorokeem
+ case N_TRAINER_ELIXIR: //Lorokeem
if (!HasAlchemySpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2);
if (player->HasSpell(S_ELIXIR))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5);
break;
- case 17909: //Lauranna Thar'well
+ case N_TRAINER_POTION: //Lauranna Thar'well
if (!HasAlchemySpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3);
if (player->HasSpell(S_POTION))
@@ -467,17 +513,17 @@ public:
{
switch (creature->GetEntry())
{
- case 22427:
+ case N_TRAINER_TRANSMUTE:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 19052:
+ case N_TRAINER_ELIXIR:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_ELIXIR, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 17909:
+ case N_TRAINER_POTION:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_POTION, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -492,17 +538,17 @@ public:
{
switch (creature->GetEntry())
{
- case 22427: //Zarevhi
+ case N_TRAINER_TRANSMUTE:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRANSMUTE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 19052: //Lorokeem
+ case N_TRAINER_ELIXIR:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELIXIR, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 17909: //Lauranna Thar'well
+ case N_TRAINER_POTION:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_POTION, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ALCHEMY_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -567,20 +613,20 @@ public:
{
switch (creatureId)
{
- case 11145: //Myolor Sunderfury
- case 11176: //Krathok Moltenfist
+ case N_TRAINER_SMITHOMNI1:
+ case N_TRAINER_SMITHOMNI2:
if (!player->HasSpell(S_ARMOR) && !player->HasSpell(S_WEAPON) && player->GetReputationRank(REP_ARMOR) >= REP_FRIENDLY)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (!player->HasSpell(S_WEAPON) && !player->HasSpell(S_ARMOR) && player->GetReputationRank(REP_WEAPON) >= REP_FRIENDLY)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_LEARN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
break;
- case 11146: //Ironus Coldsteel
- case 11178: //Borgosh Corebender
+ case N_TRAINER_WEAPON1:
+ case N_TRAINER_WEAPON2:
if (player->HasSpell(S_WEAPON))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_WEAPON_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3);
break;
- case 5164: //Grumnus Steelshaper
- case 11177: //Okothos Ironrager
+ case N_TRAINER_ARMOR1:
+ case N_TRAINER_ARMOR2:
if (player->HasSpell(S_ARMOR))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ARMOR_UNLEARN, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
break;
@@ -591,19 +637,19 @@ public:
{
switch (creatureId)
{
- case 11191: //Lilith the Lithe
+ case N_TRAINER_HAMMER:
if (!HasWeaponSub(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 5);
if (player->HasSpell(S_HAMMER))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 8);
break;
- case 11192: //Kilram
+ case N_TRAINER_AXE:
if (!HasWeaponSub(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 6);
if (player->HasSpell(S_AXE))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 9);
break;
- case 11193: //Seril Scourgebane
+ case N_TRAINER_SWORD:
if (!HasWeaponSub(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 7);
if (player->HasSpell(S_SWORD))
@@ -688,17 +734,17 @@ public:
{
switch (creature->GetEntry())
{
- case 11191:
+ case N_TRAINER_HAMMER:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_HAMMER, GOSSIP_SENDER_CHECK, action);
//unknown textID (TALK_HAMMER_LEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 11192:
+ case N_TRAINER_AXE:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_AXE, GOSSIP_SENDER_CHECK, action);
//unknown textID (TALK_AXE_LEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 11193:
+ case N_TRAINER_SWORD:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SWORD, GOSSIP_SENDER_CHECK, action);
//unknown textID (TALK_SWORD_LEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -713,26 +759,26 @@ public:
{
switch (creature->GetEntry())
{
- case 11146: //Ironus Coldsteel
- case 11178: //Borgosh Corebender
- case 5164: //Grumnus Steelshaper
- case 11177: //Okothos Ironrager
+ case N_TRAINER_WEAPON1:
+ case N_TRAINER_WEAPON2:
+ case N_TRAINER_ARMOR1:
+ case N_TRAINER_ARMOR2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SMITH_SPEC, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_ARMORORWEAPON, DoLowUnlearnCost(player), false);
//unknown textID (TALK_UNLEARN_AXEORWEAPON)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 11191:
+ case N_TRAINER_HAMMER:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_HAMMER, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false);
//unknown textID (TALK_HAMMER_UNLEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 11192:
+ case N_TRAINER_AXE:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_AXE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false);
//unknown textID (TALK_AXE_UNLEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 11193:
+ case N_TRAINER_SWORD:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SWORD, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_WEAPON_SPEC, DoMedUnlearnCost(player), false);
//unknown textID (TALK_SWORD_UNLEARN)
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -904,18 +950,18 @@ public:
{
switch (creature->GetEntry())
{
- case 7866: //Peter Galen
- case 7867: //Thorkaf Dragoneye
+ case N_TRAINER_DRAGON1:
+ case N_TRAINER_DRAGON2:
if (player->HasSpell(S_DRAGON))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 1);
break;
- case 7868: //Sarah Tanner
- case 7869: //Brumn Winterhoof
+ case N_TRAINER_ELEMENTAL1:
+ case N_TRAINER_ELEMENTAL2:
if (player->HasSpell(S_ELEMENTAL))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 2);
break;
- case 7870: //Caryssia Moonhunter
- case 7871: //Se'Jib
+ case N_TRAINER_TRIBAL1:
+ case N_TRAINER_TRIBAL2:
if (player->HasSpell(S_TRIBAL))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 3);
break;
@@ -955,20 +1001,20 @@ public:
{
switch (creature->GetEntry())
{
- case 7866: //Peter Galen
- case 7867: //Thorkaf Dragoneye
+ case N_TRAINER_DRAGON1:
+ case N_TRAINER_DRAGON2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_DRAGON, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 7868: //Sarah Tanner
- case 7869: //Brumn Winterhoof
+ case N_TRAINER_ELEMENTAL1:
+ case N_TRAINER_ELEMENTAL2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_ELEMENTAL, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 7870: //Caryssia Moonhunter
- case 7871: //Se'Jib
+ case N_TRAINER_TRIBAL1:
+ case N_TRAINER_TRIBAL2:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_TRIBAL, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_LEATHER_SPEC, DoMedUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -1030,19 +1076,19 @@ public:
{
switch (creature->GetEntry())
{
- case 22213: //Gidge Spellweaver
+ case N_TRAINER_SPELLFIRE:
if (!HasTailorSpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 1);
if (player->HasSpell(S_SPELLFIRE))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 4);
break;
- case 22208: //Nasmara Moonsong
+ case N_TRAINER_MOONCLOTH:
if (!HasTailorSpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 2);
if (player->HasSpell(S_MOONCLOTH))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_UNLEARN, GOSSIP_ACTION_INFO_DEF + 5);
break;
- case 22212: //Andrion Darkspinner
+ case N_TRAINER_SHADOWEAVE:
if (!HasTailorSpell(player))
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_LEARN, GOSSIP_ACTION_INFO_DEF + 3);
if (player->HasSpell(S_SHADOWEAVE))
@@ -1095,17 +1141,17 @@ public:
{
switch (creature->GetEntry())
{
- case 22213:
+ case N_TRAINER_SPELLFIRE:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 22208:
+ case N_TRAINER_MOONCLOTH:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 22212:
+ case N_TRAINER_SHADOWEAVE:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_LEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, action);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
@@ -1120,17 +1166,17 @@ public:
{
switch (creature->GetEntry())
{
- case 22213: //Gidge Spellweaver
+ case N_TRAINER_SPELLFIRE:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SPELLFIRE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 22208: //Nasmara Moonsong
+ case N_TRAINER_MOONCLOTH:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_MOONCLOTH, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
break;
- case 22212: //Andrion Darkspinner
+ case N_TRAINER_SHADOWEAVE:
player->ADD_GOSSIP_ITEM_EXTENDED(0, GOSSIP_UNLEARN_SHADOWEAVE, GOSSIP_SENDER_CHECK, action, BOX_UNLEARN_TAILOR_SPEC, DoHighUnlearnCost(player), false);
//unknown textID ()
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
diff --git a/src/server/scripts/World/npcs_special.cpp b/src/server/scripts/World/npcs_special.cpp
index e72e094ea06..964e69874c3 100644
--- a/src/server/scripts/World/npcs_special.cpp
+++ b/src/server/scripts/World/npcs_special.cpp
@@ -1422,6 +1422,7 @@ public:
void Reset() override
{
+ // TODO: solve this in a different way! setting them as stunned prevents dummies from parrying
me->SetControlled(true, UNIT_STATE_STUNNED);//disable rotate
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);//imune to knock aways like blast wave
diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp
index 347d3dfab5b..c50140adc34 100644
--- a/src/server/shared/DataStores/DB2StorageLoader.cpp
+++ b/src/server/shared/DataStores/DB2StorageLoader.cpp
@@ -169,9 +169,11 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
for (uint32 i = 1; i < fieldCount; i++)
{
fieldsOffset[i] = fieldsOffset[i - 1];
- if (fmt[i - 1] == 'b')
+ if (fmt[i - 1] == FT_BYTE) // byte fields
fieldsOffset[i] += 1;
- else
+ else if (fmt[i - 1] == FT_LONG)
+ fieldsOffset[i] += 8;
+ else // 4 byte fields (int32/float/strings)
fieldsOffset[i] += 4;
}
diff --git a/src/server/worldserver/CommandLine/CliRunnable.cpp b/src/server/worldserver/CommandLine/CliRunnable.cpp
index 6e961922b0e..ff55a181f71 100644
--- a/src/server/worldserver/CommandLine/CliRunnable.cpp
+++ b/src/server/worldserver/CommandLine/CliRunnable.cpp
@@ -41,9 +41,9 @@
char* command_finder(const char* text, int state)
{
- static int idx, len;
+ static size_t idx, len;
const char* ret;
- ChatCommand* cmd = ChatHandler::getCommandTable();
+ std::vector<ChatCommand> const& cmd = ChatHandler::getCommandTable();
if (!state)
{
@@ -51,20 +51,19 @@ char* command_finder(const char* text, int state)
len = strlen(text);
}
- while ((ret = cmd[idx].Name))
+ while (idx < cmd.size())
{
+ ret = cmd[idx].Name;
if (!cmd[idx].AllowConsole)
{
- idx++;
+ ++idx;
continue;
}
- idx++;
+ ++idx;
//printf("Checking %s \n", cmd[idx].Name);
if (strncmp(ret, text, len) == 0)
return strdup(ret);
- if (cmd[idx].Name == NULL)
- break;
}
return ((char*)NULL);
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 65daf1480ca..23e7c20a966 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1143,11 +1143,11 @@ FeatureSystem.CharacterUndelete.Cooldown = 2592000
# DATABASE_WORLD = 4, // World database
# DATABASE_HOTFIX = 8, // Hotfixes database
#
-# Default: 0 - (All Disabled)
+# Default: 15 - (All enabled)
# 4 - (Enable world only)
-# 15 - (All enabled)
+# 0 - (All Disabled)
-Updates.EnableDatabases = 0
+Updates.EnableDatabases = 15
#
# Updates.SourcePath
@@ -2250,6 +2250,7 @@ Battleground.StoreStatistics.Enable = 0
# Don't bother with balance)
# 1 - (Experimental, Don't allow to invite much more players
# of one faction)
+# 2 - (Experimental, Try to have even teams)
Battleground.InvitationType = 0
@@ -2659,6 +2660,14 @@ PlayerStart.MapsExplored = 0
HonorPointsAfterDuel = 0
#
+# ResetDuelCooldowns
+# Description: Reset all cooldowns before duel starts and restore them when duel ends.
+# Default: 0 - (Disabled)
+# 1 - (Enabled)
+
+ResetDuelCooldowns = 0
+
+#
# AlwaysMaxWeaponSkill
# Description: Players will automatically gain max weapon/defense skill when logging in,
# or leveling.
diff --git a/src/tools/connection_patcher/Patches/Mac.hpp b/src/tools/connection_patcher/Patches/Mac.hpp
index 89ef83459b1..17d61df9930 100644
--- a/src/tools/connection_patcher/Patches/Mac.hpp
+++ b/src/tools/connection_patcher/Patches/Mac.hpp
@@ -31,7 +31,7 @@ namespace Connection_Patcher
{
static const std::vector<unsigned char> BNet () { return { 0xB8, 0xD5, 0xF8, 0x7F, 0x82, 0x89, 0x47, 0x0C, 0x5D, 0xC3, 0x90, 0x90, 0x90 }; }
static const std::vector<unsigned char> Password () { return { 0x0F, 0x85 }; }
- static const std::vector<unsigned char> Signature() { return { 0x41, 0xB6, 0x01, 0x41, 0xBF, 0x02, 0x00, 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; }
+ static const std::vector<unsigned char> Signature() { return { 0x41, 0xBC, 0x02, 0x00, 0x00, 0x00, 0x41, 0xB6, 0x01, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }; }
};
};
}
diff --git a/src/tools/connection_patcher/Patterns/Mac.hpp b/src/tools/connection_patcher/Patterns/Mac.hpp
index b8ffc883dd4..feeaebd2f5a 100644
--- a/src/tools/connection_patcher/Patterns/Mac.hpp
+++ b/src/tools/connection_patcher/Patterns/Mac.hpp
@@ -31,7 +31,7 @@ namespace Connection_Patcher
{
static const std::vector<unsigned char> BNet () { return { 0x8B, 0x06, 0x89, 0x47, 0x0C, 0x5D, 0xC3 }; }
static const std::vector<unsigned char> Password () { return { 0x0F, 0x84, 0x00, 0xFF, 0xFF, 0xFF, 0x49, 0x8B, 0x45, 0x00, 0xB9, 0x40 }; }
- static const std::vector<unsigned char> Signature() { return { 0x45, 0x31, 0xF6, 0x31, 0xF6, 0x31, 0xD2, 0x4C, 0x89, 0xE7, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x41, 0xBF, 0x04, 0x00, 0x00, 0x00 }; }
+ static const std::vector<unsigned char> Signature() { return { 0x45, 0x31, 0xF6, 0x31, 0xF6, 0x31, 0xD2, 0x48, 0x89, 0xDF, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x41, 0xBC, 0x04, 0x00, 0x00, 0x00 }; }
};
};
}
diff --git a/src/tools/mmaps_generator/VMapExtensions.cpp b/src/tools/mmaps_generator/VMapExtensions.cpp
deleted file mode 100644
index 63c8e524542..00000000000
--- a/src/tools/mmaps_generator/VMapExtensions.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <vector>
-#include "MapTree.h"
-#include "VMapManager2.h"
-#include "WorldModel.h"
-#include "ModelInstance.h"
-
-namespace VMAP
-{
- // Need direct access to encapsulated VMAP data, so we add functions for MMAP generator
- // maybe add MapBuilder as friend to all of the below classes would be better?
-
- // declared in src/shared/vmap/MapTree.h
- void StaticMapTree::getModelInstances(ModelInstance* &models, uint32 &count)
- {
- models = iTreeValues;
- count = iNTreeValues;
- }
-
- // declared in src/shared/vmap/VMapManager2.h
- void VMapManager2::getInstanceMapTree(InstanceTreeMap &instanceMapTree)
- {
- instanceMapTree = iInstanceMapTrees;
- }
-
- // declared in src/shared/vmap/WorldModel.h
- void WorldModel::getGroupModels(std::vector<GroupModel> &groupModels)
- {
- groupModels = this->groupModels;
- }
-
- // declared in src/shared/vmap/WorldModel.h
- void GroupModel::getMeshData(std::vector<G3D::Vector3> &vertices, std::vector<MeshTriangle> &triangles, WmoLiquid* &liquid)
- {
- vertices = this->vertices;
- triangles = this->triangles;
- liquid = iLiquid;
- }
-
- // declared in src/shared/vmap/ModelInstance.h
- WorldModel* ModelInstance::getWorldModel()
- {
- return iModel;
- }
-
- // declared in src/shared/vmap/WorldModel.h
- void WmoLiquid::getPosInfo(uint32 &tilesX, uint32 &tilesY, G3D::Vector3 &corner) const
- {
- tilesX = iTilesX;
- tilesY = iTilesY;
- corner = iCorner;
- }
-}