diff --git a/sql/updates/world/3.3.5/9999_99_99_world.sql b/sql/updates/world/3.3.5/9999_99_99_world.sql new file mode 100644 index 00000000000..c1f589f4065 --- /dev/null +++ b/sql/updates/world/3.3.5/9999_99_99_world.sql @@ -0,0 +1,13 @@ +-- +-- Add missing gossip_menu +DELETE FROM `gossip_menu` WHERE (`MenuID`,`TextID`) IN ((7552,9380),(7581,9232),(7581,9233)); +INSERT INTO `gossip_menu`(`MenuID`, `TextID`, `VerifiedBuild`) VALUES +(7552, 9380, 0), +(7581, 9232, 0), +(7581, 9233, 0); + +-- Add missing npc_text +DELETE FROM `npc_text` WHERE `ID` IN (9232,9233); +INSERT INTO `npc_text`(`ID`, `text0_0`, `text0_1`, `BroadcastTextID0`, `lang0`, `Probability0`, `EmoteDelay0_0`, `Emote0_0`, `EmoteDelay0_1`, `Emote0_1`, `EmoteDelay0_2`, `Emote0_2`, `text1_0`, `text1_1`, `BroadcastTextID1`, `lang1`, `Probability1`, `EmoteDelay1_0`, `Emote1_0`, `EmoteDelay1_1`, `Emote1_1`, `EmoteDelay1_2`, `Emote1_2`, `text2_0`, `text2_1`, `BroadcastTextID2`, `lang2`, `Probability2`, `EmoteDelay2_0`, `Emote2_0`, `EmoteDelay2_1`, `Emote2_1`, `EmoteDelay2_2`, `Emote2_2`, `text3_0`, `text3_1`, `BroadcastTextID3`, `lang3`, `Probability3`, `EmoteDelay3_0`, `Emote3_0`, `EmoteDelay3_1`, `Emote3_1`, `EmoteDelay3_2`, `Emote3_2`, `text4_0`, `text4_1`, `BroadcastTextID4`, `lang4`, `Probability4`, `EmoteDelay4_0`, `Emote4_0`, `EmoteDelay4_1`, `Emote4_1`, `EmoteDelay4_2`, `Emote4_2`, `text5_0`, `text5_1`, `BroadcastTextID5`, `lang5`, `Probability5`, `EmoteDelay5_0`, `Emote5_0`, `EmoteDelay5_1`, `Emote5_1`, `EmoteDelay5_2`, `Emote5_2`, `text6_0`, `text6_1`, `BroadcastTextID6`, `lang6`, `Probability6`, `EmoteDelay6_0`, `Emote6_0`, `EmoteDelay6_1`, `Emote6_1`, `EmoteDelay6_2`, `Emote6_2`, `text7_0`, `text7_1`, `BroadcastTextID7`, `lang7`, `Probability7`, `EmoteDelay7_0`, `Emote7_0`, `EmoteDelay7_1`, `Emote7_1`, `EmoteDelay7_2`, `Emote7_2`, `VerifiedBuild`) VALUES +(9232, '', '', 15444, 0, 1, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), +(9233, '', '', 15448, 0, 1, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp index 319d5b26823..538d36b6cf1 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/boss_archimonde.cpp @@ -78,14 +78,16 @@ 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 }; enum Summons { NPC_DOOMFIRE = 18095, NPC_DOOMFIRE_SPIRIT = 18104, - NPC_ANCIENT_WISP = 17946 + NPC_ANCIENT_WISP = 17946, + WORLDTREE_CHANNEL_TARGET = 22418 }; enum Actions @@ -94,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: @@ -284,23 +288,27 @@ public: Enraged = false; HasProtected = false; + WorldtreeTraget = me->SummonCreature(WORLDTREE_CHANNEL_TARGET, 5503.713f, -3523.436f, 1608.781f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 360000s); + DoCast(WorldtreeTraget, SPELL_DRAIN_WORLD_TREE); + WorldtreeTraget->AI()->DoCast(me, SPELL_DRAIN_WORLD_TREE_TRIGGERED); } void InitializeAI() override { BossAI::InitializeAI(); - DoAction(ACTION_CHANNEL_WORLD_TREE); } void Reset() override { Initialize(); _Reset(); - me->RemoveAllAuras(); // Reset Soul Charge auras. + me->RemoveAllAuras(); // Reset Soul Charge auras. + CastProtectionOfElune(false); } void JustEngagedWith(Unit* who) override { + me->InterruptSpell(CURRENT_CHANNELED_SPELL); Talk(SAY_AGGRO); BossAI::JustEngagedWith(who); events.ScheduleEvent(EVENT_FEAR, 42s); @@ -387,11 +395,28 @@ public: DoAction(ACTION_ENRAGE); events.ScheduleEvent(EVENT_DISTANCE_CHECK, 5s); break; + case EVENT_PROTECTION_OF_ELUNE: // hp below 10% only cast hand of death + events.CancelEvent(EVENT_FEAR); + events.CancelEvent(EVENT_UNLEASH_SOUL_CHARGE); + events.CancelEvent(EVENT_GRIP_OF_THE_LEGION); + events.CancelEvent(EVENT_AIR_BURST); + events.CancelEvent(EVENT_FEAR); + events.CancelEvent(EVENT_DOOMFIRE); + events.CancelEvent(EVENT_FINGER_OF_DEATH); + events.CancelEvent(EVENT_HAND_OF_DEATH); + events.ScheduleEvent(EVENT_HAND_OF_DEATH, 2s); + CastProtectionOfElune(true); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + 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; default: @@ -399,6 +424,35 @@ public: } } + void CastProtectionOfElune(bool apply) + { + if (apply) + { + if (me->GetThreatManager().IsThreatListEmpty()) + return; + + std::vector vt = me->GetThreatManager().GetModifiableThreatList(); // GetUnsortedThreatList //Trinity::IteratorPair ThreatContainer::StorageType + for(std::vector::iterator iter=vt.begin();iter!=vt.end();iter++) + { + if (Unit* target = (*iter)->GetVictim()) + if (target->IsAlive() && target->GetTypeId() == TYPEID_PLAYER) + spellProtectionOfEluneTargets.push_back(target); + } + } + + for (auto iter = spellProtectionOfEluneTargets.begin(); iter != spellProtectionOfEluneTargets.end(); ++iter) + if (Unit* target = *iter) + { + if (apply) + target->AddAura(SPELL_PROTECTION_OF_ELUNE, target); + target->ApplySpellImmune(SPELL_HAND_OF_DEATH, IMMUNITY_ID, SPELL_HAND_OF_DEATH, apply); + //target->ApplySpellImmune(0, IMMUNITY_ID, SPELL_HAND_OF_DEATH, apply); + } + + if (!apply) + spellProtectionOfEluneTargets.clear(); + } + void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType /*damageType*/, SpellInfo const* /*spellInfo = nullptr*/) override { if (me->HealthBelowPctDamaged(10, damage)) @@ -410,9 +464,8 @@ 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); } @@ -452,11 +505,13 @@ public: void JustReachedHome() override { DoAction(ACTION_CHANNEL_WORLD_TREE); + DoCast(WorldtreeTraget, SPELL_DRAIN_WORLD_TREE); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); + CastProtectionOfElune(false); _JustDied(); // @todo: remove this when instance script gets updated, kept for compatibility only instance->SetData(DATA_ARCHIMONDE, DONE); @@ -531,6 +586,8 @@ public: uint32 _unleashSpell; bool Enraged; bool HasProtected; + Creature* WorldtreeTraget; + std::list spellProtectionOfEluneTargets; }; CreatureAI* GetAI(Creature* creature) const override diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp index 8070906e295..867ce69da6e 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal.cpp @@ -94,6 +94,7 @@ class npc_jaina_proudmoore : public CreatureScript StartEvent(player); break; case GOSSIP_ACTION_INFO_DEF + 3: + me->AI()->Talk(5); Retreat(); break; case GOSSIP_ACTION_INFO_DEF: @@ -112,16 +113,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, GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 907, me->GetGUID()); return true; } }; @@ -188,17 +196,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, 9232, 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, 9233, me->GetGUID()); + } } if (player->IsGameMaster()) AddGossipItemFor(player, GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); - SendGossipMenuFor(player, 907, me->GetGUID()); return true; } }; @@ -244,7 +260,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 3d9e1d8b687..4bd6a509195 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjalAI.cpp @@ -40,8 +40,6 @@ enum Spawns SPAWN_NEAR_TOWER = 2, }; -#define YELL_HURRY "Hurry, we don't have much time" - // Locations for summoning gargoyls and frost wyrms in special cases float SpawnPointSpecial[3][3]= { @@ -401,6 +399,7 @@ void hyjalAI::Reset() case TYRANDE: Faction = 2; + DoCast(me, SPELL_TRUESHOT_AURA, true); break; } @@ -936,7 +935,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) 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 f607c7faeb8..21c075f43f1 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -189,6 +189,7 @@ hyjal_trashAI::hyjal_trashAI(Creature* creature) : EscortAI(creature) useFlyPath = false; damageTaken = 0; memset(DummyTarget, 0, sizeof(DummyTarget)); + SetRun(); Reset(); }