/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ /* ScriptData SDName: boss_archaedas SD%Complete: 100 SDComment: Archaedas is activated when 1 person (was 3, changed in 3.0.8) clicks on his altar. Every 10 seconds he will awaken one of his minions along the wall. At 66%, he will awaken the 6 Guardians. At 33%, he will awaken the Vault Walkers On his death the vault door opens. EndScriptData */ #include "ScriptMgr.h" #include "GameObject.h" #include "GameObjectAI.h" #include "InstanceScript.h" #include "ObjectAccessor.h" #include "Player.h" #include "ScriptedCreature.h" #include "SpellInfo.h" #include "uldaman.h" enum Says { SAY_AGGRO = 0, SAY_SUMMON_GUARDIANS = 1, SAY_SUMMON_VAULT_WALKERS = 2, SAY_KILL = 3 }; enum Spells { SPELL_GROUND_TREMOR = 6524, SPELL_ARCHAEDAS_AWAKEN = 10347, SPELL_BOSS_OBJECT_VISUAL = 11206, SPELL_BOSS_AGGRO = 10340, SPELL_SUB_BOSS_AGGRO = 11568, SPELL_AWAKEN_VAULT_WALKER = 10258, SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252, SPELL_SELF_DESTRUCT = 9874, SPELL_FREEZE_ANIM = 16245, SPELL_MINION_FREEZE_ANIM = 10255 }; class boss_archaedas : public CreatureScript { public: boss_archaedas() : CreatureScript("boss_archaedas") { } struct boss_archaedasAI : public BossAI { boss_archaedasAI(Creature* creature) : BossAI(creature, BOSS_ARCHAEDAS) { Initialize(); } void Initialize() { uiTremorTimer = 60000; iAwakenTimer = 0; uiWallMinionTimer = 10000; bWakingUp = false; bGuardiansAwake = false; bVaultWalkersAwake = false; } uint32 uiTremorTimer; int32 iAwakenTimer; uint32 uiWallMinionTimer; bool bWakingUp; bool bGuardiansAwake; bool bVaultWalkersAwake; void Reset() override { _Reset(); Initialize(); instance->SetData(0, 5); // respawn any dead minions me->SetFaction(FACTION_FRIENDLY); me->SetUninteractible(true); me->SetControlled(true, UNIT_STATE_ROOT); me->AddAura(SPELL_FREEZE_ANIM, me); } void ActivateMinion(ObjectGuid uiGuid, bool flag) { Unit* minion = ObjectAccessor::GetUnit(*me, uiGuid); if (minion && minion->IsAlive()) { DoCast(minion, SPELL_AWAKEN_VAULT_WALKER, flag); minion->CastSpell(minion, SPELL_ARCHAEDAS_AWAKEN, true); minion->SetUninteractible(false); minion->SetControlled(false, UNIT_STATE_ROOT); minion->SetFaction(FACTION_MONSTER); minion->RemoveAura(SPELL_MINION_FREEZE_ANIM); } } void JustEngagedWith(Unit* who) override { _JustEngagedWith(who); me->SetFaction(FACTION_MONSTER); me->SetUninteractible(false); me->SetControlled(false, UNIT_STATE_ROOT); } void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override { // Being woken up from the altar, start the awaken sequence if (spellInfo->Id == SPELL_ARCHAEDAS_AWAKEN) { Talk(SAY_AGGRO); iAwakenTimer = 4000; bWakingUp = true; } } void KilledUnit(Unit* /*victim*/) override { Talk(SAY_KILL); } void UpdateAI(uint32 uiDiff) override { // we're still doing awaken animation if (bWakingUp && iAwakenTimer >= 0) { iAwakenTimer -= uiDiff; return; // dont do anything until we are done } else if (bWakingUp && iAwakenTimer <= 0) { bWakingUp = false; AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); return; // dont want to continue until we finish the AttackStart method } //Return since we have no target if (!UpdateVictim()) return; // wake a wall minion if (uiWallMinionTimer <= uiDiff) { instance->SetData(DATA_MINIONS, IN_PROGRESS); uiWallMinionTimer = 10000; } else uiWallMinionTimer -= uiDiff; //If we are <66 summon the guardians if (!bGuardiansAwake && !HealthAbovePct(66)) { ActivateMinion(instance->GetGuidData(5), true); // EarthenGuardian1 ActivateMinion(instance->GetGuidData(6), true); // EarthenGuardian2 ActivateMinion(instance->GetGuidData(7), true); // EarthenGuardian3 ActivateMinion(instance->GetGuidData(8), true); // EarthenGuardian4 ActivateMinion(instance->GetGuidData(9), true); // EarthenGuardian5 ActivateMinion(instance->GetGuidData(10), false); // EarthenGuardian6 Talk(SAY_SUMMON_GUARDIANS); bGuardiansAwake = true; } //If we are <33 summon the vault walkers if (!bVaultWalkersAwake && !HealthAbovePct(33)) { ActivateMinion(instance->GetGuidData(1), true); // VaultWalker1 ActivateMinion(instance->GetGuidData(2), true); // VaultWalker2 ActivateMinion(instance->GetGuidData(3), true); // VaultWalker3 ActivateMinion(instance->GetGuidData(4), false); // VaultWalker4 Talk(SAY_SUMMON_VAULT_WALKERS); bVaultWalkersAwake = true; } if (uiTremorTimer <= uiDiff) { //Cast DoCastVictim(SPELL_GROUND_TREMOR); //45 seconds until we should cast this agian uiTremorTimer = 45000; } else uiTremorTimer -= uiDiff; } void JustDied (Unit* /*killer*/) override { _JustDied(); instance->SetData(DATA_MINIONS, SPECIAL); // deactivate his minions } }; CreatureAI* GetAI(Creature* creature) const override { return GetUldamanAI(creature); } }; /* ScriptData SDName: npc_archaedas_minions SD%Complete: 100 SDComment: These mobs are initially frozen until Archaedas awakens them one at a time. EndScriptData */ class npc_archaedas_minions : public CreatureScript { public: npc_archaedas_minions() : CreatureScript("npc_archaedas_minions") { } struct npc_archaedas_minionsAI : public ScriptedAI { npc_archaedas_minionsAI(Creature* creature) : ScriptedAI(creature) { Initialize(); instance = me->GetInstanceScript(); } void Initialize() { uiArcing_Timer = 3000; iAwakenTimer = 0; bWakingUp = false; bAmIAwake = false; } uint32 uiArcing_Timer; int32 iAwakenTimer; bool bWakingUp; bool bAmIAwake; InstanceScript* instance; void Reset() override { Initialize(); me->SetFaction(35); me->SetUninteractible(true); me->SetControlled(true, UNIT_STATE_ROOT); me->RemoveAllAuras(); me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } void JustEngagedWith(Unit* /*who*/) override { me->SetFaction(FACTION_MONSTER); me->RemoveAllAuras(); me->SetUninteractible(false); me->SetControlled(false, UNIT_STATE_ROOT); bAmIAwake = true; } void SpellHit(WorldObject* /*caster*/, SpellInfo const* spellInfo) override { // time to wake up, start animation if (spellInfo->Id == SPELL_ARCHAEDAS_AWAKEN) { iAwakenTimer = 5000; bWakingUp = true; } } void MoveInLineOfSight(Unit* who) override { if (bAmIAwake) ScriptedAI::MoveInLineOfSight(who); } void UpdateAI(uint32 uiDiff) override { // we're still in the awaken animation if (bWakingUp && iAwakenTimer >= 0) { iAwakenTimer -= uiDiff; return; // dont do anything until we are done } else if (bWakingUp && iAwakenTimer <= 0) { bWakingUp = false; bAmIAwake = true; AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID return; // dont want to continue until we finish the AttackStart method } //Return since we have no target if (!UpdateVictim()) return; } }; CreatureAI* GetAI(Creature* creature) const override { return GetUldamanAI(creature); } }; /* ScriptData SDName: npc_stonekeepers SD%Complete: 100 SDComment: After activating the altar of the keepers, the stone keepers will wake up one by one. EndScriptData */ class npc_stonekeepers : public CreatureScript { public: npc_stonekeepers() : CreatureScript("npc_stonekeepers") { } struct npc_stonekeepersAI : public ScriptedAI { npc_stonekeepersAI(Creature* creature) : ScriptedAI(creature) { instance = me->GetInstanceScript(); } InstanceScript* instance; void Reset() override { me->SetFaction(FACTION_FRIENDLY); me->SetUninteractible(true); me->SetControlled(true, UNIT_STATE_ROOT); me->RemoveAllAuras(); me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } void JustEngagedWith(Unit* /*who*/) override { me->SetFaction(FACTION_FRIENDLY); me->SetUninteractible(false); me->SetControlled(false, UNIT_STATE_ROOT); } void UpdateAI(uint32 /*diff*/) override { //Return since we have no target if (!UpdateVictim()) return; } void JustDied(Unit* /*killer*/) override { DoCast (me, SPELL_SELF_DESTRUCT, true); instance->SetData(DATA_STONE_KEEPERS, IN_PROGRESS); // activate next stonekeeper } }; CreatureAI* GetAI(Creature* creature) const override { return GetUldamanAI(creature); } }; /* ScriptData SDName: go_altar_archaedas SD%Complete: 100 SDComment: Needs 1 person to activate the Archaedas script SDCategory: Uldaman EndScriptData */ class go_altar_of_archaedas : public GameObjectScript { public: go_altar_of_archaedas() : GameObjectScript("go_altar_of_archaedas") { } struct go_altar_of_archaedasAI : public GameObjectAI { go_altar_of_archaedasAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { } InstanceScript* instance; bool OnGossipHello(Player* player) override { player->CastSpell(player, SPELL_BOSS_OBJECT_VISUAL, false); instance->SetGuidData(0, player->GetGUID()); // activate archaedas return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return GetUldamanAI(go); } }; //This is the actual function called only once durring InitScripts() //It must define all handled functions that are to be run in this script void AddSC_boss_archaedas() { new boss_archaedas(); new npc_archaedas_minions(); new npc_stonekeepers(); new go_altar_of_archaedas(); }