Scripts/BWD: scripted Dwarven spirits

This commit is contained in:
Ovahlord
2020-07-15 15:40:44 +02:00
parent 322662ba69
commit 00a94593cd
4 changed files with 550 additions and 65 deletions

View File

@@ -0,0 +1,124 @@
-- Spirit of Angerforge
UPDATE `creature_template` SET `difficulty_entry_1`= 49504 WHERE `entry`= 43119;
-- Spirit of Ironstar
UPDATE `creature_template` SET `difficulty_entry_1`= 49509 WHERE `entry`= 43127;
-- Spirit of Thaurissan
UPDATE `creature_template` SET `difficulty_entry_1`= 49508 WHERE `entry`= 43126;
-- Spirit of Burningeye
UPDATE `creature_template` SET `difficulty_entry_1`= 49512 WHERE `entry`= 43130;
-- Spirit of Moltenfist
UPDATE `creature_template` SET `difficulty_entry_1`= 49507 WHERE `entry`= 43125;
-- Spirit of Anvilrage
UPDATE `creature_template` SET `difficulty_entry_1`= 49510 WHERE `entry`= 43128;
-- Spirit of Shadowforge
UPDATE `creature_template` SET `difficulty_entry_1`= 49511 WHERE `entry`= 43129;
-- Spirit of Corehammer
UPDATE `creature_template` SET `difficulty_entry_1`= 49505 WHERE `entry`= 43122;
UPDATE `creature_template` SET `minlevel`= 85, `maxlevel`= 85, `exp`= 3, `speed_walk`= 1.2, `speed_run`= 1, `faction`= 16, `unit_class`= 2, `unit_flags`= 32832, `BaseVariance`= 0.75, `DamageModifier`= 130 WHERE `entry` IN (49504, 49509, 49508, 49512, 49507, 49510, 49511, 49505);
UPDATE `creature_template` SET `ScriptName`= 'npc_bwd_dwarven_spirit' WHERE `entry` IN (43119, 43127, 43126, 43130, 43125, 43128, 43129, 43122);
-- Execution Sentence
UPDATE `creature_template` SET `unit_flags`=33587264, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 43210;
-- Execution Sentence Visual
UPDATE `creature_template` SET `unit_flags`=33587264, `flags_extra`= 128, `AIName`= 'NullCreatureAI' WHERE `entry`= 43206;
DELETE FROM `creature_template_addon` WHERE `entry`= 43206;
INSERT INTO `creature_template_addon` (`entry`, `bytes1`, `bytes2`, `auras`) VALUES
(43206, 50331648, 1, '80736');
DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (43210, 43206);
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Flight`, `Rooted`) VALUES
(43210, 0, 1, 1),
(43206, 0, 1, 0);
UPDATE `creature_template` SET `mechanic_immune_mask`= 1 | 2 | 8 | 16 | 32 | 64 | 256 | 512 | 2048 | 4096 | 8192 | 65536 | 131072 | 4194304 | 8388608 WHERE `entry` IN (49504, 43119, 49509, 43127, 49508, 43126, 49512, 43130, 49507, 43125, 49510, 43128, 49511, 43129, 49505, 43122);
DELETE FROM `creature_template_addon` WHERE `entry` IN (49504, 43119, 49509, 43127, 49508, 43126, 49512, 43130, 49507, 43125, 49510, 43128, 49511, 43129, 49505, 43122);
INSERT INTO `creature_template_addon` (`entry`, `bytes2`, `auras`) VALUES
-- Spirit of Angerforge
(49504, 1, '80611 80762'),
(43119, 1, '80611 80762'),
-- Spirit of Ironstar
(49509, 1, '80611 80767'),
(43127, 1, '80611 80767'),
-- Spirit of Thaurissan
(49508, 1, '80611 80766'),
(43126, 1, '80611 80766'),
-- Spirit of Burningeye
(49512, 1, '80611 80770'),
(43130, 1, '80611 80770'),
-- Spirit of Moltenfist
(49507, 1, '80611 80764'),
(43125, 1, '80611 80764'),
-- Spirit of Anvilrage
(49510, 1, '80611 80768'),
(43128, 1, '80611 80768'),
-- Spirit of Shadowforge
(49511, 1, '80611 80769'),
(43129, 1, '80611 80769'),
-- Spirit of Corehammer
(49505, 1, '80611 80763'),
(43122, 1, '80611 80763');
DELETE FROM `spell_proc` WHERE `SpellId`= 80718;
INSERT INTO `spell_proc` (`SpellId`, `SpellTypeMask`, `SpellPhaseMask`, `HitMask`) VALUES
(80718, 3, 2, 0);
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_bwd_execution_sentence_visual',
'spell_bwd_execution_sentence',
'spell_bwd_execution_sentence_dummy',
'spell_bwd_stoneblood');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(80729, 'spell_bwd_execution_sentence_visual'),
(80727, 'spell_bwd_execution_sentence'),
(85176, 'spell_bwd_execution_sentence_dummy'),
(80655, 'spell_bwd_stoneblood');
DELETE FROM `conditions` WHERE `SourceEntry` IN (85176, 80876, 80874, 80873, 80877, 80878, 80875, 80871, 80872) AND `SourceTypeOrReferenceId`= 13;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
(13, 1, 85176, 0, 0, 31, 0, 3, 43210, 0, 0, 0, '', 'Execution Sentence - Target Execution Sentence'),
(13, 1, 85176, 0, 1, 31, 0, 3, 43206, 0, 0, 0, '', 'Execution Sentence - Target Execution Sentence Visual'),
(13, 1, 80876, 0, 0, 31, 0, 3, 43128, 0, 0, 0, '', 'Bestowal of Moltenfist'),
(13, 1, 80876, 0, 1, 31, 0, 3, 43129, 0, 0, 0, '', 'Bestowal of Moltenfist'),
(13, 1, 80876, 0, 2, 31, 0, 3, 43122, 0, 0, 0, '', 'Bestowal of Moltenfist'),
(13, 1, 80874, 0, 0, 31, 0, 3, 43125, 0, 0, 0, '', 'Bestowal of Anvilrage'),
(13, 1, 80874, 0, 1, 31, 0, 3, 43129, 0, 0, 0, '', 'Bestowal of Anvilrage'),
(13, 1, 80874, 0, 2, 31, 0, 3, 43122, 0, 0, 0, '', 'Bestowal of Anvilrage'),
(13, 1, 80873, 0, 0, 31, 0, 3, 43125, 0, 0, 0, '', 'Bestowal of Shadowforge'),
(13, 1, 80873, 0, 1, 31, 0, 3, 43128, 0, 0, 0, '', 'Bestowal of Shadowforge'),
(13, 1, 80873, 0, 2, 31, 0, 3, 43122, 0, 0, 0, '', 'Bestowal of Shadowforge'),
(13, 1, 80877, 0, 0, 31, 0, 3, 43125, 0, 0, 0, '', 'Bestowal of Corehammer'),
(13, 1, 80877, 0, 1, 31, 0, 3, 43128, 0, 0, 0, '', 'Bestowal of Corehammer'),
(13, 1, 80877, 0, 2, 31, 0, 3, 43129, 0, 0, 0, '', 'Bestowal of Corehammer'),
(13, 1, 80878, 0, 0, 31, 0, 3, 43127, 0, 0, 0, '', 'Bestowal of Angerforge'),
(13, 1, 80878, 0, 1, 31, 0, 3, 43126, 0, 0, 0, '', 'Bestowal of Angerforge'),
(13, 1, 80878, 0, 2, 31, 0, 3, 43130, 0, 0, 0, '', 'Bestowal of Angerforge'),
(13, 1, 80875, 0, 0, 31, 0, 3, 43119, 0, 0, 0, '', 'Bestowal of Ironstar'),
(13, 1, 80875, 0, 1, 31, 0, 3, 43126, 0, 0, 0, '', 'Bestowal of Ironstar'),
(13, 1, 80875, 0, 2, 31, 0, 3, 43130, 0, 0, 0, '', 'Bestowal of Ironstar'),
(13, 1, 80871, 0, 0, 31, 0, 3, 43119, 0, 0, 0, '', 'Bestowal of Thaurissan'),
(13, 1, 80871, 0, 1, 31, 0, 3, 43127, 0, 0, 0, '', 'Bestowal of Thaurissan'),
(13, 1, 80871, 0, 2, 31, 0, 3, 43130, 0, 0, 0, '', 'Bestowal of Thaurissan'),
(13, 1, 80872, 0, 0, 31, 0, 3, 43119, 0, 0, 0, '', 'Bestowal of Burningeye'),
(13, 1, 80872, 0, 1, 31, 0, 3, 43127, 0, 0, 0, '', 'Bestowal of Burningeye'),
(13, 1, 80872, 0, 2, 31, 0, 3, 43126, 0, 0, 0, '', 'Bestowal of Burningeye');
-- Spawn Groups
DELETE FROM `spawn_group_template` WHERE `groupId` IN (435, 436);
INSERT INTO `spawn_group_template` (`groupId`, `groupName`, `groupFlags`) VALUES
(435, 'Blackwing Descent - Dwarven Spirits Left', 4),
(436, 'Blackwing Descent - Dwarven Spirits Left', 4);
DELETE FROM `spawn_group` WHERE `groupId` IN (435, 436);
INSERT INTO `spawn_group` (`groupId`, `spawnType`, `spawnId`) VALUES
(435, 0, 250134),
(435, 0, 250137),
(435, 0, 250138),
(435, 0, 250133),
(436, 0, 250132),
(436, 0, 250136),
(436, 0, 250135),
(436, 0, 250139);

View File

@@ -23,7 +23,9 @@
#include "Spell.h"
#include "SpellScript.h"
#include "SpellAuraEffects.h"
#include "TemporarySummon.h"
#include "Map.h"
#include "MoveSplineInit.h"
#include "PassiveAI.h"
#include "Player.h"
#include "InstanceScript.h"
@@ -191,7 +193,7 @@ enum DrakonidChainWielder
SPELL_OVERHEAD_SMASH_SUMMON = 79578, // Serverside spell
SPELL_OVERHEAD_SMASH = 79580,
SPELL_GRIEVOUS_WOUND = 80051,
SPELL_CONSTRICTING_CHAINS = 79589,
SPELL_CONSTRICTING_CHAINS = 79589
};
struct npc_bwd_drakonid_chainwielder : public ScriptedAI
@@ -265,15 +267,261 @@ private:
EventMap _events;
};
enum DwarvenSpirits
{
// Spells
SPELL_SPIRIT_OF_ANGERFORGE = 80762,
SPELL_SPIRIT_OF_IRONSTAR = 80767,
SPELL_SPIRIT_OF_THAURISSAN = 80766,
SPELL_SPIRIT_OF_BURNINGEYE = 80770,
SPELL_SPIRIT_OF_MOLTENFIST = 80764,
SPELL_SPIRIT_OF_ANVILRAGE = 80768,
SPELL_SPIRIT_OF_SHADOWFORGE = 80769,
SPELL_SPIRIT_OF_COREHAMMER = 80763,
SPELL_BESTOWAL_OF_THAURISSAN = 80871,
SPELL_BESTOWAL_OF_BURNINGEYE = 80872,
SPELL_BESTOWAL_OF_SHADOWFORGE = 80873,
SPELL_BESTOWAL_OF_ANVILRAGE = 80874,
SPELL_BESTOWAL_OF_IRONSTAR = 80875,
SPELL_BESTOWAL_OF_MOLTENFIST = 80876,
SPELL_BESTOWAL_OF_COREHAMMER = 80877,
SPELL_BESTOWAL_OF_ANGERFORGE = 80878,
SPELL_BURDEN_OF_THE_CROWN = 80718,
SPELL_CHAIN_LIGHTNING = 80646,
SPELL_STORMBOLT = 80648,
SPELL_THUNDERCLAP = 80649,
SPELL_WHIRLWIND = 80652,
SPELL_AVATAR = 80645,
SPELL_STONEBLOOD = 80655,
SPELL_EXECUTION_SENTENCE_SUMMON_1 = 80738,
SPELL_EXECUTION_SENTENCE_SUMMON_2 = 80729,
SPELL_EXECUTION_SENTENCE_DUMMY = 85176,
SPELL_EXECUTION_SENTENCE = 80727,
// Events
EVENT_BURDEN_OF_THE_CROWN = 1,
EVENT_CHAIN_LIGHTNING,
EVENT_STORMBOLT,
EVENT_THUNDERCLAP,
EVENT_WHIRLWIND,
EVENT_AVATAR,
EVENT_STONEBLOOD,
EVENT_SHIELD_OF_LIGHT,
EVENT_EXECUTION_SENTENCE
};
#define SPELL_SHIELD_OF_LIGHT RAID_MODE<uint32>(80747, 95537)
struct npc_bwd_dwarven_spirit : public ScriptedAI
{
npc_bwd_dwarven_spirit(Creature* creature) : ScriptedAI(creature) { }
void JustEngagedWith(Unit* /*who*/) override
{
uint32 initialEventId = 0;
switch (me->GetEntry())
{
case NPC_SPIRIT_OF_COREHAMMER: initialEventId = EVENT_BURDEN_OF_THE_CROWN; break;
case NPC_SPIRIT_OF_SHADOWFORGE: initialEventId = EVENT_CHAIN_LIGHTNING; break;
case NPC_SPIRIT_OF_ANVILRAGE: initialEventId = EVENT_STORMBOLT; break;
case NPC_SPIRIT_OF_MOLTENFIST: initialEventId = EVENT_THUNDERCLAP; break;
case NPC_SPIRIT_OF_BURNINGEYE: initialEventId = EVENT_WHIRLWIND; break;
case NPC_SPIRIT_OF_THAURISSAN: initialEventId = EVENT_AVATAR; break;
case NPC_SPIRIT_OF_ANGERFORGE: initialEventId = EVENT_STONEBLOOD; break;
case NPC_SPIRIT_OF_IRONSTAR: initialEventId = EVENT_SHIELD_OF_LIGHT; break;
default:
break;
}
if (initialEventId)
_events.ScheduleEvent(initialEventId, 11s, 18s);
}
void EnterEvadeMode(EvadeReason why) override
{
ScriptedAI::EnterEvadeMode(why);
_events.Reset();
if (InstanceScript* instance = me->GetInstanceScript())
{
switch (me->GetEntry())
{
case NPC_SPIRIT_OF_MOLTENFIST:
case NPC_SPIRIT_OF_ANVILRAGE:
case NPC_SPIRIT_OF_SHADOWFORGE:
case NPC_SPIRIT_OF_COREHAMMER:
instance->SetData(DATA_RESET_DWARVEN_SPIRIT_GROUP, DWARVEN_SPIRIT_GROUP_LEFT);
break;
default:
instance->SetData(DATA_RESET_DWARVEN_SPIRIT_GROUP, DWARVEN_SPIRIT_GROUP_RIGHT);
break;
}
}
}
void JustDied(Unit* /*killer*/) override
{
_events.Reset();
uint32 bestowalSpellId = 0;
switch (me->GetEntry())
{
case NPC_SPIRIT_OF_ANGERFORGE: bestowalSpellId = SPELL_BESTOWAL_OF_ANGERFORGE; break;
case NPC_SPIRIT_OF_ANVILRAGE: bestowalSpellId = SPELL_BESTOWAL_OF_ANVILRAGE; break;
case NPC_SPIRIT_OF_BURNINGEYE: bestowalSpellId = SPELL_BESTOWAL_OF_BURNINGEYE; break;
case NPC_SPIRIT_OF_COREHAMMER: bestowalSpellId = SPELL_BESTOWAL_OF_COREHAMMER; break;
case NPC_SPIRIT_OF_IRONSTAR: bestowalSpellId = SPELL_BESTOWAL_OF_IRONSTAR; break;
case NPC_SPIRIT_OF_MOLTENFIST: bestowalSpellId = SPELL_BESTOWAL_OF_MOLTENFIST; break;
case NPC_SPIRIT_OF_SHADOWFORGE: bestowalSpellId = SPELL_BESTOWAL_OF_SHADOWFORGE; break;
case NPC_SPIRIT_OF_THAURISSAN: bestowalSpellId = SPELL_BESTOWAL_OF_THAURISSAN; break;
default:
break;
}
if (bestowalSpellId)
DoCastAOE(bestowalSpellId);
if (InstanceScript* instance = me->GetInstanceScript())
{
switch (me->GetEntry())
{
case NPC_SPIRIT_OF_MOLTENFIST:
case NPC_SPIRIT_OF_ANVILRAGE:
case NPC_SPIRIT_OF_SHADOWFORGE:
case NPC_SPIRIT_OF_COREHAMMER:
instance->SetData(DATA_DWARVEN_SPIRIT_DIED, DWARVEN_SPIRIT_GROUP_LEFT);
break;
default:
instance->SetData(DATA_DWARVEN_SPIRIT_DIED, DWARVEN_SPIRIT_GROUP_RIGHT);
break;
}
}
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
uint32 triggeredEventId = 0;
switch (spell->Id)
{
case SPELL_BESTOWAL_OF_COREHAMMER: triggeredEventId = EVENT_BURDEN_OF_THE_CROWN; break;
case SPELL_BESTOWAL_OF_SHADOWFORGE: triggeredEventId = EVENT_CHAIN_LIGHTNING; break;
case SPELL_BESTOWAL_OF_ANVILRAGE: triggeredEventId = EVENT_STORMBOLT; break;
case SPELL_BESTOWAL_OF_MOLTENFIST: triggeredEventId = EVENT_THUNDERCLAP; break;
case SPELL_BESTOWAL_OF_BURNINGEYE: triggeredEventId = EVENT_WHIRLWIND; break;
case SPELL_BESTOWAL_OF_THAURISSAN: triggeredEventId = EVENT_AVATAR; break;
case SPELL_BESTOWAL_OF_ANGERFORGE: triggeredEventId = EVENT_AVATAR; break;
case SPELL_BESTOWAL_OF_IRONSTAR: triggeredEventId = EVENT_SHIELD_OF_LIGHT; break;
default:
break;
}
if (triggeredEventId)
_events.ScheduleEvent(triggeredEventId, 1s);
}
void JustSummoned(Creature* summon) override
{
if (summon->GetEntry() == NPC_EXECUTION_SENTENCE_VISUAL)
{
summon->m_Events.AddEventAtOffset([summon]()
{
Movement::MoveSplineInit init(summon);
init.MoveTo(summon->GetPositionX(), summon->GetPositionY(), summon->GetFloorZ(), false);
init.SetVelocity(0.54f);
init.Launch();
}, 2s+ 500ms);
}
}
void OnSpellCastFinished(SpellInfo const* spell, SpellFinishReason reason) override
{
if (spell->Id == SPELL_SHIELD_OF_LIGHT && reason == SPELL_FINISHED_SUCCESSFUL_CAST)
{
_events.DelayEvents(1s + 100ms);
_events.ScheduleEvent(EVENT_EXECUTION_SENTENCE, 1s);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while (uint32 eventId = _events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_BURDEN_OF_THE_CROWN:
DoCastVictim(SPELL_BURDEN_OF_THE_CROWN);
_events.Repeat(31s);
break;
case EVENT_CHAIN_LIGHTNING:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 90.f, true))
DoCast(target, SPELL_CHAIN_LIGHTNING);
_events.Repeat(10s, 11s);
break;
case EVENT_STORMBOLT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.f, true))
DoCast(target, SPELL_STORMBOLT);
_events.Repeat(19s, 23s);
break;
case EVENT_THUNDERCLAP:
if (me->GetVictim()->IsWithinMeleeRange(me))
{
DoCastAOE(SPELL_THUNDERCLAP);
_events.Repeat(6s, 8s);
}
else
_events.Repeat(1s);
break;
case EVENT_WHIRLWIND:
DoCastSelf(SPELL_WHIRLWIND);
_events.Repeat(34s, 36s);
break;
case EVENT_AVATAR:
DoCastSelf(SPELL_AVATAR);
_events.Repeat(34s, 36s);
break;
case EVENT_STONEBLOOD:
DoCastSelf(SPELL_STONEBLOOD);
_events.Repeat(19s, 23s);
break;
case EVENT_SHIELD_OF_LIGHT:
DoCastSelf(SPELL_SHIELD_OF_LIGHT);
break;
case EVENT_EXECUTION_SENTENCE:
if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_EXECUTION_SENTENCE))
{
DoCastVictim(SPELL_EXECUTION_SENTENCE_SUMMON_1);
DoCastVictim(SPELL_EXECUTION_SENTENCE_SUMMON_2);
DoCastVictim(SPELL_EXECUTION_SENTENCE);
}
_events.Repeat(34s, 36s);
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
struct go_bwd_ancient_bell : public GameObjectAI
{
go_bwd_ancient_bell(GameObject* go) : GameObjectAI(go), _instance(go->GetInstanceScript()) { }
bool GossipHello(Player* /*player*/) override
{
if (_instance->GetData(DATA_ATRAMEDES_INTRO) == DONE)
return true;
_instance->SetData(DATA_ATRAMEDES_INTRO, DONE);
me->SendCustomAnim(0);
me->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
@@ -341,6 +589,98 @@ class spell_bwd_grievous_wound : public AuraScript
}
};
class spell_bwd_execution_sentence_visual : public SpellScript
{
PrepareSpellScript(spell_bwd_execution_sentence_visual);
void SetDest(SpellDestination& dest)
{
dest.RelocateOffset({ 0.0f, 0.0f, 15.0f, 0.0f });
}
void Register()
{
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_bwd_execution_sentence_visual::SetDest, EFFECT_0, TARGET_DEST_TARGET_ENEMY);
}
};
class spell_bwd_execution_sentence_dummy : public SpellScript
{
PrepareSpellScript(spell_bwd_execution_sentence_dummy);
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
{
Unit* caster = GetCaster();
Creature* creature = GetHitCreature();
if (!caster || !creature)
return;
if (TempSummon* summon = creature->ToTempSummon())
if (summon->GetSummoner() == caster)
summon->DespawnOrUnsummon();
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_bwd_execution_sentence_dummy::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
class spell_bwd_execution_sentence : public AuraScript
{
PrepareAuraScript(spell_bwd_execution_sentence);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_EXECUTION_SENTENCE_DUMMY });
}
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (GetTargetApplication()->GetRemoveMode().HasFlag(AuraRemoveFlags::ByCancel | AuraRemoveFlags::ByDeath))
if (Unit* caster = GetCaster())
caster->CastSpell(caster, SPELL_EXECUTION_SENTENCE_DUMMY, true);
}
void Register() override
{
OnEffectRemove += AuraEffectRemoveFn(spell_bwd_execution_sentence::HandleRemove, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
}
};
class spell_bwd_stoneblood : public SpellScript
{
PrepareSpellScript(spell_bwd_stoneblood);
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
std::unordered_set<Aura*> aurasToRemove;
Unit* target = GetHitUnit();
for (auto itr : target->GetAppliedAuras())
{
Aura* aura = itr.second->GetBase();
if (!aura)
continue;
// Todo: this check should be more generic so it can detect actual hostile effects but it'll do for the dwarven spirits for the time being.
if (Unit* caster = aura->GetCaster())
if (caster->IsPlayer() || caster->IsSummon())
aurasToRemove.insert(aura);
}
for (std::unordered_set<Aura*>::const_iterator itr = aurasToRemove.begin(); itr != aurasToRemove.end();)
{
(*itr)->Remove(AuraRemoveFlags::ByEnemySpell);
itr = aurasToRemove.erase(itr);
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_bwd_stoneblood::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
class at_bwd_intro: public OnlyOnceAreaTriggerScript
{
public:
@@ -358,8 +698,13 @@ void AddSC_blackwing_descent()
{
RegisterBlackwingDescentCreatureAI(npc_bwd_lord_victor_nefarius);
RegisterBlackwingDescentCreatureAI(npc_bwd_drakonid_chainwielder);
RegisterBlackwingDescentCreatureAI(npc_bwd_dwarven_spirit);
RegisterGameObjectAI(go_bwd_ancient_bell);
RegisterSpellScript(spell_bwd_dragon_orb);
RegisterAuraScript(spell_bwd_grievous_wound);
RegisterSpellScript(spell_bwd_execution_sentence_visual);
RegisterSpellScript(spell_bwd_execution_sentence_dummy);
RegisterAuraScript(spell_bwd_execution_sentence);
RegisterSpellScript(spell_bwd_stoneblood);
new at_bwd_intro();
}

View File

@@ -36,7 +36,8 @@ enum BWDDataTypes
DATA_NEFARIANS_END = 5,
/*Events*/
DATA_DEAD_DWARF_SPIRITS,
DATA_RESET_DWARVEN_SPIRIT_GROUP,
DATA_DWARVEN_SPIRIT_DIED,
DATA_ANCIENT_BELL,
DATA_COLUMN_OF_LIGHT,
DATA_ATRAMEDES_INTRO,
@@ -165,7 +166,8 @@ enum BWDCreatureIds
// Generic Creatures
NPC_DRAKONID_DRUDGE = 42362,
NPC_OVERHEAD_SMASH = 42690
NPC_OVERHEAD_SMASH = 42690,
NPC_EXECUTION_SENTENCE_VISUAL = 43206
};
enum BWDGameObjectIds
@@ -181,8 +183,13 @@ enum BWDGameObjectIds
enum BWDMisc
{
// Magmaw
MASSIVE_CRASH_SIDE_LEFT = 0,
MASSIVE_CRASH_SIDE_RIGHT = 1
MASSIVE_CRASH_SIDE_RIGHT = 1,
// Dwarven Spirit Council
DWARVEN_SPIRIT_GROUP_LEFT = 0,
DWARVEN_SPIRIT_GROUP_RIGHT = 1
};
enum BWDSpells

View File

@@ -86,7 +86,9 @@ enum Events
EVENT_MAKE_ANCIENT_BELL_SELECTABLE = 1,
EVENT_RESPAWN_ATRAMEDES,
EVENT_RESPAWN_NEFARIAN,
EVENT_RAISE_ELEVATOR
EVENT_RAISE_ELEVATOR,
EVENT_RESPAWN_LEFT_DWARVEN_GROUP,
EVENT_RESPAWN_RIGHT_DWARVEN_GROUP
};
enum Actions
@@ -98,7 +100,9 @@ enum Actions
enum SpawnGroup
{
SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS = 400,
SPAWN_GROUP_NEFARIANS_END = 402
SPAWN_GROUP_NEFARIANS_END = 402,
SPAWN_GROUP_DWARVEN_SPIRITS_LEFT = 435,
SPAWN_GROUP_DWARVEN_SPIRITS_RIGHT = 436
};
enum SummonGroups
@@ -124,7 +128,8 @@ class instance_blackwing_descent : public InstanceMapScript
SetBossNumber(EncounterCount);
LoadObjectData(creatureData, gameobjectData);
LoadDoorData(doorData);
_deadDwarfSpirits = 0;
_deadDwarfSpiritsLeft = 0;
_deadDwarfSpiritsRight = 0;
_atramedesIntroState = NOT_STARTED;
_nefarianAchievementEligible = true;
_nefariansEndIntroDone = false;
@@ -133,6 +138,8 @@ class instance_blackwing_descent : public InstanceMapScript
void Create() override
{
instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true);
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_LEFT, true);
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_RIGHT, true);
}
void OnCreatureCreate(Creature* creature) override
@@ -209,36 +216,6 @@ class instance_blackwing_descent : public InstanceMapScript
if (GetBossState(DATA_MAGMAW) == DONE && GetBossState(DATA_OMNOTRON_DEFENSE_SYSTEM) == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
case GO_ANCIENT_BELL:
if (_deadDwarfSpirits == 8 && _atramedesIntroState != DONE)
{
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
if (Creature* column = instance->SummonCreature(NPC_COLUMN_OF_LIGHT, ColumnOfLightPosition))
column->CastSpell(column, SPELL_COLUMN_OF_LIGHT);
}
break;
default:
break;
}
}
void OnUnitDeath(Unit* unit) override
{
if (unit->GetTypeId() != TYPEID_UNIT)
return;
switch (unit->GetEntry())
{
case NPC_SPIRIT_OF_MOLTENFIST:
case NPC_SPIRIT_OF_ANVILRAGE:
case NPC_SPIRIT_OF_SHADOWFORGE:
case NPC_SPIRIT_OF_COREHAMMER:
case NPC_SPIRIT_OF_ANGERFORGE:
case NPC_SPIRIT_OF_IRONSTAR:
case NPC_SPIRIT_OF_THAURISSAN:
case NPC_SPIRIT_OF_BURNINGEYE:
SetData(DATA_DEAD_DWARF_SPIRITS, DONE);
break;
default:
break;
}
@@ -318,12 +295,17 @@ class instance_blackwing_descent : public InstanceMapScript
{
switch (type)
{
case DATA_DEAD_DWARF_SPIRITS:
_deadDwarfSpirits++;
SaveToDB();
case DATA_DWARVEN_SPIRIT_DIED:
if (data == DWARVEN_SPIRIT_GROUP_LEFT)
++_deadDwarfSpiritsLeft;
else
++_deadDwarfSpiritsRight;
if (_deadDwarfSpirits == 8)
if ((_deadDwarfSpiritsLeft + _deadDwarfSpiritsRight) == 8)
{
_atramedesIntroState = DONE;
SaveToDB();
std::list<TempSummon*> summoned;
instance->SummonCreatureGroup(SUMMON_GROUP_ATRAMEDES_INTRO, &summoned);
for (TempSummon* summon : summoned)
@@ -333,22 +315,38 @@ class instance_blackwing_descent : public InstanceMapScript
_events.ScheduleEvent(EVENT_MAKE_ANCIENT_BELL_SELECTABLE, 4s + 500ms);
}
break;
case DATA_ATRAMEDES_INTRO:
_atramedesIntroState = data;
if (Creature* atramedes = instance->SummonCreature(BOSS_ATRAMEDES, AtramedesIntroSummonPosition))
case DATA_RESET_DWARVEN_SPIRIT_GROUP:
if (data == DWARVEN_SPIRIT_GROUP_LEFT)
{
for (ObjectGuid guid : _atramedesIntroGUIDs)
if (Creature* intro = instance->GetCreature(guid))
intro->DespawnOrUnsummon();
atramedes->SetDisableGravity(true);
atramedes->SetReactState(REACT_PASSIVE);
atramedes->SendSetPlayHoverAnim(true);
atramedes->AI()->DoAction(ACTION_START_ATRAMEDES_INTRO);
_deadDwarfSpiritsLeft = 0;
_events.RescheduleEvent(EVENT_RESPAWN_LEFT_DWARVEN_GROUP, 30s);
instance->SpawnGroupDespawn(SPAWN_GROUP_DWARVEN_SPIRITS_LEFT);
}
else
{
_deadDwarfSpiritsRight = 0;
_events.RescheduleEvent(EVENT_RESPAWN_RIGHT_DWARVEN_GROUP, 30s);
instance->SpawnGroupDespawn(SPAWN_GROUP_DWARVEN_SPIRITS_RIGHT);
}
SaveToDB();
break;
case DATA_ATRAMEDES_INTRO:
if (!GetCreature(DATA_ATRAMEDES))
{
if (Creature* atramedes = instance->SummonCreature(BOSS_ATRAMEDES, AtramedesIntroSummonPosition))
{
for (ObjectGuid guid : _atramedesIntroGUIDs)
if (Creature* intro = instance->GetCreature(guid))
intro->DespawnOrUnsummon();
atramedes->SetDisableGravity(true);
atramedes->SetReactState(REACT_PASSIVE);
atramedes->SendSetPlayHoverAnim(true);
if (atramedes->IsAIEnabled)
atramedes->AI()->DoAction(ACTION_START_ATRAMEDES_INTRO);
}
}
break;
case DATA_ENTRANCE_INTRO:
{
@@ -481,6 +479,12 @@ class instance_blackwing_descent : public InstanceMapScript
if (Transport* transport = gameobject->ToTransport())
transport->SetTransportState(GO_STATE_TRANSPORT_STOPPED, 1);
break;
case EVENT_RESPAWN_LEFT_DWARVEN_GROUP:
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_LEFT, true);
break;
case EVENT_RESPAWN_RIGHT_DWARVEN_GROUP:
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_RIGHT, true);
break;
default:
break;
}
@@ -489,22 +493,26 @@ class instance_blackwing_descent : public InstanceMapScript
void WriteSaveDataMore(std::ostringstream& data) override
{
data << _deadDwarfSpirits << ' '
<< _atramedesIntroState;
data << _atramedesIntroState;
}
void ReadSaveDataMore(std::istringstream& data) override
{
data >> _deadDwarfSpirits;
data >> _atramedesIntroState;
// Atramedes' intro is done but he has not been defeated yet: spawm him at his respawn location
if (_atramedesIntroState == DONE && GetBossState(DATA_ATRAMEDES) != DONE)
instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition);
if (GetBossState(DATA_ATRAMEDES) != DONE)
{
instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true);
if (_atramedesIntroState == DONE)
instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition);
else
{
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_LEFT, true);
instance->SpawnGroupSpawn(SPAWN_GROUP_DWARVEN_SPIRITS_RIGHT, true);
}
}
if (IsNefarianAvailable())
instance->SpawnGroupSpawn(SPAWN_GROUP_NEFARIANS_END, true);
}
@@ -517,7 +525,8 @@ class instance_blackwing_descent : public InstanceMapScript
ObjectGuid _roomStalkerTargetDummyRightGuid;
GuidVector _roomStalkerGUIDs;
GuidVector _atramedesIntroGUIDs;
uint8 _deadDwarfSpirits;
uint8 _deadDwarfSpiritsLeft;
uint8 _deadDwarfSpiritsRight;
uint8 _atramedesIntroState;
bool _nefarianAchievementEligible;
bool _nefariansEndIntroDone;