Scripts/SFK: rewrite Baron Ashbury encounter

This commit is contained in:
Ovahlord
2018-12-25 21:30:57 +01:00
parent 58375cf35c
commit 570ffbff7b
3 changed files with 286 additions and 251 deletions

View File

@@ -0,0 +1,31 @@
UPDATE `creature_template` SET `InhabitType`= 4 WHERE `entry`= 50604;
DELETE FROM `vehicle_template_accessory` WHERE `entry`IN (46962, 49708);
INSERT INTO `vehicle_template_accessory` (`entry`, `accessory_entry`, `seat_id`, `minion`, `description`, `summontype`, `summontimer`) VALUES
(46962, 50604, 0, 1, 'Baron Ashbury - Wings', 5, 0),
(49708, 50604, 0, 1, 'Baron Ashbury - Wings', 5, 0);
DELETE FROM `npc_spellclick_spells` WHERE `npc_entry`IN (46962, 49708);
INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES
(46962, 46598, 1, 1),
(49708, 46598, 1, 1);
DELETE FROM `spell_linked_spell` WHERE `spell_trigger`= 93766;
DELETE FROM `spell_script_names` WHERE `ScriptName` IN
('spell_sfk_asphyxiate',
'spell_ashbury_asphyxiate',
'spell_sfk_pain_and_suffering',
'spell_ashbury_pain_and_suffering',
'spell_ashbury_dark_archangel_form');
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
(93423, 'spell_ashbury_asphyxiate'),
(93710, 'spell_ashbury_asphyxiate'),
(93581, 'spell_ashbury_pain_and_suffering'),
(93712, 'spell_ashbury_pain_and_suffering'),
(93757, 'spell_ashbury_dark_archangel_form');
-- Conditions
DELETE FROM `conditions` WHERE `SourceEntry`= 93766 AND `SourceTypeOrReferenceId`= 13;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ScriptName`, `Comment`) VALUES
(13, 1, 93766, 0, 0, 31, 0, 3, 50604, 0, 0, 0, '', 'Dark Archangel Form - Target Wings');

View File

@@ -30,38 +30,36 @@ enum Spells
SPELL_ASPHYXIATE = 93423,
SPELL_ASPHYXIATE_ROOT = 93422,
SPELL_ASPHYXIATE_DAMAGE = 93424,
SPELL_STAY_OF_EXECUTION = 93468,
SPELL_STAY_OF_EXECUTION_HC = 93705,
SPELL_PAIN_AND_SUFFERING = 93581,
SPELL_PAIN_AND_SUFFERING_DUMMY = 93605,
SPELL_WRACKING_PAIN = 93720,
SPELL_DARK_ARCHANGEL = 93757,
SPELL_CALAMITY_CHANNEL = 93812,
// Wings
SPELL_RIDE_VEHICLE_HARDCODED = 46598,
SPELL_CALAMITY_AURA = 93766
SPELL_DARK_ARCHANGEL_FORM = 93757,
SPELL_CALAMITY = 93812
};
#define SPELL_STAY_OF_EXECUTION RAID_MODE<uint32>(93468, 93705)
enum Texts
{
SAY_AGGRO = 1,
SAY_ASPHYXIATE = 2,
SAY_ANNOUNCE_STAY = 3,
SAY_STAY_EXECUTION = 4,
SAY_ARCHANGEL = 5,
SAY_DEATH = 6
// Baron Ashbury
SAY_AGGRO = 1,
SAY_ASPHYXIATE = 2,
SAY_ANNOUNCE_STAY_OF_EXECUTION = 3,
SAY_STAY_OF_EXECUTION = 4,
SAY_ARCHANGEL_FORM = 5,
SAY_DEATH = 6
};
enum Events
{
// Baron Ashbury
EVENT_ASPHYXIATE = 1,
EVENT_STAY_OF_EXECUTION,
EVENT_PAIN_AND_SUFFERING,
EVENT_WRACKING_PAIN,
EVENT_DARK_ARCHANGEL,
EVENT_APPLY_IMMUNITY,
EVENT_DISABLE_ACHIEVEMENT
EVENT_DARK_ARCHANGEL_FORM,
EVENT_DISABLE_ACHIEVEMENT,
EVENT_APPLY_INTERRUPT_IMMUNITY
};
enum AchievementData
@@ -69,282 +67,287 @@ enum AchievementData
DATA_PARDON_DENIED = 1
};
class boss_baron_ashbury : public CreatureScript
struct boss_baron_ashbury : public BossAI
{
public:
boss_baron_ashbury() : CreatureScript("boss_baron_ashbury") { }
struct boss_baron_ashburyAI : public BossAI
boss_baron_ashbury(Creature* creature) : BossAI(creature, DATA_BARON_ASHBURY)
{
boss_baron_ashburyAI(Creature* creature) : BossAI(creature, DATA_BARON_ASHBURY)
{
}
Initialize();
}
void Reset() override
{
_Reset();
_isArchangel = false;
_canAttack = true;
_pardonDenied = true;
me->SetReactState(REACT_PASSIVE);
MakeInterruptable(false);
}
void Initialize()
{
_phaseTwoTriggered = false;
_isInArchangelForm = false;
_canAttack = true;
_pardonDenied = true;
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
me->SetReactState(REACT_AGGRESSIVE);
events.ScheduleEvent(EVENT_ASPHYXIATE, Seconds(20));
events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, Seconds(5) + Milliseconds(500));
if (IsHeroic())
events.ScheduleEvent(EVENT_WRACKING_PAIN, Seconds(14));
}
void Reset() override
{
_Reset();
_phaseTwoTriggered = false;
_isInArchangelForm = false;
_canAttack = true;
_pardonDenied = true;
me->MakeInterruptable(false);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WRACKING_PAIN);
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me);
void EnterEvadeMode(EvadeReason /*why*/) override
{
_EnterEvadeMode();
summons.DespawnAll();
instance->SetBossState(DATA_BARON_ASHBURY, FAIL);
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WRACKING_PAIN);
MakeInterruptable(false);
me->SetReactState(REACT_PASSIVE);
_DespawnAtEvade();
}
events.ScheduleEvent(EVENT_ASPHYXIATE, 20s);
events.ScheduleEvent(EVENT_PAIN_AND_SUFFERING, 5s + 500ms);
if (IsHeroic())
events.ScheduleEvent(EVENT_WRACKING_PAIN, 14s);
}
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override
void JustDied(Unit* /*killer*/) override
{
_JustDied();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WRACKING_PAIN);
Talk(SAY_DEATH);
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
_EnterEvadeMode();
summons.DespawnAll();
instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_WRACKING_PAIN);
_DespawnAtEvade();
}
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
if (me->HealthBelowPctDamaged(25, damage) && !_phaseTwoTriggered && IsHeroic())
{
if (me->HealthBelowPct(25) && !_isArchangel && IsHeroic())
events.CancelEvent(EVENT_PAIN_AND_SUFFERING);
events.CancelEvent(EVENT_ASPHYXIATE);
events.CancelEvent(EVENT_STAY_OF_EXECUTION);
events.CancelEvent(EVENT_APPLY_INTERRUPT_IMMUNITY);
events.ScheduleEvent(EVENT_DARK_ARCHANGEL_FORM, 1ms);
_phaseTwoTriggered = true;
}
}
void OnSpellCastInterrupt(SpellInfo const* spell) override
{
me->MakeInterruptable(false);
events.CancelEvent(EVENT_APPLY_INTERRUPT_IMMUNITY);
if (spell->Id == SPELL_STAY_OF_EXECUTION && IsHeroic())
events.CancelEvent(EVENT_DISABLE_ACHIEVEMENT);
}
void OnSuccessfulSpellCast(SpellInfo const* spell) override
{
if (spell->Id == SPELL_STAY_OF_EXECUTION && !IsHeroic())
{
me->MakeInterruptable(false);
events.CancelEvent(EVENT_APPLY_INTERRUPT_IMMUNITY);
}
else if (spell->Id == SPELL_DARK_ARCHANGEL_FORM)
_isInArchangelForm = true;
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_PARDON_DENIED:
return _pardonDenied;
default:
break;
}
return 0;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING) && !_isInArchangelForm)
return;
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
events.Reset();
events.ScheduleEvent(EVENT_DARK_ARCHANGEL, Milliseconds(1));
_isArchangel = true;
}
}
void OnSpellCastInterrupt(SpellInfo const* spell) override
{
MakeInterruptable(false);
events.CancelEvent(EVENT_APPLY_IMMUNITY);
if (spell->Id == SPELL_STAY_OF_EXECUTION_HC && _pardonDenied)
events.CancelEvent(EVENT_DISABLE_ACHIEVEMENT);
}
void MakeInterruptable(bool apply)
{
me->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, !apply);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, !apply);
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_PARDON_DENIED:
return _pardonDenied;
case EVENT_ASPHYXIATE:
Talk(SAY_ASPHYXIATE);
DoCastAOE(SPELL_ASPHYXIATE);
events.ScheduleEvent(EVENT_STAY_OF_EXECUTION, 7s);
_canAttack = false;
break;
case EVENT_STAY_OF_EXECUTION:
me->StopMoving();
me->MakeInterruptable(true);
Talk(SAY_STAY_OF_EXECUTION);
Talk(SAY_ANNOUNCE_STAY_OF_EXECUTION);
DoCastAOE(SPELL_STAY_OF_EXECUTION);
events.ScheduleEvent(EVENT_ASPHYXIATE, 45s);
_canAttack = true;
if (IsHeroic())
{
events.ScheduleEvent(EVENT_DISABLE_ACHIEVEMENT, 8s);
events.ScheduleEvent(EVENT_APPLY_INTERRUPT_IMMUNITY, 8s);
}
break;
case EVENT_PAIN_AND_SUFFERING:
me->MakeInterruptable(true);
me->StopMoving();
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
{
DoCast(target, SPELL_PAIN_AND_SUFFERING);
events.ScheduleEvent(EVENT_APPLY_INTERRUPT_IMMUNITY, 6s);
}
events.Repeat(26s + 500ms);
break;
case EVENT_WRACKING_PAIN:
DoCastAOE(SPELL_WRACKING_PAIN, true);
events.Repeat(26s + 500ms);
break;
case EVENT_DARK_ARCHANGEL_FORM:
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
me->MakeInterruptable(false);
Talk(SAY_ARCHANGEL_FORM);
DoCastAOE(SPELL_DARK_ARCHANGEL_FORM);
break;
case EVENT_DISABLE_ACHIEVEMENT:
_pardonDenied = false;
break;
case EVENT_APPLY_INTERRUPT_IMMUNITY:
me->MakeInterruptable(false);
break;
default:
break;
}
return 0;
}
if (_canAttack)
DoMeleeAttackIfReady();
}
private:
bool _phaseTwoTriggered;
bool _isInArchangelForm;
bool _canAttack;
bool _pardonDenied;
};
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
class spell_ashbury_asphyxiate : public AuraScript
{
PrepareAuraScript(spell_ashbury_asphyxiate);
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ASPHYXIATE:
Talk(SAY_ASPHYXIATE);
DoCastAOE(SPELL_ASPHYXIATE);
events.ScheduleEvent(EVENT_STAY_OF_EXECUTION, Seconds(7));
_canAttack = false;
break;
case EVENT_STAY_OF_EXECUTION:
if (IsHeroic())
{
MakeInterruptable(true);
events.ScheduleEvent(EVENT_APPLY_IMMUNITY, Seconds(8));
events.ScheduleEvent(EVENT_DISABLE_ACHIEVEMENT, Seconds(8));
}
Talk(SAY_STAY_EXECUTION);
Talk(SAY_ANNOUNCE_STAY);
DoCastAOE(SPELL_STAY_OF_EXECUTION);
events.ScheduleEvent(EVENT_ASPHYXIATE, Seconds(45));
_canAttack = true;
break;
case EVENT_PAIN_AND_SUFFERING:
MakeInterruptable(true);
me->StopMoving();
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
DoCast(target, SPELL_PAIN_AND_SUFFERING);
events.ScheduleEvent(EVENT_APPLY_IMMUNITY, IsHeroic() ? Seconds(6) : Seconds(8));
events.Repeat(Seconds(26) + Milliseconds(500));
break;
case EVENT_WRACKING_PAIN:
DoCastAOE(SPELL_WRACKING_PAIN);
events.Repeat(Seconds(26) + Milliseconds(500));
break;
case EVENT_DARK_ARCHANGEL:
Talk(SAY_ARCHANGEL);
me->CastStop();
DoCastAOE(SPELL_DARK_ARCHANGEL);
me->AttackStop();
me->SetReactState(REACT_PASSIVE);
MakeInterruptable(false);
if (Creature* wings = DoSummon(NPC_ASHBURY_WINGS, me->GetPosition(), 0, TEMPSUMMON_MANUAL_DESPAWN))
wings->CastSpell(me, SPELL_RIDE_VEHICLE_HARDCODED);
break;
case EVENT_APPLY_IMMUNITY:
MakeInterruptable(true);
break;
case EVENT_DISABLE_ACHIEVEMENT:
_pardonDenied = false;
break;
default:
break;
}
}
if (_canAttack)
DoMeleeAttackIfReady();
}
private:
bool _isArchangel;
bool _canAttack;
bool _pardonDenied;
};
CreatureAI* GetAI(Creature *creature) const override
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return GetShadowfangKeepAI<boss_baron_ashburyAI>(creature);
return ValidateSpellInfo({ SPELL_ASPHYXIATE_ROOT });
}
void HandleTriggerSpell(AuraEffect const* aurEff)
{
PreventDefaultAction();
if (Unit* caster = GetCaster())
{
if (Unit* target = GetTarget())
{
uint32 triggerSpell = GetSpellInfo()->Effects[EFFECT_2].TriggerSpell;
uint64 damage = target->GetMaxHealth() / GetSpellInfo()->GetMaxTicks();
if (damage >= target->GetHealth())
damage = target->GetHealth() - 1;
if (!target->HasAura(SPELL_ASPHYXIATE_ROOT))
target->CastSpell(target, SPELL_ASPHYXIATE_ROOT, true);
target->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, damage, target, true, nullptr, aurEff, caster->GetGUID());
}
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ashbury_asphyxiate::HandleTriggerSpell, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
class spell_sfk_asphyxiate : public SpellScriptLoader
class spell_ashbury_pain_and_suffering : public AuraScript
{
public:
spell_sfk_asphyxiate() : SpellScriptLoader("spell_sfk_asphyxiate") { }
PrepareAuraScript(spell_ashbury_pain_and_suffering);
class spell_sfk_asphyxiate_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
PrepareAuraScript(spell_sfk_asphyxiate_AuraScript);
return ValidateSpellInfo({ SPELL_PAIN_AND_SUFFERING_DUMMY });
}
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_ASPHYXIATE_ROOT });
}
void HandleTriggerSpell(AuraEffect const* aurEff)
{
PreventDefaultAction();
void OnPeriodic(AuraEffect const* aurEff)
{
if (Unit* owner = GetTarget())
if (Unit* caster = GetCaster())
{
if (Unit* target = GetTarget())
{
uint32 triggerSpell = GetSpellInfo()->Effects[EFFECT_2].TriggerSpell;
uint64 damage = target->GetMaxHealth() / GetSpellInfo()->GetMaxTicks();
owner->CastSpell(caster, SPELL_PAIN_AND_SUFFERING_DUMMY, true);
if (damage > target->GetHealth())
damage = target->GetHealth() - 1;
uint64 damage = aurEff->GetBaseAmount() * aurEff->GetTickNumber();
GetEffect(EFFECT_0)->ChangeAmount(damage);
}
if (!target->HasAura(SPELL_ASPHYXIATE_ROOT))
target->CastSpell(target, SPELL_ASPHYXIATE_ROOT, true);
target->CastCustomSpell(triggerSpell, SPELLVALUE_BASE_POINT0, damage, target, true, nullptr, aurEff, caster->GetGUID());
}
}
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_sfk_asphyxiate_AuraScript::HandleTriggerSpell, EFFECT_2, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_sfk_asphyxiate_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ashbury_pain_and_suffering::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
class spell_sfk_pain_and_suffering : public SpellScriptLoader
class spell_ashbury_dark_archangel_form : public AuraScript
{
public:
spell_sfk_pain_and_suffering() : SpellScriptLoader("spell_sfk_pain_and_suffering") { }
PrepareAuraScript(spell_ashbury_dark_archangel_form);
class spell_sfk_pain_and_suffering_AuraScript : public AuraScript
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_CALAMITY });
}
void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
if (Unit* target = GetTarget())
{
PrepareAuraScript(spell_sfk_pain_and_suffering_AuraScript);
bool Validate(SpellInfo const* /*spellInfo*/) override
{
return ValidateSpellInfo({ SPELL_PAIN_AND_SUFFERING_DUMMY });
}
void OnPeriodic(AuraEffect const* aurEff)
{
if (Unit* owner = GetOwner()->ToUnit())
if (InstanceScript* instance = owner->GetInstanceScript())
if (Creature* ashbury = instance->GetCreature(DATA_BARON_ASHBURY))
owner->CastSpell(ashbury, SPELL_PAIN_AND_SUFFERING_DUMMY, true);
uint64 damage = aurEff->GetBaseAmount() * aurEff->GetTickNumber();
GetEffect(EFFECT_0)->ChangeAmount(damage);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_sfk_pain_and_suffering_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE);
}
};
AuraScript* GetAuraScript() const override
{
return new spell_sfk_pain_and_suffering_AuraScript();
target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_0].BasePoints, true);
target->CastSpell(target, SPELL_CALAMITY, true);
}
}
void Register() override
{
AfterEffectApply += AuraEffectApplyFn(spell_ashbury_dark_archangel_form::AfterApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
class achievement_pardon_denied : public AchievementCriteriaScript
{
public:
achievement_pardon_denied() : AchievementCriteriaScript("achievement_pardon_denied") { }
public:
achievement_pardon_denied() : AchievementCriteriaScript("achievement_pardon_denied") { }
bool OnCheck(Player* /*source*/, Unit* target)
{
if (!target)
return false;
if (target->GetMap()->IsHeroic())
return target->GetAI()->GetData(DATA_PARDON_DENIED);
bool OnCheck(Player* /*source*/, Unit* target)
{
if (!target)
return false;
if (target->GetMap()->IsHeroic())
return target->GetAI()->GetData(DATA_PARDON_DENIED);
return false;
}
}
};
void AddSC_boss_baron_ashbury()
{
new boss_baron_ashbury();
new spell_sfk_asphyxiate();
new spell_sfk_pain_and_suffering();
RegisterShadowfangKeepCreatureAI(boss_baron_ashbury);
RegisterAuraScript(spell_ashbury_asphyxiate);
RegisterAuraScript(spell_ashbury_pain_and_suffering);
RegisterAuraScript(spell_ashbury_dark_archangel_form);
new achievement_pardon_denied();
}

View File

@@ -45,7 +45,6 @@ enum SKCreatures
{
// Baron Ashbury
BOSS_BARON_ASHBURY = 46962,
NPC_ASHBURY_WINGS = 50604,
// Baron Silverlaine
BOSS_BARON_SILVERLAINE = 3887,
@@ -295,4 +294,6 @@ AI* GetShadowfangKeepAI(Creature* creature)
return GetInstanceAI<AI>(creature, SKScriptName);
}
#define RegisterShadowfangKeepCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetShadowfangKeepAI)
#endif