diff --git a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp index 7b40c1f81a..2eba83b899 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_blackheart_the_inciter.cpp @@ -25,6 +25,7 @@ EndScriptData */ #include "shadow_labyrinth.h" #include "AI/ScriptDevAI/base/CombatAI.h" #include "Spells/Scripts/SpellScript.h" +#include "World/WorldStateDefines.h" enum { @@ -105,6 +106,9 @@ struct boss_blackheart_the_inciterAI : public CombatAI case 1: DoBroadcastText(SAY_AGGRO_2, m_creature); break; } + m_creature->GetMap()->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_ASSASIN_01, 0); + m_creature->GetMap()->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_ASSASIN_02, 0); + if (m_instance) m_instance->SetData(TYPE_INCITER, IN_PROGRESS); } diff --git a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp index e97523a8fd..58ecbda5c7 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/boss_murmur.cpp @@ -16,7 +16,7 @@ /* ScriptData SDName: Boss_Murmur -SD%Complete: 75 +SD%Complete: 90 SDComment: Sonic Boom and Murmur's Touch require additional research and core support SDCategory: Auchindoun, Shadow Labyrinth EndScriptData */ @@ -48,24 +48,27 @@ enum enum MurmurActions { MURMUR_ACTION_MAX, + // After door opens 2 Cabal Spellbinder run out of the room, both get killed from murmur individually + MURMUR_INTRO_KILL_01, + MURMUR_INTRO_KILL_02, + // Random cast of Suppresion Blast or Murmurs Wrath MURMUR_OOC_RP_ATTACK, - MURMUR_OOC_CASTER_ATTACK }; struct boss_murmurAI : public CombatAI { boss_murmurAI(Creature* creature) : CombatAI(creature, MURMUR_ACTION_MAX), - m_instance(static_cast(creature->GetInstanceData())), m_bIsRegularMode(creature->GetMap()->IsRegularDifficulty()) + m_instance(static_cast(creature->GetInstanceData())), m_bIsRegularMode(creature->GetMap()->IsRegularDifficulty()), + m_firstCast(false) { + AddCustomAction(MURMUR_INTRO_KILL_01, true, [&]() { HandleIntroKill01(); }, TIMER_COMBAT_OOC); + AddCustomAction(MURMUR_INTRO_KILL_02, true, [&]() { HandleIntroKill02(); }, TIMER_COMBAT_OOC); AddCustomAction(MURMUR_OOC_RP_ATTACK, true, [&]() { HandleOocAttack(); }, TIMER_COMBAT_OOC); - AddCustomAction(MURMUR_OOC_CASTER_ATTACK, true, [&]() { HandleOocCasterAttack(); }, TIMER_COMBAT_OOC); } ScriptedInstance* m_instance; bool m_bIsRegularMode; - - GuidVector spellbindersVector; - GuidVector summonersVector; + bool m_firstCast; uint32 m_uiResonanceTimer; uint32 m_uiThunderingStormTimer; @@ -83,10 +86,33 @@ struct boss_murmurAI : public CombatAI { if (eventType == AI_EVENT_CUSTOM_A) { - ResetTimer(MURMUR_OOC_CASTER_ATTACK, urand(8000, 10000)); - ResetTimer(MURMUR_OOC_RP_ATTACK, urand(8000, 10000)); - m_instance->GetCreatureGuidVectorFromStorage(NPC_CABAL_SPELLBINDER, spellbindersVector); - m_instance->GetCreatureGuidVectorFromStorage(NPC_CABAL_SUMMONER, summonersVector); + // Murmur can cast Supression Blast first after door opens + // resulting in a higher timer to kill the 2 Spellbinders that run out of the room + ResetTimer(MURMUR_INTRO_KILL_01, urand(0, 5000)); + ResetTimer(MURMUR_INTRO_KILL_02, urand(0, 5000)); + // Murmur can start casting Supression Blast pretty fast after door opens + ResetTimer(MURMUR_OOC_RP_ATTACK, urand(0, 3000)); + } + } + + // After door opens 2 Cabal Spellbinder run out of the room, both get killed from murmur individually + void HandleIntroKill01() + { + std::vector const* killTarget = m_creature->GetMap()->GetCreatures(MURMURS_WRATH_TARGETS_01); + if (killTarget) + { + for (Creature* creature : *killTarget) + DoCastSpellIfCan(creature, SPELL_MURMURS_WRATH); + } + } + + void HandleIntroKill02() + { + std::vector const* killTarget = m_creature->GetMap()->GetCreatures(MURMURS_WRATH_TARGETS_02); + if (killTarget) + { + for (Creature* creature : *killTarget) + DoCastSpellIfCan(creature, SPELL_MURMURS_WRATH); } } @@ -95,71 +121,43 @@ struct boss_murmurAI : public CombatAI if (m_creature->IsInCombat()) return; - // kill one that's moving - if (urand(0, 1)) + // First cast after door opens should always be a Suprression Blast + if (!m_firstCast) { - GuidVector moversVector; - for (ObjectGuid& guid : spellbindersVector) - { - if (Creature* creature = m_creature->GetMap()->GetCreature(guid)) - { - if (creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - moversVector.push_back(guid); - } - } - } - for (ObjectGuid& guid : summonersVector) + DoCastSpellIfCan(nullptr, SPELL_SUPPRESSION_BLAST); + m_firstCast = true; + } + else + { + // Kill a moving target + if (urand(0, 1)) { - if (Creature* creature = m_creature->GetMap()->GetCreature(guid)) + GuidVector WrathTargetGuid; + std::vector const* WrathTarget = m_creature->GetMap()->GetCreatures(MURMURS_WRATH_TARGETS_03); + if (WrathTarget) { - if (creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) - { - moversVector.push_back(guid); - } + for (Creature* creature : *WrathTarget) + if(creature->IsAlive() && !creature->IsInCombat()) + WrathTargetGuid.push_back(creature->GetObjectGuid()); } - } - if (moversVector.size() > 0) - { - if (ObjectGuid& guid = moversVector[urand(0, moversVector.size() - 1)]) + + if (WrathTargetGuid.size() > 0) { + ObjectGuid guid = WrathTargetGuid[urand(0, WrathTargetGuid.size() - 1)]; if (Creature* creature = m_creature->GetMap()->GetCreature(guid)) { DoCastSpellIfCan(creature, SPELL_MURMURS_WRATH); - } + } } } + // stun 5 targets + else + DoCastSpellIfCan(nullptr, SPELL_SUPPRESSION_BLAST); } - // stun 5 targets - else - DoCastSpellIfCan(nullptr, SPELL_SUPPRESSION_BLAST); ResetTimer(MURMUR_OOC_RP_ATTACK, 3000); } - void HandleOocCasterAttack() - { - if (m_creature->IsInCombat()) - return; - - for (ObjectGuid& guid : spellbindersVector) - { - if (Creature* creature = m_creature->GetMap()->GetCreature(guid)) - { - m_creature->AI()->SendAIEvent(AI_EVENT_CUSTOM_EVENTAI_A, m_creature, creature); - } - } - for (ObjectGuid& guid : summonersVector) - { - if (Creature* creature = m_creature->GetMap()->GetCreature(guid)) - { - m_creature->AI()->SendAIEvent(AI_EVENT_CUSTOM_EVENTAI_A, m_creature, creature); - } - } - - ResetTimer(MURMUR_OOC_CASTER_ATTACK, urand(3000, 8000)); - } - void OnSpellCast(SpellEntry const* spellInfo, Unit* /*target*/) override { if (spellInfo->Id == SPELL_SONIC_BOOM || spellInfo->Id == SPELL_SONIC_BOOM_H) diff --git a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.cpp b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.cpp index 93e2a22605..332d269828 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.cpp +++ b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.cpp @@ -189,6 +189,57 @@ void instance_shadow_labyrinth::OnCreatureRespawn(Creature* creature) } } +// The Screaming Hall +// All Worldstates get Activated via database when door opens +void instance_shadow_labyrinth::OnCreatureGroupDespawn(CreatureGroup* group, Creature* /*pCreature*/) +{ + + switch (group->GetGroupId()) + { + // Blackheart the Inciter room + // All groups have a chance to spawn assasins + case SL_BLACKHEAT_GROUP_01: + case SL_BLACKHEAT_GROUP_02: + case SL_BLACKHEAT_GROUP_03: + case SL_BLACKHEAT_GROUP_04: + case SL_BLACKHEAT_GROUP_05: + case SL_BLACKHEAT_GROUP_06: + case SL_BLACKHEAT_GROUP_07: + case SL_BLACKHEAT_GROUP_08: + case SL_BLACKHEAT_GROUP_09: + case SL_BLACKHEAT_GROUP_10: + case SL_BLACKHEAT_GROUP_11: + case SL_BLACKHEAT_GROUP_12: + { + switch (urand(0, 5)) + { + case 0: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_ASSASIN_01, 1); + } + + switch (urand(0, 5)) + { + case 0: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_ASSASIN_02, 1); + } + break; + } + // Murmur Room + case SL_SPAWN_GROUP_043: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_GROUP_49, 0); + break; + case SL_SPAWN_GROUP_044: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_GROUP_50, 0); + break; + case SL_SPAWN_GROUP_045: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_GROUP_51, 0); + break; + case SL_SPAWN_GROUP_046: + instance->GetVariableManager().SetVariable(WORLD_STATE_SHADOW_LAB_GROUP_52, 0); + break; + } +} + void instance_shadow_labyrinth::Load(const char* chrIn) { if (!chrIn) diff --git a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h index 7378eba946..6bcff19d60 100644 --- a/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h +++ b/src/game/AI/ScriptDevAI/scripts/outland/auchindoun/shadow_labyrinth/shadow_labyrinth.h @@ -32,8 +32,33 @@ enum SPELL_BANISH = 30231, // spell is handled in creature_template_addon; SPELL_SHAPE_OF_BEAST = 33949, + + // Blackheart the Inciter + SL_BLACKHEAT_GROUP_01 = 5550030, + SL_BLACKHEAT_GROUP_02 = 5550031, + SL_BLACKHEAT_GROUP_03 = 5550032, + SL_BLACKHEAT_GROUP_04 = 5550033, + SL_BLACKHEAT_GROUP_05 = 5550034, + SL_BLACKHEAT_GROUP_06 = 5550035, + SL_BLACKHEAT_GROUP_07 = 5550036, + SL_BLACKHEAT_GROUP_08 = 5550037, + SL_BLACKHEAT_GROUP_09 = 5550038, + SL_BLACKHEAT_GROUP_10 = 5550039, + SL_BLACKHEAT_GROUP_11 = 5550040, + SL_BLACKHEAT_GROUP_12 = 5550041, + SL_BLACKHEAT_GROUP_13 = 5550042, + + + SL_SPAWN_GROUP_043 = 5550064, // SpawnGroup that stops respawning of first runner + SL_SPAWN_GROUP_044 = 5550065, // SpawnGroup that stops respawning of 2nd runner + SL_SPAWN_GROUP_045 = 5550066, // SpawnGroup that stops respawning of third runner + SL_SPAWN_GROUP_046 = 5550067, // SpawnGroup that stops respawning of third runner }; +const std::string MURMURS_WRATH_TARGETS_01 = "SL_MURMUR_WRATH_TARGET_01"; +const std::string MURMURS_WRATH_TARGETS_02 = "SL_MURMUR_WRATH_TARGET_02"; +const std::string MURMURS_WRATH_TARGETS_03 = "SL_MURMUR_WRATH_TARGET_03"; + class instance_shadow_labyrinth : public ScriptedInstance { public: @@ -47,6 +72,8 @@ class instance_shadow_labyrinth : public ScriptedInstance void OnCreatureDeath(Creature* pCreature) override; void OnCreatureRespawn(Creature* creature) override; + void OnCreatureGroupDespawn(CreatureGroup* pGroup, Creature* pCreature) override; + void SetData(uint32 uiType, uint32 uiData) override; uint32 GetData(uint32 uiType) const override; diff --git a/src/game/World/WorldStateDefines.h b/src/game/World/WorldStateDefines.h index 8e7ce5be5b..b8142ccfde 100644 --- a/src/game/World/WorldStateDefines.h +++ b/src/game/World/WorldStateDefines.h @@ -382,7 +382,18 @@ enum WorldStateID : int32 WORLD_STATE_SHADOW_LAB_GROUP_35 = 5550010, // 2 Possible group versions WORLD_STATE_SHADOW_LAB_GROUP_40 = 5550011, // 2 Possible group versions WORLD_STATE_SHADOW_LAB_GROUP_41 = 5550012, // 2 Possible group versions - WORLD_STATE_SHADOW_LAB_GROUP_42 = 5550013, // 2 Possible group versions + WORLD_STATE_SHADOW_LAB_GROUP_42 = 5550013, // 2 Possible group versions + // The Screaming Hall + // Worldstates that handle the respawn of runners between the groups in Murmur room + // Activated via database when door opens, deactivated when spawn_group died + WORLD_STATE_SHADOW_LAB_GROUP_48 = 5550014, // 2 Runners that instantly die after reaching last waypoint + WORLD_STATE_SHADOW_LAB_GROUP_49 = 5550015, // First runner + WORLD_STATE_SHADOW_LAB_GROUP_50 = 5550016, // 2nd runner + WORLD_STATE_SHADOW_LAB_GROUP_51 = 5550017, // 3rd runner + WORLD_STATE_SHADOW_LAB_GROUP_52 = 5550018, // 4th and 5th runner + // Cabal Assasins + WORLD_STATE_SHADOW_LAB_ASSASIN_01 = 5550019, + WORLD_STATE_SHADOW_LAB_ASSASIN_02 = 5550020, // Sethekk Halls WORLD_STATE_SETHEKK_GROUP_12 = 5560001, // 2 Possible group versions