Index: boss/sc_anubrekhan.cpp =================================================================== --- boss/sc_anubrekhan.cpp (revision 0) +++ boss/sc_anubrekhan.cpp (revision 0) @@ -0,0 +1,266 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SAY_AGGRO1 "Just a little taste..." +#define SAY_AGGRO2 "There is no way out." +#define SAY_AGGRO3 "Yes, Run! It makes the blood pump faster!" +#define SAY_GREET "Ahh... welcome to my parlor" +#define SAY_TAUNT1 "I hear little hearts beating. Yesss... beating faster now. Soon the beating will stop." +#define SAY_TAUNT2 "Where to go? What to do? So many choices that all end in pain, end in death." +#define SAY_TAUNT3 "Which one shall I eat first? So difficult to choose... the all smell so delicious." +#define SAY_TAUNT4 "Closer now... tasty morsels. I've been too long without food. Without blood to drink." +#define SAY_SLAY "Shh... it will all be over soon." + +#define SOUND_AGGRO1 8785 +#define SOUND_AGGRO2 8786 +#define SOUND_AGGRO3 8787 +#define SOUND_GREET 8788 +#define SOUND_TAUNT1 8790 +#define SOUND_TAUNT2 8791 +#define SOUND_TAUNT3 8792 +#define SOUND_TAUNT4 8793 +#define SOUND_SLAY 8789 + +#define SPELL_IMPALE 28783 //May be wrong spell id. Causes more dmg than I expect +#define SPELL_LOCUSTSWARM 28785 //This is a self buff that triggers the dmg debuff +#define SPELL_SUMMONGUARD 29508 //Summons 1 crypt guard at targeted location + +#define SPELL_SELF_SPAWN_5 29105 //This spawns 5 corpse scarabs ontop of us (most likely the player casts this on death) +#define SPELL_SELF_SPAWN_10 28864 //This is used by the crypt guards when they die + +struct MANGOS_DLL_DECL boss_anubrekhanAI : public ScriptedAI +{ + boss_anubrekhanAI(Creature *c) : ScriptedAI(c) {Reset();HasTaunted = false;} + + uint32 Impale_Timer; + uint32 LocustSwarm_Timer; + uint32 Summon_Timer; + bool InCombat; + bool HasTaunted; + + void Reset() + { + Impale_Timer = 15000; //15 seconds + LocustSwarm_Timer = 80000 + (rand()%40000); //Random time between 80 seconds and 2 minutes for initial cast + Summon_Timer = LocustSwarm_Timer + 45000; //45 seconds after initial locust swarm + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void KilledUnit(Unit* Victim) + { + //Force the player to spawn corpse scarabs via spell + Victim->CastSpell(Victim, SPELL_SELF_SPAWN_5, true); + + if (rand()%5) + return; + + DoYell(SAY_SLAY, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_SLAY); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + switch(rand()%3) + { + case 0: + DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + break; + + case 1: + DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + break; + + case 2: + DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO3); + break; + } + InCombat = true; + } + } + } + + //Extended Visbility range for taunts + bool IsVisible(Unit *who) const + { + if (!who) + return false; + + return m_creature->IsWithinDist(who, 100.0f) && who->isVisibleFor(m_creature,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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + switch(rand()%3) + { + case 0: + DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + break; + + case 1: + DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + break; + + case 2: + DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO3); + break; + } + InCombat = true; + } + } + else if (!HasTaunted && m_creature->IsWithinDist(who, 60.0f)) + { + switch(rand()%5) + { + case 0: + DoYell(SAY_TAUNT1, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_TAUNT1); + break; + + case 1: + DoYell(SAY_TAUNT2, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_TAUNT2); + break; + + case 2: + DoYell(SAY_TAUNT3, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_TAUNT3); + break; + + case 3: + DoYell(SAY_TAUNT4, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_TAUNT4); + break; + + case 4: + DoYell(SAY_GREET, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_GREET); + break; + } + HasTaunted = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //Impale_Timer + if (Impale_Timer < diff) + { + //Cast Impale on a random target + //Do NOT cast it when we are afflicted by locust swarm + if (!m_creature->HasAura(SPELL_LOCUSTSWARM,1)) + DoCast(m_creature->getVictim(),SPELL_IMPALE); + + //15 seconds until we should cast this agian + Impale_Timer = 15000; + }else Impale_Timer -= diff; + + //LocustSwarm_Timer + if (LocustSwarm_Timer < diff) + { + //Cast Locust Swarm buff on ourselves + DoCast(m_creature, SPELL_LOCUSTSWARM); + + //90 seconds until we should cast this agian + LocustSwarm_Timer = 90000; + }else LocustSwarm_Timer -= diff; + + //Summon_Timer + if (Summon_Timer < diff) + { + //Summon a crypt guard + DoCast(m_creature, SPELL_SUMMONGUARD); + + //45 seconds until we should cast this agian + Summon_Timer = 45000; + }else Summon_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_anubrekhan(Creature *_Creature) +{ + return new boss_anubrekhanAI (_Creature); +} + + +void AddSC_boss_anubrekhan() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_anubrekhan"; + newscript->GetAI = GetAI_boss_anubrekhan; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_arcanist_doan.cpp =================================================================== --- boss/sc_boss_arcanist_doan.cpp (revision 0) +++ boss/sc_boss_arcanist_doan.cpp (revision 0) @@ -0,0 +1,245 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_POLYMORPH 12826 +#define SPELL_AOESILENCE 8988 +#define SPELL_ARCANEEXPLOSION3 8438 +#define SPELL_ARCANEEXPLOSION4 8439 +#define SPELL_FIREAOE 25049 +#define SPELL_BLINK 1953 +#define SPELL_FIREBALL 21162 +#define SPELL_MANASHIELD4 10191 +#define SPELL_ARCANEBUBBLE 9438 + +#define SAY_AGGRO "You will not defile these mysteries!" +#define SAY_SPECIALAE "Burn in righteous fire!" + +#define SOUND_AGGRO 5842 +#define SOUND_SPECIALAE 5843 + +struct MANGOS_DLL_DECL boss_arcanist_doanAI : public ScriptedAI +{ + boss_arcanist_doanAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 FullAOE_Timer; + uint32 Polymorph_Timer; + uint32 Yell_Timer; + uint32 ArcaneBubble_Timer; + uint32 AoESilence_Timer; + uint32 ArcaneExplosion3_Timer; + uint32 ArcaneExplosion4_Timer; + uint32 Blink_Timer; + uint32 Fireball_Timer; + uint32 ManaShield4_Timer; + bool InCombat; + + void Reset() + { + FullAOE_Timer = 5000; + Polymorph_Timer = 1; + Yell_Timer = 2000; + ArcaneBubble_Timer = 3000; + AoESilence_Timer = 20000; + ArcaneExplosion3_Timer = 10000; + ArcaneExplosion4_Timer = 10000; + Blink_Timer = 40000; + Fireball_Timer = 6000; + ManaShield4_Timer = 70000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + if (m_creature->IsWithinDist(who, ATTACK_DIST)) + DoStartMeleeAttack(who); + else DoStartRangedAttack(who); + + //Say our dialog + DoYell(SAY_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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //If we are <50% hp cast Arcane Bubble and start casting SPECIAL FIRE AOE + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && !m_creature->m_currentSpell) + { + //SpecialAoE -> Fucking bitch took lot of my time to test :S + if (Polymorph_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_POLYMORPH); + Polymorph_Timer = 40000; + }else Polymorph_Timer -= diff; + + if (Yell_Timer < diff) + { + DoYell(SAY_SPECIALAE,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_SPECIALAE); + Yell_Timer = 40000; + }else Yell_Timer -= diff; + + if (ArcaneBubble_Timer < diff) + { + DoCast(m_creature,SPELL_ARCANEBUBBLE); + ArcaneBubble_Timer = 40000; + }else ArcaneBubble_Timer -= diff; + + if (FullAOE_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_FIREAOE); + FullAOE_Timer = 40000; + }else FullAOE_Timer -= diff; + } + + //AoESilence_Timer + if (AoESilence_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_AOESILENCE); + + //60 seconds until we should cast this agian + AoESilence_Timer = 30000; + }else AoESilence_Timer -= diff; + + //ArcaneExplosion3_Timer + if (ArcaneExplosion3_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_ARCANEEXPLOSION3); + + //30 seconds until we should cast this agian + ArcaneExplosion3_Timer = 10000; + }else ArcaneExplosion3_Timer -= diff; + + //ArcaneExplosion4_Timer + if (ArcaneExplosion4_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_ARCANEEXPLOSION4); + + //35 seconds until we should cast this agian + ArcaneExplosion4_Timer = 10000; + }else ArcaneExplosion4_Timer -= diff; + + //Blink_Timer + if (Blink_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_BLINK); + + //35 seconds until we should cast this agian + Blink_Timer = 40000; + }else Blink_Timer -= diff; + + //Fireball_Timer + if (Fireball_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FIREBALL); + + //35 seconds until we should cast this agian + Fireball_Timer = 10000; + }else Fireball_Timer -= diff; + + //ManaShiled4_Timer + if (ManaShield4_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_MANASHIELD4); + + //35 seconds until we should cast this agian + ManaShield4_Timer = 70000; + }else ManaShield4_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_arcanist_doan(Creature *_Creature) +{ + return new boss_arcanist_doanAI (_Creature); +} + + +void AddSC_boss_arcanist_doan() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_arcanist_doan"; + newscript->GetAI = GetAI_boss_arcanist_doan; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_azshir_the_sleepless.cpp =================================================================== --- boss/sc_boss_azshir_the_sleepless.cpp (revision 0) +++ boss/sc_boss_azshir_the_sleepless.cpp (revision 0) @@ -0,0 +1,152 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_CALLOFTHEGRAVE 17831 +#define SPELL_TERRIFY 7399 +#define SPELL_SOULSIPHON 7290 + +struct MANGOS_DLL_DECL boss_azshir_the_sleeplessAI : public ScriptedAI +{ + boss_azshir_the_sleeplessAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 SoulSiphon_Timer; + uint32 CallOftheGrave_Timer; + uint32 Terrify_Timer; + bool InCombat; + + void Reset() + { + SoulSiphon_Timer = 1; + CallOftheGrave_Timer = 30000; + Terrify_Timer = 20000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //If we are <50% hp cast Soul Siphon rank 1 + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && !m_creature->m_currentSpell) + { + //SoulSiphon_Timer + if (SoulSiphon_Timer < diff) + { + + DoCast(m_creature->getVictim(),SPELL_SOULSIPHON); + return; + + //180 seconds until we should cast this agian + SoulSiphon_Timer = 20000; + }else SoulSiphon_Timer -= diff; + } + + //CallOfTheGrave_Timer + if (CallOftheGrave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CALLOFTHEGRAVE); + + //70 seconds until we should cast this agian + CallOftheGrave_Timer = 30000; + }else CallOftheGrave_Timer -= diff; + + //Terrify_Timer + if (Terrify_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_TERRIFY); + + //45 seconds until we should cast this agian + Terrify_Timer = 20000; + }else Terrify_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +CreatureAI* GetAI_boss_azshir_the_sleepless(Creature *_Creature) +{ + return new boss_azshir_the_sleeplessAI (_Creature); +} + +void AddSC_boss_azshir_the_sleepless() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_azshir_the_sleepless"; + newscript->GetAI = GetAI_boss_azshir_the_sleepless; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_baron_geddon.cpp =================================================================== --- boss/sc_boss_baron_geddon.cpp (revision 173) +++ boss/sc_boss_baron_geddon.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** @@ -27,26 +27,20 @@ { boss_baron_geddonAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 Inferno_Timer; uint32 IgniteMana_Timer; uint32 LivingBomb_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; Inferno_Timer = 45000; //These times are probably wrong IgniteMana_Timer = 30000; LivingBomb_Timer = 35000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -58,36 +52,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -96,12 +88,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //If we are <2% hp cast Armageddom if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 2 && !m_creature->m_currentSpell) @@ -147,21 +133,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_bloodmage_thalnos.cpp =================================================================== --- boss/sc_boss_bloodmage_thalnos.cpp (revision 0) +++ boss/sc_boss_bloodmage_thalnos.cpp (revision 0) @@ -0,0 +1,207 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_FROSTNOVA2 865 +#define SPELL_FLAMESHOCK3 8053 +#define SPELL_SHADOWBOLT5 1106 +#define SPELL_FLAMESPIKE 8814 +#define SPELL_FIRENOVA 16079 + +#define SAY_AGGRO "We hunger for vengeance." +#define SAY_HEALTH "No rest... for the angry dead!" +#define SAY_DEATH "More... More souls!" + +#define SOUND_AGGRO 5844 +#define SOUND_HEALTH 5846 +#define SOUND_DEATH 5845 + +struct MANGOS_DLL_DECL boss_bloodmage_thalnosAI : public ScriptedAI +{ + boss_bloodmage_thalnosAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 FrostNova2_Timer; + uint32 FlameShock3_Timer; + uint32 ShadowBolt5_Timer; + uint32 FlameSpike_Timer; + uint32 FireNova_Timer; + uint32 Yell_Timer; + bool InCombat; + + void Reset() + { + Yell_Timer = 1; + FrostNova2_Timer = 10000; + FlameShock3_Timer = 15000; + ShadowBolt5_Timer = 20000; + FlameSpike_Timer = 20000; + FireNova_Timer = 10000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + if (m_creature->IsWithinDist(who, ATTACK_DIST)) + DoStartMeleeAttack(who); + else DoStartRangedAttack(who); + + //Say our dialog + DoYell(SAY_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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //If we are <35% hp + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 35) + { + Yell_Timer -= diff; + + if (Yell_Timer < diff) + { + DoYell(SAY_HEALTH,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_HEALTH); + Yell_Timer = 900000; + } + } + + //FrostNova2_Timer + if (FrostNova2_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FROSTNOVA2); + + //30 seconds until we should cast this agian + FrostNova2_Timer = 10000; + }else FrostNova2_Timer -= diff; + + //FlameShock3_Timer + if (FlameShock3_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FLAMESHOCK3); + + //30 seconds until we should cast this agian + FlameShock3_Timer = 15000; + }else FlameShock3_Timer -= diff; + + //ShadowBolt5_Timer + if (ShadowBolt5_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SHADOWBOLT5); + + //45 seconds until we should cast this agian + ShadowBolt5_Timer = 20000; + }else ShadowBolt5_Timer -= diff; + + //FlameSpike_Timer + if (FlameSpike_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FLAMESPIKE); + + //45 seconds until we should cast this agian + FlameSpike_Timer = 30000; + }else FlameSpike_Timer -= diff; + + //FireNova_Timer + if (FireNova_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FIRENOVA); + + //30 seconds until we should cast this agian + FireNova_Timer = 20000; + }else FireNova_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +CreatureAI* GetAI_boss_bloodmage_thalnos(Creature *_Creature) +{ + return new boss_bloodmage_thalnosAI (_Creature); +} + + +void AddSC_boss_bloodmage_thalnos() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_bloodmage_thalnos"; + newscript->GetAI = GetAI_boss_bloodmage_thalnos; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_broodlord_lashlayer.cpp =================================================================== --- boss/sc_boss_broodlord_lashlayer.cpp (revision 0) +++ boss/sc_boss_broodlord_lashlayer.cpp (revision 0) @@ -0,0 +1,185 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SPELL_CLEAVE 20691 +#define SPELL_BLASTWAVE 11130 +#define SPELL_MORTALSTRIKE 24573 +#define SPELL_KNOCKBACK 25778 + +#define SAY_AGGRO "None of your kind should be here! You've doomed only yourselves!" +#define SAY_LEASH "Clever Mortals but I am not so easily lured away from my sanctum!" +#define SOUND_AGGRO 8286 +#define SOUND_LEASH 8287 + +struct MANGOS_DLL_DECL boss_broodlordAI : public ScriptedAI +{ + boss_broodlordAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Cleave_Timer; + uint32 BlastWave_Timer; + uint32 MortalStrike_Timer; + uint32 KnockBack_Timer; + bool InCombat; + + void Reset() + { + Cleave_Timer = 25000; //These times are probably wrong + BlastWave_Timer = 35000; + MortalStrike_Timer = 15000; + KnockBack_Timer = 25000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + DoYell(SAY_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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO); + InCombat = true; + } + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //If they try to kite us we evade back + if (CheckTether()) + { + DoYell(SAY_LEASH,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_LEASH); + Reset(); + return; + } + + //Cleave_Timer + if (Cleave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CLEAVE); + + //25 seconds until we should cast this agian + Cleave_Timer = 25000; + }else Cleave_Timer -= diff; + + // BlastWave(fixed.thx Ntsc) + if (BlastWave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_BLASTWAVE); + + //35 seconds until we should cast this again + BlastWave_Timer = 35000; + }else BlastWave_Timer -= diff; + + //MortalStrike_Timer + if (MortalStrike_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_MORTALSTRIKE); + // he casts it first after 15 seconds and then each 35 seconds. <- now it should be desyncronised from blastwave.Thx Ntsc. + //25 seconds until we should cast this agian + MortalStrike_Timer = 35000; + }else MortalStrike_Timer -= diff; + + //KnockBack_Timer + if (KnockBack_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_KNOCKBACK); + + //25 seconds until we should cast this agian + KnockBack_Timer = 25000; + }else KnockBack_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_broodlord(Creature *_Creature) +{ + return new boss_broodlordAI (_Creature); +} + + +void AddSC_boss_broodlord() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_broodlord"; + newscript->GetAI = GetAI_boss_broodlord; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_chromaggus.cpp =================================================================== --- boss/sc_boss_chromaggus.cpp (revision 0) +++ boss/sc_boss_chromaggus.cpp (revision 0) @@ -0,0 +1,369 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +//These spells are actually called elemental shield +//What they do is decrease all damage by 75% then they increase +//One school of damage by 1100% +#define SPELL_FIRE_VURNALBILTY 22277 +#define SPELL_FROST_VURNALBILTY 22278 +#define SPELL_SHADOW_VURNALBILTY 22279 +#define SPELL_NATURE_VURNALBILTY 22280 +#define SPELL_ARCANE_VURNALBILTY 22281 + +//Incinerate 23308,23309 +#define SPELL_INCINERATE 23308 +//Time lapse 23310, 23311(old threat mod that was removed in 2.01) +#define SPELL_TIMELAPSE 23310 +//Corrosive Acid 23313, 23314 +#define SPELL_CORROSIVEACID 23313 +//Ignite Flesh 23315,23316 +#define SPELL_IGNITEFLESH 23315 +//Frost burn 23187, 23189 +#define SPELL_FROSTBURN 23187 + +//Brood Affliction 23173 - Scripted Spell that cycles through all targets within 100 yards and has a chance to cast one of the afflictions on them +//Since Scripted spells arn't coded I'll just write a function that does the same thing + +//Blue affliction 23153 +#define SPELL_BROODAF_BLUE 23153 +//Black affliction 23154 +#define SPELL_BROODAF_BLACK 23154 +//Red affliction 23155 (23168 on death) +#define SPELL_BROODAF_RED 23155 +//Bronze Affliction 23170 +#define SPELL_BROODAF_BRONZE 23170 +//Brood Affliction Green 23169 +#define SPELL_BROODAF_GREEN 23169 + +//The frenzy spell may be wrong +#define SPELL_FRENZY 19812 +#define SPELL_ENRAGE 28747 + + +struct MANGOS_DLL_DECL boss_chromaggusAI : public ScriptedAI +{ + boss_chromaggusAI(Creature *c) : ScriptedAI(c) + { + //Select the 2 breaths that we are going to use until despawned + //5 possiblities for the first breath, 4 for the second, 20 total possiblites + //This way we don't end up casting 2 of the same breath + //TL TL would be retard + switch (rand()%20) + { + //B1 - Incin + case 0: + Breath1_Spell = SPELL_INCINERATE; + Breath2_Spell = SPELL_TIMELAPSE; + break; + + case 1: + Breath1_Spell = SPELL_INCINERATE; + Breath2_Spell = SPELL_CORROSIVEACID; + break; + + case 2: + Breath1_Spell = SPELL_INCINERATE; + Breath2_Spell = SPELL_IGNITEFLESH; + break; + + case 3: + Breath1_Spell = SPELL_INCINERATE; + Breath2_Spell = SPELL_FROSTBURN; + break; + + //B1 - TL + case 4: + Breath1_Spell = SPELL_TIMELAPSE; + Breath2_Spell = SPELL_INCINERATE; + break; + + case 5: + Breath1_Spell = SPELL_TIMELAPSE; + Breath2_Spell = SPELL_CORROSIVEACID; + break; + + case 6: + Breath1_Spell = SPELL_TIMELAPSE; + Breath2_Spell = SPELL_IGNITEFLESH; + break; + + case 7: + Breath1_Spell = SPELL_TIMELAPSE; + Breath2_Spell = SPELL_FROSTBURN; + break; + + //B1 - Acid + case 8: + Breath1_Spell = SPELL_CORROSIVEACID; + Breath2_Spell = SPELL_INCINERATE; + break; + + case 9: + Breath1_Spell = SPELL_CORROSIVEACID; + Breath2_Spell = SPELL_TIMELAPSE; + break; + + case 10: + Breath1_Spell = SPELL_CORROSIVEACID; + Breath2_Spell = SPELL_IGNITEFLESH; + break; + + case 11: + Breath1_Spell = SPELL_CORROSIVEACID; + Breath2_Spell = SPELL_FROSTBURN; + break; + + //B1 - Ignite + case 12: + Breath1_Spell = SPELL_IGNITEFLESH; + Breath2_Spell = SPELL_INCINERATE; + break; + + case 13: + Breath1_Spell = SPELL_IGNITEFLESH; + Breath2_Spell = SPELL_CORROSIVEACID; + break; + + case 14: + Breath1_Spell = SPELL_IGNITEFLESH; + Breath2_Spell = SPELL_TIMELAPSE; + break; + + case 15: + Breath1_Spell = SPELL_IGNITEFLESH; + Breath2_Spell = SPELL_FROSTBURN; + break; + + //B1 - Frost + case 16: + Breath1_Spell = SPELL_FROSTBURN; + Breath2_Spell = SPELL_INCINERATE; + break; + + case 17: + Breath1_Spell = SPELL_FROSTBURN; + Breath2_Spell = SPELL_TIMELAPSE; + break; + + case 18: + Breath1_Spell = SPELL_FROSTBURN; + Breath2_Spell = SPELL_CORROSIVEACID; + break; + + case 19: + Breath1_Spell = SPELL_FROSTBURN; + Breath2_Spell = SPELL_IGNITEFLESH; + break; + }; + + Reset(); + } + + uint32 Breath1_Spell; + uint32 Breath2_Spell; + uint32 CurrentVurln_Spell; + + uint32 Shimmer_Timer; + uint32 Breath1_Timer; + uint32 Breath2_Timer; + uint32 Affliction_Timer; + uint32 Frenzy_Timer; + bool Enraged; + bool InCombat; + + void Reset() + { + CurrentVurln_Spell = 0; //We use this to store our last vurlnability spell so we can remove it later + + Shimmer_Timer = 0; //Time till we change vurlnerabilites + Breath1_Timer = 30000; //First breath is 30 seconds + Breath2_Timer = 60000; //Second is 1 minute so that we can alternate + Affliction_Timer = 10000; //This is special - 5 seconds means that we cast this on 1 player every 5 sconds + Frenzy_Timer = 15000; + + Enraged = false; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //Shimmer_Timer Timer + if (Shimmer_Timer < diff) + { + //Remove old vurlnability spell + if (CurrentVurln_Spell) + m_creature->RemoveAurasDueToSpell(CurrentVurln_Spell); + + //Cast new random vurlnabilty on self + uint32 spell; + switch (rand()%5) + { + case 0: + spell = SPELL_FIRE_VURNALBILTY; + break; + + case 1: + spell = SPELL_FROST_VURNALBILTY; + break; + + case 2: + spell = SPELL_SHADOW_VURNALBILTY; + break; + + case 3: + spell = SPELL_NATURE_VURNALBILTY; + break; + + case 4: + spell = SPELL_ARCANE_VURNALBILTY; + break; + } + + DoCast(m_creature,spell); + CurrentVurln_Spell = spell; + + //45 seconds until we should cast this agian + Shimmer_Timer = 45000; + }else Shimmer_Timer -= diff; + + //Breath1_Timer + if (Breath1_Timer < diff) + { + //Cast Breath1_Spell + DoCast(m_creature->getVictim(),Breath1_Spell); + + //30 seconds until we should cast this agian + Breath1_Timer = 30000; + }else Breath1_Timer -= diff; + + //Breath2_Timer + if (Breath2_Timer < diff) + { + //Cast Breath2_Spell + DoCast(m_creature->getVictim(),Breath2_Spell); + + //30 seconds until we should cast this agian + Breath2_Timer = 30000; + }else Breath2_Timer -= diff; + + //Affliction_Timer + if (Affliction_Timer < diff) + { + //Pick a random target then cast a random debuff + //Currently there is no ability to select a random target + //So we will just leave this code out + //DoCast(m_creature->getVictim(),SPELL_SHADOWFLAME); + + //10 seconds until we should cast this agian + Affliction_Timer = 10000; + }else Affliction_Timer -= diff; + + //Frenzy_Timer + if (Frenzy_Timer < diff) + { + //Cast Frenzy_ + DoCast(m_creature,SPELL_FRENZY); + + //10-15 seconds until we should cast this agian + Frenzy_Timer = 10000 + (rand() % 5000); + }else Frenzy_Timer -= diff; + + //Enrage if not already enraged and below 20% + if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) + { + DoCast(m_creature,SPELL_ENRAGE); + Enraged = true; + } + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_chromaggus(Creature *_Creature) +{ + return new boss_chromaggusAI (_Creature); +} + + +void AddSC_boss_chromaggus() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_chromaggus"; + newscript->GetAI = GetAI_boss_chromaggus; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_ebonroc.cpp =================================================================== --- boss/sc_boss_ebonroc.cpp (revision 0) +++ boss/sc_boss_ebonroc.cpp (revision 0) @@ -0,0 +1,148 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SPELL_SHADOWFLAME 22539 +#define SPELL_WINGBUFFET 18500 +#define SPELL_SHADOWOFEBONROC 23340 + +struct MANGOS_DLL_DECL boss_ebonrocAI : public ScriptedAI +{ + boss_ebonrocAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 ShadowFlame_Timer; + uint32 WingBuffet_Timer; + uint32 ShadowOfEbonroc_Timer; + bool InCombat; + + void Reset() + { + ShadowFlame_Timer = 60000; //These times are probably wrong + WingBuffet_Timer = 30000; + ShadowOfEbonroc_Timer = 45000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //Shadowflame Timer + if (ShadowFlame_Timer < diff) + { + //Cast Shadowflame + DoCast(m_creature->getVictim(),SPELL_SHADOWFLAME); + + //60 seconds until we should cast this agian + ShadowFlame_Timer = 60000; + }else ShadowFlame_Timer -= diff; + + //Wing Buffet Timer + if (WingBuffet_Timer < diff) + { + //Cast Wing Buffet + DoCast(m_creature->getVictim(),SPELL_WINGBUFFET); + + //30 seconds until we should cast this agian + WingBuffet_Timer = 30000; + }else WingBuffet_Timer -= diff; + + //Shadow of Ebonroc Timer + if (ShadowOfEbonroc_Timer < diff) + { + //Cast Shadow of Ebonroc + DoCast(m_creature->getVictim(),SPELL_SHADOWOFEBONROC); + + //45 seconds until we should cast this agian + ShadowOfEbonroc_Timer = 45000; + }else ShadowOfEbonroc_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_ebonroc(Creature *_Creature) +{ + return new boss_ebonrocAI (_Creature); +} + + +void AddSC_boss_ebonroc() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_ebonroc"; + newscript->GetAI = GetAI_boss_ebonroc; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_firemaw.cpp =================================================================== --- boss/sc_boss_firemaw.cpp (revision 0) +++ boss/sc_boss_firemaw.cpp (revision 0) @@ -0,0 +1,146 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SPELL_SHADOWFLAME 22539 +#define SPELL_WINGBUFFET 23339 +#define SPELL_FLAMEBUFFET 23341 + +struct MANGOS_DLL_DECL boss_firemawAI : public ScriptedAI +{ + boss_firemawAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 ShadowFlame_Timer; + uint32 WingBuffet_Timer; + uint32 FlameBuffet_Timer; + bool InCombat; + + void Reset() + { + ShadowFlame_Timer = 45000; //These times are probably wrong + WingBuffet_Timer = 25000; + FlameBuffet_Timer = 5000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //ShadowFlame_Timer + if (ShadowFlame_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SHADOWFLAME); + + //45 seconds till recast + ShadowFlame_Timer = 45000; + }else ShadowFlame_Timer -= diff; + + //WingBuffet_Timer + if (WingBuffet_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_WINGBUFFET); + + //25 seconds till recast + WingBuffet_Timer = 25000; + }else WingBuffet_Timer -= diff; + + //FlameBuffet_Timer + if (FlameBuffet_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FLAMEBUFFET); + + //cast this every 5 seconds + FlameBuffet_Timer = 5000; + }else FlameBuffet_Timer -= diff; + + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_firemaw(Creature *_Creature) +{ + return new boss_firemawAI (_Creature); +} + + +void AddSC_boss_firemaw() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_firemaw"; + newscript->GetAI = GetAI_boss_firemaw; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_flamegor.cpp =================================================================== --- boss/sc_boss_flamegor.cpp (revision 0) +++ boss/sc_boss_flamegor.cpp (revision 0) @@ -0,0 +1,146 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SPELL_SHADOWFLAME 22539 +#define SPELL_WINGBUFFET 23339 +#define SPELL_FRENZY 23342 //This spell periodically triggers fire nova + +struct MANGOS_DLL_DECL boss_flamegorAI : public ScriptedAI +{ + boss_flamegorAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 ShadowFlame_Timer; + uint32 WingBuffet_Timer; + uint32 Frenzy_Timer; + bool InCombat; + + void Reset() + { + ShadowFlame_Timer = 45000; //These times are probably wrong + WingBuffet_Timer = 25000; + Frenzy_Timer = 10000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //ShadowFlame_Timer + if (ShadowFlame_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SHADOWFLAME); + + //45 seconds till recast + ShadowFlame_Timer = 45000; + }else ShadowFlame_Timer -= diff; + + //WingBuffet_Timer + if (WingBuffet_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_WINGBUFFET); + + //25 seconds till recast + WingBuffet_Timer = 25000; + }else WingBuffet_Timer -= diff; + + //Frenzy_Timer + if (Frenzy_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_FRENZY); + + //cast this every 10-15 seconds + Frenzy_Timer = 10000 + (rand()%5000); + }else Frenzy_Timer -= diff; + + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_flamegor(Creature *_Creature) +{ + return new boss_flamegorAI (_Creature); +} + + +void AddSC_boss_flamegor() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_flamegor"; + newscript->GetAI = GetAI_boss_flamegor; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_garr.cpp =================================================================== --- boss/sc_boss_garr.cpp (revision 173) +++ boss/sc_boss_garr.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Adds NYI @@ -26,24 +26,18 @@ { boss_garrAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 AntiMagicPulse_Timer; uint32 MagmaShackles_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; AntiMagicPulse_Timer = 25000; //These times are probably wrong MagmaShackles_Timer = 15000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -55,36 +49,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -93,12 +85,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //AntiMagicPulse_Timer if (AntiMagicPulse_Timer < diff) @@ -126,21 +112,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_gehennas.cpp =================================================================== --- boss/sc_boss_gehennas.cpp (revision 173) +++ boss/sc_boss_gehennas.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** @@ -25,27 +25,20 @@ struct MANGOS_DLL_DECL boss_gehennasAI : public ScriptedAI { boss_gehennasAI(Creature *c) : ScriptedAI(c) {Reset();} - - Unit *pTarget; uint32 ShadowBolt_Timer; uint32 RainOfFire_Timer; uint32 GehennasCurse_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; ShadowBolt_Timer = 7000; RainOfFire_Timer = 35000; GehennasCurse_Timer = 30000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -57,36 +50,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -95,12 +86,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //ShadowBolt_Timer if (ShadowBolt_Timer < diff) @@ -138,21 +123,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_golemagg.cpp =================================================================== --- boss/sc_boss_golemagg.cpp (revision 173) +++ boss/sc_boss_golemagg.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Adds NYI @@ -26,22 +26,16 @@ { boss_golemaggAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 Pyroblast_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; Pyroblast_Timer = 7000; //These times are probably wrong + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -53,36 +47,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -91,12 +83,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //Pyroblast_Timer if (Pyroblast_Timer < diff) @@ -114,21 +100,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_herod.cpp =================================================================== --- boss/sc_boss_herod.cpp (revision 0) +++ boss/sc_boss_herod.cpp (revision 0) @@ -0,0 +1,282 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_RUSHINGCHARGE 32021 +#define SPELL_RUSHINGCHARGE1 6268 + +#define SPELL_CLEAVE 11608 +#define SPELL_WHIRLWIND 8989 +#define SPELL_SUNDERARMOR 16145 +#define SPELL_REND 21949 +#define SPELL_THUNDERCLAP 15588 +#define SPELL_SLAM 11430 +#define SPELL_BERSERKERSTANCE 2458 +#define SPELL_ENRAGE 28747 +#define SPELL_FIREBALL11 10151 +#define SPELL_CONEOFCOLD5 10161 + +#define SAY_AGGRO "Ah, I have been waiting for a real challenge!" +#define SAY_WHIRLWIND "Blades of Light!" +#define SAY_ENRAGE "Light, give me strength!" +#define SAY_DEATH "Ha, is that all?" + +#define SOUND_AGGRO 5830 +#define SOUND_WHIRLWIND 5832 +#define SOUND_ENRAGE 5833 +#define SOUND_DEATH 5831 + +struct MANGOS_DLL_DECL boss_herodAI : public ScriptedAI +{ + boss_herodAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Yell_Timer; + uint32 Enrage_Timer; + uint32 Cleave_Timer; + uint32 Whirlwind_Timer; + uint32 SunderArmor_Timer; + uint32 Rend_Timer; + uint32 ThunderClap_Timer; + uint32 Slam_Timer; + uint32 Fireball11_Timer; + uint32 ConeOfCold5_Timer; + bool InCombat; + + void Reset() + { + Yell_Timer = 58000; + Whirlwind_Timer = 60000; + Enrage_Timer = 0; + Cleave_Timer = 15000; + SunderArmor_Timer = 40000; + Rend_Timer = 25000; + ThunderClap_Timer = 25000; + Slam_Timer = 20000; + Fireball11_Timer = 30000; + ConeOfCold5_Timer = 40000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + + //Activate Berserker Stance + DoCast(m_creature,SPELL_BERSERKERSTANCE); + + //Switch between 2 different charge methods + switch (rand()%2) + { + case 0: + DoCast(m_creature,SPELL_RUSHINGCHARGE); + break; + + case 1: + DoCast(m_creature,SPELL_RUSHINGCHARGE1); + break; + } + + DoStartMeleeAttack(who); + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Switch between 2 different charge methods + switch (rand()%2) + { + case 0: + DoCast(m_creature,SPELL_RUSHINGCHARGE); + break; + + case 1: + DoCast(m_creature,SPELL_RUSHINGCHARGE1); + break; + } + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //If we are <10% hp goes Enraged + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10 && !m_creature->m_currentSpell && Enrage_Timer < diff) + { + DoYell(SAY_ENRAGE,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_ENRAGE); + + DoCast(m_creature,SPELL_ENRAGE); + + //Shouldn't cast this agian + Enrage_Timer = diff; + } + + //Cleave_Timer + if (Cleave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CLEAVE); + + //30 seconds until we should cast this agian + Cleave_Timer = 15000; + }else Cleave_Timer -= diff; + + //Yelling and Whirlwind casting + if (Yell_Timer < diff) + { + //Say Whirlwind monologe + DoYell(SAY_WHIRLWIND,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_WHIRLWIND); + Yell_Timer = 30000; + }else Yell_Timer -= diff; + + if (Whirlwind_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_WHIRLWIND); + Whirlwind_Timer = 30000; + }else Whirlwind_Timer -= diff; + + //SunderArmor_Timer + if (SunderArmor_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SUNDERARMOR); + + //40 seconds until we should cast this agian + SunderArmor_Timer = 40000; + }else SunderArmor_Timer -= diff; + + //Rend_Timer + if (Rend_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_REND); + + //45 seconds until we should cast this agian + Rend_Timer = 25000; + }else Rend_Timer -= diff; + + //ThunderClap_Timer + if (ThunderClap_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_THUNDERCLAP); + + //45 seconds until we should cast this agian + ThunderClap_Timer = 20000; + }else ThunderClap_Timer -= diff; + + //Slam_Timer + if (Slam_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SLAM); + + //30 seconds until we should cast this agian + Slam_Timer = 20000; + }else Slam_Timer -= diff; + + //Fireball11_Timer + if (Fireball11_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FIREBALL11); + + //30 seconds until we should cast this agian + Fireball11_Timer = 30000; + }else Fireball11_Timer -= diff; + + //ConeOfCold5_Timer + if (ConeOfCold5_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CONEOFCOLD5); + + //190 seconds until we should cast this agian + ConeOfCold5_Timer = 40000; + }else ConeOfCold5_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +CreatureAI* GetAI_boss_herod(Creature *_Creature) +{ + return new boss_herodAI (_Creature); +} + + +void AddSC_boss_herod() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_herod"; + newscript->GetAI = GetAI_boss_herod; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_high_inquisitor_fairbanks.cpp =================================================================== --- boss/sc_boss_high_inquisitor_fairbanks.cpp (revision 0) +++ boss/sc_boss_high_inquisitor_fairbanks.cpp (revision 0) @@ -0,0 +1,202 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_SLEEP2 1090 +#define SPELL_CURSEOFBLOOD 16098 +#define SPELL_SMITE 6060 +#define SPELL_SHADOWWORDPAIN 2767 +#define SPELL_FLASHHEAL4 9474 +#define SPELL_RENEW6 6078 +#define SPELL_DEVOURINGPLAGUE3 19277 +#define SPELL_MINDBLAST5 8105 + +struct MANGOS_DLL_DECL boss_high_inquisitor_fairbanksAI : public ScriptedAI +{ + boss_high_inquisitor_fairbanksAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Healing_Timer; + uint32 Sleep2_Timer; + uint32 Smite_Timer; + uint32 ShadowWordPain_Timer; + uint32 CurseOfBlood_Timer; + uint32 DevouringPlague3_Timer; + uint32 MindBlast5_Timer; + bool InCombat; + + void Reset() + { + Healing_Timer = 300; + Sleep2_Timer = 45000; + Smite_Timer = 30000; + ShadowWordPain_Timer = 30000; + CurseOfBlood_Timer = 45000; + DevouringPlague3_Timer = 60000; + MindBlast5_Timer = 20000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + InCombat = true; + } + } + + void MoveInLineOfSight(Unit *who) + { + if (!who || m_creature->getVictim()) + return; + + m_creature->HandleEmoteCommand(EMOTE_STATE_SLEEP); + + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + { + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //If we are <45% hp cast Renew rank 6 or Flash heal rank 4 + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 45 && !m_creature->m_currentSpell && Healing_Timer < diff) + { + DoCast(m_creature->getVictim(),SPELL_RENEW6 || SPELL_FLASHHEAL4); + + //30 seconds until we should cast this agian + Healing_Timer = 30000; + + }else Healing_Timer -= diff; + + //Sleep2_Timer + if (Sleep2_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SLEEP2); + + //45 seconds until we should cast this agian + Sleep2_Timer = 45000; + }else Sleep2_Timer -= diff; + + //Smite_Timer + if (Smite_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SMITE); + + //30 seconds until we should cast this agian + Smite_Timer = 20000; + }else Smite_Timer -= diff; + + //ShadowWordPain_Timer + if (ShadowWordPain_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SHADOWWORDPAIN); + + //30 seconds until we should cast this agian + ShadowWordPain_Timer = 30000; + }else ShadowWordPain_Timer -= diff; + + //CurseOfBlood_Timer + if (CurseOfBlood_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CURSEOFBLOOD); + + //45 seconds until we should cast this agian + CurseOfBlood_Timer = 25000; + }else CurseOfBlood_Timer -= diff; + + //DevouringPlague3_Timer + if (DevouringPlague3_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_DEVOURINGPLAGUE3); + + //35 seconds until we should cast this agian + DevouringPlague3_Timer = 35000; + }else DevouringPlague3_Timer -= diff; + + //MindBlast5_Timer + if (MindBlast5_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_MINDBLAST5); + + //200 seconds until we should cast this agian + MindBlast5_Timer = 30000; + }else MindBlast5_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +CreatureAI* GetAI_boss_high_inquisitor_fairbanks(Creature *_Creature) +{ + return new boss_high_inquisitor_fairbanksAI (_Creature); +} + + +void AddSC_boss_high_inquisitor_fairbanks() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_high_inquisitor_fairbanks"; + newscript->GetAI = GetAI_boss_high_inquisitor_fairbanks; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_high_inquisitor_whitemane.cpp =================================================================== --- boss/sc_boss_high_inquisitor_whitemane.cpp (revision 0) +++ boss/sc_boss_high_inquisitor_whitemane.cpp (revision 0) @@ -0,0 +1,255 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_DEEPSLEEP 9256 +#define SPELL_SCARLETRESURRECTION 9232 + +#define SPELL_CRUSADERSTRIKE 17281 +#define SPELL_HAMMEROFJUSTICE 13005 +#define SPELL_HOLYSMITE6 9481 +#define SPELL_HOLYFIRE5 15265 +#define SPELL_MINDBLAST6 8106 + +#define SPELL_POWERWORDSHIELD 6065 + +#define SPELL_RENEW 6078 +#define SPELL_FLASHHEAL6 10916 + +#define SAY_AGGRO "There is no escape for you. The Crusade shall destroy all who carry the Scourge's taint." +#define SAY_SPAWN "What, Mograine has fallen? You shall pay for this treachery! " +#define SAY_RES "Arise, my champion!" +#define SAY_DEATH "The Light has spoken!" + +//#define SOUND_AGGRO +#define SOUND_RES 5840 +#define SOUND_SPAWN 5838 +#define SOUND_DEATH 5839 + +struct MANGOS_DLL_DECL boss_high_inquisitor_whitemaneAI : public ScriptedAI +{ + boss_high_inquisitor_whitemaneAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Healing_Timer; + uint32 PowerWordShield_Timer; + uint32 CrusaderStrike_Timer; + uint32 HammerOfJustice_Timer; + uint32 HolySmite6_Timer; + uint32 HolyFire5_Timer; + uint32 MindBlast6_Timer; + bool InCombat; + + void Reset() + { + Healing_Timer = 80000; + PowerWordShield_Timer = 20000; + CrusaderStrike_Timer = 40000; + HammerOfJustice_Timer = 30000; + HolySmite6_Timer = 10000; + HolyFire5_Timer = 45000; + MindBlast6_Timer = 35000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + /* + //This is going to be a routine to make the resurrection event... + if (m_creature->isAlive && m_creature->isAlive) + { + m_creature->Relocate(1163.113370,1398.856812,32.527786,3.171014); + + DoYell(SAY_SPAWN,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_SPAWN); + DoCast(m_creature->getVictim(),SPELL_DEEPSLEEP); + DoCast(m-creature->GetGUID(51117),SPELL_SCARLETRESURRECTION) + } + */ + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //If we are <75% hp cast healing spells at self and Mograine + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 75 && !m_creature->m_currentSpell) + { + + //Healing_Timer + if (Healing_Timer < diff) + { + + DoCast(m_creature,SPELL_FLASHHEAL6); + return; + + //80 seconds until we should cast this agian + Healing_Timer = 80000; + }else Healing_Timer -= diff; + + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 30 && !m_creature->m_currentSpell) + { + + if (Healing_Timer < diff) + { + + DoCast(m_creature,SPELL_RENEW); + return; + + //80 seconds until we should cast this agian + Healing_Timer = 40000; + }else Healing_Timer -= diff; + } + return; + } + + //PowerWordShield_Timer + if (PowerWordShield_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_POWERWORDSHIELD); + + //60 seconds until we should cast this agian + PowerWordShield_Timer = 60000; + }else PowerWordShield_Timer -= diff; + + //CrusaderStrike_Timer + if (CrusaderStrike_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CRUSADERSTRIKE); + + //40 seconds until we should cast this agian + CrusaderStrike_Timer = 40000; + }else CrusaderStrike_Timer -= diff; + + //HammerOfJustice_Timer + if (HammerOfJustice_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_HAMMEROFJUSTICE); + + //40 seconds until we should cast this agian + HammerOfJustice_Timer = 30000; + }else HammerOfJustice_Timer -= diff; + + //HolySmite6_Timer + if (HolySmite6_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_HOLYSMITE6); + + //30 seconds until we should cast this agian + HolySmite6_Timer = 10000; + }else HolySmite6_Timer -= diff; + + //HolyFire5_Timer + if (HolyFire5_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_HOLYFIRE5); + + //45 seconds until we should cast this agian + HolyFire5_Timer = 45000; + }else HolyFire5_Timer -= diff; + + //MindBlast6_Timer + if (MindBlast6_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_MINDBLAST6); + + //345 seconds until we should cast this agian + MindBlast6_Timer = 35000; + }else MindBlast6_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_high_inquisitor_whitemane(Creature *_Creature) +{ + return new boss_high_inquisitor_whitemaneAI (_Creature); +} + + +void AddSC_boss_high_inquisitor_whitemane() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_high_inquisitor_whitemane"; + newscript->GetAI = GetAI_boss_high_inquisitor_whitemane; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_houndmaster_loksey.cpp =================================================================== --- boss/sc_boss_houndmaster_loksey.cpp (revision 0) +++ boss/sc_boss_houndmaster_loksey.cpp (revision 0) @@ -0,0 +1,139 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_SUMMONSCARLETHOUND 16174 +#define SPELL_ENRAGE 28747 + +#define SAY_AGGRO "Release the hounds!" + +#define SOUND_AGGRO 5841 + + +struct MANGOS_DLL_DECL boss_houndmaster_lokseyAI : public ScriptedAI +{ + boss_houndmaster_lokseyAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Enrage_Timer; + bool InCombat; + + void Reset() + { + Enrage_Timer = 6000000; + InCombat = true; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + + //Cast + DoCast(m_creature,SPELL_SUMMONSCARLETHOUND); + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Say our dialog + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //If we are <10% hp cast healing spells at self and Mograine + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 10 && !m_creature->m_currentSpell && Enrage_Timer < diff) + { + DoCast(m_creature,SPELL_ENRAGE); + + //shouldn't cast this agian + Enrage_Timer = 900000; + + }else Enrage_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_houndmaster_loksey(Creature *_Creature) +{ + return new boss_houndmaster_lokseyAI (_Creature); +} + + +void AddSC_boss_houndmaster_loksey() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_houndmaster_loksey"; + newscript->GetAI = GetAI_boss_houndmaster_loksey; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_interrogator_vishas.cpp =================================================================== --- boss/sc_boss_interrogator_vishas.cpp (revision 0) +++ boss/sc_boss_interrogator_vishas.cpp (revision 0) @@ -0,0 +1,175 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_POWERWORDSHIELD 6065 + +#define SAY_AGGRO "Tell me... tell me everything!" +#define SAY_HEALTH1 "Naughty secrets" +#define SAY_HEALTH2 "I'll rip the secrets from your flesh!" +#define SAY_DEATH "Purged by pain!" + +#define SOUND_AGGRO 5847 +#define SOUND_HEALTH1 5849 +#define SOUND_HEALTH2 5850 +#define SOUND_DEATH 5848 + +struct MANGOS_DLL_DECL boss_interrogator_vishasAI : public ScriptedAI +{ + boss_interrogator_vishasAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Yell_Timer; + uint32 PowerWordShield_Timer; + bool InCombat; + + void Reset() + { + Yell_Timer = 6000000; + PowerWordShield_Timer = 60000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + + //Say our dialog + DoYell(SAY_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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //Check if we should stop attacking because our victim is no longer in range + if (needToStop()) + { + Reset(); + return; + } + + //If we are low on hp Do sayings + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 60 && !m_creature->m_currentSpell) + { + //Yell_Timer + if (Yell_Timer < diff) + { + + DoYell(SAY_HEALTH1,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_HEALTH1); + return; + + //60 seconds until we should cast this agian + Yell_Timer = 60000; + }else Yell_Timer -= diff; + } + + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 30 && !m_creature->m_currentSpell) + { + //Yell_Timer + if (Yell_Timer < diff) + { + + DoYell(SAY_HEALTH2,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_HEALTH2); + return; + + //60 seconds until we should cast this agian + Yell_Timer = 6000000; + }else Yell_Timer -= diff; + } + + //PowerWordShield_Timer + if (PowerWordShield_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_POWERWORDSHIELD); + + //60 seconds until we should cast this agian + PowerWordShield_Timer = 60000; + }else PowerWordShield_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_interrogator_vishas(Creature *_Creature) +{ + return new boss_interrogator_vishasAI (_Creature); +} + + +void AddSC_boss_interrogator_vishas() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_interrogator_vishas"; + newscript->GetAI = GetAI_boss_interrogator_vishas; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_lucifron.cpp =================================================================== --- boss/sc_boss_lucifron.cpp (revision 173) +++ boss/sc_boss_lucifron.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** @@ -26,26 +26,20 @@ { boss_lucifronAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 ImpendingDoom_Timer; uint32 LucifronCurse_Timer; uint32 ShadowShock_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; ImpendingDoom_Timer = 10000; //Initial cast after 10 seconds so the debuffs alternate LucifronCurse_Timer = 20000; //Initial cast after 20 seconds ShadowShock_Timer = 6000; //6 seconds + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -57,36 +51,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -94,14 +86,7 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) - { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } - + { //Impending doom timer if (ImpendingDoom_Timer < diff) { @@ -138,21 +123,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_magmadar.cpp =================================================================== --- boss/sc_boss_magmadar.cpp (revision 173) +++ boss/sc_boss_magmadar.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** @@ -29,28 +29,24 @@ { boss_magmadarAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 Frenzy_Timer; uint32 LavaBreath_Timer; uint32 Panic_Timer; uint32 Lavabomb_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; Frenzy_Timer = 45000; //Just a guess, been to long since I've killed Magmadar LavaBreath_Timer = 7000; Panic_Timer = 30000; Lavabomb_Timer = 12000; + InCombat = false; if (m_creature) { - m_creature->RemoveAllAuras(); + EnterEvadeMode(); m_creature->CastSpell(m_creature,SPELL_MAGMASPIT,true); - DoStopAttack(); - DoGoHome(); } } @@ -63,36 +59,35 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); + InCombat = true; - pTarget = who; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -101,12 +96,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //Frenzy_Timer if (Frenzy_Timer < diff) @@ -155,21 +144,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_majordomo_executus.cpp =================================================================== --- boss/sc_boss_majordomo_executus.cpp (revision 173) +++ boss/sc_boss_majordomo_executus.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Adds NYI @@ -27,32 +27,53 @@ #define SAY_AGGRO "Reckless mortals, none may challenge the sons of the living flame!" #define SOUND_AGGRO 8035 +#define SAY_SPAWN "The runes of warding have been destroyed! Hunt down the infedels my bretheren." +#define SOUND_SPAWN 8039 + +#define SAY_DEFEAT "Impossible! Stay your attack mortals! I submitt! I submitt! Brashly you have come to rest the secrets of the living flame. You will soon regret the recklessness of your quest. I go now to summon the lord whos house this is. Should you seek an audiance with him your paltry lives will surly be forfit. Nevertheless seek out his lair if you dare!" +#define SOUND_DEFEAT 8038 + +#define SAY_KILL "Ashes to Ashes!" +#define SOUND_KILL 8037 + +#define SAY_SPECIAL "Burn mortals! Burn for this transgression!" +#define SOUND_SPECIAL 8036 + +#define SAY_SUMMON "Behold Ragnaros, the Firelord! He who was ancient when this world was young! Bow before him, mortals! Bow before your ending!" +#define SOUND_SUMMON 8040 + +#define SAY_ARRIVAL1 "These mortal infidels, my lord! They have invaded your sanctum, and seek to steal your secrets!" +#define SOUND_ARRIVAL1 8041 + struct MANGOS_DLL_DECL boss_majordomoAI : public ScriptedAI { boss_majordomoAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 MagicReflection_Timer; uint32 DamageReflection_Timer; uint32 Blastwave_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; MagicReflection_Timer = 60000; //Damage reflection first so we alternate DamageReflection_Timer = 30000; Blastwave_Timer = 10000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } + void KilledUnit(Unit* victim) + { + if (rand()%5) + return; + + DoYell(SAY_KILL,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_KILL); + } + void AttackStart(Unit *who) { if (!who) @@ -64,33 +85,36 @@ DoStartMeleeAttack(who); //Say our dialog - DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - DoPlaySoundToSet(m_creature,SOUND_AGGRO); - - pTarget = who; + if (!InCombat) + { + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + InCombat = true; + } } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range + if (!InCombat) + { + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + InCombat = true; + } + DoStartMeleeAttack(who); - - //Say our dialog - DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - DoPlaySoundToSet(m_creature,SOUND_AGGRO); - - pTarget = who; } } } @@ -99,7 +123,7 @@ { //If we had a target and it wasn't cleared then it means the player died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -108,12 +132,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } //Cast Ageis if less than 50% hp if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 50) @@ -124,8 +142,8 @@ //MagicReflection_Timer if (MagicReflection_Timer < diff) { - //Cast - DoCast(m_creature,SPELL_MAGICREFLECTION); + //Cast NYI in core + //DoCast(m_creature,SPELL_MAGICREFLECTION); //60 seconds until we should cast this agian MagicReflection_Timer = 60000; @@ -134,8 +152,8 @@ //DamageReflection_Timer if (DamageReflection_Timer < diff) { - //Cast - DoCast(m_creature,SPELL_DAMAGEREFLECTION); + //Cast NYI in core + //DoCast(m_creature,SPELL_DAMAGEREFLECTION); //60 seconds until we should cast this agian DamageReflection_Timer = 60000; @@ -157,21 +175,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_nefarian.cpp =================================================================== --- boss/sc_boss_nefarian.cpp (revision 0) +++ boss/sc_boss_nefarian.cpp (revision 0) @@ -0,0 +1,344 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SAY_AGGRO "Well done, my minions. The mortals' courage begins to wane! Now, let's see how they contend with the true Lord of Blackrock Spire!" +#define SAY_DEATH "This cannot be! I am the Master here! You mortals are nothing to my kind! DO YOU HEAR? NOTHING!" +#define SAY_RAISE_SKELETONS "Impossible! Rise my minions! Serve your master once more!" +#define SAY_SHADOWFLAME "Burn, you wretches! Burn!" +#define SAY_SLAY "Worthless $N! Your friends will join you soon enough!" +#define SAY_XHEALTH "Enough! Now you vermin shall feel the force of my birthright, the fury of the earth itself." +#define SAY_GAMESBEGIN "Let the games begin!" +#define SAY_START "" + +#define SOUND_AGGRO 8288 +#define SOUND_DEATH 8292 +#define SOUND_RAISE_SKELETONS 8291 +#define SOUND_SHADOWFLAME 8290 +#define SOUND_SLAY 8293 +#define SOUND_XHEALTH 8289 +#define SOUND_GAMESBEGIN 8279 +#define SOUND_START 8280 + +#define SPELL_SHADOWFLAME_INITIAL 22972 +#define SPELL_SHADOWFLAME 22539 +#define SPELL_BELLOWINGROAR 22686 +#define SPELL_VEILOFSHADOW 7068 +#define SPELL_CLEAVE 20691 +#define SPELL_TAILLASH 23364 +#define SPELL_BONECONTRUST 23363 //23362, 23361 + +#define SPELL_MAGE 23410 //wild magic +#define SPELL_WARRIOR 23397 //beserk +#define SPELL_DRUID 23398 // cat form +#define SPELL_PRIEST 23401 // corrupted healing +#define SPELL_PALADIN 23418 //syphon blessing +#define SPELL_SHAMAN 23425 //totems +#define SPELL_WARLOCK 23427 //infernals +#define SPELL_HUNTER 23436 //bow broke +#define SPELL_ROGUE 23414 //Paralise + +#define SAY_MAGE "Mages too? You should be more careful when you play with magic..." +#define SAY_WARRIOR "Warriors, I know you can hit harder than that! Let's see it!" +#define SAY_DRUID "Druids and your silly shapeshifting. Let's see it in action!" +#define SAY_PRIEST "Priests! If you're going to keep healing like that, we might as well make it a little more interesting!" +#define SAY_PALADIN "Paladins, I've heard you have many lives. Show me." +#define SAY_SHAMAN "Shamans, show me what your totems can do!" +#define SAY_WARLOCK "Warlocks, you shouldn't be playing with magic you don't understand. See what happens?" +#define SAY_HUNTER "Hunters and your annoying pea-shooters!" +#define SAY_ROGUE "Rogues? Stop hiding and face me!" + + +struct MANGOS_DLL_DECL boss_nefarianAI : public ScriptedAI +{ + boss_nefarianAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 ShadowFlame_Timer; + uint32 BellowingRoar_Timer; + uint32 VeilOfShadow_Timer; + uint32 Cleave_Timer; + uint32 TailLash_Timer; + uint32 ClassCall_Timer; + bool Phase3; + bool InCombat; + + void Reset() + { + ShadowFlame_Timer = 12000; //These times are probably wrong + BellowingRoar_Timer = 30000; + VeilOfShadow_Timer = 15000; + Cleave_Timer = 7000; + TailLash_Timer = 10000; + ClassCall_Timer = 35000; //35-40 seconds + Phase3 = false; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void KilledUnit(Unit* Victim) + { + if (rand()%5) + return; + + DoYell(SAY_SLAY,LANG_UNIVERSAL,Victim); + DoPlaySoundToSet(m_creature, SOUND_SLAY); + } + + void JustDied(Unit* Killer) + { + DoYell(SAY_DEATH,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature, SOUND_DEATH); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + InCombat = true; + switch (rand()%3) + { + case 0: + DoYell(SAY_XHEALTH,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_XHEALTH); + break; + + case 1: + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + break; + + case 2: + DoYell(SAY_SHADOWFLAME,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_SHADOWFLAME); + break; + } + + DoCast(who,SPELL_SHADOWFLAME_INITIAL); + } + } + } + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + InCombat = true; + switch (rand()%3) + { + case 0: + DoYell(SAY_XHEALTH,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_XHEALTH); + break; + + case 1: + DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_AGGRO); + break; + + case 2: + DoYell(SAY_SHADOWFLAME,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_SHADOWFLAME); + break; + } + + DoCast(who,SPELL_SHADOWFLAME_INITIAL); + } + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //ShadowFlame_Timer + if (ShadowFlame_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_SHADOWFLAME); + + //12 seconds till recast + ShadowFlame_Timer = 12000; + }else ShadowFlame_Timer -= diff; + + //BellowingRoar_Timer + if (BellowingRoar_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_BELLOWINGROAR); + + //30 seconds till recast + BellowingRoar_Timer = 30000; + }else BellowingRoar_Timer -= diff; + + //VeilOfShadow_Timer + if (VeilOfShadow_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_VEILOFSHADOW); + + //15 seconds till recast + VeilOfShadow_Timer = 15000; + }else VeilOfShadow_Timer -= diff; + + //Cleave_Timer + if (Cleave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CLEAVE); + + //5 seconds till recast + Cleave_Timer = 7000; + }else Cleave_Timer -= diff; + + //TailLash_Timer + if (TailLash_Timer < diff) + { + //Cast NYI since we need a better check for behind target + //DoCast(m_creature->getVictim(),SPELL_TAILLASH); + + //10 seconds till recast + TailLash_Timer = 10000; + }else TailLash_Timer -= diff; + + //ClassCall_Timer + if (ClassCall_Timer < diff) + { + //Cast a random class call + //On official it is based on what classes are currently on the hostil list + //but we can't do that yet so just randomly call one + + switch (rand()%9) + { + case 0: + DoYell(SAY_MAGE,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_MAGE); + break; + + case 1: + DoYell(SAY_WARRIOR,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_WARRIOR); + break; + + case 2: + DoYell(SAY_DRUID,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_DRUID); + break; + + case 3: + DoYell(SAY_PRIEST,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_PRIEST); + break; + + case 4: + DoYell(SAY_PALADIN,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_PALADIN); + break; + + case 5: + DoYell(SAY_SHAMAN,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_SHAMAN); + break; + + case 6: + DoYell(SAY_WARLOCK,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_WARLOCK); + break; + + case 7: + DoYell(SAY_HUNTER,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_HUNTER); + break; + + case 8: + DoYell(SAY_ROGUE,LANG_UNIVERSAL,NULL); + DoCast(m_creature,SPELL_ROGUE); + break; + } + + //35-40 seconds till recast + ClassCall_Timer = 35000 + (rand() % 5000); + }else ClassCall_Timer -= diff; + + //Phase3 begins when we are below X health + if (!Phase3 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20) + { + Phase3 = true; + DoYell(SAY_RAISE_SKELETONS,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_RAISE_SKELETONS); + } + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_nefarian(Creature *_Creature) +{ + return new boss_nefarianAI (_Creature); +} + + +void AddSC_boss_nefarian() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_nefarian"; + newscript->GetAI = GetAI_boss_nefarian; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_onyxia.cpp =================================================================== --- boss/sc_boss_onyxia.cpp (revision 173) +++ boss/sc_boss_onyxia.cpp (working copy) @@ -15,7 +15,7 @@ */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** @@ -51,10 +51,6 @@ uint32 reset_timer; uint32 phase; - Unit* pTarget; - - void EnterEvadeMode() {} - void Reset() { swingcounter = 0; @@ -66,19 +62,24 @@ whelpspawn_timer = 45000; bellowingroar_timer = 0; phase = 1; - pTarget = NULL; if (m_creature) { - m_creature->RemoveAllAuras(); m_creature->InterruptSpell(); m_creature->SetHover(false); - (*m_creature)->Clear(); - DoStopAttack(); - DoGoHome(); + (*m_creature)->Clear(false); + EnterEvadeMode(); } } + void KilledUnit(Unit* victim) + { + if (rand()%5) + return; + + DoYell(SAY_KILL,LANG_UNIVERSAL,NULL); + } + void AttackStart(Unit *who) { if (!who) @@ -91,22 +92,18 @@ //Initial aggro speach DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - pTarget = who; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - //Predefined aggro radius - if (m_creature->GetDistanceSq(who) > 1600.0f) - return; - if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); @@ -116,14 +113,15 @@ //Initial aggro speach DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - pTarget = who; } } } void UpdateAI(const uint32 diff) { - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (!m_creature->SelectHostilTarget()) { Reset(); return; @@ -131,14 +129,7 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) - { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } - + { //Cast phase 1 spells in phase 1 and phase 3 if (phase == 1 || phase == 3) { @@ -267,7 +258,7 @@ phase = 2; m_creature->InterruptSpell(); m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF); - (*m_creature)->Clear(); + (*m_creature)->Clear(false); (*m_creature)->Idle(); DoCast(m_creature,11010);//hover? m_creature->SetHover(true); @@ -283,7 +274,7 @@ //m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,EMOTE_STATE_STAND); m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND); m_creature->SetHover(false); - (*m_creature)->Clear(); + (*m_creature)->Clear(false); (*m_creature)->Mutate(new TargetedMovementGenerator(*m_creature->getVictim())); DoYell(SAY_PHASE_3_TRANS,LANG_UNIVERSAL,NULL); } @@ -293,11 +284,6 @@ { if( m_creature->isAttackReady() ) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); @@ -309,12 +295,6 @@ }else swingcounter++; } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } @@ -346,7 +326,7 @@ } -void AddSC_boss_onyxiaAI() +void AddSC_boss_onyxia() { Script *newscript; newscript = new Script; Index: boss/sc_boss_ragnaros.cpp =================================================================== --- boss/sc_boss_ragnaros.cpp (revision 173) +++ boss/sc_boss_ragnaros.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Adds NYI and the intro dialog is NYI @@ -25,41 +25,66 @@ #define SPELL_MAGMABURST 20565 //Ranged attack -#define SAY_AGGRO "NOW FOR YOU, INSECTS. BOLDLY YOU SAUGHT THE POWER OF RAGNAROS NOW YOU SHALL SEE IT FIRST HAND." -#define SAY_HAND "BY FIRE BE PURGED!" -#define SAY_WRATH "TASTE THE FLAMES OF SULFURON!" +#define SPELL_SONSOFFLAME_DUMMY 21108 //Server side effect +#define SPELL_RAGSUBMERGE 21107 //Stealth aura +#define SAY_ARRIVAL_1 "TOO SOON! YOU HAVE AWAKENED ME TOO SOON, EXECUTUS! WHAT IS THE MEANING OF THIS INTRUSION?" +#define SAY_ARRIVAL_3 "FOOL! YOU ALLOWED THESE INSECTS TO RUN RAMPANT THROUGH THE HALLOWED CORE, AND NOW YOU LEAD THEM TO MY VERY LAIR? YOU HAVE FAILED ME, EXECUTUS! JUSTICE SHALL BE MET, INDEED!" +#define SAY_ARRIVAL_5 "NOW FOR YOU, INSECTS. BOLDLY YOU SAUGHT THE POWER OF RAGNAROS NOW YOU SHALL SEE IT FIRST HAND." +#define SAY_REINFORCEMENTS1 "COME FORTH, MY SERVANTS! DEFEND YOUR MASTER!" +#define SAY_REINFORCEMENTS2 "YOU CANNOT DEFEAT THE LIVING FLAME! COME YOU MINIONS OF FIRE! COME FORTH YOU CREATURES OF HATE! YOUR MASTER CALLS!" +#define SAY_HAND "BY FIRE BE PURGED!" +#define SAY_WRATH "TASTE THE FLAMES OF SULFURON!" +#define SAY_KILL "DIE INSECT!" +#define SAY_MAGMABURST "MY PATIENCE IS DWINDILING! COME NATS TO YOUR DEATH!" -#define SOUND_AGGRO 8045 -#define SOUND_HAND 8046 -#define SOUND_WRATH 8047 +#define SOUND_ARRIVAL_1 8043 +#define SOUND_ARRIVAL_3 8044 +#define SOUND_ARRIVAL_5 8045 +#define SOUND_REINFORCEMENTS1 8049 +#define SOUND_REINFORCEMENTS2 8050 +#define SOUND_HAND 8046 +#define SOUND_WRATH 8047 +#define SOUND_KILL 8051 +#define SOUND_MAGMABURST 8048 struct MANGOS_DLL_DECL boss_ragnarosAI : public ScriptedAI { boss_ragnarosAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 WrathOfRagnaros_Timer; uint32 HandOfRagnaros_Timer; uint32 LavaBurst_Timer; + uint32 MagmaBurst_Timer; + uint32 Submerge_Timer; + bool HasYelledMagmaBurst; + bool HasSubmergedOnce; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; - WrathOfRagnaros_Timer = 30000; //Damage reflection first so we alternate + WrathOfRagnaros_Timer = 30000; HandOfRagnaros_Timer = 25000; LavaBurst_Timer = 10000; + MagmaBurst_Timer = 12000; + Submerge_Timer = 180000; + HasYelledMagmaBurst = false; + HasSubmergedOnce = false; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } + void KilledUnit(Unit* victim) + { + if (rand()%5) + return; + + DoYell(SAY_KILL, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_KILL); + } + void AttackStart(Unit *who) { if (!who) @@ -70,22 +95,25 @@ //Begin ranged attack because Ragnaros is rooted at all times DoStartRangedAttack(who); - //Say our dialog - DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - DoPlaySoundToSet(m_creature,SOUND_AGGRO); - - pTarget = who; + //Say our dialog on initial aggro + if (!InCombat) + { + DoYell(SAY_ARRIVAL_5,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_ARRIVAL_5); + InCombat = true; + } } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); @@ -93,20 +121,22 @@ //Begin ranged attack because Ragnaros is rooted at all times DoStartRangedAttack(who); - //Say our dialog - DoYell(SAY_AGGRO,LANG_UNIVERSAL,NULL); - DoPlaySoundToSet(m_creature,SOUND_AGGRO); - - pTarget = who; + //Say our dialog on initial aggro + if (!InCombat) + { + DoYell(SAY_ARRIVAL_5,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_ARRIVAL_5); + InCombat = true; + } } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -115,13 +145,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } - //WrathOfRagnaros_Timer if (WrathOfRagnaros_Timer < diff) { @@ -166,40 +189,59 @@ LavaBurst_Timer = 10000; }else LavaBurst_Timer -= diff; + //Submerge_Timer + if (Submerge_Timer < diff) + { + //Creature spawning and ragnaros becomming unattackable + //is not very well supported in the core + //so for now we are just going to yell some lines + + if (!HasSubmergedOnce) + { + //Say our dialog + DoYell(SAY_REINFORCEMENTS1,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_REINFORCEMENTS1); + HasSubmergedOnce = true; + }else + { + //Say our dialog + DoYell(SAY_REINFORCEMENTS2,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_REINFORCEMENTS2); + } + + //3 minutes until we should cast this agian + Submerge_Timer = 180000; + }else Submerge_Timer -= diff; + //If we are within range melee the target if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) { //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } }else { - //Ragnaros doesn't like it when he isn't in melee range so he casts magma burst - if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + //MagmaBurst_Timer + if (MagmaBurst_Timer < diff) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ + //Cast DoCast(m_creature->getVictim(),SPELL_MAGMABURST); - m_creature->resetAttackTimer(); - } + + if (!HasYelledMagmaBurst) + { + //Say our dialog + DoYell(SAY_MAGMABURST,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_MAGMABURST); + HasYelledMagmaBurst = true; + } + + //8 seconds until we should cast this agian + MagmaBurst_Timer = 8000; + }else MagmaBurst_Timer -= diff; } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_razorgore.cpp =================================================================== --- boss/sc_boss_razorgore.cpp (revision 0) +++ boss/sc_boss_razorgore.cpp (revision 0) @@ -0,0 +1,169 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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 +*/ + +//*** NEEDS ADDITIOINAL REVIEW *** + +//Razorgore Phase 2 Script +//Phase 1 script with adds NYI + +#include "../../sc_defines.h" + +#define SAY_NPC_DEATH "If I fall into the abyss I'll take all of you mortals with me..." +#define SOUND_NPC_DEATH 8278 +#define SAY_EGGS_BREAK3 "No! Not another one! I'll have your heads for this atrocity. " +#define SOUND_EGGS_BREAK3 8277 + +#define SPELL_CLEAVE 20691 +#define SPELL_WARSTOMP 27758 //Warstomp causes 1k dmg but doesn't knockback +#define SPELL_FIREBALLVOLLEY 29958 //Our fireball doesn't leave a dot +#define SPELL_CONFLAGRATION 16805 + +struct MANGOS_DLL_DECL boss_razorgoreAI : public ScriptedAI +{ + boss_razorgoreAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Cleave_Timer; + uint32 WarStomp_Timer; + uint32 FireballVolley_Timer; + uint32 Conflagration_Timer; + bool InCombat; + + void Reset() + { + Cleave_Timer = 15000; //These times are probably wrong + WarStomp_Timer = 35000; + FireballVolley_Timer = 20000; + Conflagration_Timer = 30000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //Cleave_Timer + if (Cleave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CLEAVE); + + //15 seconds until we should cast this agian + Cleave_Timer = 15000; + }else Cleave_Timer -= diff; + + //WarStomp_Timer + if (WarStomp_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_WARSTOMP); + + //35 seconds until we should cast this agian + WarStomp_Timer = 35000; + }else WarStomp_Timer -= diff; + + //FireballVolley_Timer + if (FireballVolley_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FIREBALLVOLLEY); + + //20 seconds until we should cast this agian + FireballVolley_Timer = 20000; + }else FireballVolley_Timer -= diff; + + //Conflagration_Timer + if (Conflagration_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CONFLAGRATION); + + //30 seconds until we should cast this agian + Conflagration_Timer = 30000; + }else Conflagration_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_razorgore(Creature *_Creature) +{ + return new boss_razorgoreAI (_Creature); +} + + +void AddSC_boss_razorgore() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_razorgore"; + newscript->GetAI = GetAI_boss_razorgore; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_scarlet_commander_mograine.cpp =================================================================== --- boss/sc_boss_scarlet_commander_mograine.cpp (revision 0) +++ boss/sc_boss_scarlet_commander_mograine.cpp (revision 0) @@ -0,0 +1,233 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_DIVINESHIELD2 1020 +#define SPELL_CRUSADERSTRIKE5 35395 +#define SPELL_HAMMEROFJUSTICE3 5589 +#define SPELL_HOLYLIGHT6 3472 +#define SPELL_CONSECRATION3 20922 +#define SPELL_BLESSINGOFWISDOM 1044 +#define SPELL_RETRIBUTIONAURA3 10299 +#define SPELL_BLESSINGOFPROTECTION3 10278 +#define SPELL_FLASHHEAL6 10916 + +#define SAY_AGGRO "Infidels! They must be purified!" +#define SAY_RES "At your side, milady!" +#define SAY_DEATH "Unworthy!" + +#define SOUND_AGGRO 5835 +#define SOUND_RES 5837 +#define SOUND_DEATH 5836 + +struct MANGOS_DLL_DECL boss_scarlet_commander_mograineAI : public ScriptedAI +{ + boss_scarlet_commander_mograineAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Heal_Timer; + uint32 DivineShield2_Timer; + uint32 CrusaderStrike5_Timer; + uint32 HammerOfJustice3_Timer; + uint32 Consecration3_Timer; + uint32 BlessingOfWisdom_Timer; + uint32 BlessingOfProtection3_Timer; + bool InCombat; + + void Reset() + { + Heal_Timer = 80000; + DivineShield2_Timer = 60000; + CrusaderStrike5_Timer = 20000; + HammerOfJustice3_Timer = 80000; + Consecration3_Timer = 30000; + BlessingOfWisdom_Timer = 45000; + BlessingOfProtection3_Timer = 45000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoCast(m_creature,SPELL_RETRIBUTIONAURA3); + DoStartMeleeAttack(who); + + //Say our dialog + DoYell(SAY_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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //If we are <50% hp cast Arcane Bubble and start casting SPECIAL Arcane Explosion + if ( m_creature->GetHealth()*100 / m_creature->GetMaxHealth() <= 50 && !m_creature->m_currentSpell) + { + + //heal_Timer + if (Heal_Timer < diff) + { + + //Switch between 2 different charge methods + switch (rand()%2) + { + case 0: + DoCast(m_creature,SPELL_HOLYLIGHT6); + break; + + case 1: + DoCast(m_creature,SPELL_FLASHHEAL6); + break; + } + return; + + //60 seconds until we should cast this agian + Heal_Timer = 60000; + }else Heal_Timer -= diff; + + } + + //DivineShield2_Timer + if (DivineShield2_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_DIVINESHIELD2); + + //360 seconds until we should cast this agian + DivineShield2_Timer = 60000; + }else DivineShield2_Timer -= diff; + + //CrusaderStrike5_Timer + if (CrusaderStrike5_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CRUSADERSTRIKE5); + + //20 seconds until we should cast this agian + CrusaderStrike5_Timer = 20000; + }else CrusaderStrike5_Timer -= diff; + + //HammerOfJustice3_Timer + if (HammerOfJustice3_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_HAMMEROFJUSTICE3); + + //80 seconds until we should cast this agian + HammerOfJustice3_Timer = 30000; + }else HammerOfJustice3_Timer -= diff; + + //Consecration3_Timer + if (Consecration3_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CONSECRATION3); + + //30 seconds until we should cast this agian + Consecration3_Timer = 20000; + }else Consecration3_Timer -= diff; + + //BlessingOfWisdom_Timer + if (BlessingOfWisdom_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_BLESSINGOFWISDOM); + + //45 seconds until we should cast this agian + BlessingOfWisdom_Timer = 45000; + }else BlessingOfWisdom_Timer -= diff; + + //BlessingOfProtection3_Timer + if (BlessingOfProtection3_Timer < diff) + { + //Cast + DoCast(m_creature,SPELL_BLESSINGOFPROTECTION3); + + //345 seconds until we should cast this agian + BlessingOfProtection3_Timer = 50000; + }else BlessingOfProtection3_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +CreatureAI* GetAI_boss_scarlet_commander_mograine(Creature *_Creature) +{ + return new boss_scarlet_commander_mograineAI (_Creature); +} + + +void AddSC_boss_scarlet_commander_mograine() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_scarlet_commander_mograine"; + newscript->GetAI = GetAI_boss_scarlet_commander_mograine; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_scorn.cpp =================================================================== --- boss/sc_boss_scorn.cpp (revision 0) +++ boss/sc_boss_scorn.cpp (revision 0) @@ -0,0 +1,159 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_LICHSLAP 28873 +#define SPELL_FROSTBOLTVOLLEY 8398 +#define SPELL_MINDFLAY 17313 +#define SPELL_FROSTNOVA 15531 + +struct MANGOS_DLL_DECL boss_scornAI : public ScriptedAI +{ + boss_scornAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 LichSlap_Timer; + uint32 FrostboltVolley_Timer; + uint32 MindFlay_Timer; + uint32 FrostNova_Timer; + bool InCombat; + + void Reset() + { + LichSlap_Timer = 45000; + FrostboltVolley_Timer = 30000; + MindFlay_Timer = 30000; + FrostNova_Timer = 30000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //LichSlap_Timer + if (LichSlap_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_LICHSLAP); + + //45 seconds until we should cast this agian + LichSlap_Timer = 45000; + }else LichSlap_Timer -= diff; + + //FrostboltVolley_Timer + if (FrostboltVolley_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FROSTBOLTVOLLEY); + + //30 seconds until we should cast this agian + FrostboltVolley_Timer = 20000; + }else FrostboltVolley_Timer -= diff; + + //MindFlay_Timer + if (MindFlay_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_MINDFLAY); + + //30 seconds until we should cast this agian + MindFlay_Timer = 20000; + }else MindFlay_Timer -= diff; + + //FrostNova_Timer + if (FrostNova_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FROSTNOVA); + + //30 seconds until we should cast this agian + FrostNova_Timer = 15000; + }else FrostNova_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_scorn(Creature *_Creature) +{ + return new boss_scornAI (_Creature); +} + + +void AddSC_boss_scorn() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_scorn"; + newscript->GetAI = GetAI_boss_scorn; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_boss_shazzrah.cpp =================================================================== --- boss/sc_boss_shazzrah.cpp (revision 173) +++ boss/sc_boss_shazzrah.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Teleporting NYI @@ -28,28 +28,22 @@ { boss_shazzrahAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 ArcaneExplosion_Timer; uint32 ShazzrahCurse_Timer; uint32 DeadenMagic_Timer; uint32 Countspell_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; ArcaneExplosion_Timer = 6000; //These times are probably wrong ShazzrahCurse_Timer = 30000; DeadenMagic_Timer = 45000; Countspell_Timer = 20000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -61,36 +55,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -99,13 +91,7 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } - + //ArcaneExplosion_Timer if (ArcaneExplosion_Timer < diff) { @@ -152,21 +138,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_sulfuron_harbinger.cpp =================================================================== --- boss/sc_boss_sulfuron_harbinger.cpp (revision 173) +++ boss/sc_boss_sulfuron_harbinger.cpp (working copy) @@ -14,7 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "sc_defines.h" +#include "../../sc_defines.h" // **** This script is still under Developement **** // Adds NYI @@ -28,28 +28,22 @@ { boss_sulfuronAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 DemoralizingShout_Timer; uint32 Inspire_Timer; uint32 Knockdown_Timer; uint32 Flamespear_Timer; + bool InCombat; - void EnterEvadeMode() {} - void Reset() { - pTarget = NULL; DemoralizingShout_Timer = 25000; //These times are probably wrong Inspire_Timer = 30000; Knockdown_Timer = 20000; Flamespear_Timer = 15000; + InCombat = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } void AttackStart(Unit *who) @@ -61,36 +55,34 @@ { //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - if ( m_creature->getVictim() == NULL) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - //Begin melee attack if we are within range DoStartMeleeAttack(who); - - pTarget = who; + InCombat = true; } } } void UpdateAI(const uint32 diff) { - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; @@ -99,13 +91,6 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable - if (needToStop()) - { - Reset(); - return; - } - //DemoralizingShout_Timer if (DemoralizingShout_Timer < diff) { @@ -152,21 +137,10 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ m_creature->AttackerStateUpdate(m_creature->getVictim()); m_creature->resetAttackTimer(); } } - - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; Index: boss/sc_boss_vaelastrasz.cpp =================================================================== --- boss/sc_boss_vaelastrasz.cpp (revision 0) +++ boss/sc_boss_vaelastrasz.cpp (revision 0) @@ -0,0 +1,325 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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 +*/ + +//*** NEEDS ADDITIOINAL REVIEW *** + +#include "../../sc_defines.h" + +#define SPELL_ESSENCEOFTHERED 23513 +#define SPELL_FLAMEBREATH 18435 //Wrong spell. Damage is right but it should not proc the heated blade. +#define SPELL_FIRENOVA 23462 +#define SPELL_TAILSWIPE 15847 +#define SPELL_BURNINGADRENALINE 18173 +#define SPELL_CLEAVE 20691 //Chain cleave is most likely named something different and contains a dummy effect + +//I beg you Mortals, flee! Flee before I lose all control. The Black Fire rages within my heart. I must release it! FLAME! DEATH! DESTRUCTION! COWER BEFORE THE WRATH OF LORD....NO! I MUST FIGHT THIS! +#define SAY_LINE1 "Too late...friends. Nefarius' corruption has taken hold. I cannot...control myself. " +#define SOUND_LINE1 8281 + +#define SAY_LINE2 "I beg you Mortals, flee! Flee before I lose all control. The Black Fire rages within my heart. I must release it!" +#define SOUND_LINE2 8282 + +#define SAY_LINE3 "FLAME! DEATH! DESTRUCTION! COWER MORTALS BEFORE THE WRATH OF LORD....NO! I MUST FIGHT THIS!" +#define SOUND_LINE3 8283 + +#define SAY_HALFLIFE "Nefarius' hate has made me stronger than ever before. You should have fled, while you could, mortals! The fury of Blackrock courses through my veins! " +#define SOUND_HALFLIFE 8285 + +//You can use $N or $C to specifiy the Name or Class of the target in DoYell("$N $C",LANG_UNIVERSAL, UnitTarget); +#define SAY_KILLTARGET "Forgive me $N, your death only adds to my failure." +#define SOUND_KILLTARGET 8284 + +#define GOSSIP_ITEM "" + +struct MANGOS_DLL_DECL boss_vaelAI : public ScriptedAI +{ + boss_vaelAI(Creature *c) : ScriptedAI(c) {Reset();} + + Unit *PlayerHolder; + uint32 SpeachTimer; + uint32 SpeachNum; + uint32 Cleave_Timer; + uint32 FlameBreath_Timer; + uint32 FireNova_Timer; + uint32 BurningAdrenalineCaster_Timer; + uint32 BurningAdrenalineTank_Timer; + uint32 TailSwipe_Timer; + bool HasYelled; + bool DoingSpeach; + bool InCombat; + + void Reset() + { + PlayerHolder = NULL; + SpeachTimer = NULL; + SpeachNum = 0; + Cleave_Timer = 15000; //These times are probably wrong + FlameBreath_Timer = 25000; + BurningAdrenalineCaster_Timer = 15000; + BurningAdrenalineTank_Timer = 45000; + FireNova_Timer = 5000; + TailSwipe_Timer = 20000; + HasYelled = false; + DoingSpeach = false; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void BeginSpeach(Unit* target) + { + //Stand up and begin speach + PlayerHolder = target; + + //10 seconds + DoYell(SAY_LINE1,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_LINE1); + SpeachTimer = 10000; + SpeachNum = 0; + DoingSpeach = true; + } + + void KilledUnit(Unit *victim) + { + if (rand()%5) + return; + + DoYell(SAY_KILLTARGET,LANG_UNIVERSAL,victim); + DoPlaySoundToSet(m_creature,SOUND_KILLTARGET); + } + + void AttackStart(Unit *who) + { + if (!who && who != m_creature) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + //Say our dialog + if (!InCombat) + { + DoCast(m_creature,SPELL_ESSENCEOFTHERED); + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + if (!InCombat) + { + DoCast(m_creature,SPELL_ESSENCEOFTHERED); + InCombat = true; + } + + DoStartMeleeAttack(who); + } + } + } + + void UpdateAI(const uint32 diff) + { + //Speach + if (DoingSpeach) + if (SpeachTimer < diff) + { + switch (SpeachNum) + { + case 0: + //16 seconds till next line + DoYell(SAY_LINE2,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_LINE2); + SpeachTimer = 16000; + SpeachNum++; + break; + + case 1: + //This one is actually 16 seconds but we only go to 10 seconds because he starts attacking after he says "I must fight this!" + DoYell(SAY_LINE3,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_LINE3); + SpeachTimer = 10000; + SpeachNum++; + break; + + case 2: + default: + m_creature->setFaction(103); + m_creature->SetHealth(int(m_creature->GetMaxHealth()*.3)); + if (PlayerHolder) + { + DoStartMeleeAttack(PlayerHolder); + DoCast(m_creature,SPELL_ESSENCEOFTHERED); + } + + SpeachTimer = 0; + DoingSpeach = false; + break; + } + }else SpeachTimer -= diff; + + + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + // Yell if hp lower than 15% + if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 15 && !HasYelled) + { + //Say our dialog + DoYell(SAY_HALFLIFE,LANG_UNIVERSAL,NULL); + DoPlaySoundToSet(m_creature,SOUND_HALFLIFE); + HasYelled = true; + } + + //Cleave_Timer + if (Cleave_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_CLEAVE); + + //25 seconds until we should cast this again + Cleave_Timer = 15000; + }else Cleave_Timer -= diff; + + //FlameBreath_Timer + if (FlameBreath_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FLAMEBREATH); + + //25 seconds until we should cast this again + FlameBreath_Timer = 25000; + }else FlameBreath_Timer -= diff; + + //BurningAdrenalineCaster_Timer (NOT YET IMPLEMENTED due to the fact that we can't randomly select a target yet) + if (BurningAdrenalineCaster_Timer < diff) + { + //Cast + //DoCast(m_creature->getVictim(),SPELL_BURNINGADRENALINE); + + //15 seconds until we should cast this agian + BurningAdrenalineCaster_Timer = 15000; + }else BurningAdrenalineCaster_Timer -= diff; + + //BurningAdrenalineTank_Timer + if (BurningAdrenalineTank_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_BURNINGADRENALINE); + + //45 seconds until we should cast this agian + BurningAdrenalineTank_Timer = 45000; + }else BurningAdrenalineTank_Timer -= diff; + + //FireNova_Timer + if (FireNova_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_FIRENOVA); + + //5 seconds until we should cast this again + FireNova_Timer = 5000; + }else FireNova_Timer -= diff; + + //TailSwipe_Timer + if (TailSwipe_Timer < diff) + { + //Only cast if we are behind + /*if (!m_creature->HasInArc( M_PI, m_creature->getVictim())) + { + DoCast(m_creature->getVictim(),SPELL_TAILSWIPE); + }*/ + + //20 seconds until we should cast this again + TailSwipe_Timer = 20000; + }else TailSwipe_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; + +void SendDefaultMenu_boss_vael(Player *player, Creature *_Creature, uint32 action) +{ + if (action == GOSSIP_ACTION_INFO_DEF + 1)//Fight time + { + player->PlayerTalkClass->CloseGossip(); + ((boss_vaelAI&)_Creature->AI()).BeginSpeach((Unit*)player); + } +} + +bool GossipSelect_boss_vael(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + if (sender == GOSSIP_SENDER_MAIN) + SendDefaultMenu_boss_vael(player, _Creature, action); + + return true; +} + +bool GossipHello_boss_vael(Player *player, Creature *_Creature) +{ + player->ADD_GOSSIP_ITEM( 0, GOSSIP_ITEM , GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + player->PlayerTalkClass->SendGossipMenu(907,_Creature->GetGUID()); + + return true; +} + +CreatureAI* GetAI_boss_vael(Creature *_Creature) +{ + return new boss_vaelAI (_Creature); +} + +void AddSC_boss_vael() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_vaelastrasz"; + newscript->GetAI = GetAI_boss_vael; + newscript->pGossipHello = &GossipHello_boss_vael; + newscript->pGossipSelect = &GossipSelect_boss_vael; + + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_bunthen_plainswind.cpp =================================================================== --- boss/sc_bunthen_plainswind.cpp (revision 0) +++ boss/sc_bunthen_plainswind.cpp (revision 0) @@ -0,0 +1,70 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +bool GossipHello_bunthen_plainswind(Player *player, Creature *_Creature) +{ + if (player->getClass() != CLASS_DRUID || player->GetTeam() != HORDE) + return false; + + player->ADD_GOSSIP_ITEM( 0, "I'd like to fly to Thunder Bluff.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + player->SEND_GOSSIP_MENU(4918,_Creature->GetGUID()); + + return true; +} + +/******************************************************* + * Start of GOSSIP_MENU + *******************************************************/ + +void SendDefaultMenu_bunthen_plainswind(Player *player, Creature *_Creature, uint32 action) +{ + if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->getClass() == CLASS_DRUID && player->GetTeam() == HORDE) + { + std::vector nodes; + + nodes.resize(2); + nodes[0] = 63; // Nighthaven, Moonglade + nodes[1] = 22; // Thunder Bluff, Mulgore + player->ActivateTaxiPathTo(nodes); + } +} + +bool GossipSelect_bunthen_plainswind(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + if (sender == GOSSIP_SENDER_MAIN) + SendDefaultMenu_bunthen_plainswind(player, _Creature, action); + + return true; +} + +/******************************************************* + * End of GOSSIP_MENU + *******************************************************/ + +void AddSC_bunthen_plainswind() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="bunthen_plainswind"; + newscript->pGossipHello = &GossipHello_bunthen_plainswind; + newscript->pGossipSelect = &GossipSelect_bunthen_plainswind; + + m_scripts[nrscripts++] = newscript; +} Index: boss/sc_faerlina.cpp =================================================================== --- boss/sc_faerlina.cpp (revision 0) +++ boss/sc_faerlina.cpp (revision 0) @@ -0,0 +1,14 @@ +//Fairlena +//8799 greet - Your old lives, your mortal desires, mean nothing. You are acolytes of the master now, and you will serve the cause without question! The greatest glory is to die in the master's service! +//8794 aggro1 - Slay them in the master's name! +//8795 aggro2 - You cannot hide from me! +//8796 aggro3 - Kneel before me, worm! +//8797 aggro4 - Run while you still can! +//8800 slay1 - You have failed! +//8801 slay2 - Pathetic wretch! +//8798 death - The master... will avenge me! +//8955 - Random Aggro ? - ? + +#define SPELL_POSIONBOLT_VOLLEY 28796 +#define SPELL_RAINOFFIRE 28794 //Not sure if targeted AoEs work if casted directly upon a player +#define SPELL_ENRAGE 26527 \ No newline at end of file Index: boss/sc_feugen.cpp =================================================================== --- boss/sc_feugen.cpp (revision 0) +++ boss/sc_feugen.cpp (revision 0) @@ -0,0 +1,4 @@ +//Feugen +//8801 aggro Feed you to master! +//8804 slay Feugen make master happy! +//8803 death No... more... Feugen... \ No newline at end of file Index: boss/sc_gluth.cpp =================================================================== --- boss/sc_gluth.cpp (revision 0) +++ boss/sc_gluth.cpp (revision 0) @@ -0,0 +1,6 @@ +#define MORTALWOUND 25646 +/*Enrage 28747 +Frenzy 19812 +Decimate 28374 +Decimate 28375 +Terrifying Roar 29685*/ \ No newline at end of file Index: boss/sc_gothik.cpp =================================================================== --- boss/sc_gothik.cpp (revision 0) +++ boss/sc_gothik.cpp (revision 0) @@ -0,0 +1,5 @@ +//Gothik +//8806 spch - Foolishly you have sought your own demise. Brazenly you have disregarded powers beyond your understanding. You have fought hard to invade the realm of the harvester. Now there is only one way out - to walk the lonely path of the damned. +//8808 tlpt - I have waited long enough! Now, you face the harvester of souls! +//8806 slay - Death is the only escape. +//8805 death - I... am... undone! \ No newline at end of file Index: boss/sc_grobbulus.cpp =================================================================== --- boss/sc_grobbulus.cpp (revision 0) +++ boss/sc_grobbulus.cpp (revision 0) @@ -0,0 +1,5 @@ +/*Poison Cloud 26590 +Slime Spray 28157 +Fallout slime 28218 +Mutating Injection 28169 +Enrages 26527*/ \ No newline at end of file Index: boss/sc_heigan.cpp =================================================================== --- boss/sc_heigan.cpp (revision 0) +++ boss/sc_heigan.cpp (revision 0) @@ -0,0 +1,11 @@ +//Lotheb or Heigan? +//8825 aggro1 - You are mine now! +//8826 aggro2 - I see you! +//8827 aggro3 - You...are next! +//8828 death - +//8829 slay - close your eyes... sleep +//8830 taunt1 - The races of the world will perish. It is only a matter of time. +//8831 taunt2 - I see endless suffering, I see torment, I see rage. I see... everything! +//8832 taunt3 - Soon... the world will tremble! +//8833 taunt4 - The end is upon you. +//8834 taunt5 - Hungry worms will feast on your rotten flesh! \ No newline at end of file Index: boss/sc_highlord_mograine.cpp =================================================================== --- boss/sc_highlord_mograine.cpp (revision 0) +++ boss/sc_highlord_mograine.cpp (revision 0) @@ -0,0 +1,11 @@ +//Highlord Morgraine +//8842 taunt1 - Enough prattling. Let them come! We shall grind their bones to dust. +//8843 taunt2 - Conserve your anger! Harness your rage! You will all have outlets for your frustration soon enough. +//8844 taunt3 - Life is meaningless. It is in death that we are truly tested. +//8835 aggro1 - You seek death? +//8836 aggro2 - None shall pass! +//8837 aggro3 - Be still! +//8839 slay1 - You will find no peace in death. +//8840 slay2 - The master's will is done. +//8841 special - Bow to the might of the Highlord! +//8838 death - I... am... released! Perhaps it's not too late to - noo! I need... more time... Index: boss/sc_kelthuzad.cpp =================================================================== --- boss/sc_kelthuzad.cpp (revision 0) +++ boss/sc_kelthuzad.cpp (revision 0) @@ -0,0 +1,34 @@ +//Kel'thuzad +//Dialog +//8878 dialog01 - Our preparations continue as planned, master. +//8881 lich_naxx_dialog01 - It is good that you serve me so faithfully. Soon, all will serve the Lich King and in the end, you shall be rewarded...so long as you do not falter. +//8879 dialog02 - I see no complications... Wait... What is this? +//8882 lich_naxx_dialog03 - Your security measures have failed! See to this interruption immediately! +//8880 dialog03 - Yes, master! +//Bigglesworth death +//No!!! A curse upon you, interlopers! The armies of the Lich King will hunt you down. You will not escape your fate... +//taunt +//8820 taunt01 - Who dares violate the sanctity of my domain? Be warned, all who trespass here are doomed. +//8821 taunt02 - Fools, you think yourselves triumphant? You have only taken one step closer to the abyss! +//8822 taunt03 - I grow tired of these games. Proceed, and I will banish your souls to oblivion! +//8823 taunt04 - You have no idea what horrors lie ahead. You have seen nothing! The frozen heart of Naxxramas awaits you! +//summons +//8819 summon - Minions, servants, soldiers of the cold dark, obey the call of Kel'Thuzad! +//8816 help - Master! I require aid! +//8824 lich_naxx_summon - Very well. Warriors of the frozen wastes rise up! I command you to fight, kill, and die for your master! Let none survive! +//aggr +//8809 aggro01 - Pray for mercy! +//8810 aggro02 - Scream your dying breath! +//8811 aggro03 - The end is upon you! +//spec +//9088 spec1 - Your petty magics are no challenge to the might of the Scourge! +//9089 spec2 - Fools, you have spread your powers too thin. Be free, my minions! +//9090 spec3 - Enough! I grow tired of these distractions! +//8812 chain1 - Your soul is bound to me now! +//8813 chain2 - There will be no escape! +//8815 frost - I will freeze the blood in your veins! +//slay +//8817 The dark void awaits you! +//8818 +//death +//8814 death - Do not rejoice... your victory is a hollow one... for I shall return with powers beyond your imagining! \ No newline at end of file Index: boss/sc_lady_blaumeux.cpp =================================================================== --- boss/sc_lady_blaumeux.cpp (revision 0) +++ boss/sc_lady_blaumeux.cpp (revision 0) @@ -0,0 +1,8 @@ +//Lady Blaumeux +//8896 taunt1 - Come, Zeliek, do not drive them out. Not before we've had our fun. +//8897 taunt2 - I do hope they stay alive long enough for me to... introduce myself. +//8898 taunt3 - The first kill goes to me! Anyone care to wager? +//8892 bla-naxx-aggro -Defend youself! +//8895 special - Your life is mine! +//8894 slay - Who's next? +//8893 death - Tou... ché! \ No newline at end of file Index: boss/sc_loatheb.cpp =================================================================== Index: boss/sc_maexxna.cpp =================================================================== --- boss/sc_maexxna.cpp (revision 0) +++ boss/sc_maexxna.cpp (revision 0) @@ -0,0 +1,185 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SPELL_WEBTRAP 28622 //Spell is normally used by the webtrap on the wall NOT by Maexxna +#define SPELL_WEBSPRAY 29484 +#define SPELL_POISONSHOCK 28741 +#define SPELL_NECROTICPOISON 28776 +#define SPELL_ENRAGE 28747 +#define SPELL_SUMMON_SPIDERLING 29434 + +struct MANGOS_DLL_DECL boss_maexxnaAI : public ScriptedAI +{ + boss_maexxnaAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 WebTrap_Timer; + uint32 WebSpray_Timer; + uint32 PoisonShock_Timer; + uint32 NecroticPoison_Timer; + uint32 SummonSpiderling_Timer; + bool Enraged; + bool InCombat; + + void Reset() + { + WebTrap_Timer = 20000; //20 sec init, 40 sec normal + WebSpray_Timer = 40000; //40 seconds + PoisonShock_Timer = 20000; //20 seconds + NecroticPoison_Timer = 30000; //30 seconds + SummonSpiderling_Timer = 30000; //30 sec init, 40 sec normal + InCombat = false; + Enraged = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //WebTrap_Timer + if (WebTrap_Timer < diff) + { + //Cast WebTrap on a Random target + //NYI since we can't select random target + //DoCast(m_creature->getVictim(),SPELL_WEBTRAP); + + //40 seconds until we should cast this agian + WebTrap_Timer = 40000; + }else WebTrap_Timer -= diff; + + //WebSpray_Timer + if (WebSpray_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(), SPELL_WEBSPRAY); + + //40 seconds until we should cast this agian + WebSpray_Timer = 40000; + }else WebSpray_Timer -= diff; + + //PoisonShock_Timer + if (PoisonShock_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(), SPELL_POISONSHOCK); + + //20 seconds until we should cast this agian + PoisonShock_Timer = 20000; + }else PoisonShock_Timer -= diff; + + //NecroticPoison_Timer + if (NecroticPoison_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(), SPELL_NECROTICPOISON); + + //30 seconds until we should cast this agian + NecroticPoison_Timer = 30000; + }else NecroticPoison_Timer -= diff; + + //SummonSpiderling_Timer + if (SummonSpiderling_Timer < diff) + { + //Cast + DoCast(m_creature, SPELL_SUMMON_SPIDERLING); + + //40 seconds until we should cast this agian + SummonSpiderling_Timer = 40000; + }else SummonSpiderling_Timer -= diff; + + //Enrage if not already enraged and below 30% + if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30) + { + DoCast(m_creature,SPELL_ENRAGE); + Enraged = true; + } + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_maexxna(Creature *_Creature) +{ + return new boss_maexxnaAI (_Creature); +} + + +void AddSC_boss_maexxna() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_maexxna"; + newscript->GetAI = GetAI_boss_maexxna; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_noth.cpp =================================================================== --- boss/sc_noth.cpp (revision 0) +++ boss/sc_noth.cpp (revision 0) @@ -0,0 +1,8 @@ +//Noth +//8845 aggro01 - Glory to the master! +//8846 aggro02 - Your life is forfeit! +//8847 aggro03 - Die, trespasser! +//8851 summon - Rise, my soldiers! Rise and fight once more! +//8849 slay1- My task is done! +//8850 slay2- Breathe no more! +//8848 death - I will serve the master... in... death! Index: boss/sc_patchwerk.cpp =================================================================== --- boss/sc_patchwerk.cpp (revision 0) +++ boss/sc_patchwerk.cpp (revision 0) @@ -0,0 +1,216 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +#define SAY_AGGRO1 "Patchwerk want to play!" +#define SAY_AGGRO2 "Kel'Thuzad make Patchwerk his Avatar of War!" +#define SAY_SLAY "No more play?" +#define SAY_DEATH "What happened to... Patch..." + +#define SOUND_AGGRO1 8909 +#define SOUND_AGGRO2 8910 +#define SOUND_SLAY 8912 +#define SOUND_DEATH 8911 + +#define EMOTE_BERSERK "Patchwerk goes into a berserker rage!" +#define EMOTE_ENRAGE "Patchwerk becomes enraged!" + +#define SPELL_HATEFULSTRIKE 28308 +#define SPELL_ENRAGE 29691 +#define SPELL_BERSERK 27680 +#define SPELL_SLIMEBOLT 32309 + +struct MANGOS_DLL_DECL boss_patchwerkAI : public ScriptedAI +{ + boss_patchwerkAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 HatefullStrike_Timer; + uint32 Enrage_Timer; + uint32 Slimebolt_Timer; + bool Enraged; + bool InCombat; + + void Reset() + { + HatefullStrike_Timer = 1200; //1.2 seconds + Enrage_Timer = 420000; //7 minutes 420,000 + Slimebolt_Timer = 450000; //7.5 minutes 450,000 + Enraged = false; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void KilledUnit(Unit* Victim) + { + if (rand()%5) + return; + + DoYell(SAY_SLAY, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_SLAY); + } + + void JustDied(Unit* Killer) + { + DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_DEATH); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + if (rand()%2) + { + DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + } + else + { + DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + } + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + if (rand()%2) + { + DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + } + else + { + DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL); + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + } + InCombat = true; + } + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //HatefullStrike_Timer + if (HatefullStrike_Timer < diff) + { + //Cast Hateful strike on the player with the highest + //amount of HP within melee distance + //Currently target selection not supported by the core + DoCast(m_creature->getVictim(),SPELL_HATEFULSTRIKE); + + //1.2 seconds until we should cast this agian + HatefullStrike_Timer = 1200; + }else HatefullStrike_Timer -= diff; + + //Enrage_Timer + if (Enrage_Timer < diff) + { + //Cast Berserker Rage + DoCast(m_creature, SPELL_BERSERK); + DoTextEmote(EMOTE_BERSERK, m_creature->getVictim()); + + //5 minutes until we should cast this agian + Enrage_Timer = 300000; + }else Enrage_Timer -= diff; + + //Slimebolt_Timer + if (Slimebolt_Timer < diff) + { + //Cast Slime bolt + DoCast(m_creature->getVictim(),SPELL_SLIMEBOLT); + + //5 seconds until we should cast this agian + Slimebolt_Timer = 5000; + }else Slimebolt_Timer -= diff; + + //Enrage if not already enraged and below 5% + if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 5) + { + DoCast(m_creature,SPELL_ENRAGE); + DoTextEmote(EMOTE_ENRAGE,NULL); + Enraged = true; + } + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_patchwerk(Creature *_Creature) +{ + return new boss_patchwerkAI (_Creature); +} + + +void AddSC_boss_patchwerk() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_patchwerk"; + newscript->GetAI = GetAI_boss_patchwerk; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_razuvious.cpp =================================================================== --- boss/sc_razuvious.cpp (revision 0) +++ boss/sc_razuvious.cpp (revision 0) @@ -0,0 +1,251 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +//Razuvious - NO TEXT sound only +//8852 aggro01 - Hah hah, I'm just getting warmed up! +//8853 aggro02 Stand and fight! +//8854 aggro03 Show me what you've got! +//8861 slay1 - You should've stayed home! +//8863 slay2- +//8858 cmmnd3 - You disappoint me, students! +//8855 cmmnd1 - Do as I taught you! +//8856 cmmnd2 - Show them no mercy! +//8859 cmmnd4 - The time for practice is over! Show me what you've learned! +//8861 Sweep the leg! Do you have a problem with that? +//8860 death - An honorable... death... +//8947 - Aggro Mixed? - ? + +#define SOUND_AGGRO1 8852 +#define SOUND_AGGRO2 8853 +#define SOUND_AGGRO3 8854 +#define SOUND_SLAY1 8861 +#define SOUND_SLAY2 8863 +#define SOUND_COMMND1 8855 +#define SOUND_COMMND2 8856 +#define SOUND_COMMND3 8858 +#define SOUND_COMMND4 8859 +#define SOUND_COMMND5 8861 +#define SOUND_DEATH 8860 +#define SOUND_AGGROMIX 8847 + +#define SPELL_UNBALANCINGSTRIKE 26613 +#define SPELL_DISRUPTINGSHOUT 29107 + +struct MANGOS_DLL_DECL boss_razuviousAI : public ScriptedAI +{ + boss_razuviousAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 UnbalancingStrike_Timer; + uint32 DisruptingShout_Timer; + uint32 CommandSound_Timer; + bool InCombat; + + void Reset() + { + UnbalancingStrike_Timer = 30000; //30 seconds + DisruptingShout_Timer = 25000; //25 seconds + CommandSound_Timer = 40000; //40 seconds + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void KilledUnit(Unit* Victim) + { + if (rand()%3) + return; + + switch (rand()%2) + { + case 0: + DoPlaySoundToSet(m_creature, SOUND_SLAY1); + break; + + case 1: + DoPlaySoundToSet(m_creature, SOUND_SLAY2); + break; + } + } + + void JustDied(Unit* Killer) + { + DoPlaySoundToSet(m_creature, SOUND_DEATH); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + switch (rand()%3) + { + case 0: + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + break; + + case 1: + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + break; + + case 2: + DoPlaySoundToSet(m_creature, SOUND_AGGRO3); + break; + } + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + if (!InCombat) + { + switch (rand()%3) + { + case 0: + DoPlaySoundToSet(m_creature, SOUND_AGGRO1); + break; + + case 1: + DoPlaySoundToSet(m_creature, SOUND_AGGRO2); + break; + + case 2: + DoPlaySoundToSet(m_creature, SOUND_AGGRO3); + break; + } + InCombat = true; + } + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + + //UnbalancingStrike_Timer + if (UnbalancingStrike_Timer < diff) + { + //Cast Unbalancing strike + DoCast(m_creature->getVictim(),SPELL_UNBALANCINGSTRIKE); + + //30 seconds until we should cast this agian + UnbalancingStrike_Timer = 30000; + }else UnbalancingStrike_Timer -= diff; + + //DisruptingShout_Timer + if (DisruptingShout_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(), SPELL_DISRUPTINGSHOUT); + + //25 seconds until we should cast this agian + DisruptingShout_Timer = 25000; + }else DisruptingShout_Timer -= diff; + + //CommandSound_Timer + if (CommandSound_Timer < diff) + { + //Play a random command sound + switch (rand()%5) + { + case 0: + DoPlaySoundToSet(m_creature, SOUND_COMMND1); + break; + + case 1: + DoPlaySoundToSet(m_creature, SOUND_COMMND2); + break; + + case 2: + DoPlaySoundToSet(m_creature, SOUND_COMMND3); + break; + + case 3: + DoPlaySoundToSet(m_creature, SOUND_COMMND4); + break; + + case 4: + DoPlaySoundToSet(m_creature, SOUND_COMMND5); + break; + } + + //40 seconds until we should cast this agian + CommandSound_Timer = 40000; + }else CommandSound_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_boss_razuvious(Creature *_Creature) +{ + return new boss_razuviousAI (_Creature); +} + + +void AddSC_boss_razuvious() +{ + Script *newscript; + newscript = new Script; + newscript->Name="boss_razuvious"; + newscript->GetAI = GetAI_boss_razuvious; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_sapphiron.cpp =================================================================== Index: boss/sc_scarlet_torturer.cpp =================================================================== --- boss/sc_scarlet_torturer.cpp (revision 0) +++ boss/sc_scarlet_torturer.cpp (revision 0) @@ -0,0 +1,157 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +// **** This script is still under Developement **** + +#define SPELL_IMMOLATE 37668 + +#define SAY_AGGRO1 "What? Oh no. I don't care what you have to say. I just enjoy inflicting pain." +#define SAY_AGGRO2 "You will talk eventually. You might as well spill it now." +#define SAY_AGGRO3 "Confess and we shall set you free." + +struct MANGOS_DLL_DECL scarlet_torturerAI : public ScriptedAI +{ + scarlet_torturerAI(Creature *c) : ScriptedAI(c) {Reset();} + + uint32 Immolate_Timer; + bool InCombat; + + void Reset() + { + Immolate_Timer = 45000; + InCombat = false; + + if (m_creature) + EnterEvadeMode(); + } + + void AttackStart(Unit *who) + { + if (!who) + return; + + if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + { + DoStartMeleeAttack(who); + InCombat = true; + + //Switch between 3 different aggro saying + switch (rand()%3) + { + case 0: + DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL); + break; + + case 1: + DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL); + break; + + case 2: + DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL); + break; + } + } + } + + 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->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) + { + if(who->HasStealthAura()) + who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); + + //Switch between 3 different aggro saying + switch (rand()%3) + { + case 0: + DoYell(SAY_AGGRO1,LANG_UNIVERSAL,NULL); + break; + + case 1: + DoYell(SAY_AGGRO2,LANG_UNIVERSAL,NULL); + break; + + case 2: + DoYell(SAY_AGGRO3,LANG_UNIVERSAL,NULL); + break; + } + + //Begin melee attack if we are within range + DoStartMeleeAttack(who); + + InCombat = true; + } + } + } + + void UpdateAI(const uint32 diff) + { + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce + //But we still need to reset + if (InCombat && !m_creature->SelectHostilTarget()) + { + Reset(); + return; + } + + //Check if we have a current target + if( m_creature->getVictim() && m_creature->isAlive()) + { + //Immolate_Timer + if (Immolate_Timer < diff) + { + //Cast + DoCast(m_creature->getVictim(),SPELL_IMMOLATE); + + //45 seconds until we should cast this agian + Immolate_Timer = 45000; + }else Immolate_Timer -= diff; + + //If we are within range melee the target + if( m_creature->IsWithinDist(m_creature->getVictim(), ATTACK_DIST)) + { + //Make sure our attack is ready and we arn't currently casting + if( m_creature->isAttackReady() && !m_creature->m_currentSpell) + { + m_creature->AttackerStateUpdate(m_creature->getVictim()); + m_creature->resetAttackTimer(); + } + } + } + } +}; +CreatureAI* GetAI_scarlet_torturer(Creature *_Creature) +{ + return new scarlet_torturerAI (_Creature); +} + + +void AddSC_scarlet_torturer() +{ + Script *newscript; + newscript = new Script; + newscript->Name="scarlet_torturer"; + newscript->GetAI = GetAI_scarlet_torturer; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: boss/sc_silva_filnaveth.cpp =================================================================== --- boss/sc_silva_filnaveth.cpp (revision 0) +++ boss/sc_silva_filnaveth.cpp (revision 0) @@ -0,0 +1,70 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +bool GossipHello_silva_filnaveth(Player *player, Creature *_Creature) +{ + if (player->getClass() != CLASS_DRUID || player->GetTeam() != ALLIANCE) + return false; + + player->ADD_GOSSIP_ITEM( 0, "I'd like to fly to Rut'theran Village.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); + + player->SEND_GOSSIP_MENU(4914,_Creature->GetGUID()); + + return true; +} + +/******************************************************* + * Start of GOSSIP_MENU + *******************************************************/ + +void SendDefaultMenu_silva_filnaveth(Player *player, Creature *_Creature, uint32 action) +{ + if (action == GOSSIP_ACTION_INFO_DEF + 1 && player->getClass() == CLASS_DRUID && player->GetTeam() == ALLIANCE) + { + std::vector nodes; + + nodes.resize(2); + nodes[0] = 62; // Nighthaven, Moonglade + nodes[1] = 27; // Rut'theran Village, Teldrassil + player->ActivateTaxiPathTo(nodes); + } +} + +bool GossipSelect_silva_filnaveth(Player *player, Creature *_Creature, uint32 sender, uint32 action ) +{ + if (sender == GOSSIP_SENDER_MAIN) + SendDefaultMenu_silva_filnaveth(player, _Creature, action); + + return true; +} + +/******************************************************* + * End of GOSSIP_MENU + *******************************************************/ + +void AddSC_silva_filnaveth() +{ + Script *newscript; + + newscript = new Script; + newscript->Name="silva_filnaveth"; + newscript->pGossipHello = &GossipHello_silva_filnaveth; + newscript->pGossipSelect = &GossipSelect_silva_filnaveth; + + m_scripts[nrscripts++] = newscript; +} Index: boss/sc_sir_zeliek.cpp =================================================================== --- boss/sc_sir_zeliek.cpp (revision 0) +++ boss/sc_sir_zeliek.cpp (revision 0) @@ -0,0 +1,8 @@ +//Sir Zeliek +//8913 Aggro - Flee, before it's too late! +//8916 special - I- I have no choice but to obey! +//8917 taunt1 - Invaders, cease this foolish venture at once! Turn away while you still can! +//8918 taunt2 - Perhaps they will come to their senses, and run away as fast as they can! +//8919 taunt3 - Do not continue! Turn back while there's still time! +//8914 death - It is... as it should be. +//8915 slay - Forgive me! \ No newline at end of file Index: boss/sc_stalagg.cpp =================================================================== --- boss/sc_stalagg.cpp (revision 0) +++ boss/sc_stalagg.cpp (revision 0) @@ -0,0 +1,4 @@ +//Stalagg +//8864 aggro - Stalagg crush you! +//8866 slay - Stalagg Kill! +//8865 death - Master save me... \ No newline at end of file Index: boss/sc_thaddius.cpp =================================================================== --- boss/sc_thaddius.cpp (revision 0) +++ boss/sc_thaddius.cpp (revision 0) @@ -0,0 +1,12 @@ +//Thaddus +//8873 Lamnt01 - Pleeease! +//8874 Lamnt02 - Stop, make it stop! +//8875 Lamnt03 - Help me! Save me! +//8876 Lamnt04 - Please, nooo! +//8872 greet - You are too late... I... must... OBEY! +//8867 aggro1 - KILL! +//8868 aggro2 - EAT YOUR BONES! +//8869 aggro3 - BREAK YOU! +//8871 elect - Now YOU feel pain! +//8877 slay - You die now! +//8870 die - Thank... you... \ No newline at end of file Index: boss/sc_thane_korthazz.cpp =================================================================== --- boss/sc_thane_korthazz.cpp (revision 0) +++ boss/sc_thane_korthazz.cpp (revision 0) @@ -0,0 +1,8 @@ +//Thane Korthazz +//8899 aggro - Come out and fight, ye wee ninny! +//8903 taunt1 - To arms, ye roustabouts! We've got company! +//8904 taunt2 - I heard about enough of yer sniveling. Shut yer fly trap 'afore I shut it for ye! +//8905 taunt3 - I'm gonna enjoy killin' these slack-jawed daffodils! +//8901 slay - Next time, bring more friends! +//8902 special I like my meat extra crispy! +//8900 death - What a bloody waste this is! \ No newline at end of file Index: CppScripts.cpp =================================================================== --- CppScripts.cpp (revision 173) +++ CppScripts.cpp (working copy) @@ -31,25 +31,125 @@ // -- Scripts to be added -- -//Area +//------ ZONE -------- -//Boss -extern void AddSC_boss_onyxiaAI(); -//MC bosses -extern void AddSC_boss_lucifron(); -extern void AddSC_boss_magmadar(); -extern void AddSC_boss_gehennas(); -extern void AddSC_boss_garr(); -extern void AddSC_boss_baron_geddon(); -extern void AddSC_boss_shazzrah(); -extern void AddSC_boss_golemagg(); -extern void AddSC_boss_sulfuron(); -extern void AddSC_boss_majordomo(); +//Alterac Mountains +//Arathi Highlands +//Ashenvale Forest +//Azshara +//Badlands +//Barrens +//Blackfathom Depths +//Blackwing lair +extern void AddSC_boss_razorgore(); +extern void AddSC_boss_vael(); +extern void AddSC_boss_broodlord(); +extern void AddSC_boss_firemaw(); +extern void AddSC_boss_ebonroc(); +extern void AddSC_boss_flamegor(); +extern void AddSC_boss_chromaggus(); +extern void AddSC_boss_nefarian(); + +//Blasted lands +//Burning steppes +//Darkshore +//Deadmines +//Deadwind pass +//Desolace +//Dire Maul +//Dun Morogh +//Durotar +//Duskwood +//Duskwallow marsh +//Eastern Plaguelands +//Elwynn Forest +extern void AddSC_marshal_mcbride(); +extern void AddSC_henze_faulk(); + +//Felwood +//Feralas +//Gnomeregan +//Hillsbrad Foothills +//Hinterlands +//Loch Modan +//Lower Blackrock Spire +//Maradon +//Molten core +extern void AddSC_boss_lucifron(); +extern void AddSC_boss_magmadar(); +extern void AddSC_boss_gehennas(); +extern void AddSC_boss_garr(); +extern void AddSC_boss_baron_geddon(); +extern void AddSC_boss_shazzrah(); +extern void AddSC_boss_golemagg(); +extern void AddSC_boss_sulfuron(); +extern void AddSC_boss_majordomo(); extern void AddSC_boss_ragnaros(); +//Moonglade +extern void AddSC_silva_filnaveth(); +extern void AddSC_bunthen_plainswind(); + +//Mulgore +extern void AddSC_skorn_whitecloud(); + +//Naxxramas +extern void AddSC_boss_anubrekhan(); +extern void AddSC_boss_maexxna(); +extern void AddSC_boss_patchwerk(); +extern void AddSC_boss_razuvious(); + +//Onyxia's Lair +extern void AddSC_boss_onyxia(); + +//Ragefire Chasm +//Razorfen Downs +//Redridge Mountains +//Ruins of Ahn'Qiraj +//Scarlet Monastery +extern void AddSC_boss_arcanist_doan(); +extern void AddSC_boss_azshir_the_sleepless(); +extern void AddSC_boss_bloodmage_thalnos(); +//extern void AddSC_boss_herod(); +extern void AddSC_boss_high_inquisitor_fairbanks(); +extern void AddSC_boss_high_inquisitor_whitemane(); +extern void AddSC_boss_houndmaster_loksey(); +extern void AddSC_boss_interrogator_vishas(); +extern void AddSC_boss_scarlet_commander_mograine(); +extern void AddSC_boss_scorn(); +extern void AddSC_scarlet_torturer(); + +//Scholomance +//Searing gorge +//Shadowfang keep +//Silithus +//Silverpine forest +//Stockade +//Stonetalon mountains +//Stratholme +//Sunken Temple +//Tanaris +//Teldrassil +//Temple of ahn'qiraj +//Thousand Needles +//Tirisfal Glades +//Uldaman +//Un'Goro Crater +//Upper blackrock spire +//Wailing caverns +//Western plaguelands +//Westfall +//Wetlands +//Winterspring +//Zul'Farrak +//Zul'Gurub + +// ------------------- + // Creature extern void AddSC_kobold(); extern void AddSC_generic_creature(); +extern void AddSC_defias(); //Custom extern void AddSC_custom_example(); @@ -124,25 +224,126 @@ { // -- Inicialize the Scripts to be Added -- - //Area +//-------------------- + //------ ZONE -------- -//Boss -AddSC_boss_onyxiaAI(); -//MC bosses -AddSC_boss_lucifron(); -AddSC_boss_magmadar(); -AddSC_boss_gehennas(); -AddSC_boss_garr(); -AddSC_boss_baron_geddon(); -AddSC_boss_shazzrah(); -AddSC_boss_golemagg(); -AddSC_boss_sulfuron(); -AddSC_boss_majordomo(); -AddSC_boss_ragnaros(); + //Alterac Mountains + //Arathi Highlands + //Ashenvale Forest + //Azshara + //Badlands + //Barrens + //Blackfathom Depths + //Blackwing lair + AddSC_boss_razorgore(); + AddSC_boss_vael(); + AddSC_boss_broodlord(); + AddSC_boss_firemaw(); + AddSC_boss_ebonroc(); + AddSC_boss_flamegor(); + AddSC_boss_chromaggus(); + AddSC_boss_nefarian(); + //Blasted lands + //Burning steppes + //Darkshore + //Deadmines + //Deadwind pass + //Desolace + //Dire Maul + //Dun Morogh + //Durotar + //Duskwood + //Duskwallow marsh + //Eastern Plaguelands + //Elwynn Forest + AddSC_marshal_mcbride(); + AddSC_henze_faulk(); + + //Felwood + //Feralas + //Gnomeregan + //Hillsbrad Foothills + //Hinterlands + //Loch Modan + //Lower Blackrock Spire + //Maradon + //Molten core + AddSC_boss_lucifron(); + AddSC_boss_magmadar(); + AddSC_boss_gehennas(); + AddSC_boss_garr(); + AddSC_boss_baron_geddon(); + AddSC_boss_shazzrah(); + AddSC_boss_golemagg(); + AddSC_boss_sulfuron(); + AddSC_boss_majordomo(); + AddSC_boss_ragnaros(); + + //Moonglade + AddSC_silva_filnaveth(); + AddSC_bunthen_plainswind(); + + //Mulgore + AddSC_skorn_whitecloud(); + + //Naxxramas + AddSC_boss_anubrekhan(); + AddSC_boss_maexxna(); + AddSC_boss_patchwerk(); + AddSC_boss_razuvious(); + + //Onyxia's Lair + AddSC_boss_onyxia(); + + //Ragefire Chasm + //Razorfen Downs + //Redridge Mountains + //Ruins of Ahn'Qiraj + //Scarlet Monastery + AddSC_boss_arcanist_doan(); + AddSC_boss_azshir_the_sleepless(); + AddSC_boss_bloodmage_thalnos(); + //AddSC_boss_herod(); + AddSC_boss_high_inquisitor_fairbanks(); + AddSC_boss_high_inquisitor_whitemane(); + AddSC_boss_houndmaster_loksey(); + AddSC_boss_interrogator_vishas(); + AddSC_boss_scarlet_commander_mograine(); + AddSC_boss_scorn(); + AddSC_scarlet_torturer(); + + //Scholomance + //Searing gorge + //Shadowfang keep + //Silithus + //Silverpine forest + //Stockade + //Stonetalon mountains + //Stratholme + //Sunken Temple + //Tanaris + //Teldrassil + //Temple of ahn'qiraj + //Thousand Needles + //Tirisfal Glades + //Uldaman + //Un'Goro Crater + //Upper blackrock spire + //Wailing caverns + //Western plaguelands + //Westfall + //Wetlands + //Winterspring + //Zul'Farrak + //Zul'Gurub + + // ---------------------------------------- + // Creature AddSC_kobold(); AddSC_generic_creature(); +AddSC_defias(); //Custom AddSC_custom_example(); Index: creature/sc_defias.cpp =================================================================== --- creature/sc_defias.cpp (revision 173) +++ creature/sc_defias.cpp (working copy) @@ -16,7 +16,7 @@ //*** Generic Defias script *** -#include "sc_defines.h" +#include "../sc_defines.h" #define SOUND_AGGRO 1263 //Defias aggro sound @@ -28,90 +28,51 @@ // **** This script is still under Developement **** #define GENERIC_CREATURE_COOLDOWN 5000 +#define GENERIC_CREATURE_ROOTSELF 23973 struct MANGOS_DLL_DECL defiasAI : public ScriptedAI { defiasAI(Creature *c) : ScriptedAI(c) {Reset();} - Unit *pTarget; uint32 GlobalCooldown; //This variable acts like the global cooldown that players have (1.5 seconds) uint32 BuffTimer; //This variable keeps track of buffs + bool InCombat; + bool IsSelfRooted; - void EnterEvadeMode(); - void Reset() { - pTarget = NULL; GlobalCooldown = 0; BuffTimer = 0; //Rebuff as soon as we can + InCombat = false; + IsSelfRooted = false; if (m_creature) - { - m_creature->RemoveAllAuras(); - DoStopAttack(); - DoGoHome(); - } + EnterEvadeMode(); } - void AttackStart(Unit *who) + void MoveInLineOfSight(Unit *who) { - if (!who) + if (!who || m_creature->getVictim()) return; - if (m_creature->getVictim() == NULL && who->isTargetableForAttack() && who!= m_creature) + if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { - //Begin melee attack if we are within range - if (m_creature->IsWithinDist(who, ATTACK_DIST)) - DoStartMeleeAttack(who); - else DoStartRangedAttack(who); - - //30% chance to Play Aggro sound if the attacker is a player - if (who->GetTypeId() == TYPEID_PLAYER && rand()%3 == 0) + float attackRadius = m_creature->GetAttackDistance(who); + if (m_creature->IsWithinDist(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE) { - DoPlaySoundToSet(m_creature,SOUND_AGGRO); - - //Switch between 4 different chats - switch (rand()%4) - { - case 0: - DoSay(SAY_RANDOM_0,LANG_UNIVERSAL,pTarget); - break; - - case 1: - DoSay(SAY_RANDOM_1,LANG_UNIVERSAL,pTarget); - break; - - case 2: - DoSay(SAY_RANDOM_2,LANG_UNIVERSAL,pTarget); - break; - - case 3: - DoSay(SAY_RANDOM_3,LANG_UNIVERSAL,pTarget); - break; - } - } - - pTarget = who; - } - } - - void MoveInLineOfSight(Unit *who) - { - if (!who) - return; - - if (who->isTargetableForAttack() && IsVisible(who) && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) - { - if ( m_creature->getVictim() == NULL) - { if(who->HasStealthAura()) who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); //Begin melee attack if we are within range - if (m_creature->IsWithinDist(who, ATTACK_DIST)) - DoStartMeleeAttack(who); - else DoStartRangedAttack(who); + DoStartMeleeAttack(who); + if (!m_creature->IsWithinDist(who, ATTACK_DIST)) + { + DoCast(m_creature, GENERIC_CREATURE_ROOTSELF); + IsSelfRooted = true; + } + InCombat = true; + //30% chance to Play Aggro sound if the attacker is a player if (who->GetTypeId() == TYPEID_PLAYER && rand()%3 == 0) { @@ -121,24 +82,22 @@ switch (rand()%4) { case 0: - DoSay(SAY_RANDOM_0,LANG_UNIVERSAL,pTarget); + DoSay(SAY_RANDOM_0,LANG_UNIVERSAL,who); break; - + case 1: - DoSay(SAY_RANDOM_1,LANG_UNIVERSAL,pTarget); + DoSay(SAY_RANDOM_1,LANG_UNIVERSAL,who); break; case 2: - DoSay(SAY_RANDOM_2,LANG_UNIVERSAL,pTarget); + DoSay(SAY_RANDOM_2,LANG_UNIVERSAL,who); break; case 3: - DoSay(SAY_RANDOM_3,LANG_UNIVERSAL,pTarget); + DoSay(SAY_RANDOM_3,LANG_UNIVERSAL,who); break; } } - - pTarget = who; } } } @@ -150,16 +109,16 @@ GlobalCooldown -= diff; else GlobalCooldown = 0; - //If we had a target and it wasn't cleared then it means the player died from some unknown soruce + //If we had a target and it wasn't cleared then it means the target died from some unknown soruce //But we still need to reset - if (m_creature->isAlive() && pTarget && !m_creature->getVictim()) + if (InCombat && !m_creature->SelectHostilTarget()) { Reset(); return; } //Buff timer (only buff when we are alive and not in combat - if (m_creature->isAlive() && !m_creature->getVictim()) + if (m_creature->isAlive() && !InCombat) if (BuffTimer < diff ) { //Find a spell that targets friendly and applies an aura (these are generally buffs) @@ -183,8 +142,8 @@ //Check if we have a current target if( m_creature->getVictim() && m_creature->isAlive()) { - //Check if we should stop attacking because our victim is no longer attackable or we are to far from spawn point - if (needToStop() || CheckTether()) + //Check if we should stop attacking because our victim is no longer in range or we are to far from spawn point + if (CheckTether()) { Reset(); return; @@ -196,11 +155,6 @@ //Make sure our attack is ready and we arn't currently casting if( m_creature->isAttackReady() && !m_creature->m_currentSpell) { - /* - Unit* newtarget = m_creature->SelectHostilTarget(); - if(newtarget) - AttackStart(newtarget); - */ bool Healing = false; SpellEntry const *info = NULL; @@ -247,10 +201,10 @@ if (info && !GlobalCooldown) { //If we are currently moving stop us and set the movement generator - if ((*m_creature)->top()->GetMovementGeneratorType()!=IDLE_MOTION_TYPE) + if (!IsSelfRooted) { - (*m_creature)->Clear(); - (*m_creature)->Idle(); + DoCast(m_creature, GENERIC_CREATURE_ROOTSELF); + IsSelfRooted = true; } //Face target @@ -265,20 +219,15 @@ }//If no spells available and we arn't moving run to target - else if ((*m_creature)->top()->GetMovementGeneratorType()!=TARGETED_MOTION_TYPE) + else if (IsSelfRooted) { - //Cancel our current spell and then mutate new movement generator + //Cancel our current spell and then allow movement agian m_creature->InterruptSpell(); - (*m_creature)->Clear(); - (*m_creature)->Mutate(new TargetedMovementGenerator(*m_creature->getVictim())); + m_creature->RemoveAurasDueToSpell(GENERIC_CREATURE_ROOTSELF); + IsSelfRooted = false; } } } - //If we are still alive and we lose our victim it means we killed them - if(m_creature->isAlive() && !m_creature->getVictim()) - { - Reset(); - } } } }; @@ -290,7 +239,7 @@ } -void AddSC_defiasAI() +void AddSC_defias() { Script *newscript; newscript = new Script; Index: creature/sc_lumberjack.cpp =================================================================== --- creature/sc_lumberjack.cpp (revision 0) +++ creature/sc_lumberjack.cpp (revision 0) @@ -0,0 +1,45 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +//THIS SCRIPT IS UNDER DEVELOPMENT + +struct MANGOS_DLL_DECL LumberjackAI : public ScriptedAI +{ + LumberjackAI(Creature *c) : ScriptedAI(c) {} + + void MoveInLineOfSight(Unit *who) + { + //If a player walks into LOS we should begin our chopping animation + if (who->GetTypeId() == TYPEID_PLAYER) + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 234); + } +}; + +CreatureAI* GetAI_Lumberjack(Creature *_Creature) +{ + return new LumberjackAI (_Creature); +} + +void AddSC_lumberjack() +{ + Script *newscript; + newscript = new Script; + newscript->Name="lumberjack"; + newscript->GetAI = GetAI_Lumberjack; + m_scripts[nrscripts++] = newscript; +} \ No newline at end of file Index: creature/sc_miner.cpp =================================================================== --- creature/sc_miner.cpp (revision 0) +++ creature/sc_miner.cpp (revision 0) @@ -0,0 +1,45 @@ +/* Copyright (C) 2006,2007 ScriptDev2 +* 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" + +//THIS SCRIPT IS UNDER DEVELOPMENT + +struct MANGOS_DLL_DECL MinerAI : public ScriptedAI +{ + MinerAI(Creature *c) : ScriptedAI(c) {} + + void MoveInLineOfSight(Unit *who) + { + //If a player walks into LOS we should begin our mining animation + if (who->GetTypeId() == TYPEID_PLAYER) + m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, 233); + } +}; + +CreatureAI* GetAI_Miner(Creature *_Creature) +{ + return new MinerAI (_Creature); +} + +void AddSC_miner() +{ + Script *newscript; + newscript = new Script; + newscript->Name="miner"; + newscript->GetAI = GetAI_Miner; + m_scripts[nrscripts++] = newscript; +}