rendered paste body/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
*/
/* ScriptData
SDName: Boss_Lady_Vashj
SD%Complete: 99
SDComment: Missing blizzlike Shield Generators coords
EndScriptData */
//UPDATED BY PANDORA
#include "../../../sc_defines.h"
#include "def_serpent_shrine.h"
#include "../../../creature/simple_ai.h"
#include "../../../../../../game/GameObject.h"
#include "../../../../../../game/Player.h"
#include "../../../../../../game/Spell.h"
#include "../../../../../../game/Item.h"
#include "../../../../../../game/TargetedMovementGenerator.h"
#define SPELL_MULTI_SHOT 38310
#define SPELL_SHOCK_BLAST 38509
#define SPELL_ENTANGLE 38316
#define SPELL_STATIC_CHARGE_TRIGGER 38280
#define SPELL_FORKED_LIGHTNING 40088
#define SPELL_SHOOT 40873
#define SPELL_POISON_BOLT 40095
#define SPELL_TOXIC_SPORES 38575
#define SPELL_MAGIC_BARRIER 38112
#define SAY_INTRO "Water is life. It has become a rare commodity here in Outland. A commodity that we alone shall control. We are the Highborne, and the time has come at last for us to retake our rightful place in the world!"
#define SAY_AGGRO1 "I'll split you from stem to stern! "
#define SAY_AGGRO2 "Victory to Lord Illidan!"
#define SAY_AGGRO3 "I spit on you, surface filth!"
#define SAY_AGGRO4 "Death to the outsiders!"
#define SAY_PHASE1 "I did not wish to lower myself by engaging your kind, but you leave me little choice!"
#define SAY_PHASE2 "The time is now! Leave none standing!"
#define SAY_PHASE3 "You may want to take cover."
#define SAY_BOWSHOT1 "Straight to the heart!"
#define SAY_BOWSHOT2 "Seek your mark!"
#define SAY_SLAY1 "Your time ends now!"
#define SAY_SLAY2 "You have failed!"
#define SAY_DEATH "Lord Illidan, I... I am... sorry."
#define SOUND_INTRO 11531
#define SOUND_AGGRO1 11532
#define SOUND_AGGRO2 11533
#define SOUND_AGGRO3 11534
#define SOUND_AGGRO4 11535
#define SOUND_PHASE1 11538
#define SOUND_PHASE2 11539
#define SOUND_PHASE3 11540
#define SOUND_BOWSHOT1 11536
#define SOUND_BOWSHOT2 11537
#define SOUND_SLAY1 11541
#define SOUND_SLAY2 11542
#define SOUND_DEATH 11544
#define MIDDLE_X 30.134
#define MIDDLE_Y -923.65
#define MIDDLE_Z 42.9
#define SPOREBAT_X 30.977156
#define SPOREBAT_Y -925.297761
#define SPOREBAT_Z 77.176567
#define SPOREBAT_O 5.223932
#define SHIED_GENERATOR_CHANNEL 19870
#define ENCHANTED_ELEMENTAL 21958
#define TAINTED_ELEMENTAL 22009
#define COILFANG_STRIDER 22056
#define COILFANG_ELITE 22055
#define FATHOM_SPOREBAT 22120
float ElementPos[8][4] =
{
{2.8, -876.667, 41.111, 5.267},
{-23.82, -922.21, 41.114, 6.14},
{2.44, -969.86, 41.11, 0.94},
{57.22, -970, 41, 1.8},
{79.6, -952.95, 41, 2.59},
{57.33, -873.46, 41, 4},
{-21.6, -893.4, 41, 5.8},
{29.6, -981.97, 41, 1.56}
};
float CoilfangElitePos[3][4] =
{
{28.84, -923.28, 42.9, 6},
{31.183281, -953.502625, 41.523602, 1.640957},
{58.895180, -923.124268, 41.545307, 3.152848}
};
float CoilfangStriderPos[3][4] =
{
{66.427010, -948.778503, 41.262245, 2.584220},
{7.513962, -959.538208, 41.300422, 1.034629},
{-12.843201, -907.798401, 41.239620, 6.087094}
};
float ShieldGeneratorChannelPos[4][4] =
{
{49.6262, -902.181, 43.0975, 3.95683},
{10.988, -901.616, 42.5371, 5.4373},
{10.3859, -944.036, 42.5446, 0.779888},
{49.3126, -943.398, 42.5501, 2.40174}
};
//Lady Vashj AI
struct MANGOS_DLL_DECL boss_lady_vashjAI : public ScriptedAI
{
boss_lady_vashjAI (Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint64 ShieldGeneratorChannel[4];
uint32 ShockBlast_Timer;
uint32 Entangle_Timer;
uint32 StaticCharge_Timer;
uint32 ForkedLightning_Timer;
uint32 Check_Timer;
uint32 EnchantedElemental_Timer;
uint32 TaintedElemental_Timer;
uint32 CoilfangElite_Timer;
uint32 CoilfangStrider_Timer;
uint32 SummonSporebat_Timer;
uint32 SummonSporebat_StaticTimer;
uint8 EnchantedElemental_Pos;
uint8 Phase;
bool Entangle;
bool InCombat;
void Reset()
{
ShockBlast_Timer = 1+rand()%60000;
Entangle_Timer = 30000;
StaticCharge_Timer = 10000+rand()%15000;
ForkedLightning_Timer = 2000;
Check_Timer = 1000;
EnchantedElemental_Timer = 5000;
TaintedElemental_Timer = 50000;
CoilfangElite_Timer = 45000+rand()%5000;
CoilfangStrider_Timer = 60000+rand()%10000;
SummonSporebat_Timer = 10000;
SummonSporebat_StaticTimer = 30000;
EnchantedElemental_Pos = 0;
Phase = 0;
Entangle = false;
InCombat = false;
//m_creature->RemoveAllAuras();
//m_creature->DeleteThreatList();
//m_creature->CombatStop();
//DoGoHome();
if(pInstance)
pInstance->SetData(DATA_LADYVASHJEVENT, 0);
ShieldGeneratorChannel[0] = 0;
ShieldGeneratorChannel[1] = 0;
ShieldGeneratorChannel[2] = 0;
ShieldGeneratorChannel[3] = 0;
}
//Called when a tainted elemental dies
void EventTaintedElementalDeath()
{
//the next will spawn 50 seconds after the previous one's death
if(TaintedElemental_Timer > 50000)
TaintedElemental_Timer = 50000;
}
void KilledUnit(Unit *victim)
{
switch(rand()%2)
{
case 0:
DoYell(SAY_SLAY1, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
break;
case 1:
DoPlaySoundToSet(m_creature, SOUND_SLAY1);
DoYell(SAY_SLAY2, LANG_UNIVERSAL, NULL);
break;
}
}
void DamageTaken(Unit *killer, uint32 &damage)
{
if (killer->GetGUID()==m_creature->GetGUID())
return; //potrzebne - vashj zadaje sobie dmg jak niszczymy generatory
if (ShieldGeneratorChannel[0])
{
//DoSay("1 - online", LANG_UNIVERSAL, NULL);
damage=0; //niesmiertelnosc jezeli zyje przynajmniej 1 generator
}
if (ShieldGeneratorChannel[1])
{
//DoSay("2 - online", LANG_UNIVERSAL, NULL);
damage=0; //niesmiertelnosc jezeli zyje przynajmniej 1 generator
}
if (ShieldGeneratorChannel[2])
{
//DoSay("3 - online", LANG_UNIVERSAL, NULL);
damage=0; //niesmiertelnosc jezeli zyje przynajmniej 1 generator
}
if (ShieldGeneratorChannel[3])
{
//DoSay("4 - online", LANG_UNIVERSAL, NULL);
damage=0; //niesmiertelnosc jezeli zyje przynajmniej 1 generator
}
}
void JustDied(Unit *victim)
{
DoPlaySoundToSet(m_creature, SOUND_DEATH);
DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
if(pInstance)
pInstance->SetData(DATA_LADYVASHJEVENT, 0);
}
void StartEvent()
{
switch(rand()%4)
{
case 0:
DoPlaySoundToSet(m_creature, SOUND_AGGRO1);
DoYell(SAY_AGGRO1, LANG_UNIVERSAL, NULL);
break;
case 1:
DoPlaySoundToSet(m_creature, SOUND_AGGRO2);
DoYell(SAY_AGGRO2, LANG_UNIVERSAL, NULL);
break;
case 2:
DoPlaySoundToSet(m_creature, SOUND_AGGRO3);
DoYell(SAY_AGGRO3, LANG_UNIVERSAL, NULL);
break;
case 3:
DoPlaySoundToSet(m_creature, SOUND_AGGRO4);
DoYell(SAY_AGGRO4, LANG_UNIVERSAL, NULL);
break;
}
InCombat = true;
Phase = 1;
if(pInstance)
pInstance->SetData(DATA_LADYVASHJEVENT, 1);
}
void AttackStart(Unit *who)
{
if(!who && who != m_creature)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
//Begin melee attack if we are within range
if(Phase != 2)
DoStartMeleeAttack(who);
if(!InCombat)
StartEvent();
}
}
void MoveInLineOfSight(Unit *who)
{
if (!who || m_creature->getVictim())
return;
if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
if(Phase != 2)
DoStartMeleeAttack(who);
if(!InCombat)
StartEvent();
}
}
}
void CastShootOrMultishot()
{
switch(rand()%2)
{
case 0:
//Shoot
//Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits her target for 4097-5543 Physical damage.
DoCast(m_creature->getVictim(), SPELL_SHOOT);
break;
case 1:
//Multishot
//Used in Phases 1 and 3 after Entangle or while having nobody in melee range. A shot that hits 1 person and 4 people around him for 6475-7525 physical damage.
DoCast(m_creature->getVictim(), SPELL_MULTI_SHOT);
break;
}
if(rand()%3)
{
switch(rand()%2)
{
case 0:
DoPlaySoundToSet(m_creature, SOUND_BOWSHOT1);
DoYell(SAY_BOWSHOT1, LANG_UNIVERSAL, NULL);
break;
case 1:
DoPlaySoundToSet(m_creature, SOUND_BOWSHOT2);
DoYell(SAY_BOWSHOT2, LANG_UNIVERSAL, NULL);
break;
}
}
}
void UpdateAI(const uint32 diff)
{
//to prevent abuses during phase 2
if(Phase == 2 && !m_creature->getVictim() && InCombat)
EnterEvadeMode();
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
if(Phase == 1 || Phase == 3)
{
//ShockBlast_Timer
if (ShockBlast_Timer < diff)
{
//Shock Burst
//Randomly used in Phases 1 and 3 on Vashj's target, it's a Shock spell doing 8325-9675 nature damage and stunning the target for 5 seconds, during which she will not attack her target but switch to the next person on the aggro list.
DoCast(m_creature->getVictim(), SPELL_SHOCK_BLAST);
m_creature->TauntApply(m_creature->getVictim());
ShockBlast_Timer = 1000+rand()%14000; //random cooldown
}else ShockBlast_Timer -= diff;
//StaticCharge_Timer
if(StaticCharge_Timer < diff)
{
//Static Charge
//Used on random people (only 1 person at any given time) in Phases 1 and 3, it's a debuff doing 2775 to 3225 Nature damage to the target and everybody in about 5 yards around it, every 1 seconds for 30 seconds. It can be removed by Cloak of Shadows, Iceblock, Divine Shield, etc, but not by Cleanse or Dispel Magic.
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target && !target->HasAura(SPELL_STATIC_CHARGE_TRIGGER, 0))
DoCast(target, SPELL_STATIC_CHARGE_TRIGGER); //cast Static Charge every 2 seconds for 20 seconds
StaticCharge_Timer = 10000+rand()%20000; //blizzlike
}else StaticCharge_Timer -= diff;
//Entangle_Timer
if (Entangle_Timer < diff)
{
if(!Entangle)
{
//Entangle
//Used in Phases 1 and 3, it casts Entangling Roots on everybody in a 15 yard radius of Vashj, immobilzing them for 10 seconds and dealing 500 damage every 2 seconds. It's not a magic effect so it cannot be dispelled, but is removed by various buffs such as Cloak of Shadows or Blessing of Freedom.
DoCast(m_creature->getVictim(), SPELL_ENTANGLE);
Entangle = true;
Entangle_Timer = 10000;
}
else
{
CastShootOrMultishot();
Entangle = false;
Entangle_Timer = 20000+rand()%5000;
}
}else Entangle_Timer -= diff;
//Phase 1
if(Phase == 1)
{
//Start phase 2
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 70)
{
//Phase 2 begins when Vashj hits 70%. She will run to the middle of her platform and surround herself in a shield making her invulerable.
Phase = 2;
m_creature->GetMotionMaster()->Clear();
m_creature->Relocate(MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
m_creature->SendMoveToPacket(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, false, 0);
//m_creature->RemoveAllAuras();
DoCast(m_creature, SPELL_MAGIC_BARRIER, true);
Creature *pCreature;
for(uint8 i = 0; i < 4; i++)
{
pCreature = m_creature->SummonCreature(SHIED_GENERATOR_CHANNEL, ShieldGeneratorChannelPos[i][0], ShieldGeneratorChannelPos[i][1], ShieldGeneratorChannelPos[i][2], ShieldGeneratorChannelPos[i][3], TEMPSUMMON_CORPSE_DESPAWN, 0);
if (pCreature)
ShieldGeneratorChannel[i] = pCreature->GetGUID();
}
DoPlaySoundToSet(m_creature, SOUND_PHASE2);
DoYell(SAY_PHASE2, LANG_UNIVERSAL, NULL);
}
}
//Phase 3
else
{
//SummonSporebat_Timer
if(SummonSporebat_Timer < diff)
{
Creature *Sporebat = NULL;
Sporebat = m_creature->SummonCreature(FATHOM_SPOREBAT, SPOREBAT_X, SPOREBAT_Y, SPOREBAT_Z, SPOREBAT_O, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
if(Sporebat)
{
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target)
Sporebat->AI()->AttackStart(target);
}
//summon sporebats faster and faster
if(SummonSporebat_StaticTimer > 1000)
SummonSporebat_StaticTimer -= 1000;
SummonSporebat_Timer = SummonSporebat_StaticTimer;
}else SummonSporebat_Timer -= diff;
}
//Melee attack
DoMeleeAttackIfReady();
//Check_Timer - used to check if somebody is in melee range
if(Check_Timer < diff)
{
bool InMeleeRange = false;
Unit *target;
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
for(std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
if(target && target->IsWithinDistInMap(m_creature, 5)) //if in melee range
{
InMeleeRange = true;
break;
}
}
//if nobody is in melee range
if(!InMeleeRange)
CastShootOrMultishot();
Check_Timer = 3000;
}else Check_Timer -= diff;
}
//Phase 2
else
{
//ForkedLightning_Timer
if(ForkedLightning_Timer < diff)
{
//Forked Lightning
//Used constantly in Phase 2, it shoots out completely randomly targeted bolts of lightning which hit everybody in a roughtly 60 degree cone in front of Vashj for 2313-2687 nature damage.
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(!target)
target = m_creature->getVictim();
DoCast(target, SPELL_FORKED_LIGHTNING);
ForkedLightning_Timer = 2000+rand()%6000; //blizzlike
}else ForkedLightning_Timer -= diff;
//EnchantedElemental_Timer
if(EnchantedElemental_Timer < diff)
{
Creature *Elemental;
Elemental = m_creature->SummonCreature(ENCHANTED_ELEMENTAL, ElementPos[EnchantedElemental_Pos][0], ElementPos[EnchantedElemental_Pos][1], ElementPos[EnchantedElemental_Pos][2], ElementPos[EnchantedElemental_Pos][3], TEMPSUMMON_CORPSE_DESPAWN, 0);
if(EnchantedElemental_Pos == 7)
EnchantedElemental_Pos = 0;
else
EnchantedElemental_Pos++;
EnchantedElemental_Timer = 10000+rand()%5000;
}else EnchantedElemental_Timer -= diff;
//TaintedElemental_Timer
if(TaintedElemental_Timer < diff)
{
Creature *Tain_Elemental;
uint32 pos = rand()%8;
Tain_Elemental = m_creature->SummonCreature(TAINTED_ELEMENTAL, ElementPos[pos][0], ElementPos[pos][1], ElementPos[pos][2], ElementPos[pos][3], TEMPSUMMON_DEAD_DESPAWN, 0);
TaintedElemental_Timer = 120000;
}else TaintedElemental_Timer -= diff;
//CoilfangElite_Timer
if(CoilfangElite_Timer < diff)
{
Creature *CoilfangElite;
uint32 pos = rand()%3;
CoilfangElite = m_creature->SummonCreature(COILFANG_ELITE, CoilfangElitePos[pos][0], CoilfangElitePos[pos][1], CoilfangElitePos[pos][2], CoilfangElitePos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
if(CoilfangElite)
{
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target)
CoilfangElite->AI()->AttackStart(target);
}
CoilfangElite_Timer = 45000+rand()%5000; //wowwiki says 50 seconds, bosskillers says 45
}else CoilfangElite_Timer -= diff;
//CoilfangStrider_Timer
if(CoilfangStrider_Timer < diff)
{
Creature *CoilfangStrider;
uint32 pos = rand()%3;
CoilfangStrider = m_creature->SummonCreature(COILFANG_STRIDER, CoilfangStriderPos[pos][0], CoilfangStriderPos[pos][1], CoilfangStriderPos[pos][2], CoilfangStriderPos[pos][3], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
if(CoilfangStrider)
{
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target)
CoilfangStrider->AI()->AttackStart(target);
}
CoilfangStrider_Timer = 60000+rand()%10000; //wowwiki says 60 seconds, bosskillers says 60-70
}else CoilfangStrider_Timer -= diff;
//Check_Timer
if(Check_Timer < diff)
{
//Start Phase 3
if(pInstance && pInstance->GetData(DATA_CANSTARTPHASE3))
{
//set life 50%
m_creature->SetHealth(m_creature->GetMaxHealth()/2);
m_creature->RemoveAurasDueToSpell(SPELL_MAGIC_BARRIER);
DoPlaySoundToSet(m_creature, SOUND_PHASE3);
DoYell(SAY_PHASE3, LANG_UNIVERSAL, NULL);
Phase = 3;
//return to the tank
m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature->getVictim()));
}
Check_Timer = 2000;
}else Check_Timer -= diff;
}
}
};
//Enchanted Elemental
//If one of them reaches Vashj he will increase her damage done by 5%.
struct MANGOS_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
{
mob_enchanted_elementalAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 Check_Timer;
uint32 Movement_Timer;
void Reset()
{
Check_Timer = 5000;
Movement_Timer = 500;
//m_creature->RemoveAllAuras();
//m_creature->DeleteThreatList();
//m_creature->CombatStop();
//DoGoHome();
}
void AttackStart(Unit *who) { return; }
void MoveInLineOfSight(Unit *who) { return; }
void DamageTaken(Unit *killer, uint32 &damage)
{
//patrz w UpdateAI - atakujemy Vashj by wymusić TargetMovementGenerator
//Vashj dodaje nas niestety w liscie aggro - moze nas atakowac - ignorujemy dmg
if (!pInstance)
return;
if (killer->GetGUID()==pInstance->GetData64(DATA_LADYVASHJ))
damage=0;
}
void UpdateAI(const uint32 diff)
{
if (!pInstance)
return;
//Movement_Timer
if(Movement_Timer < diff)
{
Unit *Vashj = NULL;
Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
if(Vashj)
{
// m_creature->GetMotionMaster()->Clear();
// m_creature->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*Vashj));
//kompletnie to niedziala, u graczy widac ruch ale na serwerze mob stoi w miejscu spawnu - niewiem czemu
DoStartMeleeAttack(Vashj);//zaatakuj vashj (tylko tak da sie wymusic ruch)
}
//if first movement doesn't work, apply the same movement after 10 seconds
Movement_Timer = 5000;
}else Movement_Timer -= diff;
//Check_Timer
if(Check_Timer < diff)
{
if(pInstance)
{
Unit *Vashj = NULL;
Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
if(Vashj)
{
if(Vashj->IsWithinDistInMap(m_creature, 5))
{
//increase lady vashj damage (+5%)
const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
Vashj->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 5)));
Vashj->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 5)));
m_creature->UpdateDamagePhysical(BASE_ATTACK);
//call Unsummon()
m_creature->setDeathState(JUST_DIED);
}
else if(((boss_lady_vashjAI*)((Creature*)Vashj)->AI())->InCombat == false)
{
//call Unsummon()
m_creature->setDeathState(JUST_DIED);
}
}
}
Check_Timer = 2000;
}else Check_Timer -= diff;
}
};
//Tainted Elemental
//This mob has 7,900 life, doesn't move, and shoots Poison Bolts at one person anywhere in the area, doing 3,000 nature damage and placing a posion doing 2,000 damage every 2 seconds. He will switch targets often, or sometimes just hang on a single player, but there is nothing you can do about it except heal the damage and kill the Tainted Elemental
struct MANGOS_DLL_DECL mob_tainted_elementalAI : public ScriptedAI
{
mob_tainted_elementalAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 PoisonBolt_Timer;
uint32 Despawn_Timer;
void Reset()
{
PoisonBolt_Timer = 5000+rand()%5000;
Despawn_Timer = 30000;
//m_creature->RemoveAllAuras();
//m_creature->DeleteThreatList();
//m_creature->CombatStop();
//DoGoHome();
}
void JustDied(Unit *killer)
{
if(pInstance)
{
Creature *Vashj = NULL;
Vashj = (Creature*)(Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ)));
if(Vashj)
((boss_lady_vashjAI*)Vashj->AI())->EventTaintedElementalDeath();
}
}
void AttackStart(Unit *who)
{
if(!who && who != m_creature)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
m_creature->AddThreat(who, 0.1f);
}
}
void MoveInLineOfSight(Unit *who)
{
if (!who || m_creature->getVictim())
return;
if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
m_creature->AddThreat(who, 0.1f);
}
}
}
void UpdateAI(const uint32 diff)
{
//PoisonBolt_Timer
if(PoisonBolt_Timer < diff)
{
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
if(target && target->IsWithinDistInMap(m_creature, 30))
DoCast(target, SPELL_POISON_BOLT);
PoisonBolt_Timer = 5000+rand()%5000;
}else PoisonBolt_Timer -= diff;
//Despawn_Timer
if(Despawn_Timer < diff)
{
//call Unsummon()
m_creature->setDeathState(DEAD);
//to prevent crashes
Despawn_Timer = 1000;
}else Despawn_Timer -= diff;
}
};
//Fathom Sporebat
//Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it.
struct MANGOS_DLL_DECL mob_fathom_sporebatAI : public ScriptedAI
{
mob_fathom_sporebatAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 ToxicSpore_Timer;
uint32 Check_Timer;
void Reset()
{
m_creature->setFaction(14);
ToxicSpore_Timer = 5000;
Check_Timer = 1000;
//m_creature->RemoveAllAuras();
//m_creature->DeleteThreatList();
//m_creature->CombatStop();
//DoGoHome();
}
void AttackStart(Unit *who)
{
if(!who && who != m_creature)
return;
if (who->isTargetableForAttack() && who!= m_creature)
{
DoStartMeleeAttack(who);
}
}
void MoveInLineOfSight(Unit *who)
{
if (!who || m_creature->getVictim())
return;
if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))
{
float attackRadius = m_creature->GetAttackDistance(who);
if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))
{
if(who->HasStealthAura())
who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
DoStartMeleeAttack(who);
}
}
}
void UpdateAI (const uint32 diff)
{
//Return since we have no target
if (!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
return;
//ToxicSpore_Timer
if(ToxicSpore_Timer < diff)
{
Unit *target = NULL;
target = SelectUnit(SELECT_TARGET_RANDOM, 0);
//The Spores will hit you anywhere in the instance: underwater, at the elevator, at the entrance, wherever.
if(target)
DoCast(target, SPELL_TOXIC_SPORES);
ToxicSpore_Timer = 20000+rand()%5000;
}else ToxicSpore_Timer -= diff;
//Check_Timer
// - prawdopodobnie robił freeza - usunięty
DoMeleeAttackIfReady();
}
};
//Coilfang Elite
//It's an elite Naga mob with 170,000 HP. It does about 5000 damage on plate, and has a nasty cleave hitting for about 7500 damage
CreatureAI* GetAI_mob_coilfang_elite(Creature *_Creature)
{
SimpleAI* ai = new SimpleAI (_Creature);
ai->Spell[0].Enabled = true;
ai->Spell[0].Spell_Id = 31345; //Cleave
ai->Spell[0].Cooldown = 15000;
ai->Spell[0].CooldownRandomAddition = 5000;
ai->Spell[0].First_Cast = 5000;
ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_RANDOM;
ai->EnterEvadeMode();
return ai;
}
//Coilfang Strifer
//It hits plate for about 8000 damage, has a Mind Blast spell doing about 3000 shadow damage, and a Psychic Scream Aura, which fears everybody in a 8 yard range of it every 2-3 seconds , for 5 seconds and increasing their movement speed by 150% during the fear.
CreatureAI* GetAI_mob_coilfang_strider(Creature *_Creature)
{
SimpleAI* ai = new SimpleAI (_Creature);
ai->Spell[0].Enabled = true;
ai->Spell[0].Spell_Id = 41374; //Mind Blast
ai->Spell[0].Cooldown = 30000;
ai->Spell[0].CooldownRandomAddition = 10000;
ai->Spell[0].First_Cast = 8000;
ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET;
//Scream aura not implemented
ai->EnterEvadeMode();
return ai;
}
struct MANGOS_DLL_DECL mob_shield_generator_channelAI : public ScriptedAI
{
mob_shield_generator_channelAI(Creature *c) : ScriptedAI(c)
{
pInstance = (c->GetInstanceData()) ? ((ScriptedInstance*)c->GetInstanceData()) : NULL;
EnterEvadeMode();
}
ScriptedInstance *pInstance;
uint32 Check_Timer;
bool Channeled;
void Reset()
{
Check_Timer = 1000;
Channeled = false;
//m_creature->RemoveAllAuras();
//m_creature->DeleteThreatList();
//m_creature->CombatStop();
//DoGoHome();
m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID , 11686); //invisible
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
}
void AttackStart(Unit *who) { return; }
void MoveInLineOfSight(Unit *who) { return; }
void UpdateAI (const uint32 diff)
{
if(!pInstance)
return;
if(!Channeled)
{
Unit *Vashj = NULL;
Vashj = Unit::GetUnit((*m_creature), pInstance->GetData64(DATA_LADYVASHJ));
if(Vashj && Vashj->isAlive())
{
//start visual channel
m_creature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, Vashj->GetGUID());
m_creature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_MAGIC_BARRIER);
Channeled = true;
}
}
}
};
bool ItemUse_item_tainted_core(Player *player, Item* _Item, SpellCastTargets const& targets)
{
ScriptedInstance *pInstance = (player->GetInstanceData()) ? ((ScriptedInstance*)player->GetInstanceData()) : NULL;
if(!pInstance)
{
player->GetSession()->SendNotification("Instance script not initialized");
return true;
}
Creature *Vashj = NULL;
Vashj = (Creature*)(Unit::GetUnit((*player), pInstance->GetData64(DATA_LADYVASHJ)));
if(Vashj && ((boss_lady_vashjAI*)Vashj->AI())->Phase == 2)
{
if(targets.getGOTarget() && targets.getGOTarget()->GetTypeId()==TYPEID_GAMEOBJECT)
{
uint32 identifier;
uint8 channel_identifier;
switch(targets.getGOTarget()->GetEntry())
{
case 185052:
identifier = DATA_SHIELDGENERATOR1;
channel_identifier = 0;
break;
case 185053:
identifier = DATA_SHIELDGENERATOR2;
channel_identifier = 1;
break;
case 185051:
identifier = DATA_SHIELDGENERATOR3;
channel_identifier = 2;
break;
case 185054:
identifier = DATA_SHIELDGENERATOR4;
channel_identifier = 3;
break;
default:
return true;
break;
}
if(pInstance->GetData(identifier))
{
player->GetSession()->SendNotification("Already deactivated");
return true;
}
//get and remove channel
Unit *Channel = NULL;
Channel = Unit::GetUnit((*Vashj), ((boss_lady_vashjAI*)Vashj->AI())->ShieldGeneratorChannel[channel_identifier]);
if(Channel)
{
//call Unsummon()
Channel->setDeathState(JUST_DIED);
((boss_lady_vashjAI*)Vashj->AI())->ShieldGeneratorChannel[channel_identifier]=0;
//i zabiera vashj 5% całkowiteo życia (4*5=20 - 2 faza trwa od 70% - 50%)
Vashj->DealDamage(Vashj,Vashj->GetMaxHealth()*0.05, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);
}
pInstance->SetData(identifier, 1);
//remove this item
player->RemoveItemCount(31088, 1, true);
}
}
return true;
}
CreatureAI* GetAI_boss_lady_vashj(Creature *_Creature)
{
return new boss_lady_vashjAI (_Creature);
}
CreatureAI* GetAI_mob_enchanted_elemental(Creature *_Creature)
{
return new mob_enchanted_elementalAI (_Creature);
}
CreatureAI* GetAI_mob_tainted_elemental(Creature *_Creature)
{
return new mob_tainted_elementalAI (_Creature);
}
CreatureAI* GetAI_mob_fathom_sporebat(Creature *_Creature)
{
return new mob_fathom_sporebatAI (_Creature);
}
CreatureAI* GetAI_mob_shield_generator_channel(Creature *_Creature)
{
return new mob_shield_generator_channelAI (_Creature);
}
void AddSC_boss_lady_vashj()
{
Script *newscript;
newscript = new Script;
newscript->Name="boss_lady_vashj";
newscript->GetAI = GetAI_boss_lady_vashj;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_enchanted_elemental";
newscript->GetAI = GetAI_mob_enchanted_elemental;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_tainted_elemental";
newscript->GetAI = GetAI_mob_tainted_elemental;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_fathom_sporebat";
newscript->GetAI = GetAI_mob_fathom_sporebat;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_coilfang_elite";
newscript->GetAI = GetAI_mob_coilfang_elite;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_coilfang_strider";
newscript->GetAI = GetAI_mob_coilfang_strider;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="mob_shield_generator_channel";
newscript->GetAI = GetAI_mob_shield_generator_channel;
m_scripts[nrscripts++] = newscript;
newscript = new Script;
newscript->Name="item_tainted_core";
newscript->pItemUse = ItemUse_item_tainted_core;
m_scripts[nrscripts++] = newscript;
}