Big re-organization of repository [W.I.P]

This commit is contained in:
Yehonal
2016-08-11 20:25:27 +02:00
parent c62a72c0a8
commit 0f85ce1c54
3016 changed files with 1271 additions and 1 deletions

View File

@@ -1,340 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: boss_kri, boss_yauj, boss_vem : The Bug Trio
SD%Complete: 100
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "temple_of_ahnqiraj.h"
enum Spells
{
SPELL_CLEAVE = 26350,
SPELL_TOXIC_VOLLEY = 25812,
SPELL_POISON_CLOUD = 38718, //Only Spell with right dmg.
SPELL_ENRAGE = 34624, //Changed cause 25790 is cast on gamers too. Same prob with old explosion of twin emperors.
SPELL_CHARGE = 26561,
SPELL_KNOCKBACK = 26027,
SPELL_HEAL = 25807,
SPELL_FEAR = 19408
};
class boss_kri : public CreatureScript
{
public:
boss_kri() : CreatureScript("boss_kri") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_kriAI>(creature);
}
struct boss_kriAI : public ScriptedAI
{
boss_kriAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 Cleave_Timer;
uint32 ToxicVolley_Timer;
uint32 Check_Timer;
bool VemDead;
bool Death;
void Reset()
{
Cleave_Timer = urand(4000, 8000);
ToxicVolley_Timer = urand(6000, 12000);
Check_Timer = 2000;
VemDead = false;
Death = false;
}
void EnterCombat(Unit* /*who*/)
{
}
void JustDied(Unit* /*killer*/)
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Cleave_Timer
if (Cleave_Timer <= diff)
{
DoCastVictim(SPELL_CLEAVE);
Cleave_Timer = urand(5000, 12000);
} else Cleave_Timer -= diff;
//ToxicVolley_Timer
if (ToxicVolley_Timer <= diff)
{
DoCastVictim(SPELL_TOXIC_VOLLEY);
ToxicVolley_Timer = urand(10000, 15000);
} else ToxicVolley_Timer -= diff;
if (!HealthAbovePct(5) && !Death)
{
DoCastVictim(SPELL_POISON_CLOUD);
Death = true;
}
if (!VemDead)
{
//Checking if Vem is dead. If yes we will enrage.
if (Check_Timer <= diff)
{
if (instance->GetData(DATA_VEMISDEAD))
{
DoCast(me, SPELL_ENRAGE);
VemDead = true;
}
Check_Timer = 2000;
} else Check_Timer -=diff;
}
DoMeleeAttackIfReady();
}
};
};
class boss_vem : public CreatureScript
{
public:
boss_vem() : CreatureScript("boss_vem") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_vemAI>(creature);
}
struct boss_vemAI : public ScriptedAI
{
boss_vemAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 Charge_Timer;
uint32 KnockBack_Timer;
uint32 Enrage_Timer;
bool Enraged;
void Reset()
{
Charge_Timer = urand(15000, 27000);
KnockBack_Timer = urand(8000, 20000);
Enrage_Timer = 120000;
Enraged = false;
}
void JustDied(Unit* /*killer*/)
{
instance->SetData(DATA_VEM_DEATH, 0);
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
}
void EnterCombat(Unit* /*who*/)
{
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Charge_Timer
if (Charge_Timer <= diff)
{
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (target)
{
DoCast(target, SPELL_CHARGE);
//me->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true, 1);
AttackStart(target);
}
Charge_Timer = urand(8000, 16000);
} else Charge_Timer -= diff;
//KnockBack_Timer
if (KnockBack_Timer <= diff)
{
DoCastVictim(SPELL_KNOCKBACK);
if (DoGetThreat(me->GetVictim()))
DoModifyThreatPercent(me->GetVictim(), -80);
KnockBack_Timer = urand(15000, 25000);
} else KnockBack_Timer -= diff;
//Enrage_Timer
if (!Enraged && Enrage_Timer <= diff)
{
DoCast(me, SPELL_ENRAGE);
Enraged = true;
} else Charge_Timer -= diff;
DoMeleeAttackIfReady();
}
};
};
class boss_yauj : public CreatureScript
{
public:
boss_yauj() : CreatureScript("boss_yauj") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_yaujAI>(creature);
}
struct boss_yaujAI : public ScriptedAI
{
boss_yaujAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 Heal_Timer;
uint32 Fear_Timer;
uint32 Check_Timer;
bool VemDead;
void Reset()
{
Heal_Timer = urand(25000, 40000);
Fear_Timer = urand(12000, 24000);
Check_Timer = 2000;
VemDead = false;
}
void JustDied(Unit* /*killer*/)
{
if (instance->GetData(DATA_BUG_TRIO_DEATH) < 2)// Unlootable if death
me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
instance->SetData(DATA_BUG_TRIO_DEATH, 1);
for (uint8 i = 0; i < 10; ++i)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
{
if (Creature* Summoned = me->SummonCreature(15621, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
Summoned->AI()->AttackStart(target);
}
}
}
void EnterCombat(Unit* /*who*/)
{
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Fear_Timer
if (Fear_Timer <= diff)
{
DoCastVictim(SPELL_FEAR);
DoResetThreat();
Fear_Timer = 20000;
} else Fear_Timer -= diff;
//Casting Heal to other twins or herself.
if (Heal_Timer <= diff)
{
switch (urand(0, 2))
{
case 0:
if (Creature* kri = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_KRI)))
DoCast(kri, SPELL_HEAL);
break;
case 1:
if (Creature* vem = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_VEM)))
DoCast(vem, SPELL_HEAL);
break;
case 2:
DoCast(me, SPELL_HEAL);
break;
}
Heal_Timer = 15000+rand()%15000;
} else Heal_Timer -= diff;
//Checking if Vem is dead. If yes we will enrage.
if (Check_Timer <= diff)
{
if (!VemDead)
{
if (instance->GetData(DATA_VEMISDEAD))
{
DoCast(me, SPELL_ENRAGE);
VemDead = true;
}
}
Check_Timer = 2000;
} else Check_Timer -= diff;
DoMeleeAttackIfReady();
}
};
};
void AddSC_bug_trio()
{
new boss_kri();
new boss_vem();
new boss_yauj();
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,212 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Fankriss
SD%Complete: 100
SDComment: sound not implemented
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#define SOUND_SENTENCE_YOU 8588
#define SOUND_SERVE_TO 8589
#define SOUND_LAWS 8590
#define SOUND_TRESPASS 8591
#define SOUND_WILL_BE 8592
enum Spells
{
SPELL_MORTAL_WOUND = 28467,
SPELL_ROOT = 28858,
// Enrage for his spawns
SPELL_ENRAGE = 28798
};
class boss_fankriss : public CreatureScript
{
public:
boss_fankriss() : CreatureScript("boss_fankriss") { }
CreatureAI* GetAI(Creature* creature) const
{
return new boss_fankrissAI(creature);
}
struct boss_fankrissAI : public ScriptedAI
{
boss_fankrissAI(Creature* creature) : ScriptedAI(creature) { }
uint32 MortalWound_Timer;
uint32 SpawnHatchlings_Timer;
uint32 SpawnSpawns_Timer;
int Rand;
float RandX;
float RandY;
Creature* Hatchling;
Creature* Spawn;
void Reset()
{
MortalWound_Timer = urand(10000, 15000);
SpawnHatchlings_Timer = urand(6000, 12000);
SpawnSpawns_Timer = urand(15000, 45000);
}
void SummonSpawn(Unit* victim)
{
if (!victim)
return;
Rand = 10 + (rand()%10);
switch (rand()%2)
{
case 0: RandX = 0.0f - Rand; break;
case 1: RandX = 0.0f + Rand; break;
}
Rand = 10 + (rand()%10);
switch (rand()%2)
{
case 0: RandY = 0.0f - Rand; break;
case 1: RandY = 0.0f + Rand; break;
}
Rand = 0;
Spawn = DoSpawnCreature(15630, RandX, RandY, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
if (Spawn)
Spawn->AI()->AttackStart(victim);
}
void EnterCombat(Unit* /*who*/)
{
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//MortalWound_Timer
if (MortalWound_Timer <= diff)
{
DoCastVictim(SPELL_MORTAL_WOUND);
MortalWound_Timer = urand(10000, 20000);
} else MortalWound_Timer -= diff;
//Summon 1-3 Spawns of Fankriss at random time.
if (SpawnSpawns_Timer <= diff)
{
switch (urand(0, 2))
{
case 0:
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
break;
case 1:
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
break;
case 2:
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
SummonSpawn(SelectTarget(SELECT_TARGET_RANDOM, 0));
break;
}
SpawnSpawns_Timer = urand(30000, 60000);
} else SpawnSpawns_Timer -= diff;
// Teleporting Random Target to one of the three tunnels and spawn 4 hatchlings near the gamer.
//We will only telport if fankriss has more than 3% of hp so teleported gamers can always loot.
if (HealthAbovePct(3))
{
if (SpawnHatchlings_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
{
DoCast(target, SPELL_ROOT);
if (DoGetThreat(target))
DoModifyThreatPercent(target, -100);
switch (urand(0, 2))
{
case 0:
DoTeleportPlayer(target, -8106.0142f, 1289.2900f, -74.419533f, 5.112f);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
break;
case 1:
DoTeleportPlayer(target, -7990.135354f, 1155.1907f, -78.849319f, 2.608f);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
break;
case 2:
DoTeleportPlayer(target, -8159.7753f, 1127.9064f, -76.868660f, 0.675f);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()-3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-3, target->GetPositionY()+3, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()-5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
Hatchling = me->SummonCreature(15962, target->GetPositionX()-5, target->GetPositionY()+5, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
if (Hatchling)
Hatchling->AI()->AttackStart(target);
break;
}
}
SpawnHatchlings_Timer = urand(45000, 60000);
} else SpawnHatchlings_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_fankriss()
{
new boss_fankriss();
}

View File

@@ -1,156 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Huhuran
SD%Complete: 100
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Huhuran
{
EMOTE_FRENZY_KILL = 0,
EMOTE_BERSERK = 1,
SPELL_FRENZY = 26051,
SPELL_BERSERK = 26068,
SPELL_POISONBOLT = 26052,
SPELL_NOXIOUSPOISON = 26053,
SPELL_WYVERNSTING = 26180,
SPELL_ACIDSPIT = 26050
};
class boss_huhuran : public CreatureScript
{
public:
boss_huhuran() : CreatureScript("boss_huhuran") { }
CreatureAI* GetAI(Creature* creature) const
{
return new boss_huhuranAI(creature);
}
struct boss_huhuranAI : public ScriptedAI
{
boss_huhuranAI(Creature* creature) : ScriptedAI(creature) { }
uint32 Frenzy_Timer;
uint32 Wyvern_Timer;
uint32 Spit_Timer;
uint32 PoisonBolt_Timer;
uint32 NoxiousPoison_Timer;
uint32 FrenzyBack_Timer;
bool Frenzy;
bool Berserk;
void Reset()
{
Frenzy_Timer = urand(25000, 35000);
Wyvern_Timer = urand(18000, 28000);
Spit_Timer = 8000;
PoisonBolt_Timer = 4000;
NoxiousPoison_Timer = urand(10000, 20000);
FrenzyBack_Timer = 15000;
Frenzy = false;
Berserk = false;
}
void EnterCombat(Unit* /*who*/)
{
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Frenzy_Timer
if (!Frenzy && Frenzy_Timer <= diff)
{
DoCast(me, SPELL_FRENZY);
Talk(EMOTE_FRENZY_KILL);
Frenzy = true;
PoisonBolt_Timer = 3000;
Frenzy_Timer = urand(25000, 35000);
} else Frenzy_Timer -= diff;
// Wyvern Timer
if (Wyvern_Timer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
DoCast(target, SPELL_WYVERNSTING);
Wyvern_Timer = urand(15000, 32000);
} else Wyvern_Timer -= diff;
//Spit Timer
if (Spit_Timer <= diff)
{
DoCastVictim(SPELL_ACIDSPIT);
Spit_Timer = urand(5000, 10000);
} else Spit_Timer -= diff;
//NoxiousPoison_Timer
if (NoxiousPoison_Timer <= diff)
{
DoCastVictim(SPELL_NOXIOUSPOISON);
NoxiousPoison_Timer = urand(12000, 24000);
} else NoxiousPoison_Timer -= diff;
//PoisonBolt only if frenzy or berserk
if (Frenzy || Berserk)
{
if (PoisonBolt_Timer <= diff)
{
DoCastVictim(SPELL_POISONBOLT);
PoisonBolt_Timer = 3000;
} else PoisonBolt_Timer -= diff;
}
//FrenzyBack_Timer
if (Frenzy && FrenzyBack_Timer <= diff)
{
me->InterruptNonMeleeSpells(false);
Frenzy = false;
FrenzyBack_Timer = 15000;
} else FrenzyBack_Timer -= diff;
if (!Berserk && HealthBelowPct(31))
{
me->InterruptNonMeleeSpells(false);
Talk(EMOTE_BERSERK);
DoCast(me, SPELL_BERSERK);
Berserk = true;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_huhuran()
{
new boss_huhuran();
}

View File

@@ -1,147 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Ouro
SD%Complete: 85
SDComment: No model for submerging. Currently just invisible.
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "temple_of_ahnqiraj.h"
enum Spells
{
SPELL_SWEEP = 26103,
SPELL_SANDBLAST = 26102,
SPELL_GROUND_RUPTURE = 26100,
SPELL_BIRTH = 26262, // The Birth Animation
SPELL_DIRTMOUND_PASSIVE = 26092
};
class boss_ouro : public CreatureScript
{
public:
boss_ouro() : CreatureScript("boss_ouro") { }
CreatureAI* GetAI(Creature* creature) const
{
return new boss_ouroAI(creature);
}
struct boss_ouroAI : public ScriptedAI
{
boss_ouroAI(Creature* creature) : ScriptedAI(creature) { }
uint32 Sweep_Timer;
uint32 SandBlast_Timer;
uint32 Submerge_Timer;
uint32 Back_Timer;
uint32 ChangeTarget_Timer;
uint32 Spawn_Timer;
bool Enrage;
bool Submerged;
void Reset()
{
Sweep_Timer = urand(5000, 10000);
SandBlast_Timer = urand(20000, 35000);
Submerge_Timer = urand(90000, 150000);
Back_Timer = urand(30000, 45000);
ChangeTarget_Timer = urand(5000, 8000);
Spawn_Timer = urand(10000, 20000);
Enrage = false;
Submerged = false;
}
void EnterCombat(Unit* /*who*/)
{
DoCastVictim(SPELL_BIRTH);
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
//Sweep_Timer
if (!Submerged && Sweep_Timer <= diff)
{
DoCastVictim(SPELL_SWEEP);
Sweep_Timer = urand(15000, 30000);
} else Sweep_Timer -= diff;
//SandBlast_Timer
if (!Submerged && SandBlast_Timer <= diff)
{
DoCastVictim(SPELL_SANDBLAST);
SandBlast_Timer = urand(20000, 35000);
} else SandBlast_Timer -= diff;
//Submerge_Timer
if (!Submerged && Submerge_Timer <= diff)
{
//Cast
me->HandleEmoteCommand(EMOTE_ONESHOT_SUBMERGE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->setFaction(35);
DoCast(me, SPELL_DIRTMOUND_PASSIVE);
Submerged = true;
Back_Timer = urand(30000, 45000);
} else Submerge_Timer -= diff;
//ChangeTarget_Timer
if (Submerged && ChangeTarget_Timer <= diff)
{
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
if (target)
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
ChangeTarget_Timer = urand(10000, 20000);
} else ChangeTarget_Timer -= diff;
//Back_Timer
if (Submerged && Back_Timer <= diff)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->setFaction(14);
DoCastVictim(SPELL_GROUND_RUPTURE);
Submerged = false;
Submerge_Timer = urand(60000, 120000);
} else Back_Timer -= diff;
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_ouro()
{
new boss_ouro();
}

View File

@@ -1,306 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Sartura
SD%Complete: 95
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum Sartura
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_DEATH = 2,
SPELL_WHIRLWIND = 26083,
SPELL_ENRAGE = 28747, //Not sure if right ID.
SPELL_ENRAGEHARD = 28798,
//Guard Spell
SPELL_WHIRLWINDADD = 26038,
SPELL_KNOCKBACK = 26027
};
class boss_sartura : public CreatureScript
{
public:
boss_sartura() : CreatureScript("boss_sartura") { }
CreatureAI* GetAI(Creature* creature) const
{
return new boss_sarturaAI(creature);
}
struct boss_sarturaAI : public ScriptedAI
{
boss_sarturaAI(Creature* creature) : ScriptedAI(creature) { }
uint32 WhirlWind_Timer;
uint32 WhirlWindRandom_Timer;
uint32 WhirlWindEnd_Timer;
uint32 AggroReset_Timer;
uint32 AggroResetEnd_Timer;
uint32 EnrageHard_Timer;
bool Enraged;
bool EnragedHard;
bool WhirlWind;
bool AggroReset;
void Reset()
{
WhirlWind_Timer = 30000;
WhirlWindRandom_Timer = urand(3000, 7000);
WhirlWindEnd_Timer = 15000;
AggroReset_Timer = urand(45000, 55000);
AggroResetEnd_Timer = 5000;
EnrageHard_Timer = 10*60000;
WhirlWind = false;
AggroReset = false;
Enraged = false;
EnragedHard = false;
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (WhirlWind)
{
if (WhirlWindRandom_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
{
me->AddThreat(target, 1.0f);
me->TauntApply(target);
AttackStart(target);
}
WhirlWindRandom_Timer = urand(3000, 7000);
} else WhirlWindRandom_Timer -= diff;
if (WhirlWindEnd_Timer <= diff)
{
WhirlWind = false;
WhirlWind_Timer = urand(25000, 40000);
} else WhirlWindEnd_Timer -= diff;
}
if (!WhirlWind)
{
if (WhirlWind_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWIND);
WhirlWind = true;
WhirlWindEnd_Timer = 15000;
} else WhirlWind_Timer -= diff;
if (AggroReset_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
{
me->AddThreat(target, 1.0f);
me->TauntApply(target);
AttackStart(target);
}
AggroReset = true;
AggroReset_Timer = urand(2000, 5000);
} else AggroReset_Timer -= diff;
if (AggroReset)
{
if (AggroResetEnd_Timer <= diff)
{
AggroReset = false;
AggroResetEnd_Timer = 5000;
AggroReset_Timer = urand(35000, 45000);
} else AggroResetEnd_Timer -= diff;
}
//If she is 20% enrage
if (!Enraged)
{
if (!HealthAbovePct(20) && !me->IsNonMeleeSpellCast(false))
{
DoCast(me, SPELL_ENRAGE);
Enraged = true;
}
}
//After 10 minutes hard enrage
if (!EnragedHard)
{
if (EnrageHard_Timer <= diff)
{
DoCast(me, SPELL_ENRAGEHARD);
EnragedHard = true;
} else EnrageHard_Timer -= diff;
}
DoMeleeAttackIfReady();
}
}
};
};
class npc_sartura_royal_guard : public CreatureScript
{
public:
npc_sartura_royal_guard() : CreatureScript("npc_sartura_royal_guard") { }
CreatureAI* GetAI(Creature* creature) const
{
return new npc_sartura_royal_guardAI(creature);
}
struct npc_sartura_royal_guardAI : public ScriptedAI
{
npc_sartura_royal_guardAI(Creature* creature) : ScriptedAI(creature) { }
uint32 WhirlWind_Timer;
uint32 WhirlWindRandom_Timer;
uint32 WhirlWindEnd_Timer;
uint32 AggroReset_Timer;
uint32 AggroResetEnd_Timer;
uint32 KnockBack_Timer;
bool WhirlWind;
bool AggroReset;
void Reset()
{
WhirlWind_Timer = 30000;
WhirlWindRandom_Timer = urand(3000, 7000);
WhirlWindEnd_Timer = 15000;
AggroReset_Timer = urand(45000, 55000);
AggroResetEnd_Timer = 5000;
KnockBack_Timer = 10000;
WhirlWind = false;
AggroReset = false;
}
void EnterCombat(Unit* /*who*/)
{
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (!WhirlWind && WhirlWind_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWINDADD);
WhirlWind = true;
WhirlWind_Timer = urand(25000, 40000);
WhirlWindEnd_Timer = 15000;
} else WhirlWind_Timer -= diff;
if (WhirlWind)
{
if (WhirlWindRandom_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
{
me->AddThreat(target, 1.0f);
me->TauntApply(target);
AttackStart(target);
}
WhirlWindRandom_Timer = urand(3000, 7000);
} else WhirlWindRandom_Timer -= diff;
if (WhirlWindEnd_Timer <= diff)
{
WhirlWind = false;
} else WhirlWindEnd_Timer -= diff;
}
if (!WhirlWind)
{
if (AggroReset_Timer <= diff)
{
//Attack random Gamers
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100.0f, true))
{
me->AddThreat(target, 1.0f);
me->TauntApply(target);
AttackStart(target);
}
AggroReset = true;
AggroReset_Timer = urand(2000, 5000);
} else AggroReset_Timer -= diff;
if (KnockBack_Timer <= diff)
{
DoCast(me, SPELL_WHIRLWINDADD);
KnockBack_Timer = urand(10000, 20000);
} else KnockBack_Timer -= diff;
}
if (AggroReset)
{
if (AggroResetEnd_Timer <= diff)
{
AggroReset = false;
AggroResetEnd_Timer = 5000;
AggroReset_Timer = urand(30000, 40000);
} else AggroResetEnd_Timer -= diff;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_sartura()
{
new boss_sartura();
new npc_sartura_royal_guard();
}

View File

@@ -1,228 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "temple_of_ahnqiraj.h"
enum Yells
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_SPLIT = 2,
SAY_DEATH = 3
};
enum Spells
{
SPELL_ARCANE_EXPLOSION = 26192,
SPELL_EARTH_SHOCK = 26194,
SPELL_TRUE_FULFILLMENT = 785,
SPELL_INITIALIZE_IMAGE = 3730,
SPELL_SUMMON_IMAGES = 747
};
enum Events
{
EVENT_ARCANE_EXPLOSION = 1,
EVENT_FULLFILMENT = 2,
EVENT_BLINK = 3,
EVENT_EARTH_SHOCK = 4
};
uint32 const BlinkSpells[3] = { 4801, 8195, 20449 };
class boss_skeram : public CreatureScript
{
public:
boss_skeram() : CreatureScript("boss_skeram") { }
struct boss_skeramAI : public BossAI
{
boss_skeramAI(Creature* creature) : BossAI(creature, DATA_SKERAM) { }
void Reset()
{
_flag = 0;
_hpct = 75.0f;
me->SetVisible(true);
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
void EnterEvadeMode()
{
ScriptedAI::EnterEvadeMode();
if (me->IsSummon())
((TempSummon*)me)->UnSummon();
}
void JustSummoned(Creature* creature)
{
// Shift the boss and images (Get it? *Shift*?)
uint8 rand = 0;
if (_flag != 0)
{
while (_flag & (1 << rand))
rand = urand(0, 2);
DoCast(me, BlinkSpells[rand]);
_flag |= (1 << rand);
_flag |= (1 << 7);
}
while (_flag & (1 << rand))
rand = urand(0, 2);
creature->CastSpell(creature, BlinkSpells[rand]);
_flag |= (1 << rand);
if (_flag & (1 << 7))
_flag = 0;
if (Unit* Target = SelectTarget(SELECT_TARGET_RANDOM))
creature->AI()->AttackStart(Target);
float ImageHealthPct;
if (me->GetHealthPct() < 25.0f)
ImageHealthPct = 0.50f;
else if (me->GetHealthPct() < 50.0f)
ImageHealthPct = 0.20f;
else
ImageHealthPct = 0.10f;
creature->SetMaxHealth(me->GetMaxHealth() * ImageHealthPct);
creature->SetHealth(creature->GetMaxHealth() * (me->GetHealthPct() / 100.0f));
}
void JustDied(Unit* /*killer*/)
{
if (!me->IsSummon())
Talk(SAY_DEATH);
else
me->RemoveCorpse();
}
void EnterCombat(Unit* /*who*/)
{
_EnterCombat();
events.Reset();
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(6000, 12000));
events.ScheduleEvent(EVENT_FULLFILMENT, 15000);
events.ScheduleEvent(EVENT_BLINK, urand(30000, 45000));
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
Talk(SAY_AGGRO);
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_ARCANE_EXPLOSION:
DoCastAOE(SPELL_ARCANE_EXPLOSION, true);
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, urand(8000, 18000));
break;
case EVENT_FULLFILMENT:
/// @todo For some weird reason boss does not cast this
// Spell actually works, tested in duel
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true), SPELL_TRUE_FULFILLMENT, true);
events.ScheduleEvent(EVENT_FULLFILMENT, urand(20000, 30000));
break;
case EVENT_BLINK:
DoCast(me, BlinkSpells[urand(0, 2)]);
DoResetThreat();
me->SetVisible(true);
events.ScheduleEvent(EVENT_BLINK, urand(10000, 30000));
break;
case EVENT_EARTH_SHOCK:
DoCastVictim(SPELL_EARTH_SHOCK);
events.ScheduleEvent(EVENT_EARTH_SHOCK, 2000);
break;
}
}
if (!me->IsSummon() && me->GetHealthPct() < _hpct)
{
DoCast(me, SPELL_SUMMON_IMAGES);
Talk(SAY_SPLIT);
_hpct -= 25.0f;
me->SetVisible(false);
events.RescheduleEvent(EVENT_BLINK, 2000);
}
if (me->IsWithinMeleeRange(me->GetVictim()))
{
events.RescheduleEvent(EVENT_EARTH_SHOCK, 2000);
DoMeleeAttackIfReady();
}
}
private:
float _hpct;
uint8 _flag;
};
CreatureAI* GetAI(Creature* creature) const
{
return new boss_skeramAI(creature);
}
};
class spell_skeram_arcane_explosion : public SpellScriptLoader
{
public:
spell_skeram_arcane_explosion() : SpellScriptLoader("spell_skeram_arcane_explosion") { }
class spell_skeram_arcane_explosion_SpellScript : public SpellScript
{
PrepareSpellScript(spell_skeram_arcane_explosion_SpellScript);
void FilterTargets(std::list<WorldObject*>& targets)
{
targets.remove_if(PlayerOrPetCheck());
}
void Register()
{
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_skeram_arcane_explosion_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_skeram_arcane_explosion_SpellScript();
}
};
void AddSC_boss_skeram()
{
new boss_skeram();
new spell_skeram_arcane_explosion();
}

View File

@@ -1,594 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Twinemperors
SD%Complete: 95
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "temple_of_ahnqiraj.h"
#include "WorldPacket.h"
#include "Item.h"
#include "Spell.h"
enum Spells
{
SPELL_HEAL_BROTHER = 7393,
SPELL_TWIN_TELEPORT = 800, // CTRA watches for this spell to start its teleport timer
SPELL_TWIN_TELEPORT_VISUAL = 26638, // visual
SPELL_EXPLODEBUG = 804,
SPELL_MUTATE_BUG = 802,
SPELL_BERSERK = 26662,
SPELL_UPPERCUT = 26007,
SPELL_UNBALANCING_STRIKE = 26613,
SPELL_SHADOWBOLT = 26006,
SPELL_BLIZZARD = 26607,
SPELL_ARCANEBURST = 568,
};
enum Sound
{
SOUND_VL_AGGRO = 8657, //8657 - Aggro - To Late
SOUND_VL_KILL = 8658, //8658 - Kill - You will not
SOUND_VL_DEATH = 8659, //8659 - Death
SOUND_VN_DEATH = 8660, //8660 - Death - Feel
SOUND_VN_AGGRO = 8661, //8661 - Aggro - Let none
SOUND_VN_KILL = 8662, //8661 - Kill - your fate
};
enum Misc
{
PULL_RANGE = 50,
ABUSE_BUG_RANGE = 20,
VEKLOR_DIST = 20, // VL will not come to melee when attacking
TELEPORTTIME = 30000
};
struct boss_twinemperorsAI : public ScriptedAI
{
boss_twinemperorsAI(Creature* creature): ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint32 Heal_Timer;
uint32 Teleport_Timer;
bool AfterTeleport;
uint32 AfterTeleportTimer;
bool DontYellWhenDead;
uint32 Abuse_Bug_Timer, BugsTimer;
bool tspellcast;
uint32 EnrageTimer;
virtual bool IAmVeklor() = 0;
virtual void Reset() = 0;
virtual void CastSpellOnBug(Creature* target) = 0;
void TwinReset()
{
Heal_Timer = 0; // first heal immediately when they get close together
Teleport_Timer = TELEPORTTIME;
AfterTeleport = false;
tspellcast = false;
AfterTeleportTimer = 0;
Abuse_Bug_Timer = urand(10000, 17000);
BugsTimer = 2000;
me->ClearUnitState(UNIT_STATE_STUNNED);
DontYellWhenDead = false;
EnrageTimer = 15*60000;
}
Creature* GetOtherBoss()
{
return ObjectAccessor::GetCreature(*me, instance->GetData64(IAmVeklor() ? DATA_VEKNILASH : DATA_VEKLOR));
}
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
{
Unit* pOtherBoss = GetOtherBoss();
if (pOtherBoss)
{
float dPercent = ((float)damage) / ((float)me->GetMaxHealth());
int odmg = (int)(dPercent * ((float)pOtherBoss->GetMaxHealth()));
int ohealth = pOtherBoss->GetHealth()-odmg;
pOtherBoss->SetHealth(ohealth > 0 ? ohealth : 0);
if (ohealth <= 0)
{
pOtherBoss->setDeathState(JUST_DIED);
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
}
}
}
void JustDied(Unit* /*killer*/)
{
Creature* pOtherBoss = GetOtherBoss();
if (pOtherBoss)
{
pOtherBoss->SetHealth(0);
pOtherBoss->setDeathState(JUST_DIED);
pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->DontYellWhenDead = true;
}
if (!DontYellWhenDead) // I hope AI is not threaded
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_DEATH : SOUND_VN_DEATH);
}
void KilledUnit(Unit* /*victim*/)
{
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_KILL : SOUND_VN_KILL);
}
void EnterCombat(Unit* who)
{
DoZoneInCombat();
Creature* pOtherBoss = GetOtherBoss();
if (pOtherBoss)
{
/// @todo we should activate the other boss location so he can start attackning even if nobody
// is near I dont know how to do that
ScriptedAI* otherAI = CAST_AI(ScriptedAI, pOtherBoss->AI());
if (!pOtherBoss->IsInCombat())
{
DoPlaySoundToSet(me, IAmVeklor() ? SOUND_VL_AGGRO : SOUND_VN_AGGRO);
otherAI->AttackStart(who);
otherAI->DoZoneInCombat();
}
}
}
void SpellHit(Unit* caster, const SpellInfo* entry)
{
if (caster == me)
return;
Creature* pOtherBoss = GetOtherBoss();
if (entry->Id != SPELL_HEAL_BROTHER || !pOtherBoss)
return;
// add health so we keep same percentage for both brothers
uint32 mytotal = me->GetMaxHealth(), histotal = pOtherBoss->GetMaxHealth();
float mult = ((float)mytotal) / ((float)histotal);
if (mult < 1)
mult = 1.0f/mult;
#define HEAL_BROTHER_AMOUNT 30000.0f
uint32 largerAmount = (uint32)((HEAL_BROTHER_AMOUNT * mult) - HEAL_BROTHER_AMOUNT);
if (mytotal > histotal)
{
uint32 h = me->GetHealth()+largerAmount;
me->SetHealth(std::min(mytotal, h));
}
else
{
uint32 h = pOtherBoss->GetHealth()+largerAmount;
pOtherBoss->SetHealth(std::min(histotal, h));
}
}
void TryHealBrother(uint32 diff)
{
if (IAmVeklor()) // this spell heals caster and the other brother so let VN cast it
return;
if (Heal_Timer <= diff)
{
Unit* pOtherBoss = GetOtherBoss();
if (pOtherBoss && pOtherBoss->IsWithinDist(me, 60))
{
DoCast(pOtherBoss, SPELL_HEAL_BROTHER);
Heal_Timer = 1000;
}
} else Heal_Timer -= diff;
}
void TeleportToMyBrother()
{
Teleport_Timer = TELEPORTTIME;
if (IAmVeklor())
return; // mechanics handled by veknilash so they teleport exactly at the same time and to correct coordinates
Creature* pOtherBoss = GetOtherBoss();
if (pOtherBoss)
{
//me->MonsterYell("Teleporting ...", LANG_UNIVERSAL, 0);
Position thisPos;
thisPos.Relocate(me);
Position otherPos;
otherPos.Relocate(pOtherBoss);
pOtherBoss->SetPosition(thisPos);
me->SetPosition(otherPos);
SetAfterTeleport();
CAST_AI(boss_twinemperorsAI, pOtherBoss->AI())->SetAfterTeleport();
}
}
void SetAfterTeleport()
{
me->InterruptNonMeleeSpells(false);
DoStopAttack();
DoResetThreat();
DoCast(me, SPELL_TWIN_TELEPORT_VISUAL);
me->AddUnitState(UNIT_STATE_STUNNED);
AfterTeleport = true;
AfterTeleportTimer = 2000;
tspellcast = false;
}
bool TryActivateAfterTTelep(uint32 diff)
{
if (AfterTeleport)
{
if (!tspellcast)
{
me->ClearUnitState(UNIT_STATE_STUNNED);
DoCast(me, SPELL_TWIN_TELEPORT);
me->AddUnitState(UNIT_STATE_STUNNED);
}
tspellcast = true;
if (AfterTeleportTimer <= diff)
{
AfterTeleport = false;
me->ClearUnitState(UNIT_STATE_STUNNED);
if (Unit* nearu = me->SelectNearestTarget(100))
{
//DoYell(nearu->GetName(), LANG_UNIVERSAL, 0);
AttackStart(nearu);
me->AddThreat(nearu, 10000);
}
return true;
}
else
{
AfterTeleportTimer -= diff;
// update important timers which would otherwise get skipped
if (EnrageTimer > diff)
EnrageTimer -= diff;
else
EnrageTimer = 0;
if (Teleport_Timer > diff)
Teleport_Timer -= diff;
else
Teleport_Timer = 0;
return false;
}
}
else
{
return true;
}
}
void MoveInLineOfSight(Unit* who)
{
if (!who || me->GetVictim())
return;
if (me->_CanDetectFeignDeathOf(who) && me->CanCreatureAttack(who))
{
if (me->IsWithinDistInMap(who, PULL_RANGE) && me->GetDistanceZ(who) <= /*CREATURE_Z_ATTACK_RANGE*/7 /*there are stairs*/)
{
//if (who->HasStealthAura())
// who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);
AttackStart(who);
}
}
}
Creature* RespawnNearbyBugsAndGetOne()
{
std::list<Creature*> lUnitList;
me->GetCreatureListWithEntryInGrid(lUnitList, 15316, 150.0f);
me->GetCreatureListWithEntryInGrid(lUnitList, 15317, 150.0f);
if (lUnitList.empty())
return NULL;
Creature* nearb = NULL;
for (std::list<Creature*>::const_iterator iter = lUnitList.begin(); iter != lUnitList.end(); ++iter)
{
Creature* c = *iter;
if (c)
{
if (c->isDead())
{
c->Respawn();
c->setFaction(7);
c->RemoveAllAuras();
}
if (c->IsWithinDistInMap(me, ABUSE_BUG_RANGE))
{
if (!nearb || (rand()%4) == 0)
nearb = c;
}
}
}
return nearb;
}
void HandleBugs(uint32 diff)
{
if (BugsTimer < diff || Abuse_Bug_Timer <= diff)
{
Creature* c = RespawnNearbyBugsAndGetOne();
if (Abuse_Bug_Timer <= diff)
{
if (c)
{
CastSpellOnBug(c);
Abuse_Bug_Timer = urand(10000, 17000);
}
else
{
Abuse_Bug_Timer = 1000;
}
}
else
{
Abuse_Bug_Timer -= diff;
}
BugsTimer = 2000;
}
else
{
BugsTimer -= diff;
Abuse_Bug_Timer -= diff;
}
}
void CheckEnrage(uint32 diff)
{
if (EnrageTimer <= diff)
{
if (!me->IsNonMeleeSpellCast(true))
{
DoCast(me, SPELL_BERSERK);
EnrageTimer = 60*60000;
} else EnrageTimer = 0;
} else EnrageTimer-=diff;
}
};
class boss_veknilash : public CreatureScript
{
public:
boss_veknilash() : CreatureScript("boss_veknilash") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_veknilashAI>(creature);
}
struct boss_veknilashAI : public boss_twinemperorsAI
{
bool IAmVeklor() {return false;}
boss_veknilashAI(Creature* creature) : boss_twinemperorsAI(creature) { }
uint32 UpperCut_Timer;
uint32 UnbalancingStrike_Timer;
uint32 Scarabs_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
void Reset()
{
TwinReset();
UpperCut_Timer = urand(14000, 29000);
UnbalancingStrike_Timer = urand(8000, 18000);
Scarabs_Timer = urand(7000, 14000);
//Added. Can be removed if its included in DB.
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_MAGIC, true);
}
void CastSpellOnBug(Creature* target)
{
target->setFaction(14);
target->AI()->AttackStart(me->getThreatManager().getHostilTarget());
target->AddAura(SPELL_MUTATE_BUG, target);
target->SetFullHealth();
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (!TryActivateAfterTTelep(diff))
return;
//UnbalancingStrike_Timer
if (UnbalancingStrike_Timer <= diff)
{
DoCastVictim(SPELL_UNBALANCING_STRIKE);
UnbalancingStrike_Timer = 8000+rand()%12000;
} else UnbalancingStrike_Timer -= diff;
if (UpperCut_Timer <= diff)
{
Unit* randomMelee = SelectTarget(SELECT_TARGET_RANDOM, 0, NOMINAL_MELEE_RANGE, true);
if (randomMelee)
DoCast(randomMelee, SPELL_UPPERCUT);
UpperCut_Timer = 15000+rand()%15000;
} else UpperCut_Timer -= diff;
HandleBugs(diff);
//Heal brother when 60yrds close
TryHealBrother(diff);
//Teleporting to brother
if (Teleport_Timer <= diff)
{
TeleportToMyBrother();
} else Teleport_Timer -= diff;
CheckEnrage(diff);
DoMeleeAttackIfReady();
}
};
};
class boss_veklor : public CreatureScript
{
public:
boss_veklor() : CreatureScript("boss_veklor") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_veklorAI>(creature);
}
struct boss_veklorAI : public boss_twinemperorsAI
{
bool IAmVeklor() {return true;}
boss_veklorAI(Creature* creature) : boss_twinemperorsAI(creature) { }
uint32 ShadowBolt_Timer;
uint32 Blizzard_Timer;
uint32 ArcaneBurst_Timer;
uint32 Scorpions_Timer;
int Rand;
int RandX;
int RandY;
Creature* Summoned;
void Reset()
{
TwinReset();
ShadowBolt_Timer = 0;
Blizzard_Timer = urand(15000, 20000);
ArcaneBurst_Timer = 1000;
Scorpions_Timer = urand(7000, 14000);
//Added. Can be removed if its included in DB.
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, true);
}
void CastSpellOnBug(Creature* target)
{
target->setFaction(14);
target->AddAura(SPELL_EXPLODEBUG, target);
target->SetFullHealth();
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
// reset arcane burst after teleport - we need to do this because
// when VL jumps to VN's location there will be a warrior who will get only 2s to run away
// which is almost impossible
if (AfterTeleport)
ArcaneBurst_Timer = 5000;
if (!TryActivateAfterTTelep(diff))
return;
//ShadowBolt_Timer
if (ShadowBolt_Timer <= diff)
{
if (!me->IsWithinDist(me->GetVictim(), 45.0f))
me->GetMotionMaster()->MoveChase(me->GetVictim(), VEKLOR_DIST, 0);
else
DoCastVictim(SPELL_SHADOWBOLT);
ShadowBolt_Timer = 2000;
} else ShadowBolt_Timer -= diff;
//Blizzard_Timer
if (Blizzard_Timer <= diff)
{
Unit* target = NULL;
target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45, true);
if (target)
DoCast(target, SPELL_BLIZZARD);
Blizzard_Timer = 15000+rand()%15000;
} else Blizzard_Timer -= diff;
if (ArcaneBurst_Timer <= diff)
{
Unit* mvic;
if ((mvic=SelectTarget(SELECT_TARGET_NEAREST, 0, NOMINAL_MELEE_RANGE, true)) != NULL)
{
DoCast(mvic, SPELL_ARCANEBURST);
ArcaneBurst_Timer = 5000;
}
} else ArcaneBurst_Timer -= diff;
HandleBugs(diff);
//Heal brother when 60yrds close
TryHealBrother(diff);
//Teleporting to brother
if (Teleport_Timer <= diff)
{
TeleportToMyBrother();
} else Teleport_Timer -= diff;
CheckEnrage(diff);
//VL doesn't melee
//DoMeleeAttackIfReady();
}
void AttackStart(Unit* who)
{
if (!who)
return;
if (who->isTargetableForAttack())
{
// VL doesn't melee
if (me->Attack(who, false))
{
me->GetMotionMaster()->MoveChase(who, VEKLOR_DIST, 0);
me->AddThreat(who, 0.0f);
}
}
}
};
};
void AddSC_boss_twinemperors()
{
new boss_veknilash();
new boss_veklor();
}

View File

@@ -1,306 +0,0 @@
/*
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
#include "temple_of_ahnqiraj.h"
enum Spells
{
SPELL_POISON_SHOCK = 25993,
SPELL_POISONBOLT_VOLLEY = 25991,
SPELL_TOXIN = 26575,
SPELL_VISCIDUS_SLOWED = 26034,
SPELL_VISCIDUS_SLOWED_MORE = 26036,
SPELL_VISCIDUS_FREEZE = 25937,
SPELL_REJOIN_VISCIDUS = 25896,
SPELL_VISCIDUS_EXPLODE = 25938,
SPELL_VISCIDUS_SUICIDE = 26003,
SPELL_VISCIDUS_SHRINKS = 25893, // Removed from client, in world.spell_dbc
SPELL_MEMBRANE_VISCIDUS = 25994, // damage reduction spell - removed from DBC
SPELL_VISCIDUS_WEAKNESS = 25926, // aura which procs at damage - should trigger the slow spells - removed from DBC
SPELL_VISCIDUS_GROWS = 25897, // removed from DBC
SPELL_SUMMON_GLOBS = 25885, // summons npc 15667 using spells from 25865 to 25884; All spells have target coords - removed from DBC
SPELL_VISCIDUS_TELEPORT = 25904, // removed from DBC
};
enum Events
{
EVENT_POISONBOLT_VOLLEY = 1,
EVENT_POISON_SHOCK = 2,
EVENT_RESET_PHASE = 3
};
enum Phases
{
PHASE_FROST = 1,
PHASE_MELEE = 2,
PHASE_GLOB = 3
};
enum Emotes
{
EMOTE_SLOW = 0,
EMOTE_FREEZE = 1,
EMOTE_FROZEN = 2,
EMOTE_CRACK = 3,
EMOTE_SHATTER = 4,
EMOTE_EXPLODE = 5
};
enum HitCounter
{
HITCOUNTER_SLOW = 100,
HITCOUNTER_SLOW_MORE = 150,
HITCOUNTER_FREEZE = 200,
HITCOUNTER_CRACK = 50,
HITCOUNTER_SHATTER = 100,
HITCOUNTER_EXPLODE = 150,
};
enum MovePoints
{
ROOM_CENTER = 1
};
Position const ViscidusCoord = { -7992.36f, 908.19f, -52.62f, 1.68f }; /// @todo Visci isn't in room middle
float const RoomRadius = 40.0f; /// @todo Not sure if its correct
class boss_viscidus : public CreatureScript
{
public:
boss_viscidus() : CreatureScript("boss_viscidus") { }
struct boss_viscidusAI : public BossAI
{
boss_viscidusAI(Creature* creature) : BossAI(creature, DATA_VISCIDUS) { }
void Reset()
{
_Reset();
_hitcounter = 0;
_phase = PHASE_FROST;
}
void DamageTaken(Unit* attacker, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
{
if (!attacker || _phase != PHASE_MELEE)
return;
++_hitcounter;
if (attacker->HasUnitState(UNIT_STATE_MELEE_ATTACKING) && _hitcounter >= HITCOUNTER_EXPLODE)
{
Talk(EMOTE_EXPLODE);
events.Reset();
_phase = PHASE_GLOB;
DoCast(me, SPELL_VISCIDUS_EXPLODE);
me->SetVisible(false);
me->RemoveAura(SPELL_TOXIN);
me->RemoveAura(SPELL_VISCIDUS_FREEZE);
uint8 NumGlobes = me->GetHealthPct() / 5.0f;
for (uint8 i = 0; i < NumGlobes; ++i)
{
float Angle = i * 2 * M_PI / NumGlobes;
float X = ViscidusCoord.GetPositionX() + std::cos(Angle) * RoomRadius;
float Y = ViscidusCoord.GetPositionY() + std::sin(Angle) * RoomRadius;
float Z = -35.0f;
if (TempSummon* Glob = me->SummonCreature(NPC_GLOB_OF_VISCIDUS, X, Y, Z))
{
Glob->UpdateAllowedPositionZ(X, Y, Z);
Glob->NearTeleportTo(X, Y, Z, 0.0f);
Glob->GetMotionMaster()->MovePoint(ROOM_CENTER, ViscidusCoord);
}
}
}
else if (_hitcounter == HITCOUNTER_SHATTER)
Talk(EMOTE_SHATTER);
else if (_hitcounter == HITCOUNTER_CRACK)
Talk(EMOTE_CRACK);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell)
{
if ((spell->GetSchoolMask() & SPELL_SCHOOL_MASK_FROST) && _phase == PHASE_FROST && me->GetHealthPct() > 5.0f)
{
++_hitcounter;
if (_hitcounter >= HITCOUNTER_FREEZE)
{
_hitcounter = 0;
Talk(EMOTE_FROZEN);
_phase = PHASE_MELEE;
DoCast(me, SPELL_VISCIDUS_FREEZE);
me->RemoveAura(SPELL_VISCIDUS_SLOWED_MORE);
events.ScheduleEvent(EVENT_RESET_PHASE, 15000);
}
else if (_hitcounter >= HITCOUNTER_SLOW_MORE)
{
Talk(EMOTE_FREEZE);
me->RemoveAura(SPELL_VISCIDUS_SLOWED);
DoCast(me, SPELL_VISCIDUS_SLOWED_MORE);
}
else if (_hitcounter >= HITCOUNTER_SLOW)
{
Talk(EMOTE_SLOW);
DoCast(me, SPELL_VISCIDUS_SLOWED);
}
}
}
void EnterCombat(Unit* /*who*/)
{
_EnterCombat();
events.Reset();
InitSpells();
}
void InitSpells()
{
DoCast(me, SPELL_TOXIN);
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
}
void EnterEvadeMode()
{
summons.DespawnAll();
ScriptedAI::EnterEvadeMode();
}
void JustDied(Unit* /*killer*/)
{
DoCast(me, SPELL_VISCIDUS_SUICIDE);
summons.DespawnAll();
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
if (_phase == PHASE_GLOB && summons.empty())
{
DoResetThreat();
me->NearTeleportTo(ViscidusCoord.GetPositionX(),
ViscidusCoord.GetPositionY(),
ViscidusCoord.GetPositionZ(),
ViscidusCoord.GetOrientation());
_hitcounter = 0;
_phase = PHASE_FROST;
InitSpells();
me->SetVisible(true);
}
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_POISONBOLT_VOLLEY:
DoCast(me, SPELL_POISONBOLT_VOLLEY);
events.ScheduleEvent(EVENT_POISONBOLT_VOLLEY, urand(10000, 15000));
break;
case EVENT_POISON_SHOCK:
DoCast(me, SPELL_POISON_SHOCK);
events.ScheduleEvent(EVENT_POISON_SHOCK, urand(7000, 12000));
break;
case EVENT_RESET_PHASE:
_hitcounter = 0;
_phase = PHASE_FROST;
break;
default:
break;
}
}
if (_phase != PHASE_GLOB)
DoMeleeAttackIfReady();
}
private:
uint8 _hitcounter;
Phases _phase;
};
CreatureAI* GetAI(Creature* creature) const
{
return new boss_viscidusAI(creature);
}
};
class npc_glob_of_viscidus : public CreatureScript
{
public:
npc_glob_of_viscidus() : CreatureScript("boss_glob_of_viscidus") { }
struct npc_glob_of_viscidusAI : public ScriptedAI
{
npc_glob_of_viscidusAI(Creature* creature) : ScriptedAI(creature) { }
void JustDied(Unit* /*killer*/)
{
InstanceScript* Instance = me->GetInstanceScript();
if (Creature* Viscidus = me->GetMap()->GetCreature(Instance->GetData64(DATA_VISCIDUS)))
{
if (BossAI* ViscidusAI = dynamic_cast<BossAI*>(Viscidus->GetAI()))
ViscidusAI->SummonedCreatureDespawn(me);
if (Viscidus->IsAlive() && Viscidus->GetHealthPct() < 5.0f)
{
Viscidus->SetVisible(true);
Unit::Kill(Viscidus->GetVictim(), Viscidus);
}
else
{
Viscidus->SetHealth(Viscidus->GetHealth() - Viscidus->GetMaxHealth() / 20);
Viscidus->CastSpell(Viscidus, SPELL_VISCIDUS_SHRINKS);
}
}
}
void MovementInform(uint32 /*type*/, uint32 id)
{
if (id == ROOM_CENTER)
{
DoCast(me, SPELL_REJOIN_VISCIDUS);
if (TempSummon* summon = me->ToTempSummon())
summon->UnSummon();
}
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<npc_glob_of_viscidusAI>(creature);
}
};
void AddSC_boss_viscidus()
{
new boss_viscidus();
new npc_glob_of_viscidus();
}

View File

@@ -1,188 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Instance_Temple_of_Ahnqiraj
SD%Complete: 80
SDComment:
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "temple_of_ahnqiraj.h"
class instance_temple_of_ahnqiraj : public InstanceMapScript
{
public:
instance_temple_of_ahnqiraj() : InstanceMapScript("instance_temple_of_ahnqiraj", 531) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const
{
return new instance_temple_of_ahnqiraj_InstanceMapScript(map);
}
struct instance_temple_of_ahnqiraj_InstanceMapScript : public InstanceScript
{
instance_temple_of_ahnqiraj_InstanceMapScript(Map* map) : InstanceScript(map) { }
//If Vem is dead...
bool IsBossDied[3];
//Storing Skeram, Vem and Kri.
uint64 SkeramGUID;
uint64 VemGUID;
uint64 KriGUID;
uint64 VeklorGUID;
uint64 VeknilashGUID;
uint64 ViscidusGUID;
uint32 BugTrioDeathCount;
uint32 CthunPhase;
void Initialize()
{
IsBossDied[0] = false;
IsBossDied[1] = false;
IsBossDied[2] = false;
SkeramGUID = 0;
VemGUID = 0;
KriGUID = 0;
VeklorGUID = 0;
VeknilashGUID = 0;
ViscidusGUID = 0;
BugTrioDeathCount = 0;
CthunPhase = 0;
}
void OnCreatureCreate(Creature* creature)
{
switch (creature->GetEntry())
{
case NPC_SKERAM:
SkeramGUID = creature->GetGUID();
break;
case NPC_VEM:
VemGUID = creature->GetGUID();
break;
case NPC_KRI:
KriGUID = creature->GetGUID();
break;
case NPC_VEKLOR:
VeklorGUID = creature->GetGUID();
break;
case NPC_VEKNILASH:
VeknilashGUID = creature->GetGUID();
break;
case NPC_VISCIDUS:
ViscidusGUID = creature->GetGUID();
break;
}
}
bool IsEncounterInProgress() const
{
//not active in AQ40
return false;
}
uint32 GetData(uint32 type) const
{
switch (type)
{
case DATA_VEMISDEAD:
if (IsBossDied[0])
return 1;
break;
case DATA_VEKLORISDEAD:
if (IsBossDied[1])
return 1;
break;
case DATA_VEKNILASHISDEAD:
if (IsBossDied[2])
return 1;
break;
case DATA_BUG_TRIO_DEATH:
return BugTrioDeathCount;
case DATA_CTHUN_PHASE:
return CthunPhase;
}
return 0;
}
uint64 GetData64(uint32 identifier) const
{
switch (identifier)
{
case DATA_SKERAM:
return SkeramGUID;
case DATA_VEM:
return VemGUID;
case DATA_KRI:
return KriGUID;
case DATA_VEKLOR:
return VeklorGUID;
case DATA_VEKNILASH:
return VeknilashGUID;
case DATA_VISCIDUS:
return ViscidusGUID;
}
return 0;
} // end GetData64
void SetData(uint32 type, uint32 data)
{
switch (type)
{
case DATA_VEM_DEATH:
IsBossDied[0] = true;
break;
case DATA_BUG_TRIO_DEATH:
++BugTrioDeathCount;
break;
case DATA_VEKLOR_DEATH:
IsBossDied[1] = true;
break;
case DATA_VEKNILASH_DEATH:
IsBossDied[2] = true;
break;
case DATA_CTHUN_PHASE:
CthunPhase = data;
break;
}
}
};
};
void AddSC_instance_temple_of_ahnqiraj()
{
new instance_temple_of_ahnqiraj();
}

View File

@@ -1,268 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: npc_anubisath_sentinel
SD%Complete: 95
SDComment: Shadow storm is not properly implemented in core it should only target ppl outside of melee range.
SDCategory: Temple of Ahn'Qiraj
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "WorldPacket.h"
#include "Item.h"
#include "Player.h"
#include "Spell.h"
#include "Cell.h"
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
enum Spells
{
SPELL_MENDING_BUFF = 2147,
SPELL_KNOCK_BUFF = 21737,
SPELL_KNOCK = 25778,
SPELL_MANAB_BUFF = 812,
SPELL_MANAB = 25779,
SPELL_REFLECTAF_BUFF = 13022,
SPELL_REFLECTSFr_BUFF = 19595,
SPELL_THORNS_BUFF = 25777,
SPELL_THUNDER_BUFF = 2834,
SPELL_THUNDER = 8732,
SPELL_MSTRIKE_BUFF = 9347,
SPELL_MSTRIKE = 24573,
SPELL_STORM_BUFF = 2148,
SPELL_STORM = 26546
};
class npc_anubisath_sentinel : public CreatureScript
{
public:
npc_anubisath_sentinel() : CreatureScript("npc_anubisath_sentinel") { }
CreatureAI* GetAI(Creature* creature) const
{
return new aqsentinelAI(creature);
}
struct aqsentinelAI : public ScriptedAI
{
uint32 ability;
int abselected;
void selectAbility(int asel)
{
switch (asel)
{
case 0: ability = SPELL_MENDING_BUFF;break;
case 1: ability = SPELL_KNOCK_BUFF;break;
case 2: ability = SPELL_MANAB_BUFF;break;
case 3: ability = SPELL_REFLECTAF_BUFF;break;
case 4: ability = SPELL_REFLECTSFr_BUFF;break;
case 5: ability = SPELL_THORNS_BUFF;break;
case 6: ability = SPELL_THUNDER_BUFF;break;
case 7: ability = SPELL_MSTRIKE_BUFF;break;
case 8: ability = SPELL_STORM_BUFF;break;
}
}
aqsentinelAI(Creature* creature) : ScriptedAI(creature)
{
ClearBuddyList();
abselected = 0; // just initialization of variable
}
uint64 NearbyGUID[3];
void ClearBuddyList()
{
NearbyGUID[0] = NearbyGUID[1] = NearbyGUID[2] = 0;
}
void AddBuddyToList(uint64 CreatureGUID)
{
if (CreatureGUID == me->GetGUID())
return;
for (int i=0; i<3; ++i)
{
if (NearbyGUID[i] == CreatureGUID)
return;
if (!NearbyGUID[i])
{
NearbyGUID[i] = CreatureGUID;
return;
}
}
}
void GiveBuddyMyList(Creature* c)
{
aqsentinelAI* cai = CAST_AI(aqsentinelAI, (c)->AI());
for (int i=0; i<3; ++i)
if (NearbyGUID[i] && NearbyGUID[i] != c->GetGUID())
cai->AddBuddyToList(NearbyGUID[i]);
cai->AddBuddyToList(me->GetGUID());
}
void SendMyListToBuddies()
{
for (int i=0; i<3; ++i)
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
GiveBuddyMyList(pNearby);
}
void CallBuddiesToAttack(Unit* who)
{
for (int i=0; i<3; ++i)
{
Creature* c = ObjectAccessor::GetCreature(*me, NearbyGUID[i]);
if (c)
{
if (!c->IsInCombat())
{
c->SetNoCallAssistance(true);
if (c->AI())
c->AI()->AttackStart(who);
}
}
}
}
void AddSentinelsNear(Unit* /*nears*/)
{
std::list<Creature*> assistList;
me->GetCreatureListWithEntryInGrid(assistList, 15264, 70.0f);
if (assistList.empty())
return;
for (std::list<Creature*>::const_iterator iter = assistList.begin(); iter != assistList.end(); ++iter)
AddBuddyToList((*iter)->GetGUID());
}
int pickAbilityRandom(bool *chosenAbilities)
{
for (int t = 0; t < 2; ++t)
{
for (int i = !t ? (rand()%9) : 0; i < 9; ++i)
{
if (!chosenAbilities[i])
{
chosenAbilities[i] = true;
return i;
}
}
}
return 0; // should never happen
}
void GetOtherSentinels(Unit* who)
{
bool *chosenAbilities = new bool[9];
memset(chosenAbilities, 0, 9*sizeof(bool));
selectAbility(pickAbilityRandom(chosenAbilities));
ClearBuddyList();
AddSentinelsNear(me);
int bli;
for (bli = 0; bli < 3; ++bli)
{
if (!NearbyGUID[bli])
break;
Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[bli]);
if (!pNearby)
break;
AddSentinelsNear(pNearby);
CAST_AI(aqsentinelAI, pNearby->AI())->gatherOthersWhenAggro = false;
CAST_AI(aqsentinelAI, pNearby->AI())->selectAbility(pickAbilityRandom(chosenAbilities));
}
/*if (bli < 3)
DoYell("I dont have enough buddies.", LANG_NEUTRAL, 0);*/
SendMyListToBuddies();
CallBuddiesToAttack(who);
delete[] chosenAbilities;
}
bool gatherOthersWhenAggro;
void Reset()
{
if (!me->isDead())
{
for (int i=0; i<3; ++i)
{
if (!NearbyGUID[i])
continue;
if (Creature* pNearby = ObjectAccessor::GetCreature(*me, NearbyGUID[i]))
{
if (pNearby->isDead())
pNearby->Respawn();
}
}
}
ClearBuddyList();
gatherOthersWhenAggro = true;
}
void GainSentinelAbility(uint32 id)
{
me->AddAura(id, me);
}
void EnterCombat(Unit* who)
{
if (gatherOthersWhenAggro)
GetOtherSentinels(who);
GainSentinelAbility(ability);
DoZoneInCombat();
}
void JustDied(Unit* /*killer*/)
{
for (int ni=0; ni<3; ++ni)
{
Creature* sent = ObjectAccessor::GetCreature(*me, NearbyGUID[ni]);
if (!sent)
continue;
if (sent->isDead())
continue;
sent->ModifyHealth(int32(sent->CountPctFromMaxHealth(50)));
CAST_AI(aqsentinelAI, sent->AI())->GainSentinelAbility(ability);
}
}
};
};
void AddSC_npc_anubisath_sentinel()
{
new npc_anubisath_sentinel();
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEF_TEMPLE_OF_AHNQIRAJ_H
#define DEF_TEMPLE_OF_AHNQIRAJ_H
enum DataTypes
{
DATA_SKERAM = 1,
DATA_KRI = 2,
DATA_VEM = 3,
DATA_VEMISDEAD = 4,
DATA_VEM_DEATH = 5,
DATA_VEKLOR = 6,
DATA_VEKLORISDEAD = 7,
DATA_VEKLOR_DEATH = 8,
DATA_VEKNILASH = 9,
DATA_VEKNILASHISDEAD = 10,
DATA_VEKNILASH_DEATH = 11,
DATA_BUG_TRIO_DEATH = 14,
DATA_CTHUN_PHASE = 20,
DATA_VISCIDUS = 21
};
enum Creatures
{
BOSS_EYE_OF_CTHUN = 15589,
NPC_CTHUN_PORTAL = 15896,
NPC_CLAW_TENTACLE = 15725,
NPC_EYE_TENTACLE = 15726,
NPC_SMALL_PORTAL = 15904,
NPC_BODY_OF_CTHUN = 15809,
NPC_GIANT_CLAW_TENTACLE = 15728,
NPC_GIANT_EYE_TENTACLE = 15334,
NPC_FLESH_TENTACLE = 15802,
NPC_GIANT_PORTAL = 15910,
NPC_VISCIDUS = 15299,
NPC_GLOB_OF_VISCIDUS = 15667,
NPC_SKERAM = 15263,
NPC_VEM = 15544,
NPC_KRI = 15511,
NPC_VEKLOR = 15276,
NPC_VEKNILASH = 15275
};
#endif