diff options
Diffstat (limited to 'src')
6 files changed, 149 insertions, 31 deletions
diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index 67dca6114c0..9942b3a5fc3 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -52,6 +52,7 @@ enum Spells SPELL_DRAIN_WORLD_TREE_TRIGGERED = 39141, SPELL_FINGER_OF_DEATH = 31984, + SPELL_FINGER_OF_DEATH_LAST_PHASE = 32111, SPELL_HAND_OF_DEATH = 35354, SPELL_AIR_BURST = 32014, SPELL_GRIP_OF_THE_LEGION = 31972, @@ -77,7 +78,9 @@ enum Events EVENT_AIR_BURST, EVENT_DOOMFIRE, EVENT_DISTANCE_CHECK, // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage - EVENT_SUMMON_WHISP + EVENT_SUMMON_WHISP, + EVENT_PROTECTION_OF_ELUNE, + EVENT_FINGER_OF_DEATH_LAST_PHASE }; enum Summons @@ -93,6 +96,8 @@ enum Actions ACTION_CHANNEL_WORLD_TREE }; +Position const NordrassilLoc = { 5503.713f, -3523.436f, 1608.781f, 0.0f }; + class npc_ancient_wisp : public CreatureScript { public: @@ -274,7 +279,6 @@ public: void Initialize() { - DoomfireSpiritGUID.Clear(); SoulChargeCount = 0; WispCount = 0; // When ~30 wisps are summoned, Archimonde dies @@ -288,18 +292,25 @@ public: void InitializeAI() override { BossAI::InitializeAI(); - DoAction(ACTION_CHANNEL_WORLD_TREE); } void Reset() override { Initialize(); _Reset(); - me->RemoveAllAuras(); // Reset Soul Charge auras. + DoomfireSpiritGUID.Clear(); + summons.DespawnAll(); + WorldtreeTragetGUID = instance->GetGuidData(DATA_CHANNEL_TARGET); + if (Creature* WorldtreeTraget = ObjectAccessor::GetCreature(*me, WorldtreeTragetGUID)) + { + DoCast(WorldtreeTraget, SPELL_DRAIN_WORLD_TREE); + } + me->RemoveAllAuras(); // Reset Soul Charge auras. } void JustEngagedWith(Unit* who) override { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); Talk(SAY_AGGRO); BossAI::JustEngagedWith(who); events.ScheduleEvent(EVENT_FEAR, 42s); @@ -386,13 +397,27 @@ public: DoAction(ACTION_ENRAGE); events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5s); break; + case EVENT_PROTECTION_OF_ELUNE: // hp below 10% only cast finger of death + events.Reset(); + events.ScheduleEvent(EVENT_HAND_OF_DEATH, 1s); + events.ScheduleEvent(EVENT_FINGER_OF_DEATH_LAST_PHASE, 1s); + events.ScheduleEvent(EVENT_SUMMON_WHISP, 1s); + DoCastAOE(SPELL_PROTECTION_OF_ELUNE); + break; case EVENT_SUMMON_WHISP: DoSpawnCreature(NPC_ANCIENT_WISP, float(rand32() % 40), float(rand32() % 40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15s); ++WispCount; if (WispCount >= 30) + { me->KillSelf(); + return; + } events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500ms); break; + case EVENT_FINGER_OF_DEATH_LAST_PHASE: + DoCast(SelectTarget(SelectTargetMethod::Random, 0), SPELL_FINGER_OF_DEATH_LAST_PHASE); + events.ScheduleEvent(EVENT_FINGER_OF_DEATH_LAST_PHASE, 1s); + break; default: break; } @@ -409,11 +434,9 @@ public: { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); - // All members of raid must get this buff - DoCastAOE(SPELL_PROTECTION_OF_ELUNE, true); + events.ScheduleEvent(EVENT_PROTECTION_OF_ELUNE, 1ms); HasProtected = true; - events.ScheduleEvent(EVENT_SUMMON_WHISP, 1500ms); } } } @@ -456,6 +479,7 @@ public: void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); + summons.DespawnAll(); _JustDied(); // @todo: remove this when instance script gets updated, kept for compatibility only instance->SetData(DATA_ARCHIMONDE, DONE); @@ -517,7 +541,6 @@ public: me->SummonCreature(NPC_DOOMFIRE_SPIRIT, target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 27s); - me->SummonCreature(NPC_DOOMFIRE, target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 27s); @@ -525,6 +548,7 @@ public: private: ObjectGuid DoomfireSpiritGUID; + ObjectGuid WorldtreeTragetGUID; uint8 SoulChargeCount; uint8 WispCount; uint32 _chargeSpell; @@ -572,6 +596,44 @@ class spell_archimonde_drain_world_tree_dummy : public SpellScriptLoader } }; +// Protection of Elune 38528 +class spell_protection_of_elune : public AuraScript +{ + PrepareAuraScript(spell_protection_of_elune); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_PROTECTION_OF_ELUNE + }); + } + + void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->ApplySpellImmune(SPELL_HAND_OF_DEATH, IMMUNITY_ID, SPELL_HAND_OF_DEATH, true); + target->ApplySpellImmune(SPELL_FINGER_OF_DEATH, IMMUNITY_ID, SPELL_FINGER_OF_DEATH, true); + target->ApplySpellImmune(SPELL_FINGER_OF_DEATH_LAST_PHASE, IMMUNITY_ID, SPELL_FINGER_OF_DEATH_LAST_PHASE, true); + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FINGER_OF_DEATH_LAST_PHASE, true); + } + + void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->ApplySpellImmune(SPELL_HAND_OF_DEATH, IMMUNITY_ID, SPELL_HAND_OF_DEATH, false); + target->ApplySpellImmune(SPELL_FINGER_OF_DEATH, IMMUNITY_ID, SPELL_FINGER_OF_DEATH, false); + target->ApplySpellImmune(SPELL_FINGER_OF_DEATH_LAST_PHASE, IMMUNITY_ID, SPELL_FINGER_OF_DEATH_LAST_PHASE, false); + target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_FINGER_OF_DEATH_LAST_PHASE, false); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_protection_of_elune::HandleEffectApply, EFFECT_0, SPELL_AURA_SCHOOL_IMMUNITY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_protection_of_elune::HandleEffectRemove, EFFECT_0, SPELL_AURA_SCHOOL_IMMUNITY, AURA_EFFECT_HANDLE_REAL); + } +}; + void AddSC_boss_archimonde() { new boss_archimonde(); @@ -579,4 +641,5 @@ void AddSC_boss_archimonde() new npc_doomfire_targetting(); new npc_ancient_wisp(); new spell_archimonde_drain_world_tree_dummy(); + RegisterSpellScript(spell_protection_of_elune); } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index 6723f93233c..eaee1c9c66e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -53,6 +53,11 @@ enum GOSSIPS GOSSIP_ITEM_TYRANDE_OID = 0 }; +enum NPCTEXTS +{ + JAINA_RETREAT_ALLIANCE_BASE = 5 +}; + #define ITEM_TEAR_OF_GODDESS 24494 #define GOSSIP_ITEM_GM1 "[GM] Toggle Debug Timers" @@ -94,6 +99,7 @@ class npc_jaina_proudmoore : public CreatureScript StartEvent(player); break; case GOSSIP_ACTION_INFO_DEF + 3: + me->AI()->Talk(JAINA_RETREAT_ALLIANCE_BASE); Retreat(); break; case GOSSIP_ACTION_INFO_DEF: @@ -112,16 +118,23 @@ class npc_jaina_proudmoore : public CreatureScript uint32 RageEncounter = GetInstanceData(DATA_RAGEWINTERCHILLEVENT); uint32 AnetheronEncounter = GetInstanceData(DATA_ANETHERONEVENT); if (RageEncounter == NOT_STARTED) + { AddGossipItemFor(player, GOSSIP_ITEM_BEGIN_ALLY_MID, GOSSIP_ITEM_BEGIN_ALLY_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + SendGossipMenuFor(player, 9168, me->GetGUID()); + } else if (RageEncounter == DONE && AnetheronEncounter == NOT_STARTED) + { AddGossipItemFor(player, GOSSIP_ITEM_ANETHERON_MID, GOSSIP_ITEM_ANETHERON_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + SendGossipMenuFor(player, 9380, me->GetGUID()); + } else if (RageEncounter == DONE && AnetheronEncounter == DONE) + { AddGossipItemFor(player, GOSSIP_ITEM_ALLY_RETREAT_MID, GOSSIP_ITEM_ALLY_RETREAT_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); - + SendGossipMenuFor(player, 9387, me->GetGUID()); + } if (player->IsGameMaster()) AddGossipItemFor(player, GossipOptionNpc::None, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 907, me->GetGUID()); return true; } }; @@ -188,17 +201,25 @@ class npc_thrall : public CreatureScript uint32 KazrogalEvent = GetInstanceData(DATA_KAZROGALEVENT); uint32 AzgalorEvent = GetInstanceData(DATA_AZGALOREVENT); if (KazrogalEvent == NOT_STARTED) + { AddGossipItemFor(player, GOSSIP_ITEM_BEGIN_HORDE_MID, GOSSIP_ITEM_BEGIN_HORDE_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + SendGossipMenuFor(player, 9225, me->GetGUID()); + } else if (KazrogalEvent == DONE && AzgalorEvent == NOT_STARTED) + { AddGossipItemFor(player, GOSSIP_ITEM_AZGALOR_MID, GOSSIP_ITEM_AZGALOR_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); + SendGossipMenuFor(player, 9396, me->GetGUID()); + } else if (AzgalorEvent == DONE) + { AddGossipItemFor(player, GOSSIP_ITEM_HORDE_RETREAT_MID, GOSSIP_ITEM_HORDE_RETREAT_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); + SendGossipMenuFor(player, 9398, me->GetGUID()); + } } if (player->IsGameMaster()) AddGossipItemFor(player, GossipOptionNpc::None, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 907, me->GetGUID()); return true; } }; @@ -244,7 +265,7 @@ class npc_tyrande_whisperwind : public CreatureScript // Only let them get item if Azgalor is dead. if (AzgalorEvent == DONE && !player->HasItemCount(ITEM_TEAR_OF_GODDESS)) AddGossipItemFor(player, GOSSIP_ITEM_TYRANDE_MID, GOSSIP_ITEM_TYRANDE_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 907, me->GetGUID()); + SendGossipMenuFor(player, 9410, me->GetGUID()); return true; } }; diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp index 58579b568ab..324e3d697e6 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -39,7 +39,10 @@ enum Spawns SPAWN_NEAR_TOWER = 2, }; -#define YELL_HURRY "Hurry, we don't have much time" +enum NPCTEXTS +{ + JAINA_RETREAT_HORDE_BASE = 7 +}; // Locations for summoning gargoyls and frost wyrms in special cases float SpawnPointSpecial[3][3]= @@ -391,7 +394,7 @@ void hyjalAI::Reset() { case JAINA: Faction = 0; - DoCast(me, SPELL_BRILLIANCE_AURA, true); + DoCastSelf(SPELL_BRILLIANCE_AURA, true); break; case THRALL: @@ -400,6 +403,7 @@ void hyjalAI::Reset() case TYRANDE: Faction = 2; + DoCastSelf(SPELL_TRUESHOT_AURA, true); break; } @@ -503,6 +507,7 @@ void hyjalAI::SummonCreature(uint32 entry, float Base[4][3]) ++EnemyCount; creature->SetWalk(false); + ENSURE_AI(hyjal_trashAI, creature->AI())->SetRun(); creature->setActive(true); creature->SetFarVisible(true); switch (entry) @@ -830,7 +835,10 @@ void hyjalAI::UpdateAI(uint32 diff) } else if (BossGUID[i] == BossGUID[1]) { - Talk(SUCCESS); + if (me->GetEntry() == THRALL) // thrall yell success after boss deaded,jaina yell success after select gossip + { + Talk(SUCCESS); + } SecondBossDead = true; } EventBegun = false; @@ -935,7 +943,6 @@ void hyjalAI::WaypointReached(uint32 waypointId, uint32 /*pathId*/) { if (waypointId == 1 || (waypointId == 0 && me->GetEntry() == THRALL)) { - me->Yell(YELL_HURRY, LANG_UNIVERSAL); WaitForTeleport = true; TeleportTimer = 20000; if (me->GetEntry() == JAINA) @@ -945,6 +952,7 @@ void hyjalAI::WaypointReached(uint32 waypointId, uint32 /*pathId*/) if (Creature* creature = ObjectAccessor::GetCreature(*me, DummyGuid)) { hyjalAI* ai = ENSURE_AI(hyjalAI, creature->AI()); + ai->Talk(JAINA_RETREAT_HORDE_BASE); ai->DoMassTeleport = true; ai->MassTeleportTimer = 20000; creature->CastSpell(me, SPELL_MASS_TELEPORT, false); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h index 331c04b6066..acb08d891b9 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.h @@ -36,7 +36,11 @@ enum SpellIds //Thrall spells SPELL_CHAIN_LIGHTNING = 31330, - SPELL_SUMMON_DIRE_WOLF = 31331 + SPELL_SUMMON_DIRE_WOLF = 31331, + + //Tyrande spells + SPELL_TRUESHOT_AURA = 31519, + SPELL_STARFALL = 20687 }; struct Wave diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 9eda6048261..0298b8952db 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -46,6 +46,12 @@ enum Spells SPELL_EXPLODING_SHOT = 7896, }; +enum HyjalCreatureText +{ + TRASH_SAY_SLAY = 0, + TRASH_SAY_DEATH = 1, +}; + float HordeWPs[8][3]=//basic waypoints from spawn to leader { {5492.91f, -2404.61f, 1462.63f}, @@ -475,8 +481,6 @@ public: { if (Creature* trigger = me->SummonCreature(NPC_WORLD_TRIGGER_TINY, me->GetPositionWithOffset({ 8.0f, 8.0f, frand(25.0f, 35.0f), 0.0f }), TEMPSUMMON_TIMED_DESPAWN, 1s)) { - trigger->SetVisible(false); - trigger->SetFaction(me->GetFaction()); trigger->SetDisableGravity(true); trigger->CastSpell(me, SPELL_METEOR, true); } @@ -806,6 +810,7 @@ public: void KilledUnit(Unit* /*victim*/) override { + Talk(TRASH_SAY_SLAY); switch (urand(0, 2)) { case 0: @@ -824,6 +829,12 @@ public: void JustEngagedWith(Unit* /*who*/) override { } + void JustDied(Unit* killer) override + { + hyjal_trashAI::JustDied(killer); + Talk(TRASH_SAY_DEATH); + } + void UpdateAI(uint32 diff) override { hyjal_trashAI::UpdateAI(diff); @@ -922,6 +933,17 @@ public: } } + void KilledUnit(Unit* /*victim*/) override + { + Talk(TRASH_SAY_SLAY); + } + + void JustDied(Unit* killer) override + { + hyjal_trashAI::JustDied(killer); + Talk(TRASH_SAY_DEATH); + } + void JustEngagedWith(Unit* /*who*/) override { } void UpdateAI(uint32 diff) override @@ -1186,7 +1208,6 @@ public: void Reset() override { Initialize(); - me->SetDisableGravity(true); } void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override @@ -1230,21 +1251,20 @@ public: { if (!go) { - go = true; + if (!useFlyPath) { for (uint8 i = 0; i < 3; ++i) AddWaypoint(i, FrostWyrmWPs[i][0], FrostWyrmWPs[i][1], FrostWyrmWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); } else {//fly path FlyPathWPs for (uint8 i = 0; i < 3; ++i) AddWaypoint(i, FlyPathWPs[i][0]+irand(-10, 10), FlyPathWPs[i][1]+irand(-10, 10), FlyPathWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); } + go = true; + Start(false, true); + SetDespawnAtEnd(false); } } @@ -1316,7 +1336,6 @@ public: void Reset() override { Initialize(); - me->SetDisableGravity(true); } void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override @@ -1356,19 +1375,17 @@ public: { if (!go) { - go = true; if (!useFlyPath) { for (uint8 i = 0; i < 3; ++i) AddWaypoint(i, GargoyleWPs[i][0]+irand(-10, 10), GargoyleWPs[i][1]+irand(-10, 10), GargoyleWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); }else{//fly path FlyPathWPs for (uint8 i = 0; i < 3; ++i) AddWaypoint(i, FlyPathWPs[i][0]+irand(-10, 10), FlyPathWPs[i][1]+irand(-10, 10), FlyPathWPs[i][2]); - Start(false, true); - SetDespawnAtEnd(false); } + go = true; + Start(false, true); + SetDespawnAtEnd(false); } } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp index ea5c9053228..0a15bc913d6 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/instance_hyjal.cpp @@ -143,6 +143,9 @@ public: case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break; + case NPC_CHANNEL_TARGET: + WorldtreeChannelTarget = creature->GetGUID(); + break; } InstanceScript::OnCreatureCreate(creature); @@ -160,6 +163,7 @@ public: case DATA_JAINAPROUDMOORE: return JainaProudmoore; case DATA_THRALL: return Thrall; case DATA_TYRANDEWHISPERWIND: return TyrandeWhisperwind; + case DATA_CHANNEL_TARGET: return WorldtreeChannelTarget; } return ObjectGuid::Empty; @@ -313,6 +317,7 @@ public: ObjectGuid JainaProudmoore; ObjectGuid Thrall; ObjectGuid TyrandeWhisperwind; + ObjectGuid WorldtreeChannelTarget; ObjectGuid HordeGate; ObjectGuid ElfGate; uint32 Trash; |