* Rename InstanceData to InstanceScript
* Rename *mgr to their new names in scripts project * Mass convert all the scripts (NEEDS THOROUGH TESTING, because it was done automatically) Please, report bugs on issue tracker. --HG-- branch : trunk rename : src/server/game/Instances/InstanceData.cpp => src/server/game/Instances/InstanceScript.cpp rename : src/server/game/Instances/InstanceData.h => src/server/game/Instances/InstanceScript.h
This commit is contained in:
+556
-551
File diff suppressed because it is too large
Load Diff
+265
-263
@@ -75,307 +75,309 @@ EndScriptData */
|
||||
#define SPAWN_Y_DIFF3 -4.72702
|
||||
#define SPAWN_X_DIFF4 12.577011
|
||||
#define SPAWN_Y_DIFF4 4.72702
|
||||
|
||||
struct boss_hydross_the_unstableAI : public ScriptedAI
|
||||
␍class boss_hydross_the_unstable : public CreatureScript
|
||||
{
|
||||
boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c), Summons(me)
|
||||
public:
|
||||
boss_hydross_the_unstable() : CreatureScript("boss_hydross_the_unstable") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new boss_hydross_the_unstableAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
uint64 beams[2];
|
||||
uint32 PosCheck_Timer;
|
||||
uint32 MarkOfHydross_Timer;
|
||||
uint32 MarkOfCorruption_Timer;
|
||||
uint32 WaterTomb_Timer;
|
||||
uint32 VileSludge_Timer;
|
||||
uint32 MarkOfHydross_Count;
|
||||
uint32 MarkOfCorruption_Count;
|
||||
uint32 EnrageTimer;
|
||||
bool CorruptedForm;
|
||||
bool beam;
|
||||
SummonList Summons;
|
||||
|
||||
void Reset()
|
||||
struct boss_hydross_the_unstableAI : public ScriptedAI
|
||||
{
|
||||
DeSummonBeams();
|
||||
beams[0] = 0;
|
||||
beams[1] = 0;
|
||||
PosCheck_Timer = 2500;
|
||||
MarkOfHydross_Timer = 15000;
|
||||
MarkOfCorruption_Timer = 15000;
|
||||
WaterTomb_Timer = 7000;
|
||||
VileSludge_Timer = 7000;
|
||||
MarkOfHydross_Count = 0;
|
||||
MarkOfCorruption_Count = 0;
|
||||
EnrageTimer = 600000;
|
||||
|
||||
CorruptedForm = false;
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
|
||||
|
||||
me->SetDisplayId(MODEL_CLEAN);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED);
|
||||
beam = false;
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void SummonBeams()
|
||||
{
|
||||
Creature* beamer = me->SummonCreature(ENTRY_BEAM_DUMMY,-258.333,-356.34,22.0499,5.90835,TEMPSUMMON_CORPSE_DESPAWN,0);
|
||||
if (beamer)
|
||||
boss_hydross_the_unstableAI(Creature *c) : ScriptedAI(c), Summons(me)
|
||||
{
|
||||
beamer->CastSpell(me,SPELL_BLUE_BEAM,true);
|
||||
beamer->SetDisplayId(11686); //invisible
|
||||
beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
beams[0]=beamer->GetGUID();
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
beamer = beamer = me->SummonCreature(ENTRY_BEAM_DUMMY,-219.918,-371.308,22.0042,2.73072,TEMPSUMMON_CORPSE_DESPAWN,0);
|
||||
if (beamer)
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
uint64 beams[2];
|
||||
uint32 PosCheck_Timer;
|
||||
uint32 MarkOfHydross_Timer;
|
||||
uint32 MarkOfCorruption_Timer;
|
||||
uint32 WaterTomb_Timer;
|
||||
uint32 VileSludge_Timer;
|
||||
uint32 MarkOfHydross_Count;
|
||||
uint32 MarkOfCorruption_Count;
|
||||
uint32 EnrageTimer;
|
||||
bool CorruptedForm;
|
||||
bool beam;
|
||||
SummonList Summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
beamer->CastSpell(me,SPELL_BLUE_BEAM,true);
|
||||
beamer->SetDisplayId(11686); //invisible
|
||||
beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
beams[1]=beamer->GetGUID();
|
||||
DeSummonBeams();
|
||||
beams[0] = 0;
|
||||
beams[1] = 0;
|
||||
PosCheck_Timer = 2500;
|
||||
MarkOfHydross_Timer = 15000;
|
||||
MarkOfCorruption_Timer = 15000;
|
||||
WaterTomb_Timer = 7000;
|
||||
VileSludge_Timer = 7000;
|
||||
MarkOfHydross_Count = 0;
|
||||
MarkOfCorruption_Count = 0;
|
||||
EnrageTimer = 600000;
|
||||
|
||||
CorruptedForm = false;
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
|
||||
|
||||
me->SetDisplayId(MODEL_CLEAN);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, NOT_STARTED);
|
||||
beam = false;
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
}
|
||||
void DeSummonBeams()
|
||||
{
|
||||
for (uint8 i=0; i<2; ++i)
|
||||
|
||||
void SummonBeams()
|
||||
{
|
||||
Creature* mob = Unit::GetCreature(*me,beams[i]);
|
||||
if (mob)
|
||||
Creature* beamer = me->SummonCreature(ENTRY_BEAM_DUMMY,-258.333,-356.34,22.0499,5.90835,TEMPSUMMON_CORPSE_DESPAWN,0);
|
||||
if (beamer)
|
||||
{
|
||||
mob->setDeathState(DEAD);
|
||||
mob->RemoveCorpse();
|
||||
beamer->CastSpell(me,SPELL_BLUE_BEAM,true);
|
||||
beamer->SetDisplayId(11686); //invisible
|
||||
beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
beams[0]=beamer->GetGUID();
|
||||
}
|
||||
beamer = beamer = me->SummonCreature(ENTRY_BEAM_DUMMY,-219.918,-371.308,22.0042,2.73072,TEMPSUMMON_CORPSE_DESPAWN,0);
|
||||
if (beamer)
|
||||
{
|
||||
beamer->CastSpell(me,SPELL_BLUE_BEAM,true);
|
||||
beamer->SetDisplayId(11686); //invisible
|
||||
beamer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
beams[1]=beamer->GetGUID();
|
||||
}
|
||||
}
|
||||
}
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
if (CorruptedForm)
|
||||
void DeSummonBeams()
|
||||
{
|
||||
DoScriptText(RAND(SAY_CORRUPT_SLAY1,SAY_CORRUPT_SLAY2), me);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoScriptText(RAND(SAY_CLEAN_SLAY1,SAY_CLEAN_SLAY2), me);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
if (summoned->GetEntry() == ENTRY_PURE_SPAWN)
|
||||
{
|
||||
summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
|
||||
Summons.Summon(summoned);
|
||||
}
|
||||
if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN)
|
||||
{
|
||||
summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
|
||||
summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
|
||||
Summons.Summon(summoned);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature *summon)
|
||||
{
|
||||
Summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*victim*/)
|
||||
{
|
||||
if (CorruptedForm)
|
||||
DoScriptText(SAY_CORRUPT_DEATH, me);
|
||||
else
|
||||
DoScriptText(SAY_CLEAN_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, DONE);
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!beam)
|
||||
{
|
||||
SummonBeams();
|
||||
beam=true;
|
||||
}
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// corrupted form
|
||||
if (CorruptedForm)
|
||||
{
|
||||
//MarkOfCorruption_Timer
|
||||
if (MarkOfCorruption_Timer <= diff)
|
||||
for (uint8 i=0; i<2; ++i)
|
||||
{
|
||||
if (MarkOfCorruption_Count <= 5)
|
||||
Creature* mob = Unit::GetCreature(*me,beams[i]);
|
||||
if (mob)
|
||||
{
|
||||
uint32 mark_spell = 0;
|
||||
mob->setDeathState(DEAD);
|
||||
mob->RemoveCorpse();
|
||||
}
|
||||
}
|
||||
}
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
|
||||
switch (MarkOfCorruption_Count)
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
if (CorruptedForm)
|
||||
{
|
||||
DoScriptText(RAND(SAY_CORRUPT_SLAY1,SAY_CORRUPT_SLAY2), me);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoScriptText(RAND(SAY_CLEAN_SLAY1,SAY_CLEAN_SLAY2), me);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
if (summoned->GetEntry() == ENTRY_PURE_SPAWN)
|
||||
{
|
||||
summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
|
||||
Summons.Summon(summoned);
|
||||
}
|
||||
if (summoned->GetEntry() == ENTRY_TAINTED_SPAWN)
|
||||
{
|
||||
summoned->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
|
||||
summoned->CastSpell(summoned,SPELL_ELEMENTAL_SPAWNIN,true);
|
||||
Summons.Summon(summoned);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature *summon)
|
||||
{
|
||||
Summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*victim*/)
|
||||
{
|
||||
if (CorruptedForm)
|
||||
DoScriptText(SAY_CORRUPT_DEATH, me);
|
||||
else
|
||||
DoScriptText(SAY_CLEAN_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HYDROSSTHEUNSTABLEEVENT, DONE);
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!beam)
|
||||
{
|
||||
SummonBeams();
|
||||
beam=true;
|
||||
}
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// corrupted form
|
||||
if (CorruptedForm)
|
||||
{
|
||||
//MarkOfCorruption_Timer
|
||||
if (MarkOfCorruption_Timer <= diff)
|
||||
{
|
||||
if (MarkOfCorruption_Count <= 5)
|
||||
{
|
||||
case 0: mark_spell = SPELL_MARK_OF_CORRUPTION1; break;
|
||||
case 1: mark_spell = SPELL_MARK_OF_CORRUPTION2; break;
|
||||
case 2: mark_spell = SPELL_MARK_OF_CORRUPTION3; break;
|
||||
case 3: mark_spell = SPELL_MARK_OF_CORRUPTION4; break;
|
||||
case 4: mark_spell = SPELL_MARK_OF_CORRUPTION5; break;
|
||||
case 5: mark_spell = SPELL_MARK_OF_CORRUPTION6; break;
|
||||
uint32 mark_spell = 0;
|
||||
|
||||
switch (MarkOfCorruption_Count)
|
||||
{
|
||||
case 0: mark_spell = SPELL_MARK_OF_CORRUPTION1; break;
|
||||
case 1: mark_spell = SPELL_MARK_OF_CORRUPTION2; break;
|
||||
case 2: mark_spell = SPELL_MARK_OF_CORRUPTION3; break;
|
||||
case 3: mark_spell = SPELL_MARK_OF_CORRUPTION4; break;
|
||||
case 4: mark_spell = SPELL_MARK_OF_CORRUPTION5; break;
|
||||
case 5: mark_spell = SPELL_MARK_OF_CORRUPTION6; break;
|
||||
}
|
||||
|
||||
DoCast(me->getVictim(), mark_spell);
|
||||
|
||||
if (MarkOfCorruption_Count < 5)
|
||||
++MarkOfCorruption_Count;
|
||||
}
|
||||
|
||||
DoCast(me->getVictim(), mark_spell);
|
||||
MarkOfCorruption_Timer = 15000;
|
||||
} else MarkOfCorruption_Timer -= diff;
|
||||
|
||||
if (MarkOfCorruption_Count < 5)
|
||||
++MarkOfCorruption_Count;
|
||||
}
|
||||
|
||||
MarkOfCorruption_Timer = 15000;
|
||||
} else MarkOfCorruption_Timer -= diff;
|
||||
|
||||
//VileSludge_Timer
|
||||
if (VileSludge_Timer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_VILE_SLUDGE);
|
||||
|
||||
VileSludge_Timer = 15000;
|
||||
} else VileSludge_Timer -= diff;
|
||||
|
||||
//PosCheck_Timer
|
||||
if (PosCheck_Timer <= diff)
|
||||
{
|
||||
if (me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
|
||||
//VileSludge_Timer
|
||||
if (VileSludge_Timer <= diff)
|
||||
{
|
||||
// switch to clean form
|
||||
me->SetDisplayId(MODEL_CLEAN);
|
||||
CorruptedForm = false;
|
||||
MarkOfHydross_Count = 0;
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_VILE_SLUDGE);
|
||||
|
||||
DoScriptText(SAY_SWITCH_TO_CLEAN, me);
|
||||
DoResetThreat();
|
||||
SummonBeams();
|
||||
VileSludge_Timer = 15000;
|
||||
} else VileSludge_Timer -= diff;
|
||||
|
||||
// spawn 4 adds
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
|
||||
}
|
||||
|
||||
PosCheck_Timer = 2500;
|
||||
} else PosCheck_Timer -=diff;
|
||||
}
|
||||
// clean form
|
||||
else
|
||||
{
|
||||
//MarkOfHydross_Timer
|
||||
if (MarkOfHydross_Timer <= diff)
|
||||
{
|
||||
if (MarkOfHydross_Count <= 5)
|
||||
//PosCheck_Timer
|
||||
if (PosCheck_Timer <= diff)
|
||||
{
|
||||
uint32 mark_spell = NULL;
|
||||
|
||||
switch(MarkOfHydross_Count)
|
||||
if (me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
|
||||
{
|
||||
case 0: mark_spell = SPELL_MARK_OF_HYDROSS1; break;
|
||||
case 1: mark_spell = SPELL_MARK_OF_HYDROSS2; break;
|
||||
case 2: mark_spell = SPELL_MARK_OF_HYDROSS3; break;
|
||||
case 3: mark_spell = SPELL_MARK_OF_HYDROSS4; break;
|
||||
case 4: mark_spell = SPELL_MARK_OF_HYDROSS5; break;
|
||||
case 5: mark_spell = SPELL_MARK_OF_HYDROSS6; break;
|
||||
// switch to clean form
|
||||
me->SetDisplayId(MODEL_CLEAN);
|
||||
CorruptedForm = false;
|
||||
MarkOfHydross_Count = 0;
|
||||
|
||||
DoScriptText(SAY_SWITCH_TO_CLEAN, me);
|
||||
DoResetThreat();
|
||||
SummonBeams();
|
||||
|
||||
// spawn 4 adds
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_PURE_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_FROST);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, false);
|
||||
}
|
||||
|
||||
DoCast(me->getVictim(), mark_spell);
|
||||
|
||||
if (MarkOfHydross_Count < 5)
|
||||
++MarkOfHydross_Count;
|
||||
}
|
||||
|
||||
MarkOfHydross_Timer = 15000;
|
||||
} else MarkOfHydross_Timer -= diff;
|
||||
|
||||
//WaterTomb_Timer
|
||||
if (WaterTomb_Timer <= diff)
|
||||
PosCheck_Timer = 2500;
|
||||
} else PosCheck_Timer -=diff;
|
||||
}
|
||||
// clean form
|
||||
else
|
||||
{
|
||||
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_WATER_TOMB);
|
||||
|
||||
WaterTomb_Timer = 7000;
|
||||
} else WaterTomb_Timer -= diff;
|
||||
|
||||
//PosCheck_Timer
|
||||
if (PosCheck_Timer <= diff)
|
||||
{
|
||||
if (!me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
|
||||
//MarkOfHydross_Timer
|
||||
if (MarkOfHydross_Timer <= diff)
|
||||
{
|
||||
// switch to corrupted form
|
||||
me->SetDisplayId(MODEL_CORRUPT);
|
||||
MarkOfCorruption_Count = 0;
|
||||
CorruptedForm = true;
|
||||
if (MarkOfHydross_Count <= 5)
|
||||
{
|
||||
uint32 mark_spell = NULL;
|
||||
|
||||
DoScriptText(SAY_SWITCH_TO_CORRUPT, me);
|
||||
DoResetThreat();
|
||||
DeSummonBeams();
|
||||
switch(MarkOfHydross_Count)
|
||||
{
|
||||
case 0: mark_spell = SPELL_MARK_OF_HYDROSS1; break;
|
||||
case 1: mark_spell = SPELL_MARK_OF_HYDROSS2; break;
|
||||
case 2: mark_spell = SPELL_MARK_OF_HYDROSS3; break;
|
||||
case 3: mark_spell = SPELL_MARK_OF_HYDROSS4; break;
|
||||
case 4: mark_spell = SPELL_MARK_OF_HYDROSS5; break;
|
||||
case 5: mark_spell = SPELL_MARK_OF_HYDROSS6; break;
|
||||
}
|
||||
|
||||
// spawn 4 adds
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoCast(me->getVictim(), mark_spell);
|
||||
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false);
|
||||
}
|
||||
if (MarkOfHydross_Count < 5)
|
||||
++MarkOfHydross_Count;
|
||||
}
|
||||
|
||||
PosCheck_Timer = 2500;
|
||||
} else PosCheck_Timer -=diff;
|
||||
MarkOfHydross_Timer = 15000;
|
||||
} else MarkOfHydross_Timer -= diff;
|
||||
|
||||
//WaterTomb_Timer
|
||||
if (WaterTomb_Timer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_WATER_TOMB);
|
||||
|
||||
WaterTomb_Timer = 7000;
|
||||
} else WaterTomb_Timer -= diff;
|
||||
|
||||
//PosCheck_Timer
|
||||
if (PosCheck_Timer <= diff)
|
||||
{
|
||||
if (!me->IsWithinDist2d(HYDROSS_X, HYDROSS_Y, SWITCH_RADIUS))
|
||||
{
|
||||
// switch to corrupted form
|
||||
me->SetDisplayId(MODEL_CORRUPT);
|
||||
MarkOfCorruption_Count = 0;
|
||||
CorruptedForm = true;
|
||||
|
||||
DoScriptText(SAY_SWITCH_TO_CORRUPT, me);
|
||||
DoResetThreat();
|
||||
DeSummonBeams();
|
||||
|
||||
// spawn 4 adds
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF1, SPAWN_Y_DIFF1, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF2, SPAWN_Y_DIFF2, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF3, SPAWN_Y_DIFF3, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
DoSpawnCreature(ENTRY_TAINTED_SPAWN, SPAWN_X_DIFF4, SPAWN_Y_DIFF4, 3, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
|
||||
me->SetMeleeDamageSchool(SPELL_SCHOOL_NATURE);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_NATURE, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FROST, false);
|
||||
}
|
||||
|
||||
PosCheck_Timer = 2500;
|
||||
} else PosCheck_Timer -=diff;
|
||||
}
|
||||
|
||||
//EnrageTimer
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
EnrageTimer = 60000;
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
//EnrageTimer
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
EnrageTimer = 60000;
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
CreatureAI* GetAI_boss_hydross_the_unstable(Creature* pCreature)
|
||||
{
|
||||
return new boss_hydross_the_unstableAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_hydross_the_unstable()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_hydross_the_unstable";
|
||||
newscript->GetAI = &GetAI_boss_hydross_the_unstable;
|
||||
newscript->RegisterSelf();
|
||||
new boss_hydross_the_unstable();
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+630
-621
File diff suppressed because it is too large
Load Diff
+368
-365
@@ -65,396 +65,399 @@ float AddPos[9][3] =
|
||||
{14.388216, -423.468018, -19.625271}, //MOVE_GUARDIAN_2 X, Y, Z
|
||||
{42.471519, -445.115295, -19.769423} //MOVE_GUARDIAN_3 X, Y, Z
|
||||
};
|
||||
|
||||
struct boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||
␍class boss_the_lurker_below : public CreatureScript
|
||||
{
|
||||
boss_the_lurker_belowAI(Creature *c) : Scripted_NoMovementAI(c), Summons(me)
|
||||
public:
|
||||
boss_the_lurker_below() : CreatureScript("boss_the_lurker_below") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
SpellEntry *TempSpell = GET_SPELL(SPELL_SPOUT_ANIM);
|
||||
if (TempSpell)
|
||||
return new boss_the_lurker_belowAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_the_lurker_belowAI : public Scripted_NoMovementAI
|
||||
{
|
||||
boss_the_lurker_belowAI(Creature *c) : Scripted_NoMovementAI(c), Summons(me)
|
||||
{
|
||||
TempSpell->Effect[0] = 0;//remove all spell effect, only anim is needed
|
||||
TempSpell->Effect[1] = 0;
|
||||
TempSpell->Effect[2] = 0;
|
||||
pInstance = c->GetInstanceScript();
|
||||
SpellEntry *TempSpell = GET_SPELL(SPELL_SPOUT_ANIM);
|
||||
if (TempSpell)
|
||||
{
|
||||
TempSpell->Effect[0] = 0;//remove all spell effect, only anim is needed
|
||||
TempSpell->Effect[1] = 0;
|
||||
TempSpell->Effect[2] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
SummonList Summons;
|
||||
InstanceScript* pInstance;
|
||||
SummonList Summons;
|
||||
|
||||
bool Spawned;
|
||||
bool Submerged;
|
||||
bool InRange;
|
||||
bool CanStartEvent;
|
||||
uint32 RotTimer;
|
||||
uint32 SpoutAnimTimer;
|
||||
uint32 WaterboltTimer;
|
||||
uint32 SpoutTimer;
|
||||
uint32 WhirlTimer;
|
||||
uint32 PhaseTimer;
|
||||
uint32 GeyserTimer;
|
||||
uint32 CheckTimer;
|
||||
uint32 WaitTimer;
|
||||
uint32 WaitTimer2;
|
||||
bool Spawned;
|
||||
bool Submerged;
|
||||
bool InRange;
|
||||
bool CanStartEvent;
|
||||
uint32 RotTimer;
|
||||
uint32 SpoutAnimTimer;
|
||||
uint32 WaterboltTimer;
|
||||
uint32 SpoutTimer;
|
||||
uint32 WhirlTimer;
|
||||
uint32 PhaseTimer;
|
||||
uint32 GeyserTimer;
|
||||
uint32 CheckTimer;
|
||||
uint32 WaitTimer;
|
||||
uint32 WaitTimer2;
|
||||
|
||||
bool CheckCanStart()//check if players fished
|
||||
{
|
||||
if (pInstance && pInstance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
void Reset()
|
||||
{
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
|
||||
SpoutAnimTimer = 1000;
|
||||
RotTimer = 0;
|
||||
WaterboltTimer = 15000;//give time to get in range when fight starts
|
||||
SpoutTimer = 45000;
|
||||
WhirlTimer = 18000;//after avery spout
|
||||
PhaseTimer = 120000;
|
||||
GeyserTimer = rand()%5000 + 15000;
|
||||
CheckTimer = 15000;//give time to get in range when fight starts
|
||||
WaitTimer = 60000;//never reached
|
||||
WaitTimer2 = 60000;//never reached
|
||||
|
||||
Submerged = true;//will be false at combat start
|
||||
Spawned = false;
|
||||
InRange = false;
|
||||
CanStartEvent = false;
|
||||
|
||||
Summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
bool CheckCanStart()//check if players fished
|
||||
{
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, NOT_STARTED);
|
||||
pInstance->SetData(DATA_STRANGE_POOL, NOT_STARTED);
|
||||
if (pInstance && pInstance->GetData(DATA_STRANGE_POOL) == NOT_STARTED)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
DoCast(me, SPELL_SUBMERGE);//submerge anim
|
||||
me->SetVisibility(VISIBILITY_OFF);//we start invis under water, submerged
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, DONE);
|
||||
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * who)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS);
|
||||
Scripted_NoMovementAI::EnterCombat(who);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!CanStartEvent)//boss is invisible, don't attack
|
||||
return;
|
||||
if (!me->getVictim() && who->isTargetableForAttack() && (me->IsHostileTo(who)))
|
||||
void Reset()
|
||||
{
|
||||
float attackRadius = me->GetAttackDistance(who);
|
||||
if (me->IsWithinDistInMap(who, attackRadius))
|
||||
me->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
|
||||
SpoutAnimTimer = 1000;
|
||||
RotTimer = 0;
|
||||
WaterboltTimer = 15000;//give time to get in range when fight starts
|
||||
SpoutTimer = 45000;
|
||||
WhirlTimer = 18000;//after avery spout
|
||||
PhaseTimer = 120000;
|
||||
GeyserTimer = rand()%5000 + 15000;
|
||||
CheckTimer = 15000;//give time to get in range when fight starts
|
||||
WaitTimer = 60000;//never reached
|
||||
WaitTimer2 = 60000;//never reached
|
||||
|
||||
Submerged = true;//will be false at combat start
|
||||
Spawned = false;
|
||||
InRange = false;
|
||||
CanStartEvent = false;
|
||||
|
||||
Summons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, NOT_STARTED);
|
||||
pInstance->SetData(DATA_STRANGE_POOL, NOT_STARTED);
|
||||
}
|
||||
DoCast(me, SPELL_SUBMERGE);//submerge anim
|
||||
me->SetVisibility(VISIBILITY_OFF);//we start invis under water, submerged
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, DONE);
|
||||
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * who)
|
||||
{
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_THELURKERBELOWEVENT, IN_PROGRESS);
|
||||
Scripted_NoMovementAI::EnterCombat(who);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!CanStartEvent)//boss is invisible, don't attack
|
||||
return;
|
||||
if (!me->getVictim() && who->isTargetableForAttack() && (me->IsHostileTo(who)))
|
||||
{
|
||||
float attackRadius = me->GetAttackDistance(who);
|
||||
if (me->IsWithinDistInMap(who, attackRadius))
|
||||
{
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/)
|
||||
{
|
||||
if (type == ROTATE_MOTION_TYPE)
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!CanStartEvent)//boss is invisible, don't attack
|
||||
{
|
||||
if (CheckCanStart())
|
||||
{
|
||||
if (Submerged)
|
||||
{
|
||||
me->SetVisibility(VISIBILITY_ON);
|
||||
Submerged = false;
|
||||
WaitTimer2 = 500;
|
||||
}
|
||||
if (!Submerged && WaitTimer2 <= diff)//wait 500ms before emerge anim
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||
DoCast(me, SPELL_EMERGE, false);
|
||||
WaitTimer2 = 60000;//never reached
|
||||
WaitTimer = 3000;
|
||||
} else WaitTimer2 -= diff;
|
||||
|
||||
if (WaitTimer <= diff)//wait 3secs for emerge anim, then attack
|
||||
{
|
||||
WaitTimer = 3000;
|
||||
CanStartEvent=true;//fresh fished from pool
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
} else WaitTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->getThreatManager().getThreatList().empty())//check if should evade
|
||||
{
|
||||
if (me->isInCombat())
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (!Submerged)
|
||||
{
|
||||
if (PhaseTimer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_SUBMERGE);
|
||||
PhaseTimer = 60000;//60secs submerged
|
||||
Submerged = true;
|
||||
} else PhaseTimer-=diff;
|
||||
|
||||
if (SpoutTimer <= diff)
|
||||
{
|
||||
me->MonsterTextEmote(EMOTE_SPOUT,0,true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MoveRotate(20000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
|
||||
SpoutTimer = 45000;
|
||||
WhirlTimer = 20000;//whirl directly after spout
|
||||
RotTimer = 20000;
|
||||
return;
|
||||
} else SpoutTimer -= diff;
|
||||
|
||||
//Whirl directly after a Spout and at random times
|
||||
if (WhirlTimer <= diff)
|
||||
{
|
||||
WhirlTimer = 18000;
|
||||
DoCast(me, SPELL_WHIRL);
|
||||
} else WhirlTimer -= diff;
|
||||
|
||||
if (CheckTimer <= diff)//check if there are players in melee range
|
||||
{
|
||||
InRange = false;
|
||||
Map* pMap = me->GetMap();
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (me->IsWithinMeleeRange(i->getSource()))
|
||||
InRange = true;
|
||||
}
|
||||
}
|
||||
CheckTimer = 2000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
if (RotTimer)
|
||||
{
|
||||
Map* pMap = me->GetMap();
|
||||
if (pMap->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (i->getSource() && i->getSource()->isAlive() && me->HasInArc((double)diff/20000*(double)M_PI*2,i->getSource()) && me->IsWithinDist(i->getSource(), SPOUT_DIST) && !i->getSource()->IsInWater())
|
||||
DoCast(i->getSource(), SPELL_SPOUT, true);//only knock back palyers in arc, in 100yards, not in water
|
||||
}
|
||||
}
|
||||
|
||||
if (SpoutAnimTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SPOUT_ANIM, true);
|
||||
SpoutAnimTimer = 1000;
|
||||
} else SpoutAnimTimer -= diff;
|
||||
|
||||
if (RotTimer <= diff)
|
||||
{
|
||||
RotTimer = 0;
|
||||
} else RotTimer -= diff;
|
||||
return;
|
||||
}
|
||||
|
||||
if (GeyserTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);
|
||||
if (!pTarget && me->getVictim())
|
||||
pTarget = me->getVictim();
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_GEYSER, true);
|
||||
GeyserTimer = rand()%5000 + 15000;
|
||||
} else GeyserTimer -= diff;
|
||||
|
||||
if (!InRange)//if on players in melee range cast Waterbolt
|
||||
{
|
||||
if (WaterboltTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
|
||||
if (!pTarget && me->getVictim())
|
||||
pTarget = me->getVictim();
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_WATERBOLT, true);
|
||||
WaterboltTimer = 3000;
|
||||
} else WaterboltTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateCombatState())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
}else//submerged
|
||||
{
|
||||
if (PhaseTimer <= diff)
|
||||
{
|
||||
Submerged = false;
|
||||
me->InterruptNonMeleeSpells(false);//shouldn't be any
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||
DoCast(me, SPELL_EMERGE, true);
|
||||
Spawned = false;
|
||||
SpoutTimer = 3000; // directly cast Spout after emerging!
|
||||
PhaseTimer = 120000;
|
||||
return;
|
||||
} else PhaseTimer-=diff;
|
||||
|
||||
if (me->getThreatManager().getThreatList().empty())//check if should evade
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (!me->isInCombat())
|
||||
DoZoneInCombat();
|
||||
|
||||
if (!Spawned)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
//spawn adds
|
||||
for (uint8 i = 0; i < 9; ++i)
|
||||
{
|
||||
Creature* Summoned;
|
||||
if (i < 6)
|
||||
Summoned = me->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
else Summoned = me->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
|
||||
if (Summoned)
|
||||
Summons.Summon(Summoned);
|
||||
}
|
||||
Spawned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
␍class mob_coilfang_guardian : public CreatureScript
|
||||
{
|
||||
public:
|
||||
mob_coilfang_guardian() : CreatureScript("mob_coilfang_guardian") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
SimpleAI* ai = new SimpleAI (pCreature);
|
||||
|
||||
ai->Spell[0].Enabled = true;
|
||||
ai->Spell[0].Spell_Id = SPELL_ARCINGSMASH;
|
||||
ai->Spell[0].Cooldown = 15000;
|
||||
ai->Spell[0].First_Cast = 5000;
|
||||
ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET;
|
||||
|
||||
ai->Spell[1].Enabled = true;
|
||||
ai->Spell[1].Spell_Id = SPELL_HAMSTRING;
|
||||
ai->Spell[1].Cooldown = 10000;
|
||||
ai->Spell[1].First_Cast = 2000;
|
||||
ai->Spell[1].Cast_Target_Type = CAST_HOSTILE_TARGET;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
};
|
||||
␍class mob_coilfang_ambusher : public CreatureScript
|
||||
{
|
||||
public:
|
||||
mob_coilfang_ambusher() : CreatureScript("mob_coilfang_ambusher") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new mob_coilfang_ambusherAI (pCreature);
|
||||
}
|
||||
|
||||
struct mob_coilfang_ambusherAI : public Scripted_NoMovementAI
|
||||
{
|
||||
mob_coilfang_ambusherAI(Creature *c) : Scripted_NoMovementAI(c)
|
||||
{
|
||||
SpellEntry *TempSpell = GET_SPELL(SPELL_SHOOT);
|
||||
if (TempSpell)
|
||||
TempSpell->Effect[0] = 2;//change spell effect from weapon % dmg to simple phisical dmg
|
||||
}
|
||||
|
||||
uint32 MultiShotTimer;
|
||||
uint32 ShootBowTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MultiShotTimer = 10000;
|
||||
ShootBowTimer = 4000;
|
||||
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!who || me->getVictim()) return;
|
||||
|
||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me) && me->IsHostileTo(who) && me->IsWithinDistInMap(who, 45))
|
||||
{
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 /*id*/)
|
||||
{
|
||||
if (type == ROTATE_MOTION_TYPE)
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!CanStartEvent)//boss is invisible, don't attack
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (CheckCanStart())
|
||||
if (MultiShotTimer <= diff)
|
||||
{
|
||||
if (Submerged)
|
||||
{
|
||||
me->SetVisibility(VISIBILITY_ON);
|
||||
Submerged = false;
|
||||
WaitTimer2 = 500;
|
||||
}
|
||||
if (!Submerged && WaitTimer2 <= diff)//wait 500ms before emerge anim
|
||||
{
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||
DoCast(me, SPELL_EMERGE, false);
|
||||
WaitTimer2 = 60000;//never reached
|
||||
WaitTimer = 3000;
|
||||
} else WaitTimer2 -= diff;
|
||||
if (me->getVictim())
|
||||
DoCast(me->getVictim(), SPELL_SPREAD_SHOT, true);
|
||||
|
||||
if (WaitTimer <= diff)//wait 3secs for emerge anim, then attack
|
||||
{
|
||||
WaitTimer = 3000;
|
||||
CanStartEvent=true;//fresh fished from pool
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
} else WaitTimer -= diff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
MultiShotTimer = 10000+rand()%10000;
|
||||
ShootBowTimer += 1500;//add global cooldown
|
||||
} else MultiShotTimer -= diff;
|
||||
|
||||
if (me->getThreatManager().getThreatList().empty())//check if should evade
|
||||
{
|
||||
if (me->isInCombat())
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (!Submerged)
|
||||
{
|
||||
if (PhaseTimer <= diff)
|
||||
if (ShootBowTimer <= diff)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_SUBMERGE);
|
||||
PhaseTimer = 60000;//60secs submerged
|
||||
Submerged = true;
|
||||
} else PhaseTimer-=diff;
|
||||
|
||||
if (SpoutTimer <= diff)
|
||||
{
|
||||
me->MonsterTextEmote(EMOTE_SPOUT,0,true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MoveRotate(20000, rand()%2 ? ROTATE_DIRECTION_LEFT : ROTATE_DIRECTION_RIGHT);
|
||||
SpoutTimer = 45000;
|
||||
WhirlTimer = 20000;//whirl directly after spout
|
||||
RotTimer = 20000;
|
||||
return;
|
||||
} else SpoutTimer -= diff;
|
||||
|
||||
//Whirl directly after a Spout and at random times
|
||||
if (WhirlTimer <= diff)
|
||||
{
|
||||
WhirlTimer = 18000;
|
||||
DoCast(me, SPELL_WHIRL);
|
||||
} else WhirlTimer -= diff;
|
||||
|
||||
if (CheckTimer <= diff)//check if there are players in melee range
|
||||
{
|
||||
InRange = false;
|
||||
Map* pMap = me->GetMap();
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (me->IsWithinMeleeRange(i->getSource()))
|
||||
InRange = true;
|
||||
}
|
||||
}
|
||||
CheckTimer = 2000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
if (RotTimer)
|
||||
{
|
||||
Map* pMap = me->GetMap();
|
||||
if (pMap->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (i->getSource() && i->getSource()->isAlive() && me->HasInArc((double)diff/20000*(double)M_PI*2,i->getSource()) && me->IsWithinDist(i->getSource(), SPOUT_DIST) && !i->getSource()->IsInWater())
|
||||
DoCast(i->getSource(), SPELL_SPOUT, true);//only knock back palyers in arc, in 100yards, not in water
|
||||
}
|
||||
}
|
||||
|
||||
if (SpoutAnimTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SPOUT_ANIM, true);
|
||||
SpoutAnimTimer = 1000;
|
||||
} else SpoutAnimTimer -= diff;
|
||||
|
||||
if (RotTimer <= diff)
|
||||
{
|
||||
RotTimer = 0;
|
||||
} else RotTimer -= diff;
|
||||
return;
|
||||
}
|
||||
|
||||
if (GeyserTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1);
|
||||
if (!pTarget && me->getVictim())
|
||||
pTarget = me->getVictim();
|
||||
Unit *pTarget = NULL;
|
||||
pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
int bp0 = 1100;
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_GEYSER, true);
|
||||
GeyserTimer = rand()%5000 + 15000;
|
||||
} else GeyserTimer -= diff;
|
||||
|
||||
if (!InRange)//if on players in melee range cast Waterbolt
|
||||
{
|
||||
if (WaterboltTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0);
|
||||
if (!pTarget && me->getVictim())
|
||||
pTarget = me->getVictim();
|
||||
if (pTarget)
|
||||
DoCast(pTarget, SPELL_WATERBOLT, true);
|
||||
WaterboltTimer = 3000;
|
||||
} else WaterboltTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateCombatState())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
}else//submerged
|
||||
{
|
||||
if (PhaseTimer <= diff)
|
||||
{
|
||||
Submerged = false;
|
||||
me->InterruptNonMeleeSpells(false);//shouldn't be any
|
||||
me->RemoveAllAuras();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
me->RemoveFlag(UNIT_NPC_EMOTESTATE,EMOTE_STATE_SUBMERGED);
|
||||
DoCast(me, SPELL_EMERGE, true);
|
||||
Spawned = false;
|
||||
SpoutTimer = 3000; // directly cast Spout after emerging!
|
||||
PhaseTimer = 120000;
|
||||
return;
|
||||
} else PhaseTimer-=diff;
|
||||
|
||||
if (me->getThreatManager().getThreatList().empty())//check if should evade
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
if (!me->isInCombat())
|
||||
DoZoneInCombat();
|
||||
|
||||
if (!Spawned)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
|
||||
//spawn adds
|
||||
for (uint8 i = 0; i < 9; ++i)
|
||||
{
|
||||
Creature* Summoned;
|
||||
if (i < 6)
|
||||
Summoned = me->SummonCreature(MOB_COILFANG_AMBUSHER,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
else Summoned = me->SummonCreature(MOB_COILFANG_GUARDIAN,AddPos[i][0],AddPos[i][1],AddPos[i][2], 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
|
||||
|
||||
if (Summoned)
|
||||
Summons.Summon(Summoned);
|
||||
}
|
||||
Spawned = true;
|
||||
}
|
||||
me->CastCustomSpell(pTarget,SPELL_SHOOT,&bp0,NULL,NULL,true);
|
||||
ShootBowTimer = 4000+rand()%5000;
|
||||
MultiShotTimer += 1500;//add global cooldown
|
||||
} else ShootBowTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_coilfang_guardian(Creature* pCreature)
|
||||
{
|
||||
SimpleAI* ai = new SimpleAI (pCreature);
|
||||
|
||||
ai->Spell[0].Enabled = true;
|
||||
ai->Spell[0].Spell_Id = SPELL_ARCINGSMASH;
|
||||
ai->Spell[0].Cooldown = 15000;
|
||||
ai->Spell[0].First_Cast = 5000;
|
||||
ai->Spell[0].Cast_Target_Type = CAST_HOSTILE_TARGET;
|
||||
|
||||
ai->Spell[1].Enabled = true;
|
||||
ai->Spell[1].Spell_Id = SPELL_HAMSTRING;
|
||||
ai->Spell[1].Cooldown = 10000;
|
||||
ai->Spell[1].First_Cast = 2000;
|
||||
ai->Spell[1].Cast_Target_Type = CAST_HOSTILE_TARGET;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
struct mob_coilfang_ambusherAI : public Scripted_NoMovementAI
|
||||
{
|
||||
mob_coilfang_ambusherAI(Creature *c) : Scripted_NoMovementAI(c)
|
||||
{
|
||||
SpellEntry *TempSpell = GET_SPELL(SPELL_SHOOT);
|
||||
if (TempSpell)
|
||||
TempSpell->Effect[0] = 2;//change spell effect from weapon % dmg to simple phisical dmg
|
||||
}
|
||||
|
||||
uint32 MultiShotTimer;
|
||||
uint32 ShootBowTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
MultiShotTimer = 10000;
|
||||
ShootBowTimer = 4000;
|
||||
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (!who || me->getVictim()) return;
|
||||
|
||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me) && me->IsHostileTo(who) && me->IsWithinDistInMap(who, 45))
|
||||
{
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (MultiShotTimer <= diff)
|
||||
{
|
||||
if (me->getVictim())
|
||||
DoCast(me->getVictim(), SPELL_SPREAD_SHOT, true);
|
||||
|
||||
MultiShotTimer = 10000+rand()%10000;
|
||||
ShootBowTimer += 1500;//add global cooldown
|
||||
} else MultiShotTimer -= diff;
|
||||
|
||||
if (ShootBowTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = NULL;
|
||||
pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
int bp0 = 1100;
|
||||
if (pTarget)
|
||||
me->CastCustomSpell(pTarget,SPELL_SHOOT,&bp0,NULL,NULL,true);
|
||||
ShootBowTimer = 4000+rand()%5000;
|
||||
MultiShotTimer += 1500;//add global cooldown
|
||||
} else ShootBowTimer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_coilfang_ambusher(Creature* pCreature)
|
||||
{
|
||||
return new mob_coilfang_ambusherAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_the_lurker_below(Creature* pCreature)
|
||||
{
|
||||
return new boss_the_lurker_belowAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_the_lurker_below()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_the_lurker_below";
|
||||
newscript->GetAI = &GetAI_boss_the_lurker_below;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_coilfang_guardian";
|
||||
newscript->GetAI = &GetAI_mob_coilfang_guardian;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_coilfang_ambusher";
|
||||
newscript->GetAI = &GetAI_mob_coilfang_ambusher;
|
||||
newscript->RegisterSelf();
|
||||
new boss_the_lurker_below();
|
||||
new mob_coilfang_guardian();
|
||||
new mob_coilfang_ambusher();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+233
-229
@@ -97,274 +97,278 @@ float MurlocCords[10][5] =
|
||||
#define WATER_GLOBULE 21913
|
||||
#define TIDEWALKER_LURKER 21920
|
||||
|
||||
//Morogrim Tidewalker AI
|
||||
struct boss_morogrim_tidewalkerAI : public ScriptedAI
|
||||
//Morogrim Tidewalker AI␍class boss_morogrim_tidewalker : public CreatureScript
|
||||
{
|
||||
boss_morogrim_tidewalkerAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
boss_morogrim_tidewalker() : CreatureScript("boss_morogrim_tidewalker") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new boss_morogrim_tidewalkerAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
Map::PlayerList const *PlayerList;
|
||||
|
||||
uint32 TidalWave_Timer;
|
||||
uint32 WateryGrave_Timer;
|
||||
uint32 Earthquake_Timer;
|
||||
uint32 WateryGlobules_Timer;
|
||||
uint32 globulespell[4];
|
||||
int8 Playercount;
|
||||
int8 counter;
|
||||
|
||||
bool Earthquake;
|
||||
bool Phase2;
|
||||
|
||||
void Reset()
|
||||
struct boss_morogrim_tidewalkerAI : public ScriptedAI
|
||||
{
|
||||
TidalWave_Timer = 10000;
|
||||
WateryGrave_Timer = 30000;
|
||||
Earthquake_Timer = 40000;
|
||||
WateryGlobules_Timer = 0;
|
||||
globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1;
|
||||
globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2;
|
||||
globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3;
|
||||
globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4;
|
||||
|
||||
Earthquake = false;
|
||||
Phase2 = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me);
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*victim*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, DONE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
PlayerList = &me->GetMap()->GetPlayers();
|
||||
Playercount = PlayerList->getSize();
|
||||
StartEvent();
|
||||
}
|
||||
|
||||
void ApplyWateryGrave(Unit* pPlayer, uint8 i)
|
||||
{
|
||||
switch(i)
|
||||
boss_morogrim_tidewalkerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
case 0: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_1, true); break;
|
||||
case 1: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_2, true); break;
|
||||
case 2: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_3, true); break;
|
||||
case 3: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_4, true); break;
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
InstanceScript* pInstance;
|
||||
|
||||
//Earthquake_Timer
|
||||
if (Earthquake_Timer <= diff)
|
||||
Map::PlayerList const *PlayerList;
|
||||
|
||||
uint32 TidalWave_Timer;
|
||||
uint32 WateryGrave_Timer;
|
||||
uint32 Earthquake_Timer;
|
||||
uint32 WateryGlobules_Timer;
|
||||
uint32 globulespell[4];
|
||||
int8 Playercount;
|
||||
int8 counter;
|
||||
|
||||
bool Earthquake;
|
||||
bool Phase2;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!Earthquake)
|
||||
TidalWave_Timer = 10000;
|
||||
WateryGrave_Timer = 30000;
|
||||
Earthquake_Timer = 40000;
|
||||
WateryGlobules_Timer = 0;
|
||||
globulespell[0] = SPELL_SUMMON_WATER_GLOBULE_1;
|
||||
globulespell[1] = SPELL_SUMMON_WATER_GLOBULE_2;
|
||||
globulespell[2] = SPELL_SUMMON_WATER_GLOBULE_3;
|
||||
globulespell[3] = SPELL_SUMMON_WATER_GLOBULE_4;
|
||||
|
||||
Earthquake = false;
|
||||
Phase2 = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void StartEvent()
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit * /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2,SAY_SLAY3), me);
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*victim*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MOROGRIMTIDEWALKEREVENT, DONE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
PlayerList = &me->GetMap()->GetPlayers();
|
||||
Playercount = PlayerList->getSize();
|
||||
StartEvent();
|
||||
}
|
||||
|
||||
void ApplyWateryGrave(Unit* pPlayer, uint8 i)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_EARTHQUAKE);
|
||||
Earthquake = true;
|
||||
Earthquake_Timer = 10000;
|
||||
case 0: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_1, true); break;
|
||||
case 1: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_2, true); break;
|
||||
case 2: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_3, true); break;
|
||||
case 3: pPlayer->CastSpell(pPlayer, SPELL_WATERY_GRAVE_4, true); break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Earthquake_Timer
|
||||
if (Earthquake_Timer <= diff)
|
||||
{
|
||||
if (!Earthquake)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_EARTHQUAKE);
|
||||
Earthquake = true;
|
||||
Earthquake_Timer = 10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoScriptText(RAND(SAY_SUMMON1,SAY_SUMMON2), me);
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
Creature* Murloc = me->SummonCreature(MurlocCords[i][0],MurlocCords[i][1],MurlocCords[i][2],MurlocCords[i][3],MurlocCords[i][4], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
|
||||
if (pTarget && Murloc)
|
||||
Murloc->AI()->AttackStart(pTarget);
|
||||
}
|
||||
DoScriptText(EMOTE_EARTHQUAKE, me);
|
||||
Earthquake = false;
|
||||
Earthquake_Timer = 40000+rand()%5000;
|
||||
}
|
||||
} else Earthquake_Timer -= diff;
|
||||
|
||||
//TidalWave_Timer
|
||||
if (TidalWave_Timer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_TIDAL_WAVE);
|
||||
TidalWave_Timer = 20000;
|
||||
} else TidalWave_Timer -= diff;
|
||||
|
||||
if (!Phase2)
|
||||
{
|
||||
//WateryGrave_Timer
|
||||
if (WateryGrave_Timer <= diff)
|
||||
{
|
||||
//Teleport 4 players under the waterfalls
|
||||
Unit *pTarget;
|
||||
std::set<uint64> list;
|
||||
std::set<uint64>::const_iterator itr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
counter = 0;
|
||||
do
|
||||
{
|
||||
pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only
|
||||
if (counter < Playercount)
|
||||
break;
|
||||
if (pTarget)
|
||||
itr = list.find(pTarget->GetGUID());
|
||||
++counter;
|
||||
} while (itr != list.end());
|
||||
|
||||
if (pTarget)
|
||||
{
|
||||
list.insert(pTarget->GetGUID());
|
||||
ApplyWateryGrave(pTarget, i);
|
||||
}
|
||||
}
|
||||
|
||||
DoScriptText(RAND(SAY_SUMMON_BUBL1,SAY_SUMMON_BUBL2), me);
|
||||
|
||||
DoScriptText(EMOTE_WATERY_GRAVE, me);
|
||||
WateryGrave_Timer = 30000;
|
||||
} else WateryGrave_Timer -= diff;
|
||||
|
||||
//Start Phase2
|
||||
if (HealthBelowPct(25))
|
||||
Phase2 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DoScriptText(RAND(SAY_SUMMON1,SAY_SUMMON2), me);
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
//WateryGlobules_Timer
|
||||
if (WateryGlobules_Timer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
Creature* Murloc = me->SummonCreature(MurlocCords[i][0],MurlocCords[i][1],MurlocCords[i][2],MurlocCords[i][3],MurlocCords[i][4], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
|
||||
if (pTarget && Murloc)
|
||||
Murloc->AI()->AttackStart(pTarget);
|
||||
}
|
||||
DoScriptText(EMOTE_EARTHQUAKE, me);
|
||||
Earthquake = false;
|
||||
Earthquake_Timer = 40000+rand()%5000;
|
||||
}
|
||||
} else Earthquake_Timer -= diff;
|
||||
|
||||
//TidalWave_Timer
|
||||
if (TidalWave_Timer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_TIDAL_WAVE);
|
||||
TidalWave_Timer = 20000;
|
||||
} else TidalWave_Timer -= diff;
|
||||
|
||||
if (!Phase2)
|
||||
{
|
||||
//WateryGrave_Timer
|
||||
if (WateryGrave_Timer <= diff)
|
||||
{
|
||||
//Teleport 4 players under the waterfalls
|
||||
Unit *pTarget;
|
||||
std::set<uint64> list;
|
||||
std::set<uint64>::const_iterator itr;
|
||||
for (uint8 i = 0; i < 4; ++i)
|
||||
{
|
||||
counter = 0;
|
||||
do
|
||||
Unit* pGlobuleTarget;
|
||||
std::set<uint64> globulelist;
|
||||
std::set<uint64>::const_iterator itr;
|
||||
for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD
|
||||
{
|
||||
pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 50, true); //target players only
|
||||
if (counter < Playercount)
|
||||
break;
|
||||
if (pTarget)
|
||||
itr = list.find(pTarget->GetGUID());
|
||||
++counter;
|
||||
} while (itr != list.end());
|
||||
|
||||
if (pTarget)
|
||||
{
|
||||
list.insert(pTarget->GetGUID());
|
||||
ApplyWateryGrave(pTarget, i);
|
||||
}
|
||||
}
|
||||
|
||||
DoScriptText(RAND(SAY_SUMMON_BUBL1,SAY_SUMMON_BUBL2), me);
|
||||
|
||||
DoScriptText(EMOTE_WATERY_GRAVE, me);
|
||||
WateryGrave_Timer = 30000;
|
||||
} else WateryGrave_Timer -= diff;
|
||||
|
||||
//Start Phase2
|
||||
if (HealthBelowPct(25))
|
||||
Phase2 = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//WateryGlobules_Timer
|
||||
if (WateryGlobules_Timer <= diff)
|
||||
{
|
||||
Unit* pGlobuleTarget;
|
||||
std::set<uint64> globulelist;
|
||||
std::set<uint64>::const_iterator itr;
|
||||
for (uint8 g = 0; g < 4; g++) //one unit can't cast more than one spell per update, so some players have to cast for us XD
|
||||
{
|
||||
counter = 0;
|
||||
do
|
||||
{
|
||||
pGlobuleTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
|
||||
counter = 0;
|
||||
do
|
||||
{
|
||||
pGlobuleTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
|
||||
if (pGlobuleTarget)
|
||||
itr = globulelist.find(pGlobuleTarget->GetGUID());
|
||||
if (counter > Playercount)
|
||||
break;
|
||||
++counter;
|
||||
} while (itr != globulelist.end());
|
||||
if (pGlobuleTarget)
|
||||
itr = globulelist.find(pGlobuleTarget->GetGUID());
|
||||
if (counter > Playercount)
|
||||
break;
|
||||
++counter;
|
||||
} while (itr != globulelist.end());
|
||||
if (pGlobuleTarget)
|
||||
globulelist.insert(pGlobuleTarget->GetGUID());
|
||||
pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
|
||||
}
|
||||
DoScriptText(EMOTE_WATERY_GLOBULES, me);
|
||||
WateryGlobules_Timer = 25000;
|
||||
} else WateryGlobules_Timer -= diff;
|
||||
}
|
||||
globulelist.insert(pGlobuleTarget->GetGUID());
|
||||
pGlobuleTarget->CastSpell(pGlobuleTarget, globulespell[g], true);
|
||||
}
|
||||
DoScriptText(EMOTE_WATERY_GLOBULES, me);
|
||||
WateryGlobules_Timer = 25000;
|
||||
} else WateryGlobules_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
//Water Globule AI
|
||||
#define SPELL_GLOBULE_EXPLOSION 37871
|
||||
|
||||
struct mob_water_globuleAI : public ScriptedAI
|
||||
␍class mob_water_globule : public CreatureScript
|
||||
{
|
||||
mob_water_globuleAI(Creature *c) : ScriptedAI(c) {}
|
||||
public:
|
||||
mob_water_globule() : CreatureScript("mob_water_globule") { }
|
||||
|
||||
uint32 Check_Timer;
|
||||
|
||||
void Reset()
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
Check_Timer = 1000;
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(14);
|
||||
return new mob_water_globuleAI (pCreature);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) {}
|
||||
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
struct mob_water_globuleAI : public ScriptedAI
|
||||
{
|
||||
if (!who || me->getVictim())
|
||||
return;
|
||||
mob_water_globuleAI(Creature *c) : ScriptedAI(c) {}
|
||||
|
||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me) && me->IsHostileTo(who))
|
||||
uint32 Check_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
//no attack radius check - it attacks the first target that moves in his los
|
||||
//who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(who);
|
||||
Check_Timer = 1000;
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->setFaction(14);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
void EnterCombat(Unit * /*who*/) {}
|
||||
|
||||
if (Check_Timer <= diff)
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if (me->IsWithinDistInMap(me->getVictim(), 5))
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_GLOBULE_EXPLOSION);
|
||||
|
||||
//despawn
|
||||
me->ForcedDespawn();
|
||||
if (!who || me->getVictim())
|
||||
return;
|
||||
}
|
||||
Check_Timer = 500;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
//do NOT deal any melee damage to the target.
|
||||
}
|
||||
if (who->isTargetableForAttack() && who->isInAccessiblePlaceFor(me) && me->IsHostileTo(who))
|
||||
{
|
||||
//no attack radius check - it attacks the first target that moves in his los
|
||||
//who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
|
||||
AttackStart(who);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Check_Timer <= diff)
|
||||
{
|
||||
if (me->IsWithinDistInMap(me->getVictim(), 5))
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_GLOBULE_EXPLOSION);
|
||||
|
||||
//despawn
|
||||
me->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
Check_Timer = 500;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
//do NOT deal any melee damage to the target.
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_morogrim_tidewalker(Creature* pCreature)
|
||||
{
|
||||
return new boss_morogrim_tidewalkerAI (pCreature);
|
||||
}
|
||||
CreatureAI* GetAI_mob_water_globule(Creature* pCreature)
|
||||
{
|
||||
return new mob_water_globuleAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_morogrim_tidewalker()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_morogrim_tidewalker";
|
||||
newscript->GetAI = &GetAI_boss_morogrim_tidewalker;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_water_globule";
|
||||
newscript->GetAI = &GetAI_mob_water_globule;
|
||||
newscript->RegisterSelf();
|
||||
new boss_morogrim_tidewalker();
|
||||
new mob_water_globule();
|
||||
}
|
||||
|
||||
|
||||
+309
-306
@@ -46,355 +46,358 @@ EndScriptData */
|
||||
4 - Morogrim Tidewalker Event
|
||||
5 - Lady Vashj Event
|
||||
*/
|
||||
|
||||
bool GOHello_go_bridge_console(Player* /*pPlayer*/, GameObject* pGo)
|
||||
␍class go_bridge_console : public GameObjectScript
|
||||
{
|
||||
ScriptedInstance* pInstance = pGo->GetInstanceData();
|
||||
public:
|
||||
go_bridge_console() : GameObjectScript("go_bridge_console") { }
|
||||
|
||||
if (!pInstance)
|
||||
return false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_CONTROL_CONSOLE, DONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct instance_serpentshrine_cavern : public ScriptedInstance
|
||||
{
|
||||
instance_serpentshrine_cavern(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
|
||||
|
||||
uint64 LurkerBelow;
|
||||
uint64 Sharkkis;
|
||||
uint64 Tidalvess;
|
||||
uint64 Caribdis;
|
||||
uint64 LadyVashj;
|
||||
uint64 Karathress;
|
||||
uint64 KarathressEvent_Starter;
|
||||
uint64 LeotherasTheBlind;
|
||||
uint64 LeotherasEventStarter;
|
||||
|
||||
uint64 ControlConsole;
|
||||
uint64 BridgePart[3];
|
||||
uint32 StrangePool;
|
||||
uint32 FishingTimer;
|
||||
uint32 LurkerSubEvent;
|
||||
uint32 WaterCheckTimer;
|
||||
uint32 FrenzySpawnTimer;
|
||||
uint32 Water;
|
||||
uint32 TrashCount;
|
||||
|
||||
bool ShieldGeneratorDeactivated[4];
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
bool DoSpawnFrenzy;
|
||||
|
||||
void Initialize()
|
||||
bool OnGossipHello(Player* /*pPlayer*/, GameObject* pGo)
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
InstanceScript* pInstance = pGo->GetInstanceScript();
|
||||
|
||||
LurkerBelow = 0;
|
||||
Sharkkis = 0;
|
||||
Tidalvess = 0;
|
||||
Caribdis = 0;
|
||||
LadyVashj = 0;
|
||||
Karathress = 0;
|
||||
KarathressEvent_Starter = 0;
|
||||
LeotherasTheBlind = 0;
|
||||
LeotherasEventStarter = 0;
|
||||
if (!pInstance)
|
||||
return false;
|
||||
|
||||
ControlConsole = 0;
|
||||
BridgePart[0] = 0;
|
||||
BridgePart[1] = 0;
|
||||
BridgePart[2] = 0;
|
||||
StrangePool = 0;
|
||||
Water = WATERSTATE_FRENZY;
|
||||
|
||||
ShieldGeneratorDeactivated[0] = false;
|
||||
ShieldGeneratorDeactivated[1] = false;
|
||||
ShieldGeneratorDeactivated[2] = false;
|
||||
ShieldGeneratorDeactivated[3] = false;
|
||||
FishingTimer = 1000;
|
||||
LurkerSubEvent = 0;
|
||||
WaterCheckTimer = 500;
|
||||
FrenzySpawnTimer = 2000;
|
||||
DoSpawnFrenzy = false;
|
||||
TrashCount = 0;
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_CONTROL_CONSOLE, DONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) return true;
|
||||
};
|
||||
␍class instance_serpent_shrine : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_serpent_shrine() : InstanceMapScript("instance_serpent_shrine") { }
|
||||
|
||||
return false;
|
||||
InstanceScript* GetInstanceData_instance_serpentshrine_cavern_InstanceMapScript(Map* pMap)
|
||||
{
|
||||
return new instance_serpentshrine_cavern_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
void Update (uint32 diff)
|
||||
struct instance_serpentshrine_cavern_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
//Lurker Fishing event
|
||||
if (LurkerSubEvent == LURKER_FISHING)
|
||||
instance_serpentshrine_cavern_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
|
||||
|
||||
uint64 LurkerBelow;
|
||||
uint64 Sharkkis;
|
||||
uint64 Tidalvess;
|
||||
uint64 Caribdis;
|
||||
uint64 LadyVashj;
|
||||
uint64 Karathress;
|
||||
uint64 KarathressEvent_Starter;
|
||||
uint64 LeotherasTheBlind;
|
||||
uint64 LeotherasEventStarter;
|
||||
|
||||
uint64 ControlConsole;
|
||||
uint64 BridgePart[3];
|
||||
uint32 StrangePool;
|
||||
uint32 FishingTimer;
|
||||
uint32 LurkerSubEvent;
|
||||
uint32 WaterCheckTimer;
|
||||
uint32 FrenzySpawnTimer;
|
||||
uint32 Water;
|
||||
uint32 TrashCount;
|
||||
|
||||
bool ShieldGeneratorDeactivated[4];
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
bool DoSpawnFrenzy;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
if (FishingTimer <= diff)
|
||||
{
|
||||
LurkerSubEvent = LURKER_HOOKED;
|
||||
SetData(DATA_STRANGE_POOL, IN_PROGRESS);//just fished, signal Lurker script to emerge and start fight, we use IN_PROGRESS so it won't get saved and lurker will be alway invis at start if server restarted
|
||||
} else FishingTimer -= diff;
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
LurkerBelow = 0;
|
||||
Sharkkis = 0;
|
||||
Tidalvess = 0;
|
||||
Caribdis = 0;
|
||||
LadyVashj = 0;
|
||||
Karathress = 0;
|
||||
KarathressEvent_Starter = 0;
|
||||
LeotherasTheBlind = 0;
|
||||
LeotherasEventStarter = 0;
|
||||
|
||||
ControlConsole = 0;
|
||||
BridgePart[0] = 0;
|
||||
BridgePart[1] = 0;
|
||||
BridgePart[2] = 0;
|
||||
StrangePool = 0;
|
||||
Water = WATERSTATE_FRENZY;
|
||||
|
||||
ShieldGeneratorDeactivated[0] = false;
|
||||
ShieldGeneratorDeactivated[1] = false;
|
||||
ShieldGeneratorDeactivated[2] = false;
|
||||
ShieldGeneratorDeactivated[3] = false;
|
||||
FishingTimer = 1000;
|
||||
LurkerSubEvent = 0;
|
||||
WaterCheckTimer = 500;
|
||||
FrenzySpawnTimer = 2000;
|
||||
DoSpawnFrenzy = false;
|
||||
TrashCount = 0;
|
||||
|
||||
}
|
||||
//Water checks
|
||||
if (WaterCheckTimer <= diff)
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
if (TrashCount >= MIN_KILLS)
|
||||
Water = WATERSTATE_SCALDING;
|
||||
else
|
||||
Water = WATERSTATE_FRENZY;
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) return true;
|
||||
|
||||
Map::PlayerList const &PlayerList = instance->GetPlayers();
|
||||
if (PlayerList.isEmpty())
|
||||
return;
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
return false;
|
||||
}
|
||||
|
||||
void Update (uint32 diff)
|
||||
{
|
||||
//Lurker Fishing event
|
||||
if (LurkerSubEvent == LURKER_FISHING)
|
||||
{
|
||||
if (Player* pPlayer = i->getSource())
|
||||
if (FishingTimer <= diff)
|
||||
{
|
||||
if (pPlayer->isAlive() && /*i->getSource()->GetPositionZ() <= -21.434931f*/pPlayer->IsInWater())
|
||||
{
|
||||
if (Water == WATERSTATE_SCALDING)
|
||||
{
|
||||
LurkerSubEvent = LURKER_HOOKED;
|
||||
SetData(DATA_STRANGE_POOL, IN_PROGRESS);//just fished, signal Lurker script to emerge and start fight, we use IN_PROGRESS so it won't get saved and lurker will be alway invis at start if server restarted
|
||||
} else FishingTimer -= diff;
|
||||
}
|
||||
//Water checks
|
||||
if (WaterCheckTimer <= diff)
|
||||
{
|
||||
if (TrashCount >= MIN_KILLS)
|
||||
Water = WATERSTATE_SCALDING;
|
||||
else
|
||||
Water = WATERSTATE_FRENZY;
|
||||
|
||||
if (!pPlayer->HasAura(SPELL_SCALDINGWATER))
|
||||
{
|
||||
pPlayer->CastSpell(pPlayer, SPELL_SCALDINGWATER,true);
|
||||
}
|
||||
} else if (Water == WATERSTATE_FRENZY)
|
||||
Map::PlayerList const &PlayerList = instance->GetPlayers();
|
||||
if (PlayerList.isEmpty())
|
||||
return;
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (Player* pPlayer = i->getSource())
|
||||
{
|
||||
if (pPlayer->isAlive() && /*i->getSource()->GetPositionZ() <= -21.434931f*/pPlayer->IsInWater())
|
||||
{
|
||||
//spawn frenzy
|
||||
if (DoSpawnFrenzy)
|
||||
if (Water == WATERSTATE_SCALDING)
|
||||
{
|
||||
if (Creature* frenzy = pPlayer->SummonCreature(MOB_COILFANG_FRENZY,pPlayer->GetPositionX(),pPlayer->GetPositionY(),pPlayer->GetPositionZ(),pPlayer->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,2000))
|
||||
|
||||
if (!pPlayer->HasAura(SPELL_SCALDINGWATER))
|
||||
{
|
||||
frenzy->Attack(pPlayer,false);
|
||||
frenzy->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
|
||||
pPlayer->CastSpell(pPlayer, SPELL_SCALDINGWATER,true);
|
||||
}
|
||||
} else if (Water == WATERSTATE_FRENZY)
|
||||
{
|
||||
//spawn frenzy
|
||||
if (DoSpawnFrenzy)
|
||||
{
|
||||
if (Creature* frenzy = pPlayer->SummonCreature(MOB_COILFANG_FRENZY,pPlayer->GetPositionX(),pPlayer->GetPositionY(),pPlayer->GetPositionZ(),pPlayer->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,2000))
|
||||
{
|
||||
frenzy->Attack(pPlayer,false);
|
||||
frenzy->AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_LEVITATING);
|
||||
}
|
||||
DoSpawnFrenzy = false;
|
||||
}
|
||||
DoSpawnFrenzy = false;
|
||||
}
|
||||
}
|
||||
if (!pPlayer->IsInWater())
|
||||
pPlayer->RemoveAurasDueToSpell(SPELL_SCALDINGWATER);
|
||||
}
|
||||
if (!pPlayer->IsInWater())
|
||||
pPlayer->RemoveAurasDueToSpell(SPELL_SCALDINGWATER);
|
||||
|
||||
}
|
||||
WaterCheckTimer = 500;//remove stress from core
|
||||
} else WaterCheckTimer -= diff;
|
||||
if (FrenzySpawnTimer <= diff)
|
||||
{
|
||||
DoSpawnFrenzy = true;
|
||||
FrenzySpawnTimer = 2000;
|
||||
} else FrenzySpawnTimer -= diff;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case 184568:
|
||||
ControlConsole = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
|
||||
case 184203:
|
||||
BridgePart[0] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
|
||||
case 184204:
|
||||
BridgePart[1] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
|
||||
case 184205:
|
||||
BridgePart[2] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
case GAMEOBJECT_FISHINGNODE_ENTRY://no way checking if fish is hooked, so we create a timed event
|
||||
if (LurkerSubEvent == LURKER_NOT_STARTED)
|
||||
{
|
||||
FishingTimer = 10000+rand()%30000;//random time before lurker emerges
|
||||
LurkerSubEvent = LURKER_FISHING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
WaterCheckTimer = 500;//remove stress from core
|
||||
} else WaterCheckTimer -= diff;
|
||||
if (FrenzySpawnTimer <= diff)
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
|
||||
{
|
||||
DoSpawnFrenzy = true;
|
||||
FrenzySpawnTimer = 2000;
|
||||
} else FrenzySpawnTimer -= diff;
|
||||
}
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case 21212: LadyVashj = pCreature->GetGUID(); break;
|
||||
case 21214: Karathress = pCreature->GetGUID(); break;
|
||||
case 21966: Sharkkis = pCreature->GetGUID(); break;
|
||||
case 21217: LurkerBelow = pCreature->GetGUID(); break;
|
||||
case 21965: Tidalvess = pCreature->GetGUID(); break;
|
||||
case 21964: Caribdis = pCreature->GetGUID(); break;
|
||||
case 21215: LeotherasTheBlind = pCreature->GetGUID(); break;
|
||||
/*case TRASHMOB_COILFANG_PRIESTESS:
|
||||
case TRASHMOB_COILFANG_SHATTERER:
|
||||
if (pCreature->isAlive())
|
||||
++TrashCount;
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
case 184568:
|
||||
ControlConsole = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
if (type == DATA_KARATHRESSEVENT_STARTER)
|
||||
KarathressEvent_Starter = data;
|
||||
if (type == DATA_LEOTHERAS_EVENT_STARTER)
|
||||
LeotherasEventStarter = data;
|
||||
}
|
||||
|
||||
case 184203:
|
||||
BridgePart[0] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
uint64 GetData64(uint32 identifier)
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case DATA_THELURKERBELOW: return LurkerBelow;
|
||||
case DATA_SHARKKIS: return Sharkkis;
|
||||
case DATA_TIDALVESS: return Tidalvess;
|
||||
case DATA_CARIBDIS: return Caribdis;
|
||||
case DATA_LADYVASHJ: return LadyVashj;
|
||||
case DATA_KARATHRESS: return Karathress;
|
||||
case DATA_KARATHRESSEVENT_STARTER: return KarathressEvent_Starter;
|
||||
case DATA_LEOTHERAS: return LeotherasTheBlind;
|
||||
case DATA_LEOTHERAS_EVENT_STARTER: return LeotherasEventStarter;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case 184204:
|
||||
BridgePart[1] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
|
||||
case 184205:
|
||||
BridgePart[2] = pGo->GetGUID();
|
||||
pGo->setActive(true);
|
||||
break;
|
||||
case GAMEOBJECT_FISHINGNODE_ENTRY://no way checking if fish is hooked, so we create a timed event
|
||||
if (LurkerSubEvent == LURKER_NOT_STARTED)
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_STRANGE_POOL:
|
||||
{
|
||||
FishingTimer = 10000+rand()%30000;//random time before lurker emerges
|
||||
LurkerSubEvent = LURKER_FISHING;
|
||||
StrangePool = data;
|
||||
if (data == NOT_STARTED)
|
||||
LurkerSubEvent = LURKER_NOT_STARTED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case 21212: LadyVashj = pCreature->GetGUID(); break;
|
||||
case 21214: Karathress = pCreature->GetGUID(); break;
|
||||
case 21966: Sharkkis = pCreature->GetGUID(); break;
|
||||
case 21217: LurkerBelow = pCreature->GetGUID(); break;
|
||||
case 21965: Tidalvess = pCreature->GetGUID(); break;
|
||||
case 21964: Caribdis = pCreature->GetGUID(); break;
|
||||
case 21215: LeotherasTheBlind = pCreature->GetGUID(); break;
|
||||
/*case TRASHMOB_COILFANG_PRIESTESS:
|
||||
case TRASHMOB_COILFANG_SHATTERER:
|
||||
if (pCreature->isAlive())
|
||||
++TrashCount;
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
if (type == DATA_KARATHRESSEVENT_STARTER)
|
||||
KarathressEvent_Starter = data;
|
||||
if (type == DATA_LEOTHERAS_EVENT_STARTER)
|
||||
LeotherasEventStarter = data;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier)
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case DATA_THELURKERBELOW: return LurkerBelow;
|
||||
case DATA_SHARKKIS: return Sharkkis;
|
||||
case DATA_TIDALVESS: return Tidalvess;
|
||||
case DATA_CARIBDIS: return Caribdis;
|
||||
case DATA_LADYVASHJ: return LadyVashj;
|
||||
case DATA_KARATHRESS: return Karathress;
|
||||
case DATA_KARATHRESSEVENT_STARTER: return KarathressEvent_Starter;
|
||||
case DATA_LEOTHERAS: return LeotherasTheBlind;
|
||||
case DATA_LEOTHERAS_EVENT_STARTER: return LeotherasEventStarter;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_STRANGE_POOL:
|
||||
{
|
||||
StrangePool = data;
|
||||
if (data == NOT_STARTED)
|
||||
LurkerSubEvent = LURKER_NOT_STARTED;
|
||||
}
|
||||
break;
|
||||
case DATA_CONTROL_CONSOLE:
|
||||
if (data == DONE)
|
||||
{
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
}
|
||||
ControlConsole = data;break;
|
||||
case DATA_TRASH :
|
||||
{
|
||||
if (data == 1 && TrashCount < MIN_KILLS)
|
||||
++TrashCount;//+1 died
|
||||
SaveToDB();
|
||||
break;
|
||||
}
|
||||
case DATA_WATER : Water = data;break;
|
||||
case DATA_HYDROSSTHEUNSTABLEEVENT: m_auiEncounter[0] = data; break;
|
||||
case DATA_LEOTHERASTHEBLINDEVENT: m_auiEncounter[1] = data; break;
|
||||
case DATA_THELURKERBELOWEVENT: m_auiEncounter[2] = data; break;
|
||||
case DATA_KARATHRESSEVENT: m_auiEncounter[3] = data; break;
|
||||
case DATA_MOROGRIMTIDEWALKEREVENT: m_auiEncounter[4] = data; break;
|
||||
//Lady Vashj
|
||||
case DATA_LADYVASHJEVENT:
|
||||
if (data == NOT_STARTED)
|
||||
{
|
||||
ShieldGeneratorDeactivated[0] = false;
|
||||
ShieldGeneratorDeactivated[1] = false;
|
||||
ShieldGeneratorDeactivated[2] = false;
|
||||
ShieldGeneratorDeactivated[3] = false;
|
||||
}
|
||||
m_auiEncounter[5] = data; break;
|
||||
case DATA_SHIELDGENERATOR1:ShieldGeneratorDeactivated[0] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR2:ShieldGeneratorDeactivated[1] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR3:ShieldGeneratorDeactivated[2] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR4:ShieldGeneratorDeactivated[3] = (data) ? true : false; break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_HYDROSSTHEUNSTABLEEVENT: return m_auiEncounter[0];
|
||||
case DATA_LEOTHERASTHEBLINDEVENT: return m_auiEncounter[1];
|
||||
case DATA_THELURKERBELOWEVENT: return m_auiEncounter[2];
|
||||
case DATA_KARATHRESSEVENT: return m_auiEncounter[3];
|
||||
case DATA_MOROGRIMTIDEWALKEREVENT: return m_auiEncounter[4];
|
||||
case DATA_CONTROL_CONSOLE:
|
||||
if (data == DONE)
|
||||
{
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
HandleGameObject(BridgePart[0], true);
|
||||
}
|
||||
ControlConsole = data;break;
|
||||
case DATA_TRASH :
|
||||
{
|
||||
if (data == 1 && TrashCount < MIN_KILLS)
|
||||
++TrashCount;//+1 died
|
||||
SaveToDB();
|
||||
break;
|
||||
}
|
||||
case DATA_WATER : Water = data;break;
|
||||
case DATA_HYDROSSTHEUNSTABLEEVENT: m_auiEncounter[0] = data; break;
|
||||
case DATA_LEOTHERASTHEBLINDEVENT: m_auiEncounter[1] = data; break;
|
||||
case DATA_THELURKERBELOWEVENT: m_auiEncounter[2] = data; break;
|
||||
case DATA_KARATHRESSEVENT: m_auiEncounter[3] = data; break;
|
||||
case DATA_MOROGRIMTIDEWALKEREVENT: m_auiEncounter[4] = data; break;
|
||||
//Lady Vashj
|
||||
case DATA_LADYVASHJEVENT: return m_auiEncounter[5];
|
||||
case DATA_SHIELDGENERATOR1: return ShieldGeneratorDeactivated[0];
|
||||
case DATA_SHIELDGENERATOR2: return ShieldGeneratorDeactivated[1];
|
||||
case DATA_SHIELDGENERATOR3: return ShieldGeneratorDeactivated[2];
|
||||
case DATA_SHIELDGENERATOR4: return ShieldGeneratorDeactivated[3];
|
||||
case DATA_CANSTARTPHASE3:
|
||||
if (ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3])return 1;break;
|
||||
case DATA_STRANGE_POOL: return StrangePool;
|
||||
case DATA_WATER: return Water;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
std::ostringstream stream;
|
||||
stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << TrashCount;
|
||||
char* out = new char[stream.str().length() + 1];
|
||||
strcpy(out, stream.str().c_str());
|
||||
if (out)
|
||||
{
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return out;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
case DATA_LADYVASHJEVENT:
|
||||
if (data == NOT_STARTED)
|
||||
{
|
||||
ShieldGeneratorDeactivated[0] = false;
|
||||
ShieldGeneratorDeactivated[1] = false;
|
||||
ShieldGeneratorDeactivated[2] = false;
|
||||
ShieldGeneratorDeactivated[3] = false;
|
||||
}
|
||||
m_auiEncounter[5] = data; break;
|
||||
case DATA_SHIELDGENERATOR1:ShieldGeneratorDeactivated[0] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR2:ShieldGeneratorDeactivated[1] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR3:ShieldGeneratorDeactivated[2] = (data) ? true : false; break;
|
||||
case DATA_SHIELDGENERATOR4:ShieldGeneratorDeactivated[3] = (data) ? true : false; break;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream stream(in);
|
||||
stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4] >> m_auiEncounter[5] >> TrashCount;
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_HYDROSSTHEUNSTABLEEVENT: return m_auiEncounter[0];
|
||||
case DATA_LEOTHERASTHEBLINDEVENT: return m_auiEncounter[1];
|
||||
case DATA_THELURKERBELOWEVENT: return m_auiEncounter[2];
|
||||
case DATA_KARATHRESSEVENT: return m_auiEncounter[3];
|
||||
case DATA_MOROGRIMTIDEWALKEREVENT: return m_auiEncounter[4];
|
||||
//Lady Vashj
|
||||
case DATA_LADYVASHJEVENT: return m_auiEncounter[5];
|
||||
case DATA_SHIELDGENERATOR1: return ShieldGeneratorDeactivated[0];
|
||||
case DATA_SHIELDGENERATOR2: return ShieldGeneratorDeactivated[1];
|
||||
case DATA_SHIELDGENERATOR3: return ShieldGeneratorDeactivated[2];
|
||||
case DATA_SHIELDGENERATOR4: return ShieldGeneratorDeactivated[3];
|
||||
case DATA_CANSTARTPHASE3:
|
||||
if (ShieldGeneratorDeactivated[0] && ShieldGeneratorDeactivated[1] && ShieldGeneratorDeactivated[2] && ShieldGeneratorDeactivated[3])return 1;break;
|
||||
case DATA_STRANGE_POOL: return StrangePool;
|
||||
case DATA_WATER: return Water;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
std::ostringstream stream;
|
||||
stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
|
||||
<< m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " << TrashCount;
|
||||
char* out = new char[stream.str().length() + 1];
|
||||
strcpy(out, stream.str().c_str());
|
||||
if (out)
|
||||
{
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return out;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream stream(in);
|
||||
stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3]
|
||||
>> m_auiEncounter[4] >> m_auiEncounter[5] >> TrashCount;
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as "In Progress" - reset it instead.
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_serpentshrine_cavern(Map* pMap)
|
||||
{
|
||||
return new instance_serpentshrine_cavern(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_serpentshrine_cavern()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "instance_serpent_shrine";
|
||||
newscript->GetInstanceData = &GetInstanceData_instance_serpentshrine_cavern;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "go_bridge_console";
|
||||
newscript->pGOHello = &GOHello_go_bridge_console;
|
||||
newscript->RegisterSelf();
|
||||
new instance_serpent_shrine();
|
||||
new go_bridge_console();
|
||||
}
|
||||
|
||||
|
||||
+115
-113
@@ -43,147 +43,149 @@ EndContentData */
|
||||
#define SPELL_LUNG_BURST 31481
|
||||
#define SPELL_ENVELOPING_WINDS 31718
|
||||
|
||||
struct boss_thespiaAI : public ScriptedAI
|
||||
#define SPELL_WATER_BOLT_VOLLEY 34449
|
||||
#define H_SPELL_WATER_BOLT_VOLLEY 37924
|
||||
␍class boss_hydromancer_thespia : public CreatureScript
|
||||
{
|
||||
boss_thespiaAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
boss_hydromancer_thespia() : CreatureScript("boss_hydromancer_thespia") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new boss_thespiaAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance *pInstance;
|
||||
|
||||
uint32 LightningCloud_Timer;
|
||||
uint32 LungBurst_Timer;
|
||||
uint32 EnvelopingWinds_Timer;
|
||||
|
||||
void Reset()
|
||||
struct boss_thespiaAI : public ScriptedAI
|
||||
{
|
||||
LightningCloud_Timer = 15000;
|
||||
LungBurst_Timer = 7000;
|
||||
EnvelopingWinds_Timer = 9000;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
DoScriptText(SAY_DEAD, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//LightningCloud_Timer
|
||||
if (LightningCloud_Timer <= diff)
|
||||
boss_thespiaAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_LIGHTNING_CLOUD);
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
//cast twice in Heroic mode
|
||||
if (IsHeroic())
|
||||
InstanceScript *pInstance;
|
||||
|
||||
uint32 LightningCloud_Timer;
|
||||
uint32 LungBurst_Timer;
|
||||
uint32 EnvelopingWinds_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
LightningCloud_Timer = 15000;
|
||||
LungBurst_Timer = 7000;
|
||||
EnvelopingWinds_Timer = 9000;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
DoScriptText(SAY_DEAD, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//LightningCloud_Timer
|
||||
if (LightningCloud_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_LIGHTNING_CLOUD);
|
||||
|
||||
LightningCloud_Timer = 15000+rand()%10000;
|
||||
} else LightningCloud_Timer -=diff;
|
||||
//cast twice in Heroic mode
|
||||
if (IsHeroic())
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_LIGHTNING_CLOUD);
|
||||
|
||||
//LungBurst_Timer
|
||||
if (LungBurst_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_LUNG_BURST);
|
||||
LungBurst_Timer = 7000+rand()%5000;
|
||||
} else LungBurst_Timer -=diff;
|
||||
LightningCloud_Timer = 15000+rand()%10000;
|
||||
} else LightningCloud_Timer -=diff;
|
||||
|
||||
//EnvelopingWinds_Timer
|
||||
if (EnvelopingWinds_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_ENVELOPING_WINDS);
|
||||
//LungBurst_Timer
|
||||
if (LungBurst_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_LUNG_BURST);
|
||||
LungBurst_Timer = 7000+rand()%5000;
|
||||
} else LungBurst_Timer -=diff;
|
||||
|
||||
//cast twice in Heroic mode
|
||||
if (IsHeroic())
|
||||
//EnvelopingWinds_Timer
|
||||
if (EnvelopingWinds_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_ENVELOPING_WINDS);
|
||||
EnvelopingWinds_Timer = 10000+rand()%5000;
|
||||
} else EnvelopingWinds_Timer -=diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
//cast twice in Heroic mode
|
||||
if (IsHeroic())
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_ENVELOPING_WINDS);
|
||||
EnvelopingWinds_Timer = 10000+rand()%5000;
|
||||
} else EnvelopingWinds_Timer -=diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#define SPELL_WATER_BOLT_VOLLEY 34449
|
||||
#define H_SPELL_WATER_BOLT_VOLLEY 37924
|
||||
|
||||
struct mob_coilfang_waterelementalAI : public ScriptedAI
|
||||
␍class mob_coilfang_waterelemental : public CreatureScript
|
||||
{
|
||||
mob_coilfang_waterelementalAI(Creature *c) : ScriptedAI(c) {}
|
||||
public:
|
||||
mob_coilfang_waterelemental() : CreatureScript("mob_coilfang_waterelemental") { }
|
||||
|
||||
uint32 WaterBoltVolley_Timer;
|
||||
|
||||
void Reset()
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
WaterBoltVolley_Timer = 3000+rand()%3000;
|
||||
return new mob_coilfang_waterelementalAI (pCreature);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
struct mob_coilfang_waterelementalAI : public ScriptedAI
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
mob_coilfang_waterelementalAI(Creature *c) : ScriptedAI(c) {}
|
||||
|
||||
if (WaterBoltVolley_Timer <= diff)
|
||||
uint32 WaterBoltVolley_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DoCast(me, SPELL_WATER_BOLT_VOLLEY);
|
||||
WaterBoltVolley_Timer = 7000+rand()%5000;
|
||||
} else WaterBoltVolley_Timer -= diff;
|
||||
WaterBoltVolley_Timer = 3000+rand()%3000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (WaterBoltVolley_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WATER_BOLT_VOLLEY);
|
||||
WaterBoltVolley_Timer = 7000+rand()%5000;
|
||||
} else WaterBoltVolley_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_thespiaAI(Creature* pCreature)
|
||||
{
|
||||
return new boss_thespiaAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_coilfang_waterelementalAI(Creature* pCreature)
|
||||
{
|
||||
return new mob_coilfang_waterelementalAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_hydromancer_thespia()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_hydromancer_thespia";
|
||||
newscript->GetAI = &GetAI_boss_thespiaAI;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_coilfang_waterelemental";
|
||||
newscript->GetAI = &GetAI_mob_coilfang_waterelementalAI;
|
||||
newscript->RegisterSelf();
|
||||
new boss_hydromancer_thespia();
|
||||
new mob_coilfang_waterelemental();
|
||||
}
|
||||
|
||||
|
||||
+172
-168
@@ -47,136 +47,143 @@ EndContentData */
|
||||
#define H_SPELL_ENRAGE 1 //corrent enrage spell not known
|
||||
|
||||
#define ENTRY_STREAMRIGGER_MECHANIC 17951
|
||||
|
||||
struct boss_mekgineer_steamriggerAI : public ScriptedAI
|
||||
␍class boss_mekgineer_steamrigger : public CreatureScript
|
||||
{
|
||||
boss_mekgineer_steamriggerAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
boss_mekgineer_steamrigger() : CreatureScript("boss_mekgineer_steamrigger") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new boss_mekgineer_steamriggerAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance *pInstance;
|
||||
|
||||
uint32 Shrink_Timer;
|
||||
uint32 Saw_Blade_Timer;
|
||||
uint32 Electrified_Net_Timer;
|
||||
bool Summon75;
|
||||
bool Summon50;
|
||||
bool Summon25;
|
||||
|
||||
void Reset()
|
||||
struct boss_mekgineer_steamriggerAI : public ScriptedAI
|
||||
{
|
||||
Shrink_Timer = 20000;
|
||||
Saw_Blade_Timer = 15000;
|
||||
Electrified_Net_Timer = 10000;
|
||||
|
||||
Summon75 = false;
|
||||
Summon50 = false;
|
||||
Summon25 = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, IN_PROGRESS);
|
||||
}
|
||||
|
||||
//no known summon spells exist
|
||||
void SummonMechanichs()
|
||||
{
|
||||
DoScriptText(SAY_MECHANICS, me);
|
||||
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,5,5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,-5,5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,-5,-5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
|
||||
if (rand()%2)
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,5,-7,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
if (rand()%2)
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,7,-5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Shrink_Timer <= diff)
|
||||
boss_mekgineer_steamriggerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript *pInstance;
|
||||
|
||||
uint32 Shrink_Timer;
|
||||
uint32 Saw_Blade_Timer;
|
||||
uint32 Electrified_Net_Timer;
|
||||
bool Summon75;
|
||||
bool Summon50;
|
||||
bool Summon25;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_SUPER_SHRINK_RAY);
|
||||
Shrink_Timer = 20000;
|
||||
} else Shrink_Timer -= diff;
|
||||
|
||||
if (Saw_Blade_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
DoCast(pTarget, SPELL_SAW_BLADE);
|
||||
else
|
||||
DoCast(me->getVictim(), SPELL_SAW_BLADE);
|
||||
|
||||
Saw_Blade_Timer = 15000;
|
||||
} else Saw_Blade_Timer -= diff;
|
||||
|
||||
if (Electrified_Net_Timer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_ELECTRIFIED_NET);
|
||||
Electrified_Net_Timer = 10000;
|
||||
}
|
||||
else Electrified_Net_Timer -= diff;
|
||||
|
||||
if (!Summon75)
|
||||
Summon75 = false;
|
||||
Summon50 = false;
|
||||
Summon25 = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, NOT_STARTED);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 75)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon75 = true;
|
||||
}
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, DONE);
|
||||
}
|
||||
|
||||
if (!Summon50)
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon50 = true;
|
||||
}
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), me);
|
||||
}
|
||||
|
||||
if (!Summon25)
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 25)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon25 = true;
|
||||
}
|
||||
DoScriptText(RAND(SAY_AGGRO_1,SAY_AGGRO_2,SAY_AGGRO_3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER, IN_PROGRESS);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
//no known summon spells exist
|
||||
void SummonMechanichs()
|
||||
{
|
||||
DoScriptText(SAY_MECHANICS, me);
|
||||
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,5,5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,-5,5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,-5,-5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
|
||||
if (rand()%2)
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,5,-7,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
if (rand()%2)
|
||||
DoSpawnCreature(ENTRY_STREAMRIGGER_MECHANIC,7,-5,0,0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 240000);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Shrink_Timer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_SUPER_SHRINK_RAY);
|
||||
Shrink_Timer = 20000;
|
||||
} else Shrink_Timer -= diff;
|
||||
|
||||
if (Saw_Blade_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
DoCast(pTarget, SPELL_SAW_BLADE);
|
||||
else
|
||||
DoCast(me->getVictim(), SPELL_SAW_BLADE);
|
||||
|
||||
Saw_Blade_Timer = 15000;
|
||||
} else Saw_Blade_Timer -= diff;
|
||||
|
||||
if (Electrified_Net_Timer <= diff)
|
||||
{
|
||||
DoCast(me->getVictim(), SPELL_ELECTRIFIED_NET);
|
||||
Electrified_Net_Timer = 10000;
|
||||
}
|
||||
else Electrified_Net_Timer -= diff;
|
||||
|
||||
if (!Summon75)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 75)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon75 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Summon50)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 50)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon50 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!Summon25)
|
||||
{
|
||||
if ((me->GetHealth()*100 / me->GetMaxHealth()) < 25)
|
||||
{
|
||||
SummonMechanichs();
|
||||
Summon25 = true;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_mekgineer_steamrigger(Creature* pCreature)
|
||||
{
|
||||
return new boss_mekgineer_steamriggerAI (pCreature);
|
||||
}
|
||||
|
||||
#define SPELL_DISPEL_MAGIC 17201
|
||||
#define SPELL_REPAIR 31532
|
||||
@@ -184,83 +191,80 @@ CreatureAI* GetAI_boss_mekgineer_steamrigger(Creature* pCreature)
|
||||
|
||||
#define MAX_REPAIR_RANGE (13.0f) //we should be at least at this range for repair
|
||||
#define MIN_REPAIR_RANGE (7.0f) //we can stop movement at this range to repair but not required
|
||||
|
||||
struct mob_steamrigger_mechanicAI : public ScriptedAI
|
||||
␍class mob_steamrigger_mechanic : public CreatureScript
|
||||
{
|
||||
mob_steamrigger_mechanicAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
mob_steamrigger_mechanic() : CreatureScript("mob_steamrigger_mechanic") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new mob_steamrigger_mechanicAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
uint32 Repair_Timer;
|
||||
|
||||
void Reset()
|
||||
struct mob_steamrigger_mechanicAI : public ScriptedAI
|
||||
{
|
||||
Repair_Timer = 2000;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/)
|
||||
{
|
||||
//react only if attacked
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (Repair_Timer <= diff)
|
||||
mob_steamrigger_mechanicAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
if (pInstance && pInstance->GetData64(DATA_MEKGINEERSTEAMRIGGER) && pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == IN_PROGRESS)
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* pInstance;
|
||||
|
||||
uint32 Repair_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Repair_Timer = 2000;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/)
|
||||
{
|
||||
//react only if attacked
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (Repair_Timer <= diff)
|
||||
{
|
||||
if (Unit* pMekgineer = Unit::GetUnit((*me), pInstance->GetData64(DATA_MEKGINEERSTEAMRIGGER)))
|
||||
if (pInstance && pInstance->GetData64(DATA_MEKGINEERSTEAMRIGGER) && pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == IN_PROGRESS)
|
||||
{
|
||||
if (me->IsWithinDistInMap(pMekgineer, MAX_REPAIR_RANGE))
|
||||
if (Unit* pMekgineer = Unit::GetUnit((*me), pInstance->GetData64(DATA_MEKGINEERSTEAMRIGGER)))
|
||||
{
|
||||
//are we already channeling? Doesn't work very well, find better check?
|
||||
if (!me->GetUInt32Value(UNIT_CHANNEL_SPELL))
|
||||
if (me->IsWithinDistInMap(pMekgineer, MAX_REPAIR_RANGE))
|
||||
{
|
||||
//are we already channeling? Doesn't work very well, find better check?
|
||||
if (!me->GetUInt32Value(UNIT_CHANNEL_SPELL))
|
||||
{
|
||||
//me->GetMotionMaster()->MovementExpired();
|
||||
//me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
DoCast(me, SPELL_REPAIR, true);
|
||||
}
|
||||
Repair_Timer = 5000;
|
||||
}
|
||||
else
|
||||
{
|
||||
//me->GetMotionMaster()->MovementExpired();
|
||||
//me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
DoCast(me, SPELL_REPAIR, true);
|
||||
//me->GetMotionMaster()->MoveFollow(pMekgineer,0,0);
|
||||
}
|
||||
Repair_Timer = 5000;
|
||||
}
|
||||
else
|
||||
{
|
||||
//me->GetMotionMaster()->MovementExpired();
|
||||
//me->GetMotionMaster()->MoveFollow(pMekgineer,0,0);
|
||||
}
|
||||
}
|
||||
} else Repair_Timer = 5000;
|
||||
} else Repair_Timer -= diff;
|
||||
} else Repair_Timer = 5000;
|
||||
} else Repair_Timer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_steamrigger_mechanic(Creature* pCreature)
|
||||
{
|
||||
return new mob_steamrigger_mechanicAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_mekgineer_steamrigger()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_mekgineer_steamrigger";
|
||||
newscript->GetAI = &GetAI_boss_mekgineer_steamrigger;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_steamrigger_mechanic";
|
||||
newscript->GetAI = &GetAI_mob_steamrigger_mechanic;
|
||||
newscript->RegisterSelf();
|
||||
new boss_mekgineer_steamrigger();
|
||||
new mob_steamrigger_mechanic();
|
||||
}
|
||||
|
||||
|
||||
+143
-139
@@ -41,166 +41,170 @@ EndScriptData */
|
||||
#define SPELL_WARLORDS_RAGE_NAGA 31543
|
||||
|
||||
#define SPELL_WARLORDS_RAGE_PROC 36453
|
||||
|
||||
struct mob_naga_distillerAI : public ScriptedAI
|
||||
␍class mob_naga_distiller : public CreatureScript
|
||||
{
|
||||
mob_naga_distillerAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
mob_naga_distiller() : CreatureScript("mob_naga_distiller") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
return new mob_naga_distillerAI (pCreature);
|
||||
}
|
||||
|
||||
ScriptedInstance *pInstance;
|
||||
|
||||
void Reset()
|
||||
struct mob_naga_distillerAI : public ScriptedAI
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
//hack, due to really weird spell behaviour :(
|
||||
if (pInstance)
|
||||
mob_naga_distillerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
if (pInstance->GetData(TYPE_DISTILLER) == IN_PROGRESS)
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript *pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
//hack, due to really weird spell behaviour :(
|
||||
if (pInstance)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
if (pInstance->GetData(TYPE_DISTILLER) == IN_PROGRESS)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
void EnterCombat(Unit * /*who*/) { }
|
||||
|
||||
void StartRageGen(Unit * /*caster*/)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
DoCast(me, SPELL_WARLORDS_RAGE_NAGA, true);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_DISTILLER,IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit * /*done_by*/, uint32 &damage)
|
||||
{
|
||||
if (me->GetHealth() <= damage)
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_DISTILLER,DONE);
|
||||
}
|
||||
};
|
||||
|
||||
struct boss_warlord_kalithreshAI : public ScriptedAI
|
||||
{
|
||||
boss_warlord_kalithreshAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance *pInstance;
|
||||
|
||||
uint32 Reflection_Timer;
|
||||
uint32 Impale_Timer;
|
||||
uint32 Rage_Timer;
|
||||
bool CanRage;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Reflection_Timer = 10000;
|
||||
Impale_Timer = 7000+rand()%7000;
|
||||
Rage_Timer = 45000;
|
||||
CanRage = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
|
||||
}
|
||||
|
||||
void SpellHit(Unit * /*caster*/, const SpellEntry *spell)
|
||||
{
|
||||
//hack :(
|
||||
if (spell->Id == SPELL_WARLORDS_RAGE_PROC)
|
||||
if (pInstance)
|
||||
if (pInstance->GetData(TYPE_DISTILLER) == DONE)
|
||||
me->RemoveAurasDueToSpell(SPELL_WARLORDS_RAGE_PROC);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Rage_Timer <= diff)
|
||||
void StartRageGen(Unit * /*caster*/)
|
||||
{
|
||||
if (Creature* distiller = me->FindNearestCreature(17954, 100.0f))
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
|
||||
DoCast(me, SPELL_WARLORDS_RAGE_NAGA, true);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_DISTILLER,IN_PROGRESS);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit * /*done_by*/, uint32 &damage)
|
||||
{
|
||||
if (me->GetHealth() <= damage)
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_DISTILLER,DONE);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
␍class boss_warlord_kalithresh : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_warlord_kalithresh() : CreatureScript("boss_warlord_kalithresh") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_warlord_kalithreshAI (pCreature);
|
||||
}
|
||||
|
||||
struct boss_warlord_kalithreshAI : public ScriptedAI
|
||||
{
|
||||
boss_warlord_kalithreshAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript *pInstance;
|
||||
|
||||
uint32 Reflection_Timer;
|
||||
uint32 Impale_Timer;
|
||||
uint32 Rage_Timer;
|
||||
bool CanRage;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Reflection_Timer = 10000;
|
||||
Impale_Timer = 7000+rand()%7000;
|
||||
Rage_Timer = 45000;
|
||||
CanRage = false;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_AGGRO1,SAY_AGGRO2,SAY_AGGRO3), me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
|
||||
}
|
||||
|
||||
void SpellHit(Unit * /*caster*/, const SpellEntry *spell)
|
||||
{
|
||||
//hack :(
|
||||
if (spell->Id == SPELL_WARLORDS_RAGE_PROC)
|
||||
if (pInstance)
|
||||
if (pInstance->GetData(TYPE_DISTILLER) == DONE)
|
||||
me->RemoveAurasDueToSpell(SPELL_WARLORDS_RAGE_PROC);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*Killer*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(TYPE_WARLORD_KALITHRESH, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Rage_Timer <= diff)
|
||||
{
|
||||
DoScriptText(SAY_REGEN, me);
|
||||
DoCast(me, SPELL_WARLORDS_RAGE);
|
||||
CAST_AI(mob_naga_distillerAI, distiller->AI())->StartRageGen(me);
|
||||
}
|
||||
Rage_Timer = 3000+rand()%15000;
|
||||
} else Rage_Timer -= diff;
|
||||
if (Creature* distiller = me->FindNearestCreature(17954, 100.0f))
|
||||
{
|
||||
DoScriptText(SAY_REGEN, me);
|
||||
DoCast(me, SPELL_WARLORDS_RAGE);
|
||||
CAST_AI(mob_naga_distiller::mob_naga_distillerAI, distiller->AI())->StartRageGen(me);
|
||||
}
|
||||
Rage_Timer = 3000+rand()%15000;
|
||||
} else Rage_Timer -= diff;
|
||||
|
||||
//Reflection_Timer
|
||||
if (Reflection_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SPELL_REFLECTION);
|
||||
Reflection_Timer = 15000+rand()%10000;
|
||||
} else Reflection_Timer -= diff;
|
||||
//Reflection_Timer
|
||||
if (Reflection_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SPELL_REFLECTION);
|
||||
Reflection_Timer = 15000+rand()%10000;
|
||||
} else Reflection_Timer -= diff;
|
||||
|
||||
//Impale_Timer
|
||||
if (Impale_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_IMPALE);
|
||||
//Impale_Timer
|
||||
if (Impale_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_IMPALE);
|
||||
|
||||
Impale_Timer = 7500+rand()%5000;
|
||||
} else Impale_Timer -= diff;
|
||||
Impale_Timer = 7500+rand()%5000;
|
||||
} else Impale_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_naga_distiller(Creature* pCreature)
|
||||
{
|
||||
return new mob_naga_distillerAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_warlord_kalithresh(Creature* pCreature)
|
||||
{
|
||||
return new boss_warlord_kalithreshAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_warlord_kalithresh()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_naga_distiller";
|
||||
newscript->GetAI = &GetAI_mob_naga_distiller;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_warlord_kalithresh";
|
||||
newscript->GetAI = &GetAI_boss_warlord_kalithresh;
|
||||
newscript->RegisterSelf();
|
||||
new mob_naga_distiller();
|
||||
new boss_warlord_kalithresh();
|
||||
}
|
||||
|
||||
|
||||
+164
-161
@@ -37,197 +37,200 @@ EndScriptData */
|
||||
2 - Mekgineer Steamrigger Event
|
||||
3 - Warlord Kalithresh Event
|
||||
*/
|
||||
|
||||
bool GOHello_go_main_chambers_access_panel(Player* /*pPlayer*/, GameObject* pGo)
|
||||
␍class go_main_chambers_access_panel : public GameObjectScript
|
||||
{
|
||||
ScriptedInstance* pInstance = pGo->GetInstanceData();
|
||||
public:
|
||||
go_main_chambers_access_panel() : GameObjectScript("go_main_chambers_access_panel") { }
|
||||
|
||||
if (!pInstance)
|
||||
return false;
|
||||
bool OnGossipHello(Player* /*pPlayer*/, GameObject* pGo)
|
||||
{
|
||||
InstanceScript* pInstance = pGo->GetInstanceScript();
|
||||
|
||||
if (pGo->GetEntry() == ACCESS_PANEL_HYDRO && (pInstance->GetData(TYPE_HYDROMANCER_THESPIA) == DONE || pInstance->GetData(TYPE_HYDROMANCER_THESPIA) == SPECIAL))
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA,SPECIAL);
|
||||
if (!pInstance)
|
||||
return false;
|
||||
|
||||
if (pGo->GetEntry() == ACCESS_PANEL_MEK && (pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == DONE || pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == SPECIAL))
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER,SPECIAL);
|
||||
if (pGo->GetEntry() == ACCESS_PANEL_HYDRO && (pInstance->GetData(TYPE_HYDROMANCER_THESPIA) == DONE || pInstance->GetData(TYPE_HYDROMANCER_THESPIA) == SPECIAL))
|
||||
pInstance->SetData(TYPE_HYDROMANCER_THESPIA,SPECIAL);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (pGo->GetEntry() == ACCESS_PANEL_MEK && (pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == DONE || pInstance->GetData(TYPE_MEKGINEER_STEAMRIGGER) == SPECIAL))
|
||||
pInstance->SetData(TYPE_MEKGINEER_STEAMRIGGER,SPECIAL);
|
||||
|
||||
struct instance_steam_vault : public ScriptedInstance
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
␍class instance_steam_vault : public InstanceMapScript
|
||||
{
|
||||
instance_steam_vault(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
|
||||
public:
|
||||
instance_steam_vault() : InstanceMapScript("instance_steam_vault") { }
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
uint64 ThespiaGUID;
|
||||
uint64 MekgineerGUID;
|
||||
uint64 KalithreshGUID;
|
||||
|
||||
uint64 MainChambersDoor;
|
||||
uint64 AccessPanelHydro;
|
||||
uint64 AccessPanelMek;
|
||||
|
||||
void Initialize()
|
||||
InstanceScript* GetInstanceData_InstanceMapScript(Map* pMap)
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
ThespiaGUID = 0;
|
||||
MekgineerGUID = 0;
|
||||
KalithreshGUID = 0;
|
||||
MainChambersDoor = 0;
|
||||
AccessPanelHydro = 0;
|
||||
AccessPanelMek = 0;
|
||||
return new instance_steam_vault_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
struct instance_steam_vault_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
instance_steam_vault_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
|
||||
|
||||
return false;
|
||||
}
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
uint64 ThespiaGUID;
|
||||
uint64 MekgineerGUID;
|
||||
uint64 KalithreshGUID;
|
||||
|
||||
uint64 MainChambersDoor;
|
||||
uint64 AccessPanelHydro;
|
||||
uint64 AccessPanelMek;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
case 17797: ThespiaGUID = pCreature->GetGUID(); break;
|
||||
case 17796: MekgineerGUID = pCreature->GetGUID(); break;
|
||||
case 17798: KalithreshGUID = pCreature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case MAIN_CHAMBERS_DOOR: MainChambersDoor = pGo->GetGUID(); break;
|
||||
case ACCESS_PANEL_HYDRO: AccessPanelHydro = pGo->GetGUID(); break;
|
||||
case ACCESS_PANEL_MEK: AccessPanelMek = pGo->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_HYDROMANCER_THESPIA:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
HandleGameObject(AccessPanelHydro, true);
|
||||
|
||||
if (GetData(TYPE_MEKGINEER_STEAMRIGGER) == SPECIAL)
|
||||
HandleGameObject(MainChambersDoor, true);
|
||||
|
||||
sLog.outDebug("TSCR: Instance Steamvault: Access panel used.");
|
||||
}
|
||||
m_auiEncounter[0] = data;
|
||||
break;
|
||||
case TYPE_MEKGINEER_STEAMRIGGER:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
HandleGameObject(AccessPanelMek, true);
|
||||
|
||||
if (GetData(TYPE_HYDROMANCER_THESPIA) == SPECIAL)
|
||||
HandleGameObject(MainChambersDoor, true);
|
||||
|
||||
sLog.outDebug("TSCR: Instance Steamvault: Access panel used.");
|
||||
}
|
||||
m_auiEncounter[1] = data;
|
||||
break;
|
||||
case TYPE_WARLORD_KALITHRESH:
|
||||
m_auiEncounter[2] = data;
|
||||
break;
|
||||
case TYPE_DISTILLER:
|
||||
m_auiEncounter[3] = data;
|
||||
break;
|
||||
ThespiaGUID = 0;
|
||||
MekgineerGUID = 0;
|
||||
KalithreshGUID = 0;
|
||||
MainChambersDoor = 0;
|
||||
AccessPanelHydro = 0;
|
||||
AccessPanelMek = 0;
|
||||
}
|
||||
|
||||
if (data == DONE || data == SPECIAL)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
case TYPE_HYDROMANCER_THESPIA:
|
||||
return m_auiEncounter[0];
|
||||
case TYPE_MEKGINEER_STEAMRIGGER:
|
||||
return m_auiEncounter[1];
|
||||
case TYPE_WARLORD_KALITHRESH:
|
||||
return m_auiEncounter[2];
|
||||
case TYPE_DISTILLER:
|
||||
return m_auiEncounter[3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
|
||||
uint64 GetData64(uint32 data)
|
||||
{
|
||||
switch(data)
|
||||
{
|
||||
case DATA_THESPIA:
|
||||
return ThespiaGUID;
|
||||
case DATA_MEKGINEERSTEAMRIGGER:
|
||||
return MekgineerGUID;
|
||||
case DATA_KALITRESH:
|
||||
return KalithreshGUID;
|
||||
return false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
std::ostringstream stream;
|
||||
stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
|
||||
char* out = new char[stream.str().length() + 1];
|
||||
strcpy(out, stream.str().c_str());
|
||||
if (out)
|
||||
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
|
||||
{
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return out;
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case 17797: ThespiaGUID = pCreature->GetGUID(); break;
|
||||
case 17796: MekgineerGUID = pCreature->GetGUID(); break;
|
||||
case 17798: KalithreshGUID = pCreature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case MAIN_CHAMBERS_DOOR: MainChambersDoor = pGo->GetGUID(); break;
|
||||
case ACCESS_PANEL_HYDRO: AccessPanelHydro = pGo->GetGUID(); break;
|
||||
case ACCESS_PANEL_MEK: AccessPanelMek = pGo->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream stream(in);
|
||||
stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_HYDROMANCER_THESPIA:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
HandleGameObject(AccessPanelHydro, true);
|
||||
|
||||
if (GetData(TYPE_MEKGINEER_STEAMRIGGER) == SPECIAL)
|
||||
HandleGameObject(MainChambersDoor, true);
|
||||
|
||||
sLog.outDebug("TSCR: Instance Steamvault: Access panel used.");
|
||||
}
|
||||
m_auiEncounter[0] = data;
|
||||
break;
|
||||
case TYPE_MEKGINEER_STEAMRIGGER:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
HandleGameObject(AccessPanelMek, true);
|
||||
|
||||
if (GetData(TYPE_HYDROMANCER_THESPIA) == SPECIAL)
|
||||
HandleGameObject(MainChambersDoor, true);
|
||||
|
||||
sLog.outDebug("TSCR: Instance Steamvault: Access panel used.");
|
||||
}
|
||||
m_auiEncounter[1] = data;
|
||||
break;
|
||||
case TYPE_WARLORD_KALITHRESH:
|
||||
m_auiEncounter[2] = data;
|
||||
break;
|
||||
case TYPE_DISTILLER:
|
||||
m_auiEncounter[3] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE || data == SPECIAL)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_HYDROMANCER_THESPIA:
|
||||
return m_auiEncounter[0];
|
||||
case TYPE_MEKGINEER_STEAMRIGGER:
|
||||
return m_auiEncounter[1];
|
||||
case TYPE_WARLORD_KALITHRESH:
|
||||
return m_auiEncounter[2];
|
||||
case TYPE_DISTILLER:
|
||||
return m_auiEncounter[3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data)
|
||||
{
|
||||
switch(data)
|
||||
{
|
||||
case DATA_THESPIA:
|
||||
return ThespiaGUID;
|
||||
case DATA_MEKGINEERSTEAMRIGGER:
|
||||
return MekgineerGUID;
|
||||
case DATA_KALITRESH:
|
||||
return KalithreshGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
std::ostringstream stream;
|
||||
stream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
|
||||
char* out = new char[stream.str().length() + 1];
|
||||
strcpy(out, stream.str().c_str());
|
||||
if (out)
|
||||
{
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return out;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream stream(in);
|
||||
stream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3];
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_steam_vault(Map* pMap)
|
||||
{
|
||||
return new instance_steam_vault(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_steam_vault()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "go_main_chambers_access_panel";
|
||||
newscript->pGOHello = &GOHello_go_main_chambers_access_panel;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "instance_steam_vault";
|
||||
newscript->GetInstanceData = &GetInstanceData_instance_steam_vault;
|
||||
newscript->RegisterSelf();
|
||||
new go_main_chambers_access_panel();
|
||||
new instance_steam_vault();
|
||||
}
|
||||
|
||||
|
||||
@@ -27,130 +27,134 @@ EndScriptData */
|
||||
|
||||
#define SPELL_FOUL_SPORES 31673
|
||||
#define SPELL_ACID_GEYSER 38739
|
||||
|
||||
struct boss_hungarfenAI : public ScriptedAI
|
||||
␍class boss_hungarfen : public CreatureScript
|
||||
{
|
||||
boss_hungarfenAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
boss_hungarfen() : CreatureScript("boss_hungarfen") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_hungarfenAI (pCreature);
|
||||
}
|
||||
|
||||
bool Root;
|
||||
uint32 Mushroom_Timer;
|
||||
uint32 AcidGeyser_Timer;
|
||||
|
||||
void Reset()
|
||||
struct boss_hungarfenAI : public ScriptedAI
|
||||
{
|
||||
Root = false;
|
||||
Mushroom_Timer = 5000; // 1 mushroom after 5s, then one per 10s. This should be different in heroic mode
|
||||
AcidGeyser_Timer = 10000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if ((me->GetHealth()*100) / me->GetMaxHealth() <= 20)
|
||||
boss_hungarfenAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
if (!Root)
|
||||
{
|
||||
DoCast(me, SPELL_FOUL_SPORES);
|
||||
Root = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Mushroom_Timer <= diff)
|
||||
bool Root;
|
||||
uint32 Mushroom_Timer;
|
||||
uint32 AcidGeyser_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
me->SummonCreature(17990, pTarget->GetPositionX()+(rand()%8), pTarget->GetPositionY()+(rand()%8), pTarget->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 22000);
|
||||
else
|
||||
me->SummonCreature(17990, me->GetPositionX()+(rand()%8), me->GetPositionY()+(rand()%8), me->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 22000);
|
||||
Root = false;
|
||||
Mushroom_Timer = 5000; // 1 mushroom after 5s, then one per 10s. This should be different in heroic mode
|
||||
AcidGeyser_Timer = 10000;
|
||||
}
|
||||
|
||||
Mushroom_Timer = 10000;
|
||||
} else Mushroom_Timer -= diff;
|
||||
|
||||
if (AcidGeyser_Timer <= diff)
|
||||
void EnterCombat(Unit * /*who*/)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_ACID_GEYSER);
|
||||
AcidGeyser_Timer = 10000+rand()%7500;
|
||||
} else AcidGeyser_Timer -= diff;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if ((me->GetHealth()*100) / me->GetMaxHealth() <= 20)
|
||||
{
|
||||
if (!Root)
|
||||
{
|
||||
DoCast(me, SPELL_FOUL_SPORES);
|
||||
Root = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Mushroom_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
me->SummonCreature(17990, pTarget->GetPositionX()+(rand()%8), pTarget->GetPositionY()+(rand()%8), pTarget->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 22000);
|
||||
else
|
||||
me->SummonCreature(17990, me->GetPositionX()+(rand()%8), me->GetPositionY()+(rand()%8), me->GetPositionZ(), (rand()%5), TEMPSUMMON_TIMED_DESPAWN, 22000);
|
||||
|
||||
Mushroom_Timer = 10000;
|
||||
} else Mushroom_Timer -= diff;
|
||||
|
||||
if (AcidGeyser_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_ACID_GEYSER);
|
||||
AcidGeyser_Timer = 10000+rand()%7500;
|
||||
} else AcidGeyser_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
CreatureAI* GetAI_boss_hungarfen(Creature* pCreature)
|
||||
{
|
||||
return new boss_hungarfenAI (pCreature);
|
||||
}
|
||||
|
||||
#define SPELL_SPORE_CLOUD 34168
|
||||
#define SPELL_PUTRID_MUSHROOM 31690
|
||||
#define SPELL_GROW 31698
|
||||
|
||||
struct mob_underbog_mushroomAI : public ScriptedAI
|
||||
␍class mob_underbog_mushroom : public CreatureScript
|
||||
{
|
||||
mob_underbog_mushroomAI(Creature *c) : ScriptedAI(c) {}
|
||||
public:
|
||||
mob_underbog_mushroom() : CreatureScript("mob_underbog_mushroom") { }
|
||||
|
||||
bool Stop;
|
||||
uint32 Grow_Timer;
|
||||
uint32 Shrink_Timer;
|
||||
|
||||
void Reset()
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
Stop = false;
|
||||
Grow_Timer = 0;
|
||||
Shrink_Timer = 20000;
|
||||
|
||||
DoCast(me, SPELL_PUTRID_MUSHROOM, true);
|
||||
DoCast(me, SPELL_SPORE_CLOUD, true);
|
||||
return new mob_underbog_mushroomAI (pCreature);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit * /*who*/) {}
|
||||
|
||||
void AttackStart(Unit* /*who*/) {}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
struct mob_underbog_mushroomAI : public ScriptedAI
|
||||
{
|
||||
if (Stop)
|
||||
return;
|
||||
mob_underbog_mushroomAI(Creature *c) : ScriptedAI(c) {}
|
||||
|
||||
if (Grow_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_GROW);
|
||||
Grow_Timer = 3000;
|
||||
} else Grow_Timer -= diff;
|
||||
bool Stop;
|
||||
uint32 Grow_Timer;
|
||||
uint32 Shrink_Timer;
|
||||
|
||||
if (Shrink_Timer <= diff)
|
||||
void Reset()
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_GROW);
|
||||
Stop = true;
|
||||
} else Shrink_Timer -= diff;
|
||||
}
|
||||
Stop = false;
|
||||
Grow_Timer = 0;
|
||||
Shrink_Timer = 20000;
|
||||
|
||||
DoCast(me, SPELL_PUTRID_MUSHROOM, true);
|
||||
DoCast(me, SPELL_SPORE_CLOUD, true);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit * /*who*/) {}
|
||||
|
||||
void AttackStart(Unit* /*who*/) {}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (Stop)
|
||||
return;
|
||||
|
||||
if (Grow_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_GROW);
|
||||
Grow_Timer = 3000;
|
||||
} else Grow_Timer -= diff;
|
||||
|
||||
if (Shrink_Timer <= diff)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_GROW);
|
||||
Stop = true;
|
||||
} else Shrink_Timer -= diff;
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
CreatureAI* GetAI_mob_underbog_mushroom(Creature* pCreature)
|
||||
{
|
||||
return new mob_underbog_mushroomAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_hungarfen()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_hungarfen";
|
||||
newscript->GetAI = &GetAI_boss_hungarfen;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_underbog_mushroom";
|
||||
newscript->GetAI = &GetAI_mob_underbog_mushroom;
|
||||
newscript->RegisterSelf();
|
||||
new boss_hungarfen();
|
||||
new mob_underbog_mushroom();
|
||||
}
|
||||
|
||||
|
||||
+124
-123
@@ -34,154 +34,155 @@ EndScriptData */
|
||||
#define SPELL_SUMMON_SPORE_STRIDER 38755
|
||||
|
||||
#define ENTRY_SPORE_STRIDER 22299
|
||||
|
||||
struct boss_the_black_stalkerAI : public ScriptedAI
|
||||
␍class boss_the_black_stalker : public CreatureScript
|
||||
{
|
||||
boss_the_black_stalkerAI(Creature *c) : ScriptedAI(c)
|
||||
public:
|
||||
boss_the_black_stalker() : CreatureScript("boss_the_black_stalker") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
return new boss_the_black_stalkerAI (pCreature);
|
||||
}
|
||||
|
||||
uint32 SporeStriders_Timer;
|
||||
uint32 Levitate_Timer;
|
||||
uint32 ChainLightning_Timer;
|
||||
uint32 StaticCharge_Timer;
|
||||
uint64 LevitatedTarget;
|
||||
uint32 LevitatedTarget_Timer;
|
||||
bool InAir;
|
||||
uint32 check_Timer;
|
||||
std::list<uint64> Striders;
|
||||
|
||||
void Reset()
|
||||
struct boss_the_black_stalkerAI : public ScriptedAI
|
||||
{
|
||||
Levitate_Timer = 12000;
|
||||
ChainLightning_Timer = 6000;
|
||||
StaticCharge_Timer = 10000;
|
||||
SporeStriders_Timer = 10000+rand()%5000;
|
||||
check_Timer = 5000;
|
||||
LevitatedTarget = 0;
|
||||
LevitatedTarget_Timer = 0;
|
||||
Striders.clear();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit * /*who*/) {}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
if (summon && summon->GetEntry() == ENTRY_SPORE_STRIDER)
|
||||
boss_the_black_stalkerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
Striders.push_back(summon->GetGUID());
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
summon->AI()->AttackStart(pTarget);
|
||||
else
|
||||
if (me->getVictim())
|
||||
summon->AI()->AttackStart(me->getVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*who*/)
|
||||
{
|
||||
for (std::list<uint64>::const_iterator i = Striders.begin(); i != Striders.end(); ++i)
|
||||
if (Creature *strider = Unit::GetCreature(*me, *i))
|
||||
strider->DisappearAndDie();
|
||||
}
|
||||
uint32 SporeStriders_Timer;
|
||||
uint32 Levitate_Timer;
|
||||
uint32 ChainLightning_Timer;
|
||||
uint32 StaticCharge_Timer;
|
||||
uint64 LevitatedTarget;
|
||||
uint32 LevitatedTarget_Timer;
|
||||
bool InAir;
|
||||
uint32 check_Timer;
|
||||
std::list<uint64> Striders;
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Evade if too far
|
||||
if (check_Timer <= diff)
|
||||
void Reset()
|
||||
{
|
||||
float x,y,z,o;
|
||||
me->GetHomePosition(x,y,z,o);
|
||||
if (!me->IsWithinDist3d(x,y,z, 60))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
check_Timer = 1000;
|
||||
} else check_Timer -= diff;
|
||||
|
||||
// Spore Striders
|
||||
if (IsHeroic() && SporeStriders_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_SPORE_STRIDER);
|
||||
Levitate_Timer = 12000;
|
||||
ChainLightning_Timer = 6000;
|
||||
StaticCharge_Timer = 10000;
|
||||
SporeStriders_Timer = 10000+rand()%5000;
|
||||
} else SporeStriders_Timer -= diff;
|
||||
check_Timer = 5000;
|
||||
LevitatedTarget = 0;
|
||||
LevitatedTarget_Timer = 0;
|
||||
Striders.clear();
|
||||
}
|
||||
|
||||
// Levitate
|
||||
if (LevitatedTarget)
|
||||
void EnterCombat(Unit * /*who*/) {}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
if (LevitatedTarget_Timer <= diff)
|
||||
if (summon && summon->GetEntry() == ENTRY_SPORE_STRIDER)
|
||||
{
|
||||
if (Unit *pTarget = Unit::GetUnit(*me, LevitatedTarget))
|
||||
Striders.push_back(summon->GetGUID());
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
summon->AI()->AttackStart(pTarget);
|
||||
else
|
||||
if (me->getVictim())
|
||||
summon->AI()->AttackStart(me->getVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit * /*who*/)
|
||||
{
|
||||
for (std::list<uint64>::const_iterator i = Striders.begin(); i != Striders.end(); ++i)
|
||||
if (Creature *strider = Unit::GetCreature(*me, *i))
|
||||
strider->DisappearAndDie();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Evade if too far
|
||||
if (check_Timer <= diff)
|
||||
{
|
||||
float x,y,z,o;
|
||||
me->GetHomePosition(x,y,z,o);
|
||||
if (!me->IsWithinDist3d(x,y,z, 60))
|
||||
{
|
||||
if (!pTarget->HasAura(SPELL_LEVITATE))
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
check_Timer = 1000;
|
||||
} else check_Timer -= diff;
|
||||
|
||||
// Spore Striders
|
||||
if (IsHeroic() && SporeStriders_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SUMMON_SPORE_STRIDER);
|
||||
SporeStriders_Timer = 10000+rand()%5000;
|
||||
} else SporeStriders_Timer -= diff;
|
||||
|
||||
// Levitate
|
||||
if (LevitatedTarget)
|
||||
{
|
||||
if (LevitatedTarget_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = Unit::GetUnit(*me, LevitatedTarget))
|
||||
{
|
||||
LevitatedTarget = 0;
|
||||
return;
|
||||
}
|
||||
if (InAir)
|
||||
{
|
||||
pTarget->AddAura(SPELL_SUSPENSION, pTarget);
|
||||
LevitatedTarget = 0;
|
||||
if (!pTarget->HasAura(SPELL_LEVITATE))
|
||||
{
|
||||
LevitatedTarget = 0;
|
||||
return;
|
||||
}
|
||||
if (InAir)
|
||||
{
|
||||
pTarget->AddAura(SPELL_SUSPENSION, pTarget);
|
||||
LevitatedTarget = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTarget->CastSpell(pTarget, SPELL_MAGNETIC_PULL, true);
|
||||
InAir = true;
|
||||
LevitatedTarget_Timer = 1500;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pTarget->CastSpell(pTarget, SPELL_MAGNETIC_PULL, true);
|
||||
InAir = true;
|
||||
LevitatedTarget_Timer = 1500;
|
||||
}
|
||||
}
|
||||
else
|
||||
LevitatedTarget = 0;
|
||||
} else LevitatedTarget_Timer -= diff;
|
||||
}
|
||||
if (Levitate_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
{
|
||||
DoCast(pTarget, SPELL_LEVITATE);
|
||||
LevitatedTarget = pTarget->GetGUID();
|
||||
LevitatedTarget_Timer = 2000;
|
||||
InAir = false;
|
||||
LevitatedTarget = 0;
|
||||
} else LevitatedTarget_Timer -= diff;
|
||||
}
|
||||
Levitate_Timer = 12000+rand()%3000;
|
||||
} else Levitate_Timer -= diff;
|
||||
if (Levitate_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,1))
|
||||
{
|
||||
DoCast(pTarget, SPELL_LEVITATE);
|
||||
LevitatedTarget = pTarget->GetGUID();
|
||||
LevitatedTarget_Timer = 2000;
|
||||
InAir = false;
|
||||
}
|
||||
Levitate_Timer = 12000+rand()%3000;
|
||||
} else Levitate_Timer -= diff;
|
||||
|
||||
// Chain Lightning
|
||||
if (ChainLightning_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_CHAIN_LIGHTNING);
|
||||
ChainLightning_Timer = 7000;
|
||||
} else ChainLightning_Timer -= diff;
|
||||
// Chain Lightning
|
||||
if (ChainLightning_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM,0))
|
||||
DoCast(pTarget, SPELL_CHAIN_LIGHTNING);
|
||||
ChainLightning_Timer = 7000;
|
||||
} else ChainLightning_Timer -= diff;
|
||||
|
||||
// Static Charge
|
||||
if (StaticCharge_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0,30,true))
|
||||
DoCast(pTarget, SPELL_STATIC_CHARGE);
|
||||
StaticCharge_Timer = 10000;
|
||||
} else StaticCharge_Timer -= diff;
|
||||
// Static Charge
|
||||
if (StaticCharge_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM,0,30,true))
|
||||
DoCast(pTarget, SPELL_STATIC_CHARGE);
|
||||
StaticCharge_Timer = 10000;
|
||||
} else StaticCharge_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_the_black_stalker(Creature* pCreature)
|
||||
{
|
||||
return new boss_the_black_stalkerAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_the_black_stalker()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_the_black_stalker";
|
||||
newscript->GetAI = &GetAI_boss_the_black_stalker;
|
||||
newscript->RegisterSelf();
|
||||
new boss_the_black_stalker();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user