Core/Scripts: Mother Shahraz encounter rewrite (#18446)

This commit is contained in:
Keader authored and Aokromes committed 2016-12-28 16:04:12 +01:00
1 parent 75ad9b01fd
commit c96d92eb8a
3 files changed
+317 -161

No files matched your search

@@ -0,0 +1,24 @@
DELETE FROM `spell_script_names` WHERE `ScriptName` IN (
'spell_mother_shahraz_fatal_attraction',
'spell_mother_shahraz_fatal_attraction_link',
'spell_mother_shahraz_saber_lash',
'spell_mother_shahraz_generic_periodic',
'spell_mother_shahraz_random_periodic');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(40869,'spell_mother_shahraz_fatal_attraction'),
(40870,'spell_mother_shahraz_fatal_attraction_link'),
(40816,'spell_mother_shahraz_saber_lash'),
(40863,'spell_mother_shahraz_generic_periodic'),
(40865,'spell_mother_shahraz_generic_periodic'),
(40866,'spell_mother_shahraz_generic_periodic'),
(40862,'spell_mother_shahraz_generic_periodic'),
(40867,'spell_mother_shahraz_random_periodic');
DELETE FROM `creature_addon` WHERE `guid`=52760;
INSERT INTO `creature_addon` (`guid`, `path_id`, `mount`, `bytes1`, `bytes2`, `emote`, `auras`) VALUES
(52760, 0, 0, 0, 0, 0, 40816);
DELETE FROM `creature_text` WHERE entry=22947 AND `groupid` IN(6,7);
INSERT INTO `creature_text` (`entry`, `groupid`, `id`, `text`, `type`, `language`, `probability`, `emote`, `duration`, `sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
(22947, 6, 0, '%s goes into a frenzy!', 41, 0, 100, 0, 0, 0, 2384, 0, 'shahraz EMOTE_ENRAGE'),
(22947, 7, 0, '%s goes into a berserker rage!', 16, 0, 100, 0, 0, 0, 4428, 0, 'shahraz EMOTE_BERSERK');
@@ -15,82 +15,96 @@
* 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 "ScriptedCreature.h"
#include "black_temple.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
};
G3D::Vector3 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
@@ -100,45 +114,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
@@ -147,30 +146,18 @@ public:
Talk(SAY_DEATH);
}
void TeleportPlayers()
void EnterEvadeMode(EvadeReason /*why*/) override
{
uint32 random = urand(0, 6);
float X = TeleportPoint[random].x;
float Y = TeleportPoint[random].y;
float Z = TeleportPoint[random].z;
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);
}
}
@@ -180,81 +167,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])
{
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));
events.Repeat(Seconds(18), Seconds(30));
break;
case EVENT_SABER_SLASH:
DoCastVictim(SPELL_SABER_LASH);
events.ScheduleEvent(EVENT_SABER_SLASH, urand(25000, 35000));
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;
@@ -262,11 +197,7 @@ public:
}
private:
ObjectGuid TargetGUID[3];
uint32 BeamCount;
uint32 CurrentBeam;
uint32 ExplosionCount;
bool Enraged;
bool _enraged;
};
CreatureAI* GetAI(Creature* creature) const override
@@ -275,7 +206,208 @@ 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* /*spell*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_SABER_LASH_IMMUNITY)
|| !sSpellMgr->GetSpellInfo(SPELL_FATAL_ATTRACTION))
return false;
return true;
}
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* /*spell*/) override
{
if (!sSpellMgr->GetSpellInfo(SPELL_FATAL_ATTRACTION_DAMAGE))
return false;
return true;
}
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
{
if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_1].TriggerSpell))
return false;
return true;
}
void OnTrigger(AuraEffect const* aurEff)
{
PreventDefaultAction();
uint32 triggerSpell = GetSpellInfo()->Effects[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
{
if (!sSpellMgr->GetSpellInfo(spellInfo->Effects[EFFECT_0].TriggerSpell))
return false;
return true;
}
void OnTrigger(AuraEffect const* aurEff)
{
PreventDefaultAction();
uint32 triggerSpell = GetSpellInfo()->Effects[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
{
for (uint32 spellId : RandomBeam)
if (!sSpellMgr->GetSpellInfo(spellId))
return false;
return true;
}
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();
}
@@ -46,7 +46,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) }
};