diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp | 446 | ||||
-rw-r--r-- | src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp | 2 |
2 files changed, 287 insertions, 161 deletions
diff --git a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp index a720873e9d8..f80677350e6 100644 --- a/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp +++ b/src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp @@ -15,84 +15,98 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Mother_Shahraz -SD%Complete: 80 -SDComment: Fatal Attraction slightly incorrect; need to damage only if affected players are within range of each other -SDCategory: Black Temple -EndScriptData */ #include "ScriptMgr.h" #include "black_temple.h" #include "Containers.h" #include "ObjectAccessor.h" #include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" +#include "GridNotifiers.h" enum Texts { - //Speech'n'Sounds - SAY_TAUNT = 0, - SAY_AGGRO = 1, - SAY_SPELL = 2, - SAY_SLAY = 3, - SAY_ENRAGE = 4, - SAY_DEATH = 5 + SAY_TAUNT = 0, + SAY_AGGRO = 1, + SAY_SPELL = 2, + SAY_SLAY = 3, + SAY_ENRAGE = 4, + SAY_DEATH = 5, + EMOTE_ENRAGE = 6, + EMOTE_BERSERK = 7 }; enum Spells { - SPELL_BEAM_SINISTER = 40859, - SPELL_BEAM_VILE = 40860, - SPELL_BEAM_WICKED = 40861, - SPELL_BEAM_SINFUL = 40827, - SPELL_ATTRACTION = 40871, - SPELL_SILENCING_SHRIEK = 40823, - SPELL_ENRAGE = 23537, - SPELL_SABER_LASH = 40810, //43267 - SPELL_SABER_LASH_IMM = 43690, - SPELL_TELEPORT_VISUAL = 40869, - SPELL_BERSERK = 45078 + SPELL_FATAL_ATTRACTION_DAMAGE = 40871, + SPELL_SILENCING_SHRIEK = 40823, + SPELL_SABER_LASH_IMMUNITY = 43690, + SPELL_FATAL_ATTACTION_TELEPORT = 40869, + SPELL_BERSERK = 45078, + SPELL_FATAL_ATTRACTION = 41001, + SPELL_SINISTER_PERIODIC = 40863, + SPELL_VILE_PERIODIC = 40865, + SPELL_RANDOM_PERIODIC = 40867, + SPELL_WICKED_PERIODIC = 40866, + SPELL_SINFUL_PERIODIC = 40862, + SPELL_PRISMATIC_AURA_SHADOW = 40880, + SPELL_PRISMATIC_AURA_FIRE = 40882, + SPELL_PRISMATIC_AURA_NATURE = 40883, + SPELL_PRISMATIC_AURA_ARCANE = 40891, + SPELL_PRISMATIC_AURA_FROST = 40896, + SPELL_PRISMATIC_AURA_HOLY = 40897, + SPELL_BEAM_SINISTER = 40859, + SPELL_BEAM_VILE = 40860, + SPELL_BEAM_WICKED = 40861, + SPELL_BEAM_SINFUL = 40827 }; enum Events { - EVENT_RANDOM_BEAM = 1, + EVENT_RANDOM_BEAM = 1, EVENT_PRISMATIC_SHIELD, EVENT_FATAL_ATTRACTION, - EVENT_FATAL_ATTRACTION_EXPLOSION, - EVENT_SABER_SLASH, EVENT_SILENCING_SHRIEK, - EVENT_RANDOM_TAUNT, + EVENT_TAUNT, EVENT_BERSERK }; -enum Beams +uint32 const BeamTriggers[4] = { - SINISTER_BEAM, - VILE_BEAM, - WICKED_BEAM, - SINFUL_BEAM + SPELL_SINISTER_PERIODIC, + SPELL_VILE_PERIODIC, + SPELL_WICKED_PERIODIC, + SPELL_SINFUL_PERIODIC }; -uint32 PrismaticAuras[]= +uint32 const RandomBeam[4] = { - 40880, // Shadow - 40882, // Fire - 40883, // Nature - 40891, // Arcane - 40896, // Frost - 40897, // Holy + SPELL_BEAM_SINISTER, + SPELL_BEAM_VILE, + SPELL_BEAM_WICKED, + SPELL_BEAM_SINFUL }; -Position const TeleportPoint[]= +uint32 const PrismaticAuras[6]= { - {959.996f, 212.576f, 193.843f}, - {932.537f, 231.813f, 193.838f}, - {958.675f, 254.767f, 193.822f}, - {946.955f, 201.316f, 192.535f}, - {944.294f, 149.676f, 197.551f}, - {930.548f, 284.888f, 193.367f}, - {965.997f, 278.398f, 195.777f} + SPELL_PRISMATIC_AURA_SHADOW, + SPELL_PRISMATIC_AURA_FIRE, + SPELL_PRISMATIC_AURA_NATURE, + SPELL_PRISMATIC_AURA_ARCANE, + SPELL_PRISMATIC_AURA_FROST, + SPELL_PRISMATIC_AURA_HOLY +}; + +Position const TeleportPoint[7]= +{ + { 959.996f, 212.576f, 193.843f }, + { 932.537f, 231.813f, 193.838f }, + { 958.675f, 254.767f, 193.822f }, + { 946.955f, 201.316f, 192.535f }, + { 944.294f, 149.676f, 197.551f }, + { 930.548f, 284.888f, 193.367f }, + { 965.997f, 278.398f, 195.777f } }; class boss_mother_shahraz : public CreatureScript @@ -102,45 +116,30 @@ public: struct boss_shahrazAI : public BossAI { - boss_shahrazAI(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ) - { - Initialize(); - } - - void Initialize() - { - for (uint8 i = 0; i < 3; ++i) - TargetGUID[i].Clear(); - - BeamCount = 0; - CurrentBeam = SINISTER_BEAM; // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful - ExplosionCount = 0; - Enraged = false; - } + boss_shahrazAI(Creature* creature) : BossAI(creature, DATA_MOTHER_SHAHRAZ), _enraged(false) { } void Reset() override { - Initialize(); _Reset(); + _enraged = false; } void EnterCombat(Unit* /*who*/) override { _EnterCombat(); - events.ScheduleEvent(EVENT_RANDOM_BEAM, 20000); // Timers may be incorrect - events.ScheduleEvent(EVENT_FATAL_ATTRACTION, 60000); - events.ScheduleEvent(EVENT_FATAL_ATTRACTION_EXPLOSION, 70000); - events.ScheduleEvent(EVENT_SILENCING_SHRIEK, 30000); - events.ScheduleEvent(EVENT_SABER_SLASH, 35000); - events.ScheduleEvent(EVENT_RANDOM_TAUNT, urand(70000, 111000)); - events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, 1000); - events.ScheduleEvent(EVENT_BERSERK, 600000); Talk(SAY_AGGRO); + events.ScheduleEvent(EVENT_SILENCING_SHRIEK, Seconds(22)); + events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, Seconds(15)); + events.ScheduleEvent(EVENT_FATAL_ATTRACTION, Seconds(35)); + events.ScheduleEvent(EVENT_RANDOM_BEAM, Seconds(6)); + events.ScheduleEvent(EVENT_BERSERK, Minutes(10)); + events.ScheduleEvent(EVENT_TAUNT, Seconds(35)); } - void KilledUnit(Unit* /*victim*/) override + void KilledUnit(Unit* victim) override { - Talk(SAY_SLAY); + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); } void JustDied(Unit* /*killer*/) override @@ -149,30 +148,18 @@ public: Talk(SAY_DEATH); } - void TeleportPlayers() + void EnterEvadeMode(EvadeReason /*why*/) override { - Position const& random = Trinity::Containers::SelectRandomContainerElement(TeleportPoint); - float X = random.GetPositionX(); - float Y = random.GetPositionY(); - float Z = random.GetPositionZ(); - for (uint8 i = 0; i < 3; ++i) - { - if (Unit* unit = SelectTarget(SELECT_TARGET_RANDOM, 1)) - if (unit->IsAlive() && unit->GetTypeId() == TYPEID_PLAYER) - { - TargetGUID[i] = unit->GetGUID(); - unit->CastSpell(unit, SPELL_TELEPORT_VISUAL, true); - DoTeleportPlayer(unit, X, Y, Z, unit->GetOrientation()); - } - } + _DespawnAtEvade(); } void DamageTaken(Unit* /*attacker*/, uint32 &damage) override { - if (!Enraged && me->HealthBelowPctDamaged(10, damage)) + if (!_enraged && me->HealthBelowPctDamaged(10, damage)) { - Enraged = true; - DoCast(me, SPELL_ENRAGE, true); + _enraged = true; + DoCastSelf(SPELL_RANDOM_PERIODIC, true); + Talk(EMOTE_ENRAGE, me); Talk(SAY_ENRAGE); } } @@ -182,81 +169,29 @@ public: switch (eventId) { case EVENT_RANDOM_BEAM: - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - switch (CurrentBeam) - { - case SINISTER_BEAM: - DoCast(target, SPELL_BEAM_SINISTER); - break; - case VILE_BEAM: - DoCast(target, SPELL_BEAM_VILE); - break; - case WICKED_BEAM: - DoCast(target, SPELL_BEAM_WICKED); - break; - case SINFUL_BEAM: - DoCast(target, SPELL_BEAM_SINFUL); - break; - default: - break; - } - - ++BeamCount; - uint32 Beam = CurrentBeam; - if (BeamCount > 3) - while (CurrentBeam == Beam) - CurrentBeam = urand(0, 3); - } - events.ScheduleEvent(EVENT_RANDOM_BEAM, 9000); + DoCastSelf(BeamTriggers[urand(0, 3)]); + events.Repeat(Seconds(30)); break; case EVENT_PRISMATIC_SHIELD: - // Random Prismatic Shield every 15 seconds. - DoCast(me, PrismaticAuras[urand(0, 5)]); - events.ScheduleEvent(EVENT_PRISMATIC_SHIELD, 15000); + DoCastSelf(PrismaticAuras[urand(0, 5)]); + events.Repeat(Seconds(15)); break; case EVENT_FATAL_ATTRACTION: - // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other. - ExplosionCount = 0; - TeleportPlayers(); Talk(SAY_SPELL); - events.ScheduleEvent(EVENT_FATAL_ATTRACTION_EXPLOSION, 2000); - events.ScheduleEvent(EVENT_FATAL_ATTRACTION, 40000, 71000); - break; - case EVENT_FATAL_ATTRACTION_EXPLOSION: - // Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later. - if (ExplosionCount < 3) - { - for (uint8 i = 0; i < 3; ++i) - { - if (!TargetGUID[i].IsEmpty()) - { - if (Unit* unit = ObjectAccessor::GetUnit(*me, TargetGUID[i])) - unit->CastSpell(unit, SPELL_ATTRACTION, true); - TargetGUID[i].Clear(); - } - } - ++ExplosionCount; - } - else - ExplosionCount = 0; - events.ScheduleEvent(EVENT_FATAL_ATTRACTION_EXPLOSION, ExplosionCount < 3 ? 1000 : events.GetTimeUntilEvent(EVENT_FATAL_ATTRACTION) + 2000); + me->CastCustomSpell(SPELL_FATAL_ATTACTION_TELEPORT, SPELLVALUE_MAX_TARGETS, 3, me); + events.Repeat(Seconds(30)); break; case EVENT_SILENCING_SHRIEK: DoCastVictim(SPELL_SILENCING_SHRIEK); - events.ScheduleEvent(EVENT_SILENCING_SHRIEK, urand(25000, 35000)); - break; - case EVENT_SABER_SLASH: - DoCastVictim(SPELL_SABER_LASH); - events.ScheduleEvent(EVENT_SABER_SLASH, urand(25000, 35000)); + events.Repeat(Seconds(18), Seconds(30)); break; - case EVENT_RANDOM_TAUNT: + case EVENT_TAUNT: Talk(SAY_TAUNT); - events.ScheduleEvent(EVENT_RANDOM_TAUNT, urand(60000, 151000)); + events.Repeat(Seconds(30), Seconds(40)); break; case EVENT_BERSERK: - DoCast(me, SPELL_BERSERK); - Talk(SAY_ENRAGE); + Talk(EMOTE_BERSERK, me); + DoCastSelf(SPELL_BERSERK); break; default: break; @@ -264,11 +199,7 @@ public: } private: - ObjectGuid TargetGUID[3]; - uint32 BeamCount; - uint32 CurrentBeam; - uint32 ExplosionCount; - bool Enraged; + bool _enraged; }; CreatureAI* GetAI(Creature* creature) const override @@ -277,7 +208,202 @@ public: } }; +// 40869 - Fatal Attraction +class spell_mother_shahraz_fatal_attraction : public SpellScriptLoader +{ + public: + spell_mother_shahraz_fatal_attraction() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction") { } + + class spell_mother_shahraz_fatal_attraction_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mother_shahraz_fatal_attraction_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_SABER_LASH_IMMUNITY, SPELL_FATAL_ATTRACTION }); + } + + void FilterTargets(std::list<WorldObject*>& targets) + { + targets.remove_if(Trinity::UnitAuraCheck(true, SPELL_SABER_LASH_IMMUNITY)); + } + + void SetDest(SpellDestination& dest) + { + dest.Relocate(TeleportPoint[urand(0, 6)]); + } + + void HandleTeleport(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetHitUnit(), SPELL_FATAL_ATTRACTION, true); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::FilterTargets, EFFECT_ALL, TARGET_UNIT_SRC_AREA_ENEMY); + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_mother_shahraz_fatal_attraction_SpellScript::SetDest, EFFECT_1, TARGET_DEST_CASTER_RANDOM); + OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_SpellScript::HandleTeleport, EFFECT_1, SPELL_EFFECT_TELEPORT_UNITS); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mother_shahraz_fatal_attraction_SpellScript(); + } +}; + +// 40870 - Fatal Attraction Dummy Visual +class spell_mother_shahraz_fatal_attraction_link : public SpellScriptLoader +{ + public: + spell_mother_shahraz_fatal_attraction_link() : SpellScriptLoader("spell_mother_shahraz_fatal_attraction_link") { } + + class spell_mother_shahraz_fatal_attraction_link_SpellScript : public SpellScript + { + PrepareSpellScript(spell_mother_shahraz_fatal_attraction_link_SpellScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_FATAL_ATTRACTION_DAMAGE }); + } + + void HandleDummy(SpellEffIndex /*effIndex*/) + { + GetCaster()->CastSpell(GetCaster(), SPELL_FATAL_ATTRACTION_DAMAGE, true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_mother_shahraz_fatal_attraction_link_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const override + { + return new spell_mother_shahraz_fatal_attraction_link_SpellScript(); + } +}; + +// 40816 - Saber Lash +class spell_mother_shahraz_saber_lash : public SpellScriptLoader +{ + public: + spell_mother_shahraz_saber_lash() : SpellScriptLoader("spell_mother_shahraz_saber_lash") { } + + class spell_mother_shahraz_saber_lash_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mother_shahraz_saber_lash_AuraScript); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_1)->TriggerSpell }); + } + + void OnTrigger(AuraEffect const* aurEff) + { + PreventDefaultAction(); + + uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell; + if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + GetUnitOwner()->CastSpell(target, triggerSpell, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_saber_lash_AuraScript::OnTrigger, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mother_shahraz_saber_lash_AuraScript(); + } +}; + +/* 40863 - Sinister Periodic + 40865 - Vile Periodic + 40866 - Wicked Periodic + 40862 - Sinful Periodic */ +class spell_mother_shahraz_generic_periodic : public SpellScriptLoader +{ + public: + spell_mother_shahraz_generic_periodic() : SpellScriptLoader("spell_mother_shahraz_generic_periodic") { } + + class spell_mother_shahraz_generic_periodic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mother_shahraz_generic_periodic_AuraScript); + + bool Validate(SpellInfo const* spellInfo) override + { + return ValidateSpellInfo({ spellInfo->GetEffect(EFFECT_0)->TriggerSpell }); + } + + void OnTrigger(AuraEffect const* aurEff) + { + PreventDefaultAction(); + + uint32 triggerSpell = GetSpellInfo()->GetEffect(aurEff->GetEffIndex())->TriggerSpell; + if (Unit* target = GetUnitOwner()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0)) + GetUnitOwner()->CastSpell(target, triggerSpell, true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_generic_periodic_AuraScript::OnTrigger, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mother_shahraz_generic_periodic_AuraScript(); + } +}; + +// 40867 - Random Periodic +class spell_mother_shahraz_random_periodic : public SpellScriptLoader +{ + public: + spell_mother_shahraz_random_periodic() : SpellScriptLoader("spell_mother_shahraz_random_periodic") { } + + class spell_mother_shahraz_random_periodic_AuraScript : public AuraScript + { + PrepareAuraScript(spell_mother_shahraz_random_periodic_AuraScript); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_BEAM_SINISTER, + SPELL_BEAM_VILE, + SPELL_BEAM_WICKED, + SPELL_BEAM_SINFUL + }); + } + + void OnPeriodic(AuraEffect const* /*aurEffect*/) + { + PreventDefaultAction(); + GetUnitOwner()->CastSpell(GetUnitOwner(), RandomBeam[urand(0, 3)], true); + } + + void Register() override + { + OnEffectPeriodic += AuraEffectPeriodicFn(spell_mother_shahraz_random_periodic_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); + } + }; + + AuraScript* GetAuraScript() const override + { + return new spell_mother_shahraz_random_periodic_AuraScript(); + } +}; + void AddSC_boss_mother_shahraz() { new boss_mother_shahraz(); + new spell_mother_shahraz_fatal_attraction(); + new spell_mother_shahraz_fatal_attraction_link(); + new spell_mother_shahraz_saber_lash(); + new spell_mother_shahraz_generic_periodic(); + new spell_mother_shahraz_random_periodic(); } diff --git a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp index e2dcc71114e..4d4bc26cecd 100644 --- a/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp +++ b/src/server/scripts/Outland/BlackTemple/instance_black_temple.cpp @@ -51,7 +51,7 @@ BossBoundaryData const boundaries = { DATA_GURTOGG_BLOODBOIL, new RectangleBoundary(720.5f, 864.5f, 159.3f, 316.0f) }, { DATA_RELIQUARY_OF_SOULS, new RectangleBoundary(435.9f, 660.3f, 21.2f, 229.6f) }, { DATA_RELIQUARY_OF_SOULS, new ZRangeBoundary(81.8f, 148.0f) }, - { DATA_MOTHER_SHAHRAZ, new RectangleBoundary(903.4f, 982.1f, 92.4f, 476.7f) }, + { DATA_MOTHER_SHAHRAZ, new RectangleBoundary(903.4f, 982.1f, 92.4f, 313.2f) }, { DATA_ILLIDARI_COUNCIL, new EllipseBoundary(Position(696.6f, 305.0f), 70.0 , 85.0) }, { DATA_ILLIDAN_STORMRAGE, new EllipseBoundary(Position(694.8f, 309.0f), 70.0 , 85.0) } }; |