rendered paste body/* Copyright (C) 2006,2007 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>* 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, write to the Free Software* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#include "../../../sc_defines.h"#include "../../../../../../game/Unit.h"#include "../../../../../../game/Player.h"#include "../../../../../../game/TemporarySummon.h"#define SPELL_DRAIN_WORLD_TREE_VISUAL 39140#define SPELL_DRAIN_WORLD_TREE_VISUAL2 39141#define SPELL_GREEN_BEAM 35846#define SPELL_SOUL_CHARGE_PURPLE_BUFF 32052#define SPELL_SOUL_CHARGE_YELLOW_BUFF 32045#define SPELL_SOUL_CHARGE_GREEN_BUFF 32051#define SPELL_SOUL_CHARGE_PURPLE 32053#define SPELL_SOUL_CHARGE_YELLOW 32054#define SPELL_SOUL_CHARGE_GREEN 32057#define SPELL_AIR_BURST 32014#define SPELL_GRIP_OF_THE_LEGION 31972#define SPELL_FEAR 31970#define SPELL_HAND_OF_DEATH 35354#define SPELL_FINGER_OF_DEATH 31984#define SPELL_DOOMFIRE_PILLAR 32074#define SPELL_DOOMFIRE 31945#define SPELL_PROTECTION_OF_ELUNE 38528#define ENTRY_DOOMFIRE_TARGETING 18104#define CHANNEL_X 5641#define CHANNEL_Y -3445#define CHANNEL_Z 1586#define CHANNEL_TARGET_ENTRY 22418#define CHANNEL_TARGET_X 5506#define CHANNEL_TARGET_Y -3524#define CHANNEL_TARGET_Z 1608#define CHANNEL_TARGET_FACING 0//Still need those values for position at well//#define WELL_X//#define WELL_Y#define SOUND_AGGRO 10987#define SOUND_INTRO 10986#define SOUND_CHARM_ONE 10988//uh..? Is this for "on-offi-nyi"-spell? like Mind Control?#define SOUND_CHARM_TWO 11042//uh..? Is this for "on-offi-nyi"-spell? like Mind Control?#define SOUND_KNOCKUP_ONE 10989#define SOUND_KNOCKUP_TWO 11043#define SOUND_BURN_ONE 10990#define SOUND_BURN_TWO 11041#define SOUND_SLAY_ONE 10991#define SOUND_SLAY_TWO 11044#define SOUND_SLAY_THREE 11045#define SOUND_LOSE 10992#define SOUND_PLAYERLOSE 10993#define YELL_AGGRO "Your resistance is insignificant."#define YELL_INTRO "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."#define YELL_CHARM_ONE "You are mine now."#define YELL_CHARM_TWO "Bow to my will."#define YELL_KNOCKUP_ONE "A-kreesh!"#define YELL_KNOCKUP_TWO "Away vermin!"#define YELL_BURN_ONE "This world will burn!"#define YELL_BURN_TWO "Manach sheek-thrish!"#define YELL_SLAY_ONE "Your soul will languish for eternity."#define YELL_SLAY_TWO "All creation will be devoured!"#define YELL_SLAY_THREE "I am the coming of the end!"#define YELL_LOSE "No, it cannot be! Nooo!"#define YELL_PLAYERLOSE "At last it is here. Mourn and lament the passing of all you have ever known and all that would have been! Akmin-kurai!"struct MANGOS_DLL_DECL boss_archimondeAI : public ScriptedAI{ boss_archimondeAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();} bool InCombat; bool ShoutedLowHP; bool inPosition; uint32 VisualTwoTimer; uint32 DoomFireTimer; uint32 AirBurstTimer; uint32 LegionGripTimer; uint32 HandofDeathTimer; uint32 FearTimer; uint32 SoulChargeTimer; uint32 ActivePurpleCharges; uint32 ActiveYellowCharges; uint32 ActiveGreenCharges; uint32 EnrageTimer; float DoomFireSpawnX; float DoomFireSpawnY; float DoomFireSpawnZ; void EnterEvadeMode() { if (InCombat == true) { //We WERE in combat so we killed off the raid DoYell(YELL_PLAYERLOSE,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_PLAYERLOSE); } else { //We weren't in combat, let's shout our intro (not sure where to place it otherwise) DoYell(YELL_INTRO,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_INTRO); } InCombat = false; ShoutedLowHP = false; inPosition = false; m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(); DoGoHome(); VisualTwoTimer = 300 + rand()%200; DoomFireTimer = 5000 + rand()%5000; AirBurstTimer = 10000 + rand()%10000; LegionGripTimer = 1000; HandofDeathTimer = 5000; FearTimer = 30000 + rand()%10000; SoulChargeTimer = 5000; ActivePurpleCharges = 0; ActiveYellowCharges = 0; ActiveGreenCharges = 0; EnrageTimer = 600000; DoomFireSpawnX = 0; DoomFireSpawnY = 0; DoomFireSpawnZ = 0; m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DISARM, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_POLYMORPH, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_INTERRUPT, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_DAZE, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FEAR, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CHARM, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_ROOT, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_FREEZE, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SILENCE, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_STUN, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_CONFUSED, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_SLEEP, true); m_creature->ApplySpellImmune(0, IMMUNITY_MECHANIC, MECHANIC_BANISH, true); /*TODO //Show cool "drain-world-tree" animation Creature* ChannelTarget = NULL; ChannelTarget = m_creature->SummonCreature(CHANNEL_TARGET_ENTRY,CHANNEL_TARGET_X,CHANNEL_TARGET_Y,CHANNEL_TARGET_Z,CHANNEL_TARGET_FACING,TEMPSUMMON_TIMED_DESPAWN,3600000); //SuperInvis DoCast(ChannelTarget,8149); ChannelTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(ChannelTarget,SPELL_GREEN_BEAM);*/ } void KilledUnit(Unit* victim) { switch(rand()%3) { case 0: DoYell(YELL_SLAY_ONE,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_SLAY_ONE); break; case 1: DoYell(YELL_SLAY_TWO,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_SLAY_TWO); break; case 2: DoYell(YELL_SLAY_THREE,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_SLAY_THREE); break; } //Soul Charge Spell Buff Handling switch(victim->getClass()) { case CLASS_PRIEST: case CLASS_PALADIN: case CLASS_WARLOCK: DoCast(m_creature,SPELL_SOUL_CHARGE_PURPLE_BUFF); ActivePurpleCharges++; break; case CLASS_WARRIOR: case CLASS_ROGUE: case CLASS_MAGE: DoCast(m_creature,SPELL_SOUL_CHARGE_YELLOW_BUFF); ActiveYellowCharges++; break; case CLASS_DRUID: case CLASS_SHAMAN: case CLASS_HUNTER: DoCast(m_creature,SPELL_SOUL_CHARGE_GREEN_BUFF); ActiveGreenCharges++; break; } } void AttackStart(Unit *who) { if(!who && who != m_creature) return; if (who->isTargetableForAttack() && who!= m_creature) { //Begin melee attack if we are within range DoStartMeleeAttack(who); //Say our dialog if (!InCombat) { DoYell(YELL_AGGRO, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_AGGRO); InCombat = true; } } } void MoveInLineOfSight(Unit *who) { if (!who || m_creature->getVictim()) return; if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { float attackRadius = m_creature->GetAttackDistance(who); if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); if (!InCombat) { DoYell(YELL_AGGRO, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_AGGRO); InCombat = true; } DoStartMeleeAttack(who); } } } void UpdateAI(const uint32 diff) { /*TODO: Drain World Tree Animation if (InCombat == false && ChannelTarget != NULL) { if(VisualTwoTimer < diff) { m_creature->ChannelTarget->DoCast(m_creature,SPELL_DRAIN_WORLD_TREE_VISUAL2); VisualTwoTimer = 300 + rand()%200; }else VisualTwoTimer -= diff; }*/ //Return since we have no target if (!m_creature->SelectHostilTarget()) return; //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) //If we are within range melee the target if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE)) { //Make sure our attack is ready and we aren't currently casting if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false)) { //Doomfire (about every 30seconds) if (DoomFireTimer < diff && ShoutedLowHP == false) { switch(rand()%2) { case 0: DoYell(YELL_BURN_ONE, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_BURN_ONE); break; case 1: DoYell(YELL_BURN_TWO, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_BURN_TWO); break; } switch(rand()%8) { case 0: DoomFireSpawnX = (m_creature->GetPositionX()) - 5; DoomFireSpawnY = (m_creature->GetPositionY()) - 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 1: DoomFireSpawnX = (m_creature->GetPositionX()) - 5; DoomFireSpawnY = m_creature->GetPositionY(); DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 2: DoomFireSpawnX = (m_creature->GetPositionX()) - 5; DoomFireSpawnY = (m_creature->GetPositionY()) + 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 3: DoomFireSpawnX = m_creature->GetPositionX(); DoomFireSpawnY = (m_creature->GetPositionY()) - 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 4: DoomFireSpawnX = m_creature->GetPositionX(); DoomFireSpawnY = (m_creature->GetPositionY()) + 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 5: DoomFireSpawnX = (m_creature->GetPositionX()) + 5; DoomFireSpawnY = (m_creature->GetPositionY()) - 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 6: DoomFireSpawnX = (m_creature->GetPositionX()) + 5; DoomFireSpawnY = m_creature->GetPositionY(); DoomFireSpawnZ = m_creature->GetPositionZ(); break; case 7: DoomFireSpawnX = (m_creature->GetPositionX()) + 5; DoomFireSpawnY = (m_creature->GetPositionY()) + 5; DoomFireSpawnZ = m_creature->GetPositionZ(); break; } Creature* DoomFire = NULL; DoomFire = m_creature->SummonCreature(ENTRY_DOOMFIRE_TARGETING,DoomFireSpawnX,DoomFireSpawnY,DoomFireSpawnZ,0,TEMPSUMMON_TIMED_DESPAWN,27000); DoomFire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); DoCast(DoomFire,SPELL_DOOMFIRE_PILLAR); DoomFireTimer = 30000 + rand()%10000; }else DoomFireTimer -= diff; //Air Burst (can be used from 6 seconds to up to a minute) if (AirBurstTimer < diff && ShoutedLowHP == false) { switch(rand()%2) { case 0: DoYell(YELL_KNOCKUP_ONE, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_KNOCKUP_ONE); break; case 1: DoYell(YELL_KNOCKUP_TWO, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature, SOUND_KNOCKUP_TWO); break; } Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if (target == m_creature->getVictim()) target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) { DoCast(target,SPELL_AIR_BURST); AirBurstTimer = 6000 + rand()%54000; } else { DoCast(m_creature->getVictim(),SPELL_AIR_BURST); AirBurstTimer = 6000 + rand()%54000; } }else AirBurstTimer -= diff; //Grip of the Legion (very often, if not constantly) if (LegionGripTimer < diff && ShoutedLowHP == false) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) { DoCast(target,SPELL_GRIP_OF_THE_LEGION); LegionGripTimer = 500 + rand()%2000; } else { DoCast(m_creature->getVictim(),SPELL_GRIP_OF_THE_LEGION); LegionGripTimer = 500 + rand()%2000; } }else LegionGripTimer -= diff; //Fear, has a 30sec cooldown but can take longer to be casted again (30-40sec) if (FearTimer < diff && ShoutedLowHP == false) { DoCast(m_creature->getVictim(),SPELL_FEAR); FearTimer = 30000 + rand()%10000; }else FearTimer -= diff; //Soul Charge (Mostly happens in 5-10 seconds, but can be instant or after a long pause) if (SoulChargeTimer < diff && ShoutedLowHP == false) { switch(rand()%3) { case 0: if (ActivePurpleCharges != 0) { DoCast(m_creature->getVictim(),SPELL_SOUL_CHARGE_PURPLE); m_creature->RemoveAurasDueToSpell(SPELL_SOUL_CHARGE_PURPLE_BUFF); ActivePurpleCharges--; } break; case 1: if (ActiveYellowCharges != 0) { DoCast(m_creature->getVictim(),SPELL_SOUL_CHARGE_YELLOW); m_creature->RemoveAurasDueToSpell(SPELL_SOUL_CHARGE_YELLOW_BUFF); ActiveYellowCharges--; } break; case 2: if (ActiveGreenCharges != 0) { DoCast(m_creature->getVictim(),SPELL_SOUL_CHARGE_GREEN); m_creature->RemoveAurasDueToSpell(SPELL_SOUL_CHARGE_GREEN_BUFF); ActiveGreenCharges--; } break; } SoulChargeTimer = 1000 + rand()%10000; }else SoulChargeTimer -= diff; /*TODO: If Archimonde gets too close to the Well of Eternity, he casts Hand of Death if (m_creature->GetPositionX() < WELL_X && m_creature->GetPositionY() > WELL_Y) { //We are too close to the Well of Eternity! Kill Raid. if (HandofDeathTimer < diff) { DoCast(m_creature->getVictim(),SPELL_HAND_OF_DEATH); HandofDeathTimer = 5000; }else HandofDeathTimer -= diff; }*/ //Enrage after 10mins if (EnrageTimer < diff) { DoCast(m_creature->getVictim(),SPELL_HAND_OF_DEATH); EnrageTimer = 1000; }else EnrageTimer -= diff; if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 10) { //Below 10% HP, free kill phase :) (you have one minute starting from inPosition = true) if (ShoutedLowHP == false) { DoYell(YELL_LOSE,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature,SOUND_LOSE); //Want to get back to spawnpoint.. m_creature->SendMoveToPacket(CHANNEL_X, CHANNEL_Y, CHANNEL_Z,true); ShoutedLowHP = true; } if(inPosition == false) { if(m_creature->GetPositionX() == CHANNEL_X && m_creature->GetPositionY() == CHANNEL_Y) { m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); DoCast(m_creature,SPELL_DRAIN_WORLD_TREE_VISUAL); //Cast Protection of Elune on raid (should be done by Tyrande?) DoCast(m_creature->getVictim(),SPELL_PROTECTION_OF_ELUNE); //TODO: Spawn Whisps?? inPosition = true; } } if (inPosition == true) { //SPAM Finger of Death xD Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) { DoCast(target,SPELL_FINGER_OF_DEATH); } else { DoCast(m_creature->getVictim(),SPELL_FINGER_OF_DEATH); } } } } } DoMeleeAttackIfReady(); }}; CreatureAI* GetAI_boss_archimonde(Creature *_Creature){ return new boss_archimondeAI (_Creature);} void AddSC_boss_archimonde(){ Script *newscript; newscript = new Script; newscript->Name="boss_archimonde"; newscript->GetAI = GetAI_boss_archimonde; m_scripts[nrscripts++] = newscript;}struct MANGOS_DLL_DECL mob_doomfireAI : public ScriptedAI{ mob_doomfireAI(Creature *c) : ScriptedAI(c) {EnterEvadeMode();} uint32 TimeToTargetSwitch; uint32 TargetPosX; uint32 TargetPosY; uint32 TargetPosZ; bool HasAura; void UpdateAI(const uint32 diff) { if (HasAura != true) { DoCast(m_creature,SPELL_DOOMFIRE); HasAura = true; } if (!TimeToTargetSwitch) { TimeToTargetSwitch = 500; } else if (TimeToTargetSwitch < diff) { Unit* target = NULL; target = SelectUnit(SELECT_TARGET_RANDOM,0); if(target) { TargetPosX = target->GetPositionX(); TargetPosY = target->GetPositionY(); TargetPosZ = target->GetPositionZ(); m_creature->SendMoveToPacket(TargetPosX, TargetPosY, TargetPosZ,true); } else if (TargetPosX) { m_creature->SendMoveToPacket(TargetPosX, TargetPosY, TargetPosZ,true); } TimeToTargetSwitch = 5000 + rand()%5000; }else TimeToTargetSwitch -= diff; } };CreatureAI* GetAI_mob_doomfire(Creature *_Creature){ return new mob_doomfireAI (_Creature);} void AddSC_mob_doomfire(){ Script *newscript; newscript = new Script; newscript->Name="mob_doomfire"; newscript->GetAI = GetAI_mob_doomfire; m_scripts[nrscripts++] = newscript;}