aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp1347
1 files changed, 1302 insertions, 45 deletions
diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
index 7f7a2fcc343..57736e31c01 100644
--- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
@@ -1150,11 +1150,14 @@ class spell_silverpine_forsaken_trooper_masterscript_high_command : public Spell
enum SylvanasForsakenHighCommand
{
- NPC_FORSAKEN_WARHORSE = 73595,
+ QUEST_NO_ESCAPE = 27099,
- SPELL_SUMMON_FORSAKEN_WARHORSE = 148164,
+ NPC_FORSAKEN_WARHORSE_SERVERSIDE = 73595,
+
+ SPELL_SUMMON_FORSAKEN_WARHORSE_SERVERSIDE = 148164,
SPELL_APPLY_INVIS_ZONE_1 = 83231,
- SPELL_APPLY_INVIS_ZONE_4 = 84183
+ SPELL_APPLY_INVIS_ZONE_4 = 84183,
+ SPELL_DESPAWN_ALL_SUMMONS_AGATHA = 84011
};
// 44365 - Lady Sylvanas Windrunner (Forsaken High Command)
@@ -1164,11 +1167,32 @@ struct npc_silverpine_sylvanas_windrunner_high_command : public ScriptedAI
void JustAppeared() override
{
- DoCastSelf(SPELL_SUMMON_FORSAKEN_WARHORSE);
+ DoCastSelf(SPELL_SUMMON_FORSAKEN_WARHORSE_SERVERSIDE);
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ switch (summon->GetEntry())
+ {
+ case NPC_FORSAKEN_WARHORSE_SERVERSIDE:
+ // Note: the Forsaken Horse must be set in the same visibility mask that Sylvanas is in.
+ summon->CastSpell(summon, me->HasAura(SPELL_APPLY_INVIS_ZONE_1) ? SPELL_APPLY_INVIS_ZONE_1 : SPELL_APPLY_INVIS_ZONE_4, true);
+ break;
+ default:
+ break;
+ }
+ }
- // Note: the Forsaken Horse must be set in the same visibility mask that Sylvanas is in.
- if (Creature* forsakenWarhorse = me->FindNearestCreature(NPC_FORSAKEN_WARHORSE, 5.0f, true))
- forsakenWarhorse->CastSpell(forsakenWarhorse, me->HasAura(SPELL_APPLY_INVIS_ZONE_1) ? SPELL_APPLY_INVIS_ZONE_1 : SPELL_APPLY_INVIS_ZONE_4, true);
+ void OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 /*opt*/) override
+ {
+ switch (quest->GetQuestId())
+ {
+ case QUEST_NO_ESCAPE:
+ player->CastSpell(player, SPELL_DESPAWN_ALL_SUMMONS_AGATHA, true);
+ break;
+ default:
+ break;
+ }
}
};
@@ -3945,36 +3969,30 @@ enum SkitterwebMatriarch
SPELL_VENOM_SPLASH = 79607,
EVENT_MATRIARCH_AGGRO = 1,
- EVENT_SUMMON_SPIDERLINGS = 4,
- EVENT_VENOM_SPLASH = 5,
+ EVENT_RESET_POSITION = 4,
+ EVENT_SUMMON_SPIDERLINGS = 5,
+ EVENT_VENOM_SPLASH = 6,
ANIMKIT_MATRIARCH_INTERACT = 1,
- ANIMKIT_MATRIARCH_POSITION1 = 865,
- ANIMKIT_MATRIARCH_POSITION2 = 866
+ ANIMKIT_MATRIARCH_LURKING_ON_CEILING = 865,
+ ANIMKIT_MATRIARCH_HANGING_BY_WEB = 866
};
// 44906 - Skitterweb Matriarch
struct npc_silverpine_skitterweb_matriarch : public ScriptedAI
{
- npc_silverpine_skitterweb_matriarch(Creature* creature) : ScriptedAI(creature), _alreadyPulled(false) { }
+ npc_silverpine_skitterweb_matriarch(Creature* creature) : ScriptedAI(creature) {}
void JustAppeared() override
{
- _alreadyPulled = false;
-
me->SetDisableGravity(true);
me->SetHover(true);
- me->SetAIAnimKitId(ANIMKIT_MATRIARCH_POSITION1);
+ _lurkingOnCeilingPos = me->GetPosition();
- me->SetReactState(REACT_PASSIVE);
+ me->SetAIAnimKitId(ANIMKIT_MATRIARCH_LURKING_ON_CEILING);
me->CastSpell(nullptr, SPELL_SKITTERWEB, true);
-
- std::vector<Creature*> stalkers;
- me->GetCreatureListWithEntryInGrid(stalkers, NPC_MUTANT_BUSH_CHICKEN, 5.0f);
- for (Creature* stalker : stalkers)
- _stalkerGUIDs.push_back(stalker->GetGUID());
}
void Reset() override
@@ -3982,19 +4000,36 @@ struct npc_silverpine_skitterweb_matriarch : public ScriptedAI
_events.Reset();
}
- void JustEngagedWith(Unit* /*who*/) override
+ void JustReachedHome() override
{
- if (!_alreadyPulled)
- {
- _alreadyPulled = true;
+ me->SetDisableGravity(true);
+ me->SetHover(true);
+
+ me->CastSpell(nullptr, SPELL_SKITTERWEB, true);
- me->SetAIAnimKitId(ANIMKIT_RESET);
- me->PlayOneShotAnimKitId(ANIMKIT_MATRIARCH_POSITION2);
+ me->SetAIAnimKitId(ANIMKIT_MATRIARCH_HANGING_BY_WEB);
- _events.ScheduleEvent(EVENT_MATRIARCH_AGGRO, 2s + 500ms);
- }
- else
- ScheduleEvents();
+ me->GetMotionMaster()->MoveJump(_lurkingOnCeilingPos, 8.0f, 8.0f);
+
+ _events.ScheduleEvent(EVENT_RESET_POSITION, 1s + 500ms);
+ }
+
+ void JustSummoned(Creature* summon) override
+ {
+ if (Unit* victim = me->GetVictim())
+ summon->Attack(victim, true);
+ }
+
+ void JustEngagedWith(Unit* who) override
+ {
+ _attackerGUID = who->GetGUID();
+
+ me->AttackStop();
+
+ me->SetAIAnimKitId(ANIMKIT_RESET);
+ me->PlayOneShotAnimKitId(ANIMKIT_MATRIARCH_HANGING_BY_WEB);
+
+ _events.ScheduleEvent(EVENT_MATRIARCH_AGGRO, 3s + 500ms);
}
void UpdateAI(uint32 diff) override
@@ -4013,19 +4048,22 @@ struct npc_silverpine_skitterweb_matriarch : public ScriptedAI
break;
case EVENT_MATRIARCH_AGGRO + 1:
- for (ObjectGuid const& stalkerGUID : _stalkerGUIDs)
- {
- if (Creature* stalker = ObjectAccessor::GetCreature(*me, stalkerGUID))
- stalker->RemoveAura(SPELL_SKITTERWEB);
- }
- me->SetAIAnimKitId(ANIMKIT_MATRIARCH_INTERACT);
+ me->PlayOneShotAnimKitId(ANIMKIT_MATRIARCH_INTERACT);
+ me->CastStop();
me->SetHomePosition(me->GetPosition());
- _events.ScheduleEvent(EVENT_MATRIARCH_AGGRO + 2, 1s);
+ _events.ScheduleEvent(EVENT_MATRIARCH_AGGRO + 2, 1s + 500ms);
break;
case EVENT_MATRIARCH_AGGRO + 2:
- me->SetReactState(REACT_AGGRESSIVE);
- ScheduleEvents();
+ if (Unit* attacker = ObjectAccessor::GetUnit(*me, _attackerGUID))
+ ScheduleCombatEvents(attacker);
+ break;
+
+ case EVENT_RESET_POSITION:
+ me->SetFacingTo(0.820305f);
+ me->SetHomePosition(me->GetPosition());
+
+ me->SetAIAnimKitId(ANIMKIT_MATRIARCH_LURKING_ON_CEILING);
break;
case EVENT_SUMMON_SPIDERLINGS:
@@ -4048,16 +4086,1219 @@ struct npc_silverpine_skitterweb_matriarch : public ScriptedAI
DoMeleeAttackIfReady();
}
- void ScheduleEvents()
+ void ScheduleCombatEvents(Unit* who)
+ {
+ me->Attack(who, true);
+
+ _events.ScheduleEvent(EVENT_SUMMON_SPIDERLINGS, 5s);
+ _events.ScheduleEvent(EVENT_VENOM_SPLASH, 9s, 14s);
+ }
+
+private:
+ EventMap _events;
+ Position _lurkingOnCeilingPos;
+ ObjectGuid _attackerGUID;
+};
+
+enum BondoftheValkyr
+{
+ SPELL_SUMMON_AGATHA_FENRIS = 83982
+};
+
+// 83979 - Bond of the Val'kyr
+class spell_silverpine_bond_of_the_valkyr : public AuraScript
+{
+ PrepareAuraScript(spell_silverpine_bond_of_the_valkyr);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_SUMMON_AGATHA_FENRIS });
+ }
+
+ void OnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->CastSpell(GetTarget(), SPELL_SUMMON_AGATHA_FENRIS, true);
+ }
+
+ void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
+ {
+ GetTarget()->RemoveAura(SPELL_SUMMON_AGATHA_FENRIS);
+ }
+
+ void Register() override
+ {
+ OnEffectApply += AuraEffectApplyFn(spell_silverpine_bond_of_the_valkyr::OnApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ OnEffectRemove += AuraEffectRemoveFn(spell_silverpine_bond_of_the_valkyr::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
+ }
+};
+
+Position const AgathaBackFrontyardPos = { 982.57f, 671.04f, 77.298f };
+
+enum AgathaFenrisIsle
+{
+ NPC_AGATHA_FENRIS = 44951,
+
+ SPELL_BOND_OF_THE_VALKYR = 83979,
+ SPELL_MARK_MASTER_AS_DESUMMONED = 80929,
+ SPELL_AGATHA_BROADCAST = 83978,
+ SPELL_DOOMHOWL = 84012,
+ SPELL_UNHOLY_DARKNESS = 84013,
+ SPELL_UNHOLY_SMITE = 84014,
+ SPELL_GENERAL_TRIGGER_84114 = 84114,
+ SPELL_GENERAL_TRIGGER_84107 = 84107,
+ SPELL_ARMORE_CAMERA_1 = 84112,
+ SPELL_ARMORE_CAMERA_4 = 84111,
+ SPELL_GENERAL_TRIGGER_84079 = 84079,
+
+ SPELL_RIDE_REVERSE_CAST_NO_ESCAPE = 84109,
+
+ EVENT_AGATHA_CHECK_PLAYER = 1,
+ EVENT_UNHOLY_SMITE = 2,
+ EVENT_DOOMHOWL = 3,
+ EVENT_FLEE_FROM_FENRIS = 4,
+
+ TALK_AGATHA_BROADCAST = 0,
+ TALK_AGATHA_RISE_FORSAKEN = 1,
+ TALK_AGATHA_PRE_EVENT = 2,
+ TALK_AGATHA_POST_EVENT1 = 3,
+ TALK_AGATHA_POST_EVENT2 = 4,
+
+ PATH_AGATHA_TO_FORSAKEN = 449510,
+
+ WAYPOINT_SPEED_UP = 14,
+ WAYPOINT_ARRIVED_TO_FORSAKEN = 19,
+
+ POINT_AGATHA_BACK_FRONTYARD = 1
+};
+
+// 44951 - Agatha
+struct npc_silverpine_agatha_fenris_isle : public ScriptedAI
+{
+ npc_silverpine_agatha_fenris_isle(Creature* creature) : ScriptedAI(creature), _isSceneStarted(false) { }
+
+ void JustAppeared() override
+ {
+ // Note: SummonPropertiesFlags::HelpWhenSummonedInCombat is NYI.
+ me->SetReactState(REACT_ASSIST);
+
+ me->RemoveNpcFlag(UNIT_NPC_FLAG_SPELLCLICK);
+
+ // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(me->GetOwner(), 3.0f, float(M_PI / 2.0f));
+
+ _events.ScheduleEvent(EVENT_AGATHA_CHECK_PLAYER, 1s);
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ switch (spellInfo->Id)
+ {
+ case SPELL_AGATHA_BROADCAST:
+ if (_isSceneStarted)
+ return;
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ Talk(TALK_AGATHA_BROADCAST, summoner);
+ break;
+
+ case SPELL_GENERAL_TRIGGER_84114:
+ if (!_isSceneStarted)
+ SetEventNoEscape();
+ break;
+
+ case SPELL_GENERAL_TRIGGER_84107:
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ me->CastSpell(summoner, SPELL_ARMORE_CAMERA_1, true);
+ break;
+
+ case SPELL_ARMORE_CAMERA_4:
+ _events.ScheduleEvent(EVENT_FLEE_FROM_FENRIS + 1, 1s);
+ break;
+
+ case SPELL_GENERAL_TRIGGER_84079:
+ _events.ScheduleEvent(EVENT_FLEE_FROM_FENRIS + 2, 1s);
+ break;
+
+ case SPELL_DESPAWN_ALL_SUMMONS_AGATHA:
+ DoCastSelf(SPELL_MARK_MASTER_AS_DESUMMONED);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void WaypointReached(uint32 waypointId, uint32 pathId) override
+ {
+ if (pathId == PATH_AGATHA_TO_FORSAKEN)
+ {
+ if (waypointId == WAYPOINT_SPEED_UP)
+ me->SetSpeed(MOVE_RUN, 15.880999f);
+ else if (waypointId == WAYPOINT_ARRIVED_TO_FORSAKEN)
+ _events.ScheduleEvent(EVENT_FLEE_FROM_FENRIS + 3, 100ms);
+ }
+ }
+
+ void Reset() override
+ {
+ _events.CancelEvent(EVENT_UNHOLY_SMITE);
+ _events.CancelEvent(EVENT_DOOMHOWL);
+
+ // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(me->GetOwner(), 3.0f, float(M_PI / 2.0f));
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_UNHOLY_SMITE, 500ms);
+ _events.ScheduleEvent(EVENT_DOOMHOWL, 2s, 3s);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ // Note: SummonPropertiesFlags::DespawnOnSummonerDeath, SummonPropertiesFlags::DespawnOnSummonerLogout and SummonPropertiesFlags::DespawnWhenExpired are NYI.
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (!summoner->IsAlive() || !summoner->IsInWorld() || !summoner->HasAura(SPELL_SUMMON_AGATHA_FENRIS))
+ me->DespawnOrUnsummon();
+ }
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_AGATHA_CHECK_PLAYER:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (!me->HasUnitState(UNIT_STATE_CASTING) && summoner->GetHealthPct() < 75.0f)
+ me->CastSpell(summoner, SPELL_UNHOLY_DARKNESS, false);
+
+ _events.Repeat(1s);
+ }
+ break;
+ }
+
+ case EVENT_DOOMHOWL:
+ DoCastVictim(SPELL_DOOMHOWL);
+ _events.Repeat(14s, 18s);
+ break;
+
+ case EVENT_UNHOLY_SMITE:
+ DoCastVictim(SPELL_UNHOLY_SMITE);
+ _events.Repeat(4s, 6s);
+ break;
+
+ case EVENT_FLEE_FROM_FENRIS + 1:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ me->SetFacingTo(3.159046f);
+
+ Talk(TALK_AGATHA_POST_EVENT1, summoner);
+ }
+ break;
+ }
+
+ case EVENT_FLEE_FROM_FENRIS + 2:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ me->CastSpell(summoner, SPELL_RIDE_REVERSE_CAST_NO_ESCAPE, true);
+
+ Talk(TALK_AGATHA_POST_EVENT2, summoner);
+
+ if (Player* player = summoner->ToPlayer())
+ player->KilledMonsterCredit(NPC_AGATHA_FENRIS);
+
+ me->SetDisableGravity(true);
+ me->SetCanFly(true);
+
+ me->SetSpeed(MOVE_RUN, 7.7937083f);
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePath(PATH_AGATHA_TO_FORSAKEN, false);
+ }
+ break;
+ }
+
+ case EVENT_FLEE_FROM_FENRIS + 3:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->ExitVehicle();
+
+ _isSceneStarted = false;
+
+ me->SetSpeed(MOVE_RUN, 1.14286f);
+
+ // Note: SummonPropertiesFlags::JoinSummonerSpawnGroup is NYI.
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MoveFollow(summoner, 3.0f, float(M_PI / 2.0f));
+
+ me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_ASSIST);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+
+ void SetEventNoEscape()
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ if (_isSceneStarted)
+ return;
+
+ _isSceneStarted = true;
+
+ me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_PASSIVE);
+
+ me->GetMotionMaster()->Clear();
+ me->GetMotionMaster()->MovePoint(POINT_AGATHA_BACK_FRONTYARD, AgathaBackFrontyardPos);
+
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ Talk(TALK_AGATHA_PRE_EVENT, summoner);
+ }
+
+private:
+ EventMap _events;
+ bool _isSceneStarted;
+};
+
+enum NotifyAgatha
+{
+ SPELL_RISE_FORSAKEN_FENRIS = 83993
+};
+
+// 83990 - Notify Agatha
+class spell_silverpine_notify_agatha : public SpellScript
+{
+ PrepareSpellScript(spell_silverpine_notify_agatha);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo({ SPELL_RISE_FORSAKEN_FENRIS });
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ Unit* caster = GetCaster();
+ Unit* target = GetExplTargetUnit();
+
+ if (caster)
+ {
+ if (Creature* agatha = target->FindNearestCreature(NPC_AGATHA_FENRIS, 50.0f, true))
+ {
+ if (agatha->GetOwner() == target)
+ {
+ agatha->CastSpell(caster, SPELL_RISE_FORSAKEN_FENRIS, true);
+
+ if (Player* player = target->ToPlayer())
+ {
+ if (roll_chance_i(50))
+ {
+ if (agatha->IsAIEnabled())
+ agatha->AI()->Talk(TALK_AGATHA_RISE_FORSAKEN, player);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_silverpine_notify_agatha::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+enum SpellForsakenTrooperMasterScriptFenrisIsle
+{
+ SPELL_FORSAKEN_TROOPER_MALE_01_F = 83998,
+ SPELL_FORSAKEN_TROOPER_MALE_02_F = 83999,
+ SPELL_FORSAKEN_TROOPER_MALE_03_F = 84000,
+ SPELL_FORSAKEN_TROOPER_MALE_04_F = 84001,
+ SPELL_FORSAKEN_TROOPER_FEMALE_01_F = 84002,
+ SPELL_FORSAKEN_TROOPER_FEMALE_02_F = 84003,
+ SPELL_FORSAKEN_TROOPER_FEMALE_03_F = 84004,
+ SPELL_FORSAKEN_TROOPER_FEMALE_04_F = 84005,
+
+ DISPLAY_MALE_01_F = 33978,
+ DISPLAY_MALE_02_F = 33979,
+ DISPLAY_MALE_03_F = 33980,
+ DISPLAY_MALE_04_F = 33981,
+ DISPLAY_FEMALE_01_F = 33982,
+ DISPLAY_FEMALE_02_F = 33983,
+ DISPLAY_FEMALE_03_F = 33984,
+ DISPLAY_FEMALE_04_F = 33985
+};
+
+// 83997 - Forsaken Trooper Master Script (Fenris Isle)
+class spell_silverpine_forsaken_trooper_masterscript_fenris_isle : public SpellScript
+{
+ PrepareSpellScript(spell_silverpine_forsaken_trooper_masterscript_fenris_isle);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo
+ ({
+ SPELL_FORSAKEN_TROOPER_MALE_01_F,
+ SPELL_FORSAKEN_TROOPER_MALE_02_F,
+ SPELL_FORSAKEN_TROOPER_MALE_03_F,
+ SPELL_FORSAKEN_TROOPER_MALE_04_F,
+ SPELL_FORSAKEN_TROOPER_FEMALE_01_F,
+ SPELL_FORSAKEN_TROOPER_FEMALE_02_F,
+ SPELL_FORSAKEN_TROOPER_FEMALE_03_F,
+ SPELL_FORSAKEN_TROOPER_FEMALE_04_F
+ });
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ Unit* unit = GetCaster();
+
+ if (Creature* hillsbradRefugee = unit->ToCreature())
+ {
+ uint32 spellId = unit->GetGender() == GENDER_MALE ? SPELL_FORSAKEN_TROOPER_MALE_01_F : SPELL_FORSAKEN_TROOPER_FEMALE_01_F;
+
+ switch (hillsbradRefugee->GetDisplayId())
+ {
+ case DISPLAY_MALE_01_F:
+ spellId = SPELL_FORSAKEN_TROOPER_MALE_01_F;
+ break;
+ case DISPLAY_MALE_02_F:
+ spellId = SPELL_FORSAKEN_TROOPER_MALE_02_F;
+ break;
+ case DISPLAY_MALE_03_F:
+ spellId = SPELL_FORSAKEN_TROOPER_MALE_03_F;
+ break;
+ case DISPLAY_MALE_04_F:
+ spellId = SPELL_FORSAKEN_TROOPER_MALE_04_F;
+ break;
+ case DISPLAY_FEMALE_01_F:
+ spellId = SPELL_FORSAKEN_TROOPER_FEMALE_01_F;
+ break;
+ case DISPLAY_FEMALE_02_F:
+ spellId = SPELL_FORSAKEN_TROOPER_FEMALE_02_F;
+ break;
+ case DISPLAY_FEMALE_03_F:
+ spellId = SPELL_FORSAKEN_TROOPER_FEMALE_03_F;
+ break;
+ case DISPLAY_FEMALE_04_F:
+ spellId = SPELL_FORSAKEN_TROOPER_FEMALE_04_F;
+ break;
+ default:
+ break;
+ }
+
+ hillsbradRefugee->CastSpell(hillsbradRefugee, spellId, true);
+ }
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_silverpine_forsaken_trooper_masterscript_fenris_isle::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+enum HillsbradRefugee
+{
+ QUEST_RISE_FORSAKEN = 27097,
+
+ SPELL_TROOPER_MASTERSCRIPT_FENRIS = 83997,
+ SPELL_NOTIFY_AGATHA_FENRIS = 83990,
+ SPELL_LORDAERON_MIGHT = 87104,
+
+ EVENT_LORDAERON_MIGHT = 1
+};
+
+// 44954, 44966 - Hillsbrad Refugee
+struct npc_silverpine_hillsbrad_refugee : public ScriptedAI
+{
+ npc_silverpine_hillsbrad_refugee(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
+ {
+ case SPELL_RISE_FORSAKEN_FENRIS:
+ DoCastSelf(SPELL_TROOPER_MASTERSCRIPT_FENRIS);
+ me->DespawnOrUnsummon(2s);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void JustDied(Unit* killer) override
+ {
+ if (Player* player = killer->ToPlayer())
+ {
+ if (player->GetQuestStatus(QUEST_RISE_FORSAKEN) == QUEST_STATUS_INCOMPLETE)
+ me->CastSpell(player, SPELL_NOTIFY_AGATHA_FENRIS, true);
+ }
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ _events.ScheduleEvent(EVENT_LORDAERON_MIGHT, 3s, 8s);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_LORDAERON_MIGHT:
+ DoCastSelf(SPELL_LORDAERON_MIGHT);
+ _events.Repeat(15s, 18s);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+private:
+ EventMap _events;
+};
+
+enum ForsakenTrooperFenrisIsle
+{
+ EVENT_REFUGEE_JUST_RISEN = 1,
+
+ TALK_REFUGEE_JUST_RISEN = 0,
+
+ DISPLAY_MALE_01_D_F = 33986,
+ DISPLAY_MALE_02_D_F = 33987,
+ DISPLAY_MALE_03_D_F = 33988,
+ DISPLAY_MALE_04_D_F = 33989,
+ DISPLAY_FEMALE_01_D_F = 33991,
+ DISPLAY_FEMALE_02_D_F = 33992,
+ DISPLAY_FEMALE_03_D_F = 33993,
+ DISPLAY_FEMALE_04_D_F = 33994
+};
+
+// 44958, 44959, 44960, 44961 - Forsaken Trooper (Male)
+// 44962, 44963, 44964, 44965 - Forsaken Trooper (Female)
+struct npc_silverpine_forsaken_trooper_fenris_isle : public ScriptedAI
+{
+ npc_silverpine_forsaken_trooper_fenris_isle(Creature* creature) : ScriptedAI(creature) {}
+
+ void IsSummonedBy(WorldObject* summoner) override
+ {
+ if (!summoner->IsCreature())
+ return;
+
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_PASSIVE);
+
+ uint32 displayId = me->GetGender() == GENDER_MALE ? DISPLAY_MALE_01_D_F : DISPLAY_FEMALE_01_D_F;
+
+ switch (summoner->ToCreature()->GetDisplayId())
+ {
+ case DISPLAY_MALE_01_F:
+ displayId = DISPLAY_MALE_01_D_F;
+ break;
+ case DISPLAY_MALE_02_F:
+ displayId = DISPLAY_MALE_02_D_F;
+ break;
+ case DISPLAY_MALE_03_F:
+ displayId = DISPLAY_MALE_03_D_F;
+ break;
+ case DISPLAY_MALE_04_F:
+ displayId = DISPLAY_MALE_04_D_F;
+ break;
+ case DISPLAY_FEMALE_01_F:
+ displayId = DISPLAY_FEMALE_01_D_F;
+ break;
+ case DISPLAY_FEMALE_02_F:
+ displayId = DISPLAY_FEMALE_02_D_F;
+ break;
+ case DISPLAY_FEMALE_03_F:
+ displayId = DISPLAY_FEMALE_03_D_F;
+ break;
+ case DISPLAY_FEMALE_04_F:
+ displayId = DISPLAY_FEMALE_04_D_F;
+ break;
+ default:
+ break;
+ }
+
+ me->SetDisplayId(displayId);
+
+ _events.ScheduleEvent(EVENT_REFUGEE_JUST_RISEN, 1s);
+
+ me->DespawnOrUnsummon(4s);
+ }
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_REFUGEE_JUST_RISEN:
+ Talk(TALK_REFUGEE_JUST_RISEN);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ EventMap _events;
+};
+
+enum WorgenSentry
+{
+ SPELL_BATTLE_ROAR = 6507,
+ SPELL_UNDYING_FRENZY = 80515,
+
+ EVENT_UNDYING_FRENZY = 1,
+
+ TALK_SENTRY_WARNING = 0
+};
+
+// 44987 - Worgen Sentry
+struct npc_silverpine_worgen_sentry : public ScriptedAI
+{
+ npc_silverpine_worgen_sentry(Creature* creature) : ScriptedAI(creature) {}
+
+ void Reset() override
+ {
+ _events.Reset();
+ }
+
+ void JustDied(Unit* /*killer*/) override
+ {
+ Talk(TALK_SENTRY_WARNING);
+ }
+
+ void JustEngagedWith(Unit* /*who*/) override
+ {
+ DoCastSelf(SPELL_BATTLE_ROAR);
+
+ _events.ScheduleEvent(EVENT_UNDYING_FRENZY, 3s);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ _events.Update(diff);
+
+ if (!UpdateVictim())
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_UNDYING_FRENZY:
+ DoCastVictim(SPELL_UNDYING_FRENZY);
+ _events.Repeat(10s, 12s);
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ }
+
+private:
+ EventMap _events;
+};
+
+Position const NoEscapeStartPos = { 981.782f, 670.953f, 74.898f, 3.1887f };
+
+enum FenrisKeepStalker
+{
+ SPELL_FORCE_CAST_FENRIS_CAMERA = 84113
+};
+
+// 45032 - Fenris Keep Stalker
+struct npc_silverpine_fenris_keep_stalker : public ScriptedAI
+{
+ npc_silverpine_fenris_keep_stalker(Creature* creature) : ScriptedAI(creature), eventIsTriggered(false) { }
+
+ void Reset() override
{
- _events.ScheduleEvent(EVENT_SUMMON_SPIDERLINGS, 2s);
- _events.ScheduleEvent(EVENT_VENOM_SPLASH, 4s, 7s);
+ eventIsTriggered = false;
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
+ {
+ case SPELL_GENERAL_TRIGGER_84107:
+ Reset();
+ break;
+ default:
+ break;
+ }
+ }
+
+ void OnTriggerNoEscape(ObjectGuid playerGuid)
+ {
+ if (eventIsTriggered)
+ return;
+
+ if (Player* player = ObjectAccessor::GetPlayer(*me, playerGuid))
+ {
+ eventIsTriggered = true;
+
+ me->CastSpell(player, SPELL_FORCE_CAST_FENRIS_CAMERA, true);
+
+ player->NearTeleportTo(NoEscapeStartPos, true);
+ }
+ }
+
+private:
+ bool eventIsTriggered;
+};
+
+enum AtNoEscape
+{
+ NPC_FENRIS_KEEP_STALKER = 45032
+};
+
+// 6230 - No Escape
+class at_silverpine_no_escape : public AreaTriggerScript
+{
+public:
+ at_silverpine_no_escape() : AreaTriggerScript("at_silverpine_no_escape") { }
+
+ bool OnTrigger(Player* player, AreaTriggerEntry const* /*at*/) override
+ {
+ if (!player->IsAlive() || player->GetQuestStatus(QUEST_NO_ESCAPE) != QUEST_STATUS_INCOMPLETE)
+ return true;
+
+ if (Creature* agatha = player->FindNearestCreature(NPC_AGATHA_FENRIS, 10.0f, true))
+ {
+ if (agatha->GetOwner() == player)
+ {
+ if (Creature* fenrisStalker = player->FindNearestCreature(NPC_FENRIS_KEEP_STALKER, 50.0f, true))
+ {
+ if (npc_silverpine_fenris_keep_stalker* fenrisKeepStalkerAI = CAST_AI(npc_silverpine_fenris_keep_stalker, fenrisStalker->AI()))
+ fenrisKeepStalkerAI->OnTriggerNoEscape(player->GetGUID());
+ }
+ }
+ }
+
+ return true;
+ }
+};
+
+enum SummonFenrisActors
+{
+ SPELL_SUMMON_BLOODFANG_FENRIS = 84054,
+ SPELL_SUMMON_CROWLEY_FENRIS = 84055,
+ SPELL_SUMMON_PHIN_ODELIC = 84056,
+ SPELL_SUMMON_BARTOLO_GINSETTI = 84057,
+ SPELL_SUMMON_LOREMASTER_DIBBS = 84058,
+ SPELL_SUMMON_MAGISTRATE_HENRY = 84059,
+ SPELL_SUMMON_CARETAKER_SMITHERS = 84060,
+ SPELL_SUMMON_SOPHIA = 84061
+};
+
+// 84053 - Summon Fenris Actors
+class spell_silverpine_summon_fenris_keep_actors : public SpellScript
+{
+ PrepareSpellScript(spell_silverpine_summon_fenris_keep_actors);
+
+ bool Validate(SpellInfo const* /*spellInfo*/) override
+ {
+ return ValidateSpellInfo
+ ({
+ SPELL_SUMMON_BLOODFANG_FENRIS,
+ SPELL_SUMMON_CROWLEY_FENRIS,
+ SPELL_SUMMON_PHIN_ODELIC,
+ SPELL_SUMMON_BARTOLO_GINSETTI,
+ SPELL_SUMMON_LOREMASTER_DIBBS,
+ SPELL_SUMMON_MAGISTRATE_HENRY,
+ SPELL_SUMMON_CARETAKER_SMITHERS,
+ SPELL_SUMMON_SOPHIA
+ });
+ }
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ Unit* target = GetHitUnit();
+
+ target->CastSpell(target, SPELL_SUMMON_BLOODFANG_FENRIS, true);
+ target->CastSpell(target, SPELL_SUMMON_CROWLEY_FENRIS, true);
+ target->CastSpell(target, SPELL_SUMMON_PHIN_ODELIC, true);
+ target->CastSpell(target, SPELL_SUMMON_BARTOLO_GINSETTI, true);
+ target->CastSpell(target, SPELL_SUMMON_LOREMASTER_DIBBS, true);
+ target->CastSpell(target, SPELL_SUMMON_MAGISTRATE_HENRY, true);
+ target->CastSpell(target, SPELL_SUMMON_CARETAKER_SMITHERS, true);
+ target->CastSpell(target, SPELL_SUMMON_SOPHIA, true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_silverpine_summon_fenris_keep_actors::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
+Position const CameraFrontyardPos = { 980.7f, 689.14f, 76.9f };
+
+enum FenrisKeepCamera
+{
+ SPELL_SUMMON_FENRIS_ACTORS = 84053,
+ SPELL_GENERAL_TRIGGER_84102 = 84102,
+ SPELL_FORCE_SEAT_2 = 84091,
+ SPELL_DESPAWN_ALL_SUMMONS_FENRIS = 84066,
+
+ EVENT_MOVE_TO_START_POINT = 1,
+ EVENT_CHANGE_TO_SEAT_2 = 2,
+ EVENT_TRIGGER_84102 = 3,
+ EVENT_SCENE_FINISH_FENRIS = 4,
+
+ POINT_CAMERA_FRONTYARD = 1,
+
+ SEAT_FENRIS_CAMERA = 0,
+ SEAT_FENRIS_CAMERA_FORCE = 1
+};
+
+// 45003 - Fenris Keep Camera
+struct npc_silverpine_fenris_keep_camera : public ScriptedAI
+{
+ npc_silverpine_fenris_keep_camera(Creature* creature) : ScriptedAI(creature) { }
+
+ void IsSummonedBy(WorldObject* summoner) override
+ {
+ if (Unit* unit = summoner->ToUnit())
+ unit->EnterVehicle(me, SEAT_FENRIS_CAMERA);
+
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ switch (spellInfo->Id)
+ {
+ case SPELL_GENERAL_TRIGGER_84107:
+ _events.ScheduleEvent(EVENT_SCENE_FINISH_FENRIS, 2s + 500ms);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void PassengerBoarded(Unit* passenger, int8 seatId, bool apply) override
+ {
+ if (apply)
+ {
+ if (seatId == SEAT_FENRIS_CAMERA)
+ {
+ _events.ScheduleEvent(EVENT_MOVE_TO_START_POINT, 10ms);
+
+ me->CastSpell(passenger, SPELL_SUMMON_FENRIS_ACTORS, true);
+ }
+ else if (seatId == SEAT_FENRIS_CAMERA_FORCE)
+ passenger->SetFacingTo(0.0f);
+ }
+ else
+ {
+ if (seatId == SEAT_FENRIS_CAMERA_FORCE)
+ _events.ScheduleEvent(EVENT_SCENE_FINISH_FENRIS, 1s);
+ }
+ }
+
+ void MovementInform(uint32 type, uint32 id) override
+ {
+ if (type == POINT_MOTION_TYPE && id == POINT_CAMERA_FRONTYARD)
+ _events.ScheduleEvent(EVENT_CHANGE_TO_SEAT_2, 500ms);
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* summon = me->ToTempSummon();
+ if (!summon)
+ return;
+ Unit* summoner = summon->GetSummonerUnit();
+ if (!summoner)
+ return;
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MOVE_TO_START_POINT:
+ me->GetMotionMaster()->MovePoint(POINT_CAMERA_FRONTYARD, CameraFrontyardPos);
+ break;
+
+ case EVENT_CHANGE_TO_SEAT_2:
+ me->CastSpell(summoner, SPELL_FORCE_SEAT_2, true);
+ _events.ScheduleEvent(EVENT_TRIGGER_84102, 2s);
+ break;
+
+ case EVENT_TRIGGER_84102:
+ summoner->CastSpell(summoner, SPELL_GENERAL_TRIGGER_84102, true);
+ break;
+
+ case EVENT_SCENE_FINISH_FENRIS:
+ if (Creature* agatha = me->FindNearestCreature(NPC_AGATHA_FENRIS, 60.0f))
+ me->CastSpell(agatha, SPELL_GENERAL_TRIGGER_84079, true);
+ me->SetFacingTo(0.08278348f);
+ _events.ScheduleEvent(EVENT_SCENE_FINISH_FENRIS + 1, 4s);
+ break;
+
+ case EVENT_SCENE_FINISH_FENRIS + 1:
+ me->CastSpell(summoner, SPELL_DESPAWN_ALL_SUMMONS_FENRIS, true);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ EventMap _events;
+};
+
+enum DariusCrowleyFenris
+{
+ NPC_CROWLEY_FENRIS = 44989,
+ NPC_MAGISTRATE_HENRY_MALEB = 44996,
+
+ SPELL_ARMORE_CAMERA_FENRIS = 83768,
+ SPELL_CONVERSATION_TRIGGER_84076 = 84076,
+
+ EVENT_CROWLEY_ANIMATION_FENRIS = 1,
+
+ TALK_CROWLEY_NO_ESCAPE_0 = 0,
+ TALK_CROWLEY_NO_ESCAPE_1 = 1,
+ TALK_CROWLEY_NO_ESCAPE_2 = 2,
+ TALK_CROWLEY_NO_ESCAPE_3 = 3,
+ TALK_CROWLEY_NO_ESCAPE_4 = 4,
+ TALK_CROWLEY_NO_ESCAPE_5 = 5,
+ TALK_CROWLEY_NO_ESCAPE_6 = 6
+};
+
+// 44989 - Lord Darius Crowley, 44990 - Packleader Ivar Bloodfang
+struct npc_silverpine_crowley_bloodfang_fenris_keep : public ScriptedAI
+{
+ npc_silverpine_crowley_bloodfang_fenris_keep(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ if (me->GetEntry() != NPC_CROWLEY_FENRIS)
+ return;
+
+ switch (spellInfo->Id)
+ {
+ case SPELL_GENERAL_TRIGGER_84102:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ me->CastSpell(summoner, SPELL_ARMORE_CAMERA_FENRIS, true);
+
+ Talk(TALK_CROWLEY_NO_ESCAPE_6, summoner);
+
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS, 2s + 500ms);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ Unit* summoner = tempSummon->GetSummonerUnit();
+ if (!summoner)
+ return;
+ _events.Update(diff);
+
+ if (me->GetEntry() != NPC_CROWLEY_FENRIS)
+ return;
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_CROWLEY_ANIMATION_FENRIS:
+ Talk(TALK_CROWLEY_NO_ESCAPE_0, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 1, 4s + 700ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 1:
+ Talk(TALK_CROWLEY_NO_ESCAPE_1, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 2, 4s + 700ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 2:
+ Talk(TALK_CROWLEY_NO_ESCAPE_2, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 3, 4s + 700ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 3:
+ Talk(TALK_CROWLEY_NO_ESCAPE_3, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 4, 4s + 700ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 4:
+ Talk(TALK_CROWLEY_NO_ESCAPE_4, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 5, 6s + 100ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 5:
+ Talk(TALK_CROWLEY_NO_ESCAPE_5, summoner);
+ _events.ScheduleEvent(EVENT_CROWLEY_ANIMATION_FENRIS + 6, 9s + 500ms);
+ break;
+
+ case EVENT_CROWLEY_ANIMATION_FENRIS + 6:
+ if (Creature* henry = me->FindNearestCreature(NPC_MAGISTRATE_HENRY_MALEB, 30.0f))
+ me->CastSpell(henry, SPELL_CONVERSATION_TRIGGER_84076, true);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ EventMap _events;
+};
+
+enum GeneralActorFenris
+{
+ NPC_BLOODFANG_FENRIS = 44990,
+ NPC_PHIN_ODELIC = 44993,
+ NPC_BARTOLO_GINSETTI = 44994,
+ NPC_LOREMASTER_DIBBS = 44995,
+ NPC_CARETAKER_SMITHERS = 44997,
+ NPC_SOPHIA_ZWOSKI = 45002,
+ NPC_FENRIS_KEEP_CAMERA = 45003,
+
+ SPELL_CONVERSATION_TRIGGER_84077 = 84077,
+ SPELL_ARMORE_CAMERA_2 = 84104,
+ SPELL_ARMORE_CAMERA_3 = 84103,
+ SPELL_BLOOD_ODELIC = 84094,
+ SPELL_BLOOD_BARTOLO = 84095,
+ SPELL_BLOOD_DIBBS = 84096,
+ SPELL_BLOOD_HENRY = 84097,
+ SPELL_BLOOD_SMITHERS = 84098,
+ SPELL_BLOOD_ZWOSKI = 84099,
+
+ EVENT_MAGISTRATE_ANIMATION = 1,
+ EVENT_ACTOR_FENRIS_DRINK = 4,
+ EVENT_ACTOR_FENRIS_MORPH = 5,
+
+ TALK_HENRY_NO_ESCAPE_0 = 0,
+ TALK_HENRY_NO_ESCAPE_1 = 1,
+
+ SOUND_HOWLING = 17671
+};
+
+// 44993 - Phin Odelic, 44994 - Bartolo Ginsetti, 44995 - Loremaster Dibbs, 44996 - Magistrate Henry Maleb, 44997 - Caretaker Smithers, 45002 - Sophia Zwoski
+struct npc_silverpine_generic_actor_fenris_keep : public ScriptedAI
+{
+ npc_silverpine_generic_actor_fenris_keep(Creature* creature) : ScriptedAI(creature), _isWorgen(false) { }
+
+ void JustAppeared() override
+ {
+ if (Creature* fenrisStalker = me->FindNearestCreature(NPC_FENRIS_KEEP_STALKER, 50.0f, true))
+ me->SetFacingToObject(fenrisStalker);
+
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
+
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ switch (spellInfo->Id)
+ {
+ case SPELL_CONVERSATION_TRIGGER_84076:
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ me->CastSpell(summoner, SPELL_ARMORE_CAMERA_2, true);
+ break;
+
+ case SPELL_ARMORE_CAMERA_3:
+ _events.ScheduleEvent(EVENT_MAGISTRATE_ANIMATION, 1s + 300ms);
+ break;
+
+ case SPELL_CONVERSATION_TRIGGER_84077:
+ _events.ScheduleEvent(EVENT_ACTOR_FENRIS_DRINK, 1s);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_MAGISTRATE_ANIMATION:
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ Talk(TALK_HENRY_NO_ESCAPE_0, summoner);
+ _events.ScheduleEvent(EVENT_MAGISTRATE_ANIMATION + 1, 10s + 800ms);
+ break;
+
+ case EVENT_MAGISTRATE_ANIMATION + 1:
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ Talk(TALK_HENRY_NO_ESCAPE_1, summoner);
+ _events.ScheduleEvent(EVENT_MAGISTRATE_ANIMATION + 2, 2s);
+ break;
+
+ case EVENT_MAGISTRATE_ANIMATION + 2:
+ DoCastSelf(SPELL_CONVERSATION_TRIGGER_84077, true);
+ break;
+
+ case EVENT_ACTOR_FENRIS_DRINK:
+ _events.ScheduleEvent(EVENT_ACTOR_FENRIS_MORPH, 1s + 500ms);
+ break;
+
+ case EVENT_ACTOR_FENRIS_MORPH:
+ {
+ _isWorgen = true;
+
+ uint32 spellId = 0;
+
+ switch (me->GetEntry())
+ {
+ case NPC_PHIN_ODELIC:
+ spellId = SPELL_BLOOD_ODELIC;
+ break;
+ case NPC_BARTOLO_GINSETTI:
+ spellId = SPELL_BLOOD_BARTOLO;
+ break;
+ case NPC_LOREMASTER_DIBBS:
+ spellId = SPELL_BLOOD_DIBBS;
+ break;
+ case NPC_MAGISTRATE_HENRY_MALEB:
+ spellId = SPELL_BLOOD_HENRY;
+ break;
+ case NPC_CARETAKER_SMITHERS:
+ spellId = SPELL_BLOOD_SMITHERS;
+ break;
+ case NPC_SOPHIA_ZWOSKI:
+ spellId = SPELL_BLOOD_ZWOSKI;
+ me->PlayDirectSound(SOUND_HOWLING);
+ break;
+ default:
+ break;
+ }
+
+ DoCastSelf(spellId);
+
+ _events.ScheduleEvent(EVENT_ACTOR_FENRIS_MORPH + 1, 1s);
+ break;
+ }
+
+ case EVENT_ACTOR_FENRIS_MORPH + 1:
+ me->HandleEmoteCommand(EMOTE_STATE_READY_UNARMED);
+ if (me->GetEntry() == NPC_MAGISTRATE_HENRY_MALEB)
+ _events.ScheduleEvent(EVENT_ACTOR_FENRIS_MORPH + 2, 2s);
+ break;
+
+ case EVENT_ACTOR_FENRIS_MORPH + 2:
+ if (Creature* agatha = me->FindNearestCreature(NPC_AGATHA_FENRIS, 60.0f))
+ me->CastSpell(agatha, SPELL_GENERAL_TRIGGER_84107, true);
+ break;
+
+ default:
+ break;
+ }
+ }
}
private:
EventMap _events;
- bool _alreadyPulled;
- std::vector<ObjectGuid> _stalkerGUIDs;
+ bool _isWorgen;
};
void AddSC_silverpine_forest()
@@ -4114,4 +5355,20 @@ void AddSC_silverpine_forest()
RegisterSpellScript(spell_silverpine_free_webbed_victim_random);
RegisterCreatureAI(npc_silverpine_orc_sea_dog);
RegisterCreatureAI(npc_silverpine_skitterweb_matriarch);
+
+ /* Fenris Isle */
+
+ RegisterSpellScript(spell_silverpine_bond_of_the_valkyr);
+ RegisterCreatureAI(npc_silverpine_agatha_fenris_isle);
+ RegisterSpellScript(spell_silverpine_notify_agatha);
+ RegisterSpellScript(spell_silverpine_forsaken_trooper_masterscript_fenris_isle);
+ RegisterCreatureAI(npc_silverpine_hillsbrad_refugee);
+ RegisterCreatureAI(npc_silverpine_forsaken_trooper_fenris_isle);
+ RegisterCreatureAI(npc_silverpine_worgen_sentry);
+ new at_silverpine_no_escape();
+ RegisterSpellScript(spell_silverpine_summon_fenris_keep_actors);
+ RegisterCreatureAI(npc_silverpine_fenris_keep_stalker);
+ RegisterCreatureAI(npc_silverpine_fenris_keep_camera);
+ RegisterCreatureAI(npc_silverpine_crowley_bloodfang_fenris_keep);
+ RegisterCreatureAI(npc_silverpine_generic_actor_fenris_keep);
}