mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-26 11:52:32 +01:00
Scripts/BWD: more work on Atramedes encounter and initial work on heroic mechanics
This commit is contained in:
@@ -5363,8 +5363,8 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->MaxAffectedTargets = 4;
|
||||
});
|
||||
|
||||
// Sonic Breath
|
||||
ApplySpellFix({ 78075 }, [](SpellInfo* spellInfo)
|
||||
// Roaring Flame Breath
|
||||
ApplySpellFix({ 78207 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->MaxAffectedTargets = 1;
|
||||
});
|
||||
@@ -5375,12 +5375,6 @@ void SpellMgr::LoadSpellInfoCorrections()
|
||||
spellInfo->Effects[EFFECT_0].TargetA = SpellImplicitTargetInfo(TARGET_UNIT_TARGET_ANY);
|
||||
});
|
||||
|
||||
// Sonic Flames
|
||||
ApplySpellFix({ 78945 }, [](SpellInfo* spellInfo)
|
||||
{
|
||||
spellInfo->Effects[EFFECT_0].RadiusEntry = sSpellRadiusStore.LookupEntry(EFFECT_RADIUS_500_YARDS);
|
||||
});
|
||||
|
||||
// END OF BLACKWING DESCENT SPELLS
|
||||
|
||||
// Living Bomb
|
||||
|
||||
@@ -55,6 +55,7 @@ enum BWDDataTypes
|
||||
|
||||
/*Atramedes*/
|
||||
DATA_ATHENAEUM_DOOR,
|
||||
DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES
|
||||
};
|
||||
|
||||
enum BWDCreatureIds
|
||||
@@ -100,6 +101,7 @@ enum BWDCreatureIds
|
||||
NPC_SONAR_PULSE_BOMB = 49623,
|
||||
NPC_TRACKING_FLAMES = 41879,
|
||||
NPC_REVERBERATING_FLAME = 41962,
|
||||
NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES = 49580,
|
||||
|
||||
/*Events*/
|
||||
NPC_SPIRIT_OF_MOLTENFIST = 43125,
|
||||
@@ -138,12 +140,6 @@ enum BWDSpells
|
||||
SPELL_COLUMN_OF_LIGHT = 95660
|
||||
};
|
||||
|
||||
enum BWDSummonGroups
|
||||
{
|
||||
SUMMON_GROUP_ATRAMEDES_INTRO = 0,
|
||||
SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS = 1
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetBlackwingDescentAI(T* obj)
|
||||
{
|
||||
|
||||
@@ -17,15 +17,14 @@
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "CommonPredicates.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuraEffects.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "GameObject.h"
|
||||
#include "GridNotifiers.h"
|
||||
#include "PassiveAI.h"
|
||||
#include "Player.h"
|
||||
#include "MoveSpline.h"
|
||||
#include "blackwing_descent.h"
|
||||
|
||||
enum Spells
|
||||
@@ -44,7 +43,6 @@ enum Spells
|
||||
SPELL_SONAR_PULSE_TRIGGER = 92519,
|
||||
SPELL_SONAR_BOMB = 92765,
|
||||
SPELL_ROARING_FLAME_BREATH = 78207,
|
||||
SPELL_RESONATING_CLASH_AIR_CLEAR = 78958,
|
||||
|
||||
// Sonar Pulse
|
||||
SPELL_SONAR_PULSE_PERIODIC_TRIGGER = 77674,
|
||||
@@ -56,7 +54,11 @@ enum Spells
|
||||
SPELL_ROARING_FLAME_BREATH_REVERSE_CAST = 78230,
|
||||
SPELL_ROARING_FLAME_SUMMON = 78272,
|
||||
SPELL_AGGRO_CREATOR = 63709,
|
||||
SPELL_SONIC_FLAMES_FLIGHT = 78945,
|
||||
SPELL_SONIC_FLAMES = 78945,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
SPELL_SUMMON_IMP = 92625,
|
||||
SPELL_DESTROY_SHIELD = 92607,
|
||||
|
||||
// Player
|
||||
SPELL_RESONATING_CLASH_GROUND = 77611,
|
||||
@@ -72,6 +74,11 @@ enum Texts
|
||||
SAY_ANNOUNCE_SEARING_FLAME = 1,
|
||||
SAY_SEARING_FLAME = 2,
|
||||
SAY_FLIGHT_PHASE = 3,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
SAY_INTRO = 0,
|
||||
SAY_SUMMON_IMP = 1,
|
||||
SAY_DESTROY_SHIELD = 2
|
||||
};
|
||||
|
||||
enum Sounds
|
||||
@@ -90,16 +97,23 @@ enum Events
|
||||
EVENT_SEARING_FLAME,
|
||||
EVENT_SONIC_BREATH,
|
||||
EVENT_LIFTOFF,
|
||||
EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT,
|
||||
EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD,
|
||||
EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING,
|
||||
EVENT_LAND,
|
||||
EVENT_REENGAGE_PLAYERS
|
||||
EVENT_LANDED,
|
||||
EVENT_REENGAGE_PLAYERS,
|
||||
|
||||
// Lord Victor Nefarius
|
||||
EVENT_SAY_INTRO,
|
||||
EVENT_SUMMON_IMP
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
// Atramedes
|
||||
ACTION_START_INTRO = 0,
|
||||
ACTION_HALT_REVERBERATING_FLAME = 1
|
||||
ACTION_HALT_REVERBERATING_FLAME = 1,
|
||||
ACTION_DESTROY_SHIELD = 2
|
||||
};
|
||||
|
||||
enum MovePoints
|
||||
@@ -122,39 +136,27 @@ enum Phases
|
||||
enum Data
|
||||
{
|
||||
// Setter
|
||||
DATA_LAST_ANCIENT_DWARVEN_SHIELD = 0,
|
||||
DATA_ADD_NOISY_PLAYER = 1,
|
||||
DATA_REMOVE_NOISY_PLAYER = 2,
|
||||
DATA_LAST_SHIELD_USER = 3,
|
||||
DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD = 0,
|
||||
DATA_ADD_NOISY_PLAYER = 1,
|
||||
DATA_REMOVE_NOISY_PLAYER = 2,
|
||||
DATA_LAST_SHIELD_USER = 3,
|
||||
|
||||
// Getter
|
||||
DATA_IS_IN_AIR = 0,
|
||||
DATA_HAS_NOISY_PLAYER = 1
|
||||
DATA_IS_IN_AIR = 0,
|
||||
DATA_HAS_NOISY_PLAYER = 1,
|
||||
DATA_IS_IN_INTRO_PHASE = 2
|
||||
};
|
||||
|
||||
Position const IntroFlightPosition1 = { 249.432f, -223.616f, 98.6447f };
|
||||
Position const IntroFlightPosition2 = { 214.531f, -223.918f, 93.4661f };
|
||||
Position const IntroLandingPosition = { 214.531f, -223.918f, 74.7668f };
|
||||
Position const LiftoffPosition = { 130.655f, -226.637f, 113.21f };
|
||||
Position const LandPosition = { 124.575f, -224.797f, 75.4534f };
|
||||
Position const IntroFlightPosition1 = { 249.432f, -223.616f, 98.6447f };
|
||||
Position const IntroFlightPosition2 = { 214.531f, -223.918f, 93.4661f };
|
||||
Position const IntroLandingPosition = { 214.531f, -223.918f, 74.7668f };
|
||||
Position const LiftoffPosition = { 130.655f, -226.637f, 113.21f };
|
||||
Position const LandPosition = { 124.575f, -224.797f, 75.4534f };
|
||||
Position const LordVictorNefariusSummonPosition = { 92.91319f, -223.9931f, 96.8985f, 0.0f };
|
||||
|
||||
struct boss_atramedes : public BossAI
|
||||
{
|
||||
boss_atramedes(Creature* creature) : BossAI(creature, DATA_ATRAMEDES)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
~boss_atramedes()
|
||||
{
|
||||
delete _lastAncientDwarvenShieldGUIDs;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_allowVertigoCast = false;
|
||||
_lastAncientDwarvenShieldGUIDs = new std::queue<ObjectGuid>();
|
||||
}
|
||||
boss_atramedes(Creature* creature) : BossAI(creature, DATA_ATRAMEDES) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
@@ -177,7 +179,8 @@ struct boss_atramedes : public BossAI
|
||||
events.ScheduleEvent(EVENT_SONIC_BREATH, 24s, 0, PHASE_GROUND);
|
||||
events.ScheduleEvent(EVENT_LIFTOFF, 1min + 31s, 0, PHASE_GROUND);
|
||||
|
||||
_allowVertigoCast = !me->HasByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
if (IsHeroic())
|
||||
DoSummon(NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES, LordVictorNefariusSummonPosition, 0, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason /*why*/) override
|
||||
@@ -190,6 +193,12 @@ struct boss_atramedes : public BossAI
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
@@ -252,6 +261,8 @@ struct boss_atramedes : public BossAI
|
||||
return (uint8(events.IsInPhase(PHASE_AIR)));
|
||||
case DATA_HAS_NOISY_PLAYER:
|
||||
return (uint8(!_noisyPlayerGUIDs.empty()));
|
||||
case DATA_IS_IN_INTRO_PHASE:
|
||||
return (uint8(events.IsInPhase(PHASE_INTRO)));
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -261,8 +272,8 @@ struct boss_atramedes : public BossAI
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_LAST_ANCIENT_DWARVEN_SHIELD:
|
||||
_lastAncientDwarvenShieldGUIDs->push(guid);
|
||||
case DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD:
|
||||
_lastUsedAncientDwarvenShieldGUID = guid;
|
||||
break;
|
||||
case DATA_ADD_NOISY_PLAYER:
|
||||
_noisyPlayerGUIDs.insert(guid);
|
||||
@@ -282,15 +293,8 @@ struct boss_atramedes : public BossAI
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_LAST_ANCIENT_DWARVEN_SHIELD:
|
||||
{
|
||||
if (_lastAncientDwarvenShieldGUIDs->empty())
|
||||
return ObjectGuid::Empty;
|
||||
|
||||
ObjectGuid guid = _lastAncientDwarvenShieldGUIDs->front();
|
||||
_lastAncientDwarvenShieldGUIDs->pop();
|
||||
return guid;
|
||||
}
|
||||
case DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD:
|
||||
return _lastUsedAncientDwarvenShieldGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
@@ -311,16 +315,14 @@ struct boss_atramedes : public BossAI
|
||||
break;
|
||||
case POINT_LAND_INTRO:
|
||||
me->SetDisableGravity(false);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
me->SetHover(false);
|
||||
me->SendSetPlayHoverAnim(false);
|
||||
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
_allowVertigoCast = true;
|
||||
break;
|
||||
case POINT_LIFTOFF:
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
me->SetDisableGravity(true);
|
||||
me->SendSetPlayHoverAnim(true);
|
||||
Talk(SAY_FLIGHT_PHASE);
|
||||
DoCastSelf(SPELL_SONAR_PULSE_TRIGGER);
|
||||
DoCastSelf(SPELL_ROARING_FLAME_BREATH);
|
||||
@@ -348,23 +350,18 @@ struct boss_atramedes : public BossAI
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_START_INTRO:
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
me->GetMotionMaster()->MovePoint(POINT_CAST_ROARING_BREATH, IntroFlightPosition1, false);
|
||||
break;
|
||||
case ACTION_HALT_REVERBERATING_FLAME:
|
||||
if (Creature* flame = ObjectAccessor::GetCreature(*me, _reverberatingFlameGUID))
|
||||
{
|
||||
flame->m_Events.AddEventAtOffset([flame]()
|
||||
{
|
||||
flame->InterruptNonMeleeSpells(true);
|
||||
flame->GetMotionMaster()->Clear();
|
||||
flame->StopMoving();
|
||||
flame->CastSpell(flame, SPELL_SONIC_FLAMES_FLIGHT, true);
|
||||
}, 1s);
|
||||
flame->InterruptNonMeleeSpells(true);
|
||||
flame->GetMotionMaster()->Clear();
|
||||
flame->StopMoving();
|
||||
|
||||
events.CancelEvent(EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT);
|
||||
events.ScheduleEvent(EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT, 7s, 0, PHASE_AIR);
|
||||
events.CancelEvent(EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD);
|
||||
events.CancelEvent(EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING);
|
||||
events.ScheduleEvent(EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD, 2s, 0, PHASE_AIR);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -411,7 +408,7 @@ struct boss_atramedes : public BossAI
|
||||
me->StopMoving();
|
||||
DoCastSelf(SPELL_SEARING_FLAME);
|
||||
// Patch 4.1: Searing Flame will put Modulation on a 6 seconds cooldown
|
||||
events.RescheduleEvent(EVENT_MODULATION, 6s);
|
||||
events.RescheduleEvent(EVENT_MODULATION, 6s, 0, PHASE_GROUND);
|
||||
break;
|
||||
case EVENT_SONIC_BREATH:
|
||||
DoCastAOE(SPELL_SONIC_BREATH);
|
||||
@@ -424,11 +421,22 @@ struct boss_atramedes : public BossAI
|
||||
DoCastSelf(SPELL_TAKE_OFF_ANIM_KIT);
|
||||
me->GetMotionMaster()->MoveTakeoff(POINT_LIFTOFF, LiftoffPosition);
|
||||
break;
|
||||
case EVENT_RESUME_REVERBERATING_FLAME_MOVEMENT:
|
||||
case EVENT_MOVE_REVERBERATING_FLAME_TO_SHIELD:
|
||||
if (Creature* flame = ObjectAccessor::GetCreature(*me, _reverberatingFlameGUID))
|
||||
{
|
||||
if (Creature* shield = ObjectAccessor::GetCreature(*me, _lastUsedAncientDwarvenShieldGUID))
|
||||
flame->GetMotionMaster()->MovePoint(POINT_NONE, shield->GetPosition());
|
||||
|
||||
if (flame->movespline)
|
||||
events.ScheduleEvent(EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING, flame->movespline->Duration(), 0, PHASE_AIR);
|
||||
}
|
||||
break;
|
||||
case EVENT_DESTROY_SHIELD_AND_RESUME_PLAYER_TRACKING:
|
||||
if (Unit* target = ObjectAccessor::GetUnit(*me, _lastShieldUserGUID))
|
||||
{
|
||||
if (Unit* flame = ObjectAccessor::GetUnit(*me, _reverberatingFlameGUID))
|
||||
{
|
||||
flame->CastSpell(flame, SPELL_SONIC_FLAMES);
|
||||
flame->CastSpell(target, SPELL_TRACKING);
|
||||
flame->GetMotionMaster()->MoveFollow(target, 0.0f, ChaseAngle(0.0f, 0.0f));
|
||||
}
|
||||
@@ -458,10 +466,9 @@ private:
|
||||
door->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
bool _allowVertigoCast;
|
||||
std::queue<ObjectGuid>* _lastAncientDwarvenShieldGUIDs;
|
||||
GuidSet _noisyPlayerGUIDs;
|
||||
ObjectGuid _lastShieldUserGUID;
|
||||
ObjectGuid _lastUsedAncientDwarvenShieldGUID;
|
||||
ObjectGuid _reverberatingFlameGUID;
|
||||
};
|
||||
|
||||
@@ -493,6 +500,51 @@ private:
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
struct npc_atramedes_lord_victor_nefarius : public NullCreatureAI
|
||||
{
|
||||
npc_atramedes_lord_victor_nefarius(Creature* creature) : NullCreatureAI(creature), _instance(me->GetInstanceScript()) { }
|
||||
|
||||
void IsSummonedBy(Unit* /*summoner*/) override
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_SAY_INTRO, 10s);
|
||||
me->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SAY_INTRO:
|
||||
Talk(SAY_INTRO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_DESTROY_SHIELD:
|
||||
Talk(SAY_DESTROY_SHIELD);
|
||||
DoCastAOE(SPELL_DESTROY_SHIELD);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
class spell_atramedes_modulation : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_atramedes_modulation);
|
||||
@@ -578,10 +630,7 @@ class spell_atramedes_resonating_clash_ground : public SpellScript
|
||||
if (!target || !caster || !target->IsAIEnabled)
|
||||
return;
|
||||
|
||||
target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_ANCIENT_DWARVEN_SHIELD);
|
||||
|
||||
// Verify this if it's blizzlike to destroy the shield immediately or just leave it not selectable...
|
||||
target->RemoveAurasDueToSpell(sSpellMgr->GetSpellIdForDifficulty(GetSpellInfo()->Effects[effIndex].BasePoints, target));
|
||||
target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD);
|
||||
target->CastSpell(target, GetSpellInfo()->Effects[effIndex].BasePoints, true);
|
||||
target->PlayDirectSound(SOUND_ID_ATRAMEDES_VERTIGO);
|
||||
|
||||
@@ -607,7 +656,7 @@ class spell_atramedes_resonating_clash_air : public SpellScript
|
||||
return;
|
||||
|
||||
if (Unit* shield = GetSpell()->GetOriginalCaster())
|
||||
target->AI()->SetGUID(shield->GetGUID(), DATA_LAST_ANCIENT_DWARVEN_SHIELD);
|
||||
target->AI()->SetGUID(shield->GetGUID(), DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD);
|
||||
|
||||
target->AI()->SetGUID(caster->GetGUID(), DATA_LAST_SHIELD_USER);
|
||||
|
||||
@@ -688,7 +737,24 @@ class spell_atramedes_vertigo : public AuraScript
|
||||
|
||||
void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
GetTarget()->CastSpell(GetTarget(), GetSpellInfo()->Effects[EFFECT_1].BasePoints, true);
|
||||
Unit* target = GetTarget();
|
||||
target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_1].BasePoints, true);
|
||||
|
||||
if (Creature* atramedes = target->ToCreature())
|
||||
{
|
||||
if (atramedes->IsAIEnabled)
|
||||
{
|
||||
if (InstanceScript* instance = atramedes->GetInstanceScript())
|
||||
{
|
||||
if (instance->GetData(DATA_IS_IN_INTRO_PHASE))
|
||||
atramedes->GetMotionMaster()->MovePoint(POINT_PREPARE_LAND_INTRO, IntroFlightPosition2, false);
|
||||
|
||||
if (Creature* nefarius = instance->GetCreature(DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES))
|
||||
if (nefarius->IsAIEnabled)
|
||||
nefarius->AI()->DoAction(ACTION_DESTROY_SHIELD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -705,7 +771,7 @@ class spell_atramedes_sonic_flames : public SpellScript
|
||||
{
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* atramedes = instance->GetCreature(DATA_ATRAMEDES))
|
||||
if (Creature* shield = ObjectAccessor::GetCreature(*GetCaster(), atramedes->AI()->GetGUID(DATA_LAST_ANCIENT_DWARVEN_SHIELD)))
|
||||
if (Creature* shield = ObjectAccessor::GetCreature(*GetCaster(), atramedes->AI()->GetGUID(DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD)))
|
||||
target = shield;
|
||||
}
|
||||
|
||||
@@ -748,27 +814,6 @@ private:
|
||||
ObjectGuid _guid;
|
||||
};
|
||||
|
||||
class spell_atramedes_sonic_flames_flight : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_atramedes_sonic_flames_flight);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
if (InstanceScript* instance = GetCaster()->GetInstanceScript())
|
||||
if (Creature* atramedes = instance->GetCreature(DATA_ATRAMEDES))
|
||||
if (ObjectGuid guid = atramedes->AI()->GetGUID(DATA_LAST_ANCIENT_DWARVEN_SHIELD))
|
||||
targets.remove_if(SonicFlamesGuidCheck(guid));
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_sonic_flames_flight::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_atramedes_devastation_trigger : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_atramedes_devastation_trigger);
|
||||
@@ -787,10 +832,68 @@ class spell_atramedes_devastation_trigger : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_atramedes_sonic_breath : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_atramedes_sonic_breath);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
targets.remove_if(Trinity::Predicates::IsVictimOf(GetCaster()));
|
||||
|
||||
if (targets.size() > 1)
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_sonic_breath::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class ValidInvalidShieldCheck
|
||||
{
|
||||
public:
|
||||
ValidInvalidShieldCheck(ObjectGuid guid) : _guid(guid) { }
|
||||
|
||||
bool operator()(WorldObject const* obj) const
|
||||
{
|
||||
return obj->GetGUID() == _guid || obj->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
private:
|
||||
ObjectGuid _guid;
|
||||
};
|
||||
|
||||
class spell_atramedes_destroy_shield : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_atramedes_destroy_shield);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
if (targets.empty())
|
||||
return;
|
||||
|
||||
if (Creature* creature = GetCaster()->ToCreature())
|
||||
if (creature->IsAIEnabled)
|
||||
targets.remove_if(ValidInvalidShieldCheck(creature->AI()->GetGUID(DATA_LAST_USED_ANCIENT_DWARVEN_SHIELD)));
|
||||
|
||||
if (targets.size() > 1)
|
||||
Trinity::Containers::RandomResize(targets, 1);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_atramedes_destroy_shield::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_atramedes()
|
||||
{
|
||||
RegisterBlackwingDescentCreatureAI(boss_atramedes);
|
||||
RegisterBlackwingDescentCreatureAI(npc_atramedes_ancient_dwarven_shield);
|
||||
RegisterBlackwingDescentCreatureAI(npc_atramedes_lord_victor_nefarius);
|
||||
RegisterSpellScript(spell_atramedes_modulation);
|
||||
RegisterSpellScript(spell_atramedes_roaring_flame_breath_reverse_cast);
|
||||
RegisterAuraScript(spell_atramedes_roaring_flame_breath);
|
||||
@@ -802,6 +905,7 @@ void AddSC_boss_atramedes()
|
||||
RegisterAuraScript(spell_atramedes_noisy);
|
||||
RegisterAuraScript(spell_atramedes_vertigo);
|
||||
RegisterSpellAndAuraScriptPair(spell_atramedes_sonic_flames, spell_atramedes_sonic_flames_AuraScript);
|
||||
RegisterSpellScript(spell_atramedes_sonic_flames_flight);
|
||||
RegisterAuraScript(spell_atramedes_devastation_trigger);
|
||||
RegisterSpellScript(spell_atramedes_sonic_breath);
|
||||
RegisterSpellScript(spell_atramedes_destroy_shield);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "Creature.h"
|
||||
#include "GameObject.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "MapManager.h"
|
||||
#include "blackwing_descent.h"
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
@@ -33,6 +34,7 @@ ObjectData const creatureData[] =
|
||||
{ NPC_NEFARIAN_MAGMAW, DATA_NEFARIAN_MAGMAW },
|
||||
{ NPC_LORD_VICTOR_NEFARIUS_OMNOTRON, DATA_LORD_VICTOR_NEFARIUS_OMNOTRON },
|
||||
{ NPC_COLUMN_OF_LIGHT, DATA_COLUMN_OF_LIGHT },
|
||||
{ NPC_LORD_VICTOR_NEFARIUS_ATRAMEDES, DATA_LORD_VICTOR_NEFARIUS_ATRAMEDES },
|
||||
{ 0, 0 } // END
|
||||
};
|
||||
|
||||
@@ -68,6 +70,16 @@ enum Actions
|
||||
ACTION_START_ATRAMEDES_INTRO = 0
|
||||
};
|
||||
|
||||
enum SpawnGroup
|
||||
{
|
||||
SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS = 400
|
||||
};
|
||||
|
||||
enum SummonGroups
|
||||
{
|
||||
SUMMON_GROUP_ATRAMEDES_INTRO = 0
|
||||
};
|
||||
|
||||
class instance_blackwing_descent : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
@@ -87,21 +99,12 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
void Initialize()
|
||||
{
|
||||
_deadDwarfSpirits = 0;
|
||||
_initialized = false;
|
||||
_atramedesIntro = NOT_STARTED;
|
||||
_atramedesIntroState = NOT_STARTED;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* /*player*/) override
|
||||
void Create() override
|
||||
{
|
||||
if (_initialized)
|
||||
return;
|
||||
|
||||
std::list<TempSummon*> summoned;
|
||||
instance->SummonCreatureGroup(SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS, &summoned);
|
||||
for (TempSummon* summon : summoned)
|
||||
_ancientDwarvenShieldGUIDs.push_back(summon->GetGUID());
|
||||
|
||||
_initialized = true;
|
||||
instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
@@ -166,7 +169,7 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ANCIENT_BELL:
|
||||
if (_deadDwarfSpirits == 8 && _atramedesIntro != DONE)
|
||||
if (_deadDwarfSpirits == 8 && _atramedesIntroState != DONE)
|
||||
{
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
if (Creature* column = instance->SummonCreature(NPC_COLUMN_OF_LIGHT, ColumnOfLightPosition))
|
||||
@@ -228,13 +231,11 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
case DATA_ATRAMEDES:
|
||||
if (state == FAIL)
|
||||
{
|
||||
for (ObjectGuid guid : _ancientDwarvenShieldGUIDs)
|
||||
if (Creature* shield = instance->GetCreature(guid))
|
||||
shield->DespawnOrUnsummon();
|
||||
|
||||
_ancientDwarvenShieldGUIDs.clear();
|
||||
_events.ScheduleEvent(EVENT_RESPAWN_ATRAMEDES, 30s);
|
||||
instance->SpawnGroupDespawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, false);
|
||||
}
|
||||
else if (state == DONE)
|
||||
instance->SpawnGroupDespawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -253,18 +254,28 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
|
||||
if (_deadDwarfSpirits == 8)
|
||||
{
|
||||
instance->SummonCreatureGroup(SUMMON_GROUP_ATRAMEDES_INTRO);
|
||||
std::list<TempSummon*> summoned;
|
||||
instance->SummonCreatureGroup(SUMMON_GROUP_ATRAMEDES_INTRO, &summoned);
|
||||
for (TempSummon* summon : summoned)
|
||||
_atramedesIntroGUIDs.push_back(summon->GetGUID());
|
||||
|
||||
instance->SummonCreature(NPC_COLUMN_OF_LIGHT, ColumnOfLightPosition);
|
||||
_events.ScheduleEvent(EVENT_MAKE_ANCIENT_BELL_SELECTABLE, 4s + 500ms);
|
||||
}
|
||||
break;
|
||||
case DATA_ATRAMEDES_INTRO:
|
||||
_atramedesIntro = data;
|
||||
_atramedesIntroState = data;
|
||||
|
||||
if (Creature* atramedes = instance->SummonCreature(BOSS_ATRAMEDES, AtramedesIntroSummonPosition))
|
||||
{
|
||||
for (ObjectGuid guid : _atramedesIntroGUIDs)
|
||||
if (Creature* intro = instance->GetCreature(guid))
|
||||
intro->DespawnOrUnsummon();
|
||||
|
||||
atramedes->SetDisableGravity(true);
|
||||
atramedes->SetHover(true);
|
||||
atramedes->SetReactState(REACT_PASSIVE);
|
||||
atramedes->SendSetPlayHoverAnim(true);
|
||||
atramedes->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_HOVER);
|
||||
atramedes->AI()->DoAction(ACTION_START_ATRAMEDES_INTRO);
|
||||
}
|
||||
|
||||
@@ -280,7 +291,7 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
switch (type)
|
||||
{
|
||||
case DATA_ATRAMEDES_INTRO:
|
||||
return _atramedesIntro;
|
||||
return _atramedesIntroState;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -357,7 +368,7 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
column->CastSpell(column, SPELL_COLUMN_OF_LIGHT);
|
||||
break;
|
||||
case EVENT_RESPAWN_ATRAMEDES:
|
||||
instance->SummonCreatureGroup(SUMMON_GROUP_ANCIENT_DWARVEN_SHIELDS);
|
||||
instance->SpawnGroupSpawn(SPAWN_GROUP_ANCIENT_DWARVEN_SHIELDS, true);
|
||||
instance->SummonCreature(BOSS_ATRAMEDES, AtramedesRespawnPosition);
|
||||
break;
|
||||
default:
|
||||
@@ -369,17 +380,20 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
void WriteSaveDataMore(std::ostringstream& data) override
|
||||
{
|
||||
data << _deadDwarfSpirits << ' '
|
||||
<< _atramedesIntro;
|
||||
<< _atramedesIntroState;
|
||||
}
|
||||
|
||||
void ReadSaveDataMore(std::istringstream& data) override
|
||||
{
|
||||
data >> _deadDwarfSpirits;
|
||||
data >> _atramedesIntro;
|
||||
data >> _atramedesIntroState;
|
||||
|
||||
// Atramedes' intro is done but he has not been defeated yet: spawm him at his respawn location
|
||||
if (_atramedesIntro == DONE && GetBossState(DATA_ATRAMEDES) != DONE)
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -389,10 +403,9 @@ class instance_blackwing_descent : public InstanceMapScript
|
||||
ObjectGuid _roomStalkerTargetDummyLeftGuid;
|
||||
ObjectGuid _roomStalkerTargetDummyRightGuid;
|
||||
GuidVector _roomStalkerGUIDs;
|
||||
GuidVector _ancientDwarvenShieldGUIDs;
|
||||
GuidVector _atramedesIntroGUIDs;
|
||||
uint8 _deadDwarfSpirits;
|
||||
uint8 _atramedesIntro;
|
||||
bool _initialized;
|
||||
uint8 _atramedesIntroState;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
|
||||
Reference in New Issue
Block a user