mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-24 14:16:31 +00:00
Merge commit '26c583c24ab7dbbf1fecf3dcd737c1ad543c8b33' into Playerbot_1017
This commit is contained in:
@@ -126,7 +126,7 @@ public:
|
||||
for (std::unordered_multimap<uint32, Creature*>::const_iterator itr = creBounds.first; itr != creBounds.second;)
|
||||
{
|
||||
if (handler->GetSession())
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " ");
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, cInfo->Entry, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " ");
|
||||
else
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, itr->second->GetGUID().ToString().c_str(), itr->second->IsAlive() ? "*" : " ");
|
||||
++itr;
|
||||
@@ -138,7 +138,7 @@ public:
|
||||
if (!liveFound)
|
||||
{
|
||||
if (handler->GetSession())
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, cInfo->Name.c_str(), x, y, z, mapId, "", "");
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, cInfo->Entry, guid, cInfo->Name.c_str(), x, y, z, mapId, "", "");
|
||||
else
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CONSOLE, guid, cInfo->Name.c_str(), x, y, z, mapId, "", "");
|
||||
}
|
||||
|
||||
@@ -15,13 +15,6 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
Name: npc_commandscript
|
||||
%Complete: 100
|
||||
Comment: All npc related commands
|
||||
Category: commandscripts
|
||||
EndScriptData */
|
||||
|
||||
#include "Chat.h"
|
||||
#include "CreatureAI.h"
|
||||
#include "CreatureGroups.h"
|
||||
@@ -720,7 +713,7 @@ public:
|
||||
if (!creatureTemplate)
|
||||
continue;
|
||||
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, guid, creatureTemplate->Name.c_str(), x, y, z, mapId, "", "");
|
||||
handler->PSendSysMessage(LANG_CREATURE_LIST_CHAT, guid, entry, guid, creatureTemplate->Name.c_str(), x, y, z, mapId, "", "");
|
||||
|
||||
++count;
|
||||
} while (result->NextRow());
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
enum Emotes
|
||||
{
|
||||
EMOTE_PHASE_PORTAL = 0,
|
||||
EMOTE_PHASE_BANISH = 1
|
||||
EMOTE_PHASE_BANISH = 0,
|
||||
EMOTE_PHASE_PORTAL = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
@@ -50,7 +50,7 @@ enum Portals
|
||||
enum Groups
|
||||
{
|
||||
PORTAL_PHASE = 0,
|
||||
VANISH_PHASE = 1
|
||||
BANISH_PHASE = 1
|
||||
};
|
||||
|
||||
const float PortalCoord[3][3] =
|
||||
@@ -101,7 +101,6 @@ struct boss_netherspite : public BossAI
|
||||
BossAI::Reset();
|
||||
berserk = false;
|
||||
HandleDoors(true);
|
||||
DestroyPortals();
|
||||
}
|
||||
|
||||
void SummonPortals()
|
||||
@@ -121,23 +120,6 @@ struct boss_netherspite : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void DestroyPortals()
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
if (Creature* portal = ObjectAccessor::GetCreature(*me, PortalGUID[i]))
|
||||
{
|
||||
portal->DisappearAndDie();
|
||||
}
|
||||
if (Creature* portal = ObjectAccessor::GetCreature(*me, BeamerGUID[i]))
|
||||
{
|
||||
portal->DisappearAndDie();
|
||||
}
|
||||
PortalGUID[i].Clear();
|
||||
BeamTarget[i].Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePortals() // Here we handle the beams' behavior
|
||||
{
|
||||
for (int j = 0; j < 3; ++j) // j = color
|
||||
@@ -203,9 +185,14 @@ struct boss_netherspite : public BossAI
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchToPortalPhase()
|
||||
void SwitchToPortalPhase(bool aggro = false)
|
||||
{
|
||||
scheduler.CancelGroup(VANISH_PHASE);
|
||||
if (!aggro)
|
||||
{
|
||||
Talk(EMOTE_PHASE_PORTAL);
|
||||
}
|
||||
|
||||
scheduler.CancelGroup(BANISH_PHASE);
|
||||
me->RemoveAurasDueToSpell(SPELL_BANISH_ROOT);
|
||||
me->RemoveAurasDueToSpell(SPELL_BANISH_VISUAL);
|
||||
SummonPortals();
|
||||
@@ -230,27 +217,33 @@ struct boss_netherspite : public BossAI
|
||||
DoCastRandomTarget(SPELL_VOIDZONE, 1, 45.0f, true, true);
|
||||
context.Repeat(15s);
|
||||
});
|
||||
Talk(EMOTE_PHASE_PORTAL);
|
||||
}
|
||||
|
||||
void SwitchToBanishPhase()
|
||||
{
|
||||
Talk(EMOTE_PHASE_BANISH);
|
||||
scheduler.CancelGroup(PORTAL_PHASE);
|
||||
me->RemoveAurasDueToSpell(SPELL_EMPOWERMENT);
|
||||
me->RemoveAurasDueToSpell(SPELL_NETHERBURN_AURA);
|
||||
DoCastSelf(SPELL_BANISH_VISUAL, true);
|
||||
DoCastSelf(SPELL_BANISH_ROOT, true);
|
||||
DestroyPortals();
|
||||
|
||||
for (uint32 id : PortalID)
|
||||
{
|
||||
summons.DespawnEntry(id);
|
||||
}
|
||||
|
||||
scheduler.Schedule(30s, [this](TaskContext)
|
||||
{
|
||||
SwitchToPortalPhase();
|
||||
DoResetThreatList();
|
||||
return;
|
||||
}).Schedule(10s, VANISH_PHASE, [this](TaskContext context)
|
||||
}).Schedule(10s, BANISH_PHASE, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_NETHERBREATH, 0, 40.0f, true);
|
||||
context.Repeat(5s, 7s);
|
||||
});
|
||||
Talk(EMOTE_PHASE_BANISH);
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
me->RemoveAurasDueToSpell(NetherBuff[i]);
|
||||
@@ -269,7 +262,7 @@ struct boss_netherspite : public BossAI
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
HandleDoors(false);
|
||||
SwitchToPortalPhase();
|
||||
SwitchToPortalPhase(true);
|
||||
DoZoneInCombat();
|
||||
scheduler.Schedule(9min, [this](TaskContext /*context*/)
|
||||
{
|
||||
@@ -286,7 +279,6 @@ struct boss_netherspite : public BossAI
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
HandleDoors(true);
|
||||
DestroyPortals();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
|
||||
@@ -205,13 +205,12 @@ struct boss_malchezaar : public BossAI
|
||||
});
|
||||
|
||||
context.SetGroup(GROUP_ENFEEBLE);
|
||||
scheduler.DelayGroup(GROUP_SHADOW_NOVA, 5s);
|
||||
context.Repeat();
|
||||
}).Schedule(35500ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastAOE(SPELL_SHADOW_NOVA);
|
||||
context.SetGroup(GROUP_SHADOW_NOVA);
|
||||
context.Repeat();
|
||||
context.Repeat(30s);
|
||||
}).Schedule(40s, [this](TaskContext context)
|
||||
{
|
||||
if (!MaxSpawns(infernalTargets)) // only spawn infernal when the area is not full
|
||||
|
||||
@@ -22,45 +22,52 @@
|
||||
#include "karazhan.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
enum ShadeOfAran
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_AGGRO = 0,
|
||||
SAY_FLAMEWREATH = 1,
|
||||
SAY_BLIZZARD = 2,
|
||||
SAY_EXPLOSION = 3,
|
||||
SAY_DRINK = 4,
|
||||
SAY_ELEMENTALS = 5,
|
||||
SAY_KILL = 6,
|
||||
SAY_TIMEOVER = 7,
|
||||
SAY_DEATH = 8,
|
||||
SAY_BLIZZARD = 2,
|
||||
SAY_EXPLOSION = 3,
|
||||
SAY_DRINK = 4,
|
||||
SAY_ELEMENTALS = 5,
|
||||
SAY_KILL = 6,
|
||||
SAY_TIMEOVER = 7,
|
||||
SAY_DEATH = 8
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
//Spells
|
||||
SPELL_FROSTBOLT = 29954,
|
||||
SPELL_FIREBALL = 29953,
|
||||
SPELL_ARCMISSLE = 29955,
|
||||
SPELL_CHAINSOFICE = 29991,
|
||||
SPELL_DRAGONSBREATH = 29964,
|
||||
SPELL_MASSSLOW = 30035,
|
||||
SPELL_FLAME_WREATH = 29946,
|
||||
SPELL_AOE_CS = 29961,
|
||||
SPELL_PLAYERPULL = 32265,
|
||||
SPELL_AEXPLOSION = 29973,
|
||||
SPELL_MASS_POLY = 29963,
|
||||
SPELL_BLINK_CENTER = 29967,
|
||||
SPELL_ELEMENTALS = 29962,
|
||||
SPELL_CONJURE = 29975,
|
||||
SPELL_DRINK = 30024,
|
||||
SPELL_POTION = 32453,
|
||||
SPELL_AOE_PYROBLAST = 29978,
|
||||
SPELL_FROSTBOLT = 29954,
|
||||
SPELL_FIREBALL = 29953,
|
||||
SPELL_ARCMISSLE = 29955,
|
||||
SPELL_CHAINSOFICE = 29991,
|
||||
SPELL_DRAGONSBREATH = 29964,
|
||||
SPELL_MASSSLOW = 30035,
|
||||
SPELL_FLAME_WREATH = 29946,
|
||||
SPELL_AOE_CS = 29961,
|
||||
SPELL_PLAYERPULL = 32265,
|
||||
SPELL_AEXPLOSION = 29973,
|
||||
SPELL_MASS_POLY = 29963,
|
||||
SPELL_BLINK_CENTER = 29967,
|
||||
SPELL_CONJURE = 29975,
|
||||
SPELL_DRINK = 30024,
|
||||
SPELL_POTION = 32453,
|
||||
SPELL_AOE_PYROBLAST = 29978,
|
||||
|
||||
//Creature Spells
|
||||
SPELL_CIRCULAR_BLIZZARD = 29951,
|
||||
SPELL_SHADOW_PYRO = 29978,
|
||||
SPELL_SUMMON_WELEMENTAL_1 = 29962,
|
||||
SPELL_SUMMON_WELEMENTAL_2 = 37051,
|
||||
SPELL_SUMMON_WELEMENTAL_3 = 37052,
|
||||
SPELL_SUMMON_WELEMENTAL_4 = 37053,
|
||||
|
||||
//Creatures
|
||||
NPC_WATER_ELEMENTAL = 17167,
|
||||
NPC_SHADOW_OF_ARAN = 18254,
|
||||
NPC_ARAN_BLIZZARD = 17161,
|
||||
SPELL_SUMMON_BLIZZARD = 29969, // Activates the Blizzard NPC
|
||||
|
||||
SPELL_SHADOW_PYRO = 29978
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_SHADOW_OF_ARAN = 18254
|
||||
};
|
||||
|
||||
enum SuperSpell
|
||||
@@ -133,17 +140,11 @@ struct boss_shade_of_aran : public BossAI
|
||||
ScheduleHealthCheckEvent(40, [&]{
|
||||
Talk(SAY_ELEMENTALS);
|
||||
|
||||
for(Position pos : elementalPos)
|
||||
std::vector<uint32> elementalSpells = { SPELL_SUMMON_WELEMENTAL_1, SPELL_SUMMON_WELEMENTAL_2, SPELL_SUMMON_WELEMENTAL_3, SPELL_SUMMON_WELEMENTAL_4 };
|
||||
|
||||
for (auto const& spell : elementalSpells)
|
||||
{
|
||||
if(Creature* elemental = me->SummonCreature(NPC_WATER_ELEMENTAL, pos, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000))
|
||||
{
|
||||
if(Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true))
|
||||
{
|
||||
DoStartNoMovement(target);
|
||||
elemental->SetInCombatWithZone();
|
||||
elemental->CombatStart(target);
|
||||
}
|
||||
}
|
||||
DoCastAOE(spell, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -255,7 +256,20 @@ struct boss_shade_of_aran : public BossAI
|
||||
if (AvailableSpells)
|
||||
{
|
||||
CurrentNormalSpell = Spells[rand() % AvailableSpells];
|
||||
DoCast(target, CurrentNormalSpell);
|
||||
|
||||
if (!me->CanCastSpell(CurrentNormalSpell))
|
||||
{
|
||||
me->SetWalk(false);
|
||||
me->ResumeChasingVictim();
|
||||
}
|
||||
else
|
||||
{
|
||||
DoCast(target, CurrentNormalSpell);
|
||||
if (me->GetVictim())
|
||||
{
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim(), 45.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Repeat(2s);
|
||||
@@ -341,12 +355,7 @@ struct boss_shade_of_aran : public BossAI
|
||||
|
||||
case SUPER_BLIZZARD:
|
||||
Talk(SAY_BLIZZARD);
|
||||
|
||||
if (Creature* pSpawn = me->SummonCreature(NPC_ARAN_BLIZZARD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 25000))
|
||||
{
|
||||
pSpawn->SetFaction(me->GetFaction());
|
||||
pSpawn->CastSpell(me, SPELL_CIRCULAR_BLIZZARD, false);
|
||||
}
|
||||
DoCastAOE(SPELL_SUMMON_BLIZZARD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -947,7 +947,7 @@ enum JulianneRomulo
|
||||
|
||||
SAY_ROMULO_AGGRO = 0,
|
||||
SAY_ROMULO_DEATH = 1,
|
||||
SAY_ROMULO_ENTER = 2,
|
||||
SAY_ROMULO_DEATH2 = 2,
|
||||
SAY_ROMULO_RESURRECT = 3,
|
||||
SAY_ROMULO_SLAY = 4,
|
||||
|
||||
@@ -985,12 +985,10 @@ enum RAJGroups
|
||||
|
||||
enum RAJActions
|
||||
{
|
||||
ACTION_DIED_ANNOUNCE = 0,
|
||||
ACTION_PHASE_SET = 1,
|
||||
ACTION_FAKING_DEATH = 2,
|
||||
ACTION_COMBAT_SCHEDULE = 3,
|
||||
ACTION_DO_RESURRECT = 4,
|
||||
ACTION_EARLY_REVIVE = 5,
|
||||
//ACTION_DO_RESURRECT = 4,
|
||||
//ACTION_RESS_ROMULO = 5,
|
||||
ACTION_CANCEL_COMBAT = 6
|
||||
};
|
||||
|
||||
@@ -999,7 +997,6 @@ void PretendToDie(Creature* creature)
|
||||
creature->AI()->DoAction(ACTION_CANCEL_COMBAT);
|
||||
creature->InterruptNonMeleeSpells(true);
|
||||
creature->RemoveAllAuras();
|
||||
creature->SetHealth(0);
|
||||
creature->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
creature->SetReactState(REACT_PASSIVE);
|
||||
creature->GetMotionMaster()->MovementExpired(false);
|
||||
@@ -1032,14 +1029,6 @@ struct boss_julianne : public ScriptedAI
|
||||
isFakingDeath = false;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 phase;
|
||||
|
||||
bool isFakingDeath;
|
||||
bool summonedRomulo;
|
||||
bool romuloDied;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
phase = PHASE_JULIANNE;
|
||||
@@ -1051,10 +1040,8 @@ struct boss_julianne : public ScriptedAI
|
||||
}
|
||||
|
||||
summonedRomulo = false;
|
||||
romuloDied = false;
|
||||
me->SetImmuneToPC(true);
|
||||
|
||||
//intro sequence
|
||||
_scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
Talk(SAY_JULIANNE_ENTER);
|
||||
@@ -1071,38 +1058,29 @@ struct boss_julianne : public ScriptedAI
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case ACTION_DIED_ANNOUNCE:
|
||||
romuloDied = true;
|
||||
break;
|
||||
case ACTION_EARLY_REVIVE:
|
||||
romuloDied = true;
|
||||
_resurrectScheduler.Schedule(10s, [this](TaskContext)
|
||||
{
|
||||
Talk(SAY_JULIANNE_RESURRECT);
|
||||
romuloDied = false;
|
||||
});
|
||||
break;
|
||||
case ACTION_PHASE_SET:
|
||||
phase = PHASE_BOTH;
|
||||
isFakingDeath = false;
|
||||
break;
|
||||
case ACTION_FAKING_DEATH:
|
||||
isFakingDeath = false;
|
||||
break;
|
||||
case ACTION_COMBAT_SCHEDULE:
|
||||
ScheduleCombat();
|
||||
break;
|
||||
case ACTION_DO_RESURRECT:
|
||||
_resurrectScheduler.Schedule(1s, [this](TaskContext)
|
||||
case ACTION_RESS_ROMULO:
|
||||
me->m_Events.AddEventAtOffset([this]
|
||||
{
|
||||
if (Creature* Romulo = instance->GetCreature(DATA_ROMULO))
|
||||
if (Creature* romulo = instance->GetCreature(DATA_ROMULO))
|
||||
{
|
||||
Talk(SAY_JULIANNE_RESURRECT);
|
||||
Resurrect(Romulo);
|
||||
Romulo->AI()->DoAction(ACTION_FAKING_DEATH);
|
||||
romuloDied = false;
|
||||
Resurrect(romulo);
|
||||
romulo->AI()->DoAction(ACTION_FAKING_DEATH);
|
||||
romulo->AI()->Talk(SAY_ROMULO_RESURRECT);
|
||||
}
|
||||
});
|
||||
}, 1s);
|
||||
break;
|
||||
case ACTION_DO_RESURRECT:
|
||||
phase = PHASE_BOTH;
|
||||
isFakingDeath = false;
|
||||
Resurrect(me);
|
||||
me->ResumeChasingVictim();
|
||||
break;
|
||||
case ACTION_CANCEL_COMBAT:
|
||||
_scheduler.CancelGroup(GROUP_COMBAT);
|
||||
@@ -1128,11 +1106,11 @@ struct boss_julianne : public ScriptedAI
|
||||
{
|
||||
if (urand(0, 1) && summonedRomulo)
|
||||
{
|
||||
if (Creature* Romulo = instance->GetCreature(DATA_ROMULO))
|
||||
if (Creature* romulo = instance->GetCreature(DATA_ROMULO))
|
||||
{
|
||||
if (Romulo->IsAlive() && !romuloDied)
|
||||
if (!romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
{
|
||||
DoCast(Romulo, SPELL_ETERNAL_AFFECTION);
|
||||
DoCast(romulo, SPELL_ETERNAL_AFFECTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1149,22 +1127,6 @@ struct boss_julianne : public ScriptedAI
|
||||
ScheduleCombat();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
||||
return;
|
||||
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
me->DespawnOrUnsummon();
|
||||
@@ -1183,10 +1145,9 @@ struct boss_julianne : public ScriptedAI
|
||||
phase = PHASE_ROMULO;
|
||||
_scheduler.Schedule(10s, GROUP_RP, [this](TaskContext)
|
||||
{
|
||||
if (Creature* pRomulo = me->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR * 2 * IN_MILLISECONDS))
|
||||
if (Creature* romulo = me->SummonCreature(CREATURE_ROMULO, ROMULO_X, ROMULO_Y, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR * 2 * IN_MILLISECONDS))
|
||||
{
|
||||
pRomulo->AI()->DoAction(ACTION_PHASE_SET);
|
||||
pRomulo->SetInCombatWithZone();
|
||||
romulo->SetInCombatWithZone();
|
||||
}
|
||||
summonedRomulo = true;
|
||||
});
|
||||
@@ -1201,13 +1162,12 @@ struct boss_julianne : public ScriptedAI
|
||||
return;
|
||||
}
|
||||
|
||||
//anything below only used if incoming damage will kill
|
||||
damage = me->GetHealth() - 1;
|
||||
|
||||
if (phase == PHASE_JULIANNE)
|
||||
{
|
||||
damage = 0;
|
||||
me->ClearTarget();
|
||||
|
||||
//this means already drinking, so return
|
||||
if (isFakingDeath)
|
||||
{
|
||||
return;
|
||||
@@ -1222,50 +1182,12 @@ struct boss_julianne : public ScriptedAI
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase == PHASE_ROMULO)
|
||||
if (phase == PHASE_BOTH && !isFakingDeath)
|
||||
{
|
||||
//LOG_ERROR("scripts", "boss_julianneAI: cannot take damage in PHASE_ROMULO, why was i here?");
|
||||
damage = 0;
|
||||
return;
|
||||
PretendToDie(me);
|
||||
isFakingDeath = true;
|
||||
instance->DoAction(ACTION_SCHEDULE_RAJ_CHECK);
|
||||
}
|
||||
|
||||
if (phase == PHASE_BOTH)
|
||||
{
|
||||
//if this is true then we have to kill romulo too
|
||||
if (romuloDied)
|
||||
{
|
||||
if (Creature* Romulo = instance->GetCreature(DATA_ROMULO))
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_resurrectScheduler.CancelAll();
|
||||
Romulo->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
Romulo->GetMotionMaster()->Clear();
|
||||
Romulo->setDeathState(JUST_DIED);
|
||||
Romulo->CombatStop(true);
|
||||
Romulo->GetThreatMgr().ClearAllThreat();
|
||||
Romulo->ReplaceAllDynamicFlags(UNIT_DYNFLAG_LOOTABLE);
|
||||
//this does not seem to really work - the lootable dynamic flags
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//if not already returned, then romulo is alive and we can pretend die
|
||||
if (Creature* Romulo = instance->GetCreature(DATA_ROMULO))
|
||||
{
|
||||
PretendToDie(me);
|
||||
isFakingDeath = true;
|
||||
Romulo->AI()->DoAction(ACTION_EARLY_REVIVE);
|
||||
_scheduler.Schedule(10050ms, [this](TaskContext)
|
||||
{
|
||||
Resurrect(me);
|
||||
isFakingDeath = false;
|
||||
});
|
||||
damage = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
//LOG_ERROR("scripts", "boss_julianneAI: DamageTaken reach end of code, that should not happen.");
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason reason) override
|
||||
@@ -1286,15 +1208,17 @@ struct boss_julianne : public ScriptedAI
|
||||
instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
Talk(SAY_JULIANNE_SLAY);
|
||||
if (victim != me)
|
||||
{
|
||||
Talk(SAY_JULIANNE_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
_resurrectScheduler.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
@@ -1307,50 +1231,30 @@ struct boss_julianne : public ScriptedAI
|
||||
}
|
||||
}
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
uint32 phase;
|
||||
bool isFakingDeath;
|
||||
bool summonedRomulo;
|
||||
TaskScheduler _scheduler;
|
||||
TaskScheduler _resurrectScheduler;
|
||||
};
|
||||
|
||||
struct boss_romulo : public ScriptedAI
|
||||
{
|
||||
boss_romulo(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript(); //not necessary
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 phase;
|
||||
|
||||
bool isFakingDeath;
|
||||
bool julianneDead;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
phase = PHASE_ROMULO;
|
||||
|
||||
isFakingDeath = false;
|
||||
julianneDead = false;
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case ACTION_DIED_ANNOUNCE:
|
||||
julianneDead = true;
|
||||
break;
|
||||
case ACTION_EARLY_REVIVE:
|
||||
julianneDead = true;
|
||||
_resurrectScheduler.Schedule(10s, [this](TaskContext)
|
||||
{
|
||||
Talk(SAY_ROMULO_RESURRECT);
|
||||
julianneDead = false;
|
||||
});
|
||||
break;
|
||||
case ACTION_PHASE_SET:
|
||||
phase = PHASE_ROMULO;
|
||||
break;
|
||||
case ACTION_FAKING_DEATH:
|
||||
isFakingDeath = false;
|
||||
break;
|
||||
@@ -1375,9 +1279,11 @@ struct boss_romulo : public ScriptedAI
|
||||
void DamageTaken(Unit*, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage < me->GetHealth())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//anything below only used if incoming damage will kill
|
||||
damage = me->GetHealth() - 1;
|
||||
|
||||
if (phase == PHASE_ROMULO)
|
||||
{
|
||||
@@ -1386,63 +1292,24 @@ struct boss_romulo : public ScriptedAI
|
||||
isFakingDeath = true;
|
||||
phase = PHASE_BOTH;
|
||||
|
||||
if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE))
|
||||
me->m_Events.AddEventAtOffset([this]
|
||||
{
|
||||
Julianne->AI()->DoAction(ACTION_DIED_ANNOUNCE);
|
||||
//resurrect julianne
|
||||
_scheduler.Schedule(10s, GROUP_RP, [this](TaskContext)
|
||||
Resurrect(me);
|
||||
isFakingDeath = false;
|
||||
if (Creature* julliane = instance->GetCreature(DATA_JULIANNE))
|
||||
{
|
||||
if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE))
|
||||
{
|
||||
Resurrect(Julianne);
|
||||
Julianne->AI()->DoAction(ACTION_PHASE_SET);
|
||||
Julianne->AI()->DoAction(ACTION_DO_RESURRECT);
|
||||
if (Julianne->GetVictim())
|
||||
{
|
||||
AttackStart(Julianne->GetVictim());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
damage = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase == PHASE_BOTH)
|
||||
{
|
||||
if (julianneDead)
|
||||
{
|
||||
if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE))
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_resurrectScheduler.CancelAll();
|
||||
Julianne->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
Julianne->GetMotionMaster()->Clear();
|
||||
Julianne->setDeathState(JUST_DIED);
|
||||
Julianne->CombatStop(true);
|
||||
Julianne->GetThreatMgr().ClearAllThreat();
|
||||
Julianne->ReplaceAllDynamicFlags(UNIT_DYNFLAG_LOOTABLE);
|
||||
//this does not seem to really work
|
||||
julliane->AI()->DoAction(ACTION_DO_RESURRECT);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Creature* Julianne = instance->GetCreature(DATA_JULIANNE))
|
||||
{
|
||||
PretendToDie(me);
|
||||
isFakingDeath = true;
|
||||
Julianne->AI()->DoAction(ACTION_EARLY_REVIVE);
|
||||
_scheduler.Schedule(10050ms, [this](TaskContext)
|
||||
{
|
||||
Resurrect(me);
|
||||
isFakingDeath = false;
|
||||
});
|
||||
damage = 0;
|
||||
return;
|
||||
}
|
||||
}, 3s);
|
||||
}
|
||||
|
||||
if (phase == PHASE_BOTH && !isFakingDeath)
|
||||
{
|
||||
Talk(SAY_ROMULO_DEATH2);
|
||||
PretendToDie(me);
|
||||
instance->DoAction(ACTION_SCHEDULE_RAJ_CHECK);
|
||||
isFakingDeath = true;
|
||||
}
|
||||
//LOG_ERROR("scripts", "boss_romuloAI: DamageTaken reach end of code, that should not happen.");
|
||||
}
|
||||
|
||||
void ScheduleCombat()
|
||||
@@ -1488,14 +1355,6 @@ struct boss_romulo : public ScriptedAI
|
||||
ScheduleCombat();
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (me->HasUnitFlag(UNIT_FLAG_NON_ATTACKABLE))
|
||||
return;
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void EnterEvadeMode(EvadeReason reason) override
|
||||
{
|
||||
ScriptedAI::EnterEvadeMode(reason);
|
||||
@@ -1510,15 +1369,17 @@ struct boss_romulo : public ScriptedAI
|
||||
instance->SetBossState(DATA_OPERA_PERFORMANCE, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
Talk(SAY_ROMULO_SLAY);
|
||||
if (victim != me)
|
||||
{
|
||||
Talk(SAY_ROMULO_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_scheduler.Update(diff);
|
||||
_resurrectScheduler.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
@@ -1531,8 +1392,10 @@ struct boss_romulo : public ScriptedAI
|
||||
}
|
||||
}
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
uint32 phase;
|
||||
bool isFakingDeath;
|
||||
TaskScheduler _scheduler;
|
||||
TaskScheduler _resurrectScheduler;
|
||||
};
|
||||
|
||||
void AddSC_bosses_opera()
|
||||
|
||||
@@ -240,6 +240,9 @@ public:
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DONE:
|
||||
HandleGameObject(m_uiGamesmansExitDoor, true);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
DoRemoveAurasDueToSpellOnPlayers(SPELL_GAME_IN_SESSION);
|
||||
@@ -418,6 +421,42 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DoAction(int32 actionId) override
|
||||
{
|
||||
if (actionId == ACTION_SCHEDULE_RAJ_CHECK)
|
||||
{
|
||||
scheduler.Schedule(10s, [this](TaskContext)
|
||||
{
|
||||
Creature* julliane = GetCreature(DATA_JULIANNE);
|
||||
Creature* romulo = GetCreature(DATA_ROMULO);
|
||||
|
||||
if (julliane && romulo)
|
||||
{
|
||||
if (julliane->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE)
|
||||
&& romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
{
|
||||
julliane->KillSelf();
|
||||
julliane->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
romulo->KillSelf();
|
||||
romulo->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (romulo->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
{
|
||||
julliane->AI()->DoAction(ACTION_RESS_ROMULO);
|
||||
}
|
||||
|
||||
if (julliane->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
|
||||
{
|
||||
julliane->AI()->DoAction(ACTION_DO_RESURRECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 data) const override
|
||||
{
|
||||
switch (data)
|
||||
|
||||
@@ -204,6 +204,14 @@ enum KarazhanChessGameFactions
|
||||
CHESS_FACTION_BOTH = 536
|
||||
};
|
||||
|
||||
enum InstanceActions
|
||||
{
|
||||
ACTION_SCHEDULE_RAJ_CHECK,
|
||||
|
||||
ACTION_DO_RESURRECT = 4,
|
||||
ACTION_RESS_ROMULO = 5,
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetKarazhanAI(T* obj)
|
||||
{
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_INTERRUPT_CAST, false);
|
||||
instance->SetData(DATA_KAELTHAS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_KAELTHAS, NOT_STARTED);
|
||||
me->SetImmuneToAll(false);
|
||||
}
|
||||
|
||||
@@ -125,12 +125,17 @@ public:
|
||||
|
||||
void JustDied(Unit*) override
|
||||
{
|
||||
instance->SetData(DATA_KAELTHAS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_KAELTHAS, DONE);
|
||||
|
||||
if (GameObject* orb = instance->GetGameObject(DATA_ESCAPE_ORB))
|
||||
{
|
||||
orb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
instance->SetData(DATA_KAELTHAS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
|
||||
me->SetInCombatWithZone();
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_FIREBALL, 0);
|
||||
|
||||
@@ -105,7 +105,7 @@ public:
|
||||
{
|
||||
PlayersKilled = SAY_PLAYER_KILLED;
|
||||
HelpersKilled = SAY_HELPER_DIED;
|
||||
instance->SetData(DATA_DELRISSA_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_DELRISSA, NOT_STARTED);
|
||||
summons.Respawn();
|
||||
|
||||
me->SetLootMode(0);
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
{
|
||||
me->loot.clear();
|
||||
me->loot.FillLoot(me->GetCreatureTemplate()->lootid, LootTemplates_Creature, me->GetLootRecipient(), false, false, 1, me);
|
||||
instance->SetData(DATA_DELRISSA_EVENT, DONE);
|
||||
instance->SetBossState(DATA_DELRISSA, DONE);
|
||||
me->SetDynamicFlag(UNIT_DYNFLAG_LOOTABLE);
|
||||
}
|
||||
++HelpersKilled;
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
summons.DoZoneInCombat();
|
||||
instance->SetData(DATA_DELRISSA_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_DELRISSA, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_FLASH_HEAL, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_RENEW, 10000);
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (HelpersKilled == MAX_ACTIVE_HELPERS + 1)
|
||||
instance->SetData(DATA_DELRISSA_EVENT, DONE);
|
||||
instance->SetBossState(DATA_DELRISSA, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
|
||||
@@ -106,7 +106,7 @@ public:
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
SpawnCrystals();
|
||||
instance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, NOT_STARTED);
|
||||
CrystalGUID.Clear();
|
||||
me->SetPower(POWER_MANA, 0);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetData(DATA_SELIN_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_DRAIN_LIFE, 2500, 1);
|
||||
events.ScheduleEvent(EVENT_SPELL_FEL_EXPLOSION, 2000);
|
||||
@@ -134,7 +134,7 @@ public:
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete!
|
||||
instance->SetBossState(DATA_SELIN_FIREHEART, DONE); // Encounter complete!
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public:
|
||||
summons.DespawnAll();
|
||||
IntervalHealthAmount = 1;
|
||||
|
||||
instance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
|
||||
instance->SetBossState(DATA_VEXALLUS, NOT_STARTED);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
|
||||
@@ -100,14 +100,14 @@ public:
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
summons.DespawnAll();
|
||||
instance->SetData(DATA_VEXALLUS_EVENT, DONE);
|
||||
instance->SetBossState(DATA_VEXALLUS, DONE);
|
||||
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_ENERGY_FEEDBACK);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
instance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_VEXALLUS, IN_PROGRESS);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CHAIN_LIGHTNING, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ARCANE_SHOCK, 5000);
|
||||
|
||||
@@ -26,6 +26,21 @@ ObjectData const creatureData[] =
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
ObjectData const gameobjectData[] =
|
||||
{
|
||||
{ GO_ESCAPE_ORB, DATA_ESCAPE_ORB },
|
||||
{ 0, 0, }
|
||||
};
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_SELIN_DOOR, DATA_SELIN_FIREHEART, DOOR_TYPE_PASSAGE },
|
||||
{ GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN_FIREHEART, DOOR_TYPE_ROOM },
|
||||
{ GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE },
|
||||
{ GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE },
|
||||
{ 0, 0, DOOR_TYPE_ROOM } // END
|
||||
};
|
||||
|
||||
Position const KalecgosSpawnPos = { 164.3747f, -397.1197f, 2.151798f, 1.66219f };
|
||||
|
||||
class instance_magisters_terrace : public InstanceMapScript
|
||||
@@ -38,47 +53,16 @@ public:
|
||||
instance_magisters_terrace_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
SetBossNumber(MAX_ENCOUNTER);
|
||||
LoadObjectData(creatureData, gameobjectData);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
|
||||
uint32 Encounter[MAX_ENCOUNTER];
|
||||
|
||||
ObjectGuid VexallusDoorGUID;
|
||||
ObjectGuid SelinDoorGUID;
|
||||
ObjectGuid SelinEncounterDoorGUID;
|
||||
ObjectGuid DelrissaDoorGUID;
|
||||
ObjectGuid KaelDoorGUID;
|
||||
ObjectGuid EscapeOrbGUID;
|
||||
|
||||
ObjectGuid DelrissaGUID;
|
||||
ObjectGuid KaelGUID;
|
||||
|
||||
void Initialize() override
|
||||
{
|
||||
memset(&Encounter, 0, sizeof(Encounter));
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const override
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (Encounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 identifier) const override
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SELIN_EVENT:
|
||||
case DATA_VEXALLUS_EVENT:
|
||||
case DATA_DELRISSA_EVENT:
|
||||
case DATA_KAELTHAS_EVENT:
|
||||
return Encounter[identifier];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) override
|
||||
{
|
||||
if (eventId == EVENT_SPAWN_KALECGOS)
|
||||
@@ -97,37 +81,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 identifier, uint32 data) override
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SELIN_EVENT:
|
||||
HandleGameObject(SelinDoorGUID, data == DONE);
|
||||
HandleGameObject(SelinEncounterDoorGUID, data != IN_PROGRESS);
|
||||
Encounter[identifier] = data;
|
||||
break;
|
||||
case DATA_VEXALLUS_EVENT:
|
||||
if (data == DONE)
|
||||
HandleGameObject(VexallusDoorGUID, true);
|
||||
Encounter[identifier] = data;
|
||||
break;
|
||||
case DATA_DELRISSA_EVENT:
|
||||
if (data == DONE)
|
||||
HandleGameObject(DelrissaDoorGUID, true);
|
||||
Encounter[identifier] = data;
|
||||
break;
|
||||
case DATA_KAELTHAS_EVENT:
|
||||
HandleGameObject(KaelDoorGUID, data != IN_PROGRESS);
|
||||
if (data == DONE)
|
||||
if (GameObject* escapeOrb = instance->GetGameObject(EscapeOrbGUID))
|
||||
escapeOrb->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
Encounter[identifier] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
@@ -148,60 +101,11 @@ public:
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_SELIN_DOOR:
|
||||
if (GetData(DATA_SELIN_EVENT) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
SelinDoorGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_SELIN_ENCOUNTER_DOOR:
|
||||
SelinEncounterDoorGUID = go->GetGUID();
|
||||
break;
|
||||
|
||||
case GO_VEXALLUS_DOOR:
|
||||
if (GetData(DATA_VEXALLUS_EVENT) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
VexallusDoorGUID = go->GetGUID();
|
||||
break;
|
||||
|
||||
case GO_DELRISSA_DOOR:
|
||||
if (GetData(DATA_DELRISSA_EVENT) == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, go);
|
||||
DelrissaDoorGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_KAEL_DOOR:
|
||||
KaelDoorGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_ESCAPE_ORB:
|
||||
if (GetData(DATA_KAELTHAS_EVENT) == DONE)
|
||||
go->RemoveGameObjectFlag(GO_FLAG_NOT_SELECTABLE);
|
||||
EscapeOrbGUID = go->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// @todo: Use BossStates. This is for code compatibility
|
||||
void ReadSaveDataMore(std::istringstream& data) override
|
||||
{
|
||||
data >> Encounter[1];
|
||||
data >> Encounter[2];
|
||||
data >> Encounter[3];
|
||||
}
|
||||
|
||||
void WriteSaveDataMore(std::ostringstream& data) override
|
||||
{
|
||||
data << Encounter[0] << ' ' << Encounter[1] << ' ' << Encounter[2] << ' ' << Encounter[3];
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 identifier) const override
|
||||
{
|
||||
switch (identifier)
|
||||
if (identifier == NPC_DELRISSA)
|
||||
{
|
||||
case NPC_DELRISSA:
|
||||
return DelrissaGUID;
|
||||
return DelrissaGUID;
|
||||
}
|
||||
|
||||
return ObjectGuid::Empty;
|
||||
|
||||
@@ -28,13 +28,14 @@
|
||||
|
||||
enum MTData
|
||||
{
|
||||
DATA_SELIN_EVENT = 0,
|
||||
DATA_VEXALLUS_EVENT = 1,
|
||||
DATA_DELRISSA_EVENT = 2,
|
||||
DATA_KAELTHAS_EVENT = 3,
|
||||
DATA_SELIN_FIREHEART = 0,
|
||||
DATA_VEXALLUS = 1,
|
||||
DATA_DELRISSA = 2,
|
||||
DATA_KAELTHAS = 3,
|
||||
MAX_ENCOUNTER = 4,
|
||||
|
||||
DATA_KALECGOS = 5
|
||||
DATA_KALECGOS = 5,
|
||||
DATA_ESCAPE_ORB = 6
|
||||
};
|
||||
|
||||
enum MTCreatures
|
||||
|
||||
@@ -1031,35 +1031,32 @@ class spell_brewfest_apple_trap : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_q11117_catch_the_wild_wolpertinger : public SpellScript
|
||||
enum Catch
|
||||
{
|
||||
PrepareSpellScript(spell_q11117_catch_the_wild_wolpertinger);
|
||||
NPC_WILD_WOLPERTINGER = 23487,
|
||||
|
||||
SpellCastResult CheckTarget()
|
||||
ITEM_STUNNED_WOLPERTINGER = 32906
|
||||
};
|
||||
|
||||
class spell_catch_the_wild_wolpertinger : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_catch_the_wild_wolpertinger);
|
||||
|
||||
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (caster->ToPlayer())
|
||||
if (Unit* target = caster->ToPlayer()->GetSelectedUnit())
|
||||
if (target->GetEntry() == 23487 && target->IsAlive())
|
||||
return SPELL_CAST_OK;
|
||||
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
}
|
||||
|
||||
void HandleDummyEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (GetCaster() && GetCaster()->ToPlayer())
|
||||
if (Creature* wild = GetTarget()->ToCreature())
|
||||
{
|
||||
GetCaster()->ToPlayer()->AddItem(32906, 1);
|
||||
if (Unit* target = GetCaster()->ToPlayer()->GetSelectedUnit())
|
||||
target->ToCreature()->DespawnOrUnsummon(500);
|
||||
if (wild->GetEntry() == NPC_WILD_WOLPERTINGER)
|
||||
{
|
||||
wild->ToCreature()->DespawnOrUnsummon(1s, 0s);
|
||||
GetCaster()->ToPlayer()->AddItem(ITEM_STUNNED_WOLPERTINGER, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_q11117_catch_the_wild_wolpertinger::CheckTarget);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_q11117_catch_the_wild_wolpertinger::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
OnEffectApply += AuraEffectApplyFn(spell_catch_the_wild_wolpertinger::HandleEffectApply, EFFECT_0, SPELL_AURA_MOD_PACIFY_SILENCE, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2072,7 +2069,7 @@ void AddSC_event_brewfest_scripts()
|
||||
RegisterSpellScript(spell_brewfest_ram_fatigue);
|
||||
RegisterSpellScript(spell_brewfest_apple_trap);
|
||||
// other
|
||||
RegisterSpellScript(spell_q11117_catch_the_wild_wolpertinger);
|
||||
RegisterSpellScript(spell_catch_the_wild_wolpertinger);
|
||||
RegisterSpellScript(spell_brewfest_fill_keg);
|
||||
RegisterSpellScript(spell_brewfest_unfill_keg);
|
||||
RegisterSpellScript(spell_brewfest_toss_mug);
|
||||
|
||||
@@ -253,6 +253,39 @@ class spell_midsummer_ribbon_pole : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_midsummer_ribbon_pole_visual : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_midsummer_ribbon_pole_visual)
|
||||
|
||||
void UpdateTarget(WorldObject*& target)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
// find NPC at ribbon pole top as target
|
||||
// trap 181604 also spawns NPCs at pole bottom - ignore those
|
||||
std::list<Creature*> crList;
|
||||
target->GetCreaturesWithEntryInRange(crList, 30.0f, NPC_RIBBON_POLE_DEBUG_TARGET);
|
||||
if (crList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<Creature*>::const_iterator itr = crList.begin(); itr != crList.end(); ++itr)
|
||||
{
|
||||
// NPC on ribbon pole top is no tempsummon
|
||||
if (!(*itr)->ToTempSummon())
|
||||
{
|
||||
target = *itr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectTargetSelect += SpellObjectTargetSelectFn(spell_midsummer_ribbon_pole_visual::UpdateTarget, EFFECT_0, TARGET_UNIT_NEARBY_ENTRY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_midsummer_torch_quest : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_midsummer_torch_quest)
|
||||
@@ -296,6 +329,7 @@ enum flingTorch
|
||||
SPELL_FLING_TORCH_DUMMY = 46747,
|
||||
SPELL_MISSED_TORCH = 45676,
|
||||
SPELL_TORCH_COUNTER = 45693,
|
||||
SPELL_TORCH_SHADOW = 46105
|
||||
};
|
||||
|
||||
class spell_midsummer_fling_torch : public SpellScript
|
||||
@@ -339,7 +373,10 @@ class spell_midsummer_fling_torch : public SpellScript
|
||||
|
||||
// we have any pos
|
||||
if (pos.GetPositionX())
|
||||
{
|
||||
caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_FLING_TORCH, true);
|
||||
caster->CastSpell(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), SPELL_TORCH_SHADOW, true);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleFinish()
|
||||
@@ -417,15 +454,18 @@ enum eJuggle
|
||||
SPELL_TORCH_CHECK = 45644,
|
||||
SPELL_GIVE_TORCH = 45280,
|
||||
QUEST_TORCH_CATCHING_A = 11657,
|
||||
QUEST_TORCH_CATCHING_H = 11923
|
||||
QUEST_TORCH_CATCHING_H = 11923,
|
||||
|
||||
SPELL_TORCH_SHADOW_SELF = 46121,
|
||||
SPELL_TORCH_SHADOW_SLOW = 46120,
|
||||
SPELL_TORCH_SHADOW_MED = 46118,
|
||||
SPELL_TORCH_SHADOW_FAST = 46117
|
||||
};
|
||||
|
||||
class spell_midsummer_juggling_torch : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_midsummer_juggling_torch);
|
||||
|
||||
bool handled;
|
||||
bool Load() override { handled = false; return true; }
|
||||
void HandleFinish()
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
@@ -435,39 +475,36 @@ class spell_midsummer_juggling_torch : public SpellScript
|
||||
if (const WorldLocation* loc = GetExplTargetDest())
|
||||
{
|
||||
if (loc->GetExactDist(caster) < 3.0f)
|
||||
{
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SELF, true);
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SELF, true);
|
||||
}
|
||||
else if (loc->GetExactDist(caster) < 10.0f)
|
||||
{
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_SLOW, true);
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_SLOW, true);
|
||||
}
|
||||
else if (loc->GetExactDist(caster) < 25.0f)
|
||||
{
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_MED, true);
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_MED, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_JUGGLE_FAST, true);
|
||||
caster->CastSpell(loc->GetPositionX(), loc->GetPositionY(), loc->GetPositionZ(), SPELL_TORCH_SHADOW_FAST, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_JUGGLE_SELF, true);
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex effIndex)
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (Player* target = GetHitPlayer())
|
||||
if (!handled && target->GetQuestRewardStatus(target->GetTeamId() == TEAM_ALLIANCE ? 11657 : 11923))
|
||||
{
|
||||
handled = true;
|
||||
caster->CastSpell(target, SPELL_GIVE_TORCH, true);
|
||||
}
|
||||
caster->CastSpell(caster, SPELL_TORCH_SHADOW_SELF, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
if (m_scriptSpellId == SPELL_TORCH_CHECK)
|
||||
OnEffectHitTarget += SpellEffectFn(spell_midsummer_juggling_torch::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
else
|
||||
AfterCast += SpellCastFn(spell_midsummer_juggling_torch::HandleFinish);
|
||||
AfterCast += SpellCastFn(spell_midsummer_juggling_torch::HandleFinish);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -510,6 +547,7 @@ void AddSC_event_midsummer_scripts()
|
||||
// Spells
|
||||
RegisterSpellScript(spell_gen_crab_disguise);
|
||||
RegisterSpellScript(spell_midsummer_ribbon_pole);
|
||||
RegisterSpellScript(spell_midsummer_ribbon_pole_visual);
|
||||
RegisterSpellScript(spell_midsummer_torch_quest);
|
||||
RegisterSpellScript(spell_midsummer_fling_torch);
|
||||
RegisterSpellScript(spell_midsummer_juggling_torch);
|
||||
|
||||
@@ -366,6 +366,9 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_ALGALON, FAIL);
|
||||
|
||||
ScriptedAI::EnterEvadeMode(why);
|
||||
}
|
||||
|
||||
|
||||
@@ -786,6 +786,18 @@ public:
|
||||
go->SetGoState(data == IN_PROGRESS ? GO_STATE_ACTIVE : GO_STATE_READY);
|
||||
go->EnableCollision(false);
|
||||
}
|
||||
|
||||
if (data == FAIL)
|
||||
{
|
||||
scheduler.Schedule(5s, [this](TaskContext)
|
||||
{
|
||||
if (m_algalonTimer && (m_algalonTimer <= 60 || m_algalonTimer == TIMER_ALGALON_TO_SUMMON))
|
||||
{
|
||||
instance->SummonCreature(NPC_ALGALON, AlgalonLandPos);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Achievement
|
||||
@@ -1109,6 +1121,8 @@ public:
|
||||
|
||||
void Update(uint32 diff) override
|
||||
{
|
||||
InstanceScript::Update(diff);
|
||||
|
||||
if (_events.Empty())
|
||||
return;
|
||||
|
||||
|
||||
@@ -83,13 +83,13 @@ struct boss_anzu : public BossAI
|
||||
|
||||
uint32 talkTimer;
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override
|
||||
{
|
||||
if (summon->GetEntry() == NPC_BROOD_OF_ANZU)
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
summons.RemoveNotExisting();
|
||||
if (summons.empty())
|
||||
if (!summons.HasEntry(NPC_BROOD_OF_ANZU))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "serpent_shrine.h"
|
||||
#include "TaskScheduler.h"
|
||||
|
||||
enum Talk
|
||||
{
|
||||
@@ -32,26 +33,41 @@ enum Talk
|
||||
|
||||
enum Spells
|
||||
{
|
||||
//Fathomlord Karathress
|
||||
SPELL_CATACLYSMIC_BOLT = 38441,
|
||||
SPELL_SEAR_NOVA = 38445,
|
||||
SPELL_ENRAGE = 24318,
|
||||
SPELL_BLESSING_OF_THE_TIDES = 38449
|
||||
SPELL_BLESSING_OF_THE_TIDES = 38449,
|
||||
//Fathomguard Sharkkis
|
||||
SPELL_HURL_TRIDENT = 38374,
|
||||
SPELL_LEECHING_THROW = 29436,
|
||||
SPELL_MULTI_TOSS = 38366,
|
||||
SPELL_SUMMON_FATHOM_SPOREBAT = 38431,
|
||||
SPELL_SUMMON_FATHOM_LURKER = 38433,
|
||||
SPELL_THE_BEAST_WITHIN = 38373,
|
||||
SPELL_BESTIAL_WRATH = 38371,
|
||||
SPELL_POWER_OF_SHARKKIS = 38455,
|
||||
//Fathomguard Tidalvess
|
||||
SPELL_FROST_SHOCK = 38234,
|
||||
SPELL_EARTHBIND_TOTEM = 38304,
|
||||
SPELL_POISON_CLEANSING_TOTEM = 38306,
|
||||
SPELL_SPITFIRE_TOTEM = 38236,
|
||||
SPELL_POWER_OF_TIDALVESS = 38452,
|
||||
//Fathomguard Caribdis
|
||||
SPELL_SUMMON_CYCLONE = 38337,
|
||||
SPELL_WATER_BOLT_VOLLEY = 38335,
|
||||
SPELL_TIDAL_SURGE = 38358,
|
||||
SPELL_HEALING_WAVE = 38330,
|
||||
SPELL_POWER_OF_CARIBDIS = 38451,
|
||||
//Spitfire Totem
|
||||
SPELL_ATTACK = 38296
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
MAX_ADVISORS = 3,
|
||||
NPC_FATHOM_GUARD_CARIBDIS = 21964,
|
||||
NPC_FATHOM_GUARD_TIDALVESS = 21965,
|
||||
NPC_FATHOM_GUARD_SHARKKIS = 21966,
|
||||
NPC_SEER_OLUM = 22820,
|
||||
GO_CAGE = 185952,
|
||||
|
||||
EVENT_SPELL_CATACLYSMIC_BOLT = 1,
|
||||
EVENT_SPELL_ENRAGE = 2,
|
||||
EVENT_SPELL_SEAR_NOVA = 3,
|
||||
EVENT_HEALTH_CHECK = 4,
|
||||
EVENT_KILL_TALK = 5
|
||||
};
|
||||
|
||||
const Position advisorsPosition[MAX_ADVISORS + 2] =
|
||||
@@ -63,124 +79,463 @@ const Position advisorsPosition[MAX_ADVISORS + 2] =
|
||||
{457.37f, -544.71f, -7.54f, 0.00f}
|
||||
};
|
||||
|
||||
class boss_fathomlord_karathress : public CreatureScript
|
||||
struct boss_fathomlord_karathress : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_fathomlord_karathress() : CreatureScript("boss_fathomlord_karathress") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_fathomlord_karathress(Creature* creature) : BossAI(creature, DATA_FATHOM_LORD_KARATHRESS)
|
||||
{
|
||||
return GetSerpentShrineAI<boss_fathomlord_karathressAI>(creature);
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
struct boss_fathomlord_karathressAI : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_fathomlord_karathressAI(Creature* creature) : BossAI(creature, DATA_FATHOM_LORD_KARATHRESS)
|
||||
{
|
||||
}
|
||||
BossAI::Reset();
|
||||
_recentlySpoken = false;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_TIDALVESS, advisorsPosition[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_SHARKKIS, advisorsPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_CARIBDIS, advisorsPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_TIDALVESS, advisorsPosition[0], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_SHARKKIS, advisorsPosition[1], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
me->SummonCreature(NPC_FATHOM_GUARD_CARIBDIS, advisorsPosition[2], TEMPSUMMON_CORPSE_TIMED_DESPAWN, 600000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == NPC_SEER_OLUM)
|
||||
ScheduleHealthCheckEvent(75, [&]{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
{
|
||||
summon->SetWalk(true);
|
||||
summon->GetMotionMaster()->MovePoint(0, advisorsPosition[MAX_ADVISORS + 1], false);
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_TIDALVESS)
|
||||
Talk(SAY_GAIN_ABILITY1);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_SHARKKIS)
|
||||
Talk(SAY_GAIN_ABILITY2);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_CARIBDIS)
|
||||
Talk(SAY_GAIN_ABILITY3);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
me->SummonCreature(NPC_SEER_OLUM, advisorsPosition[MAX_ADVISORS], TEMPSUMMON_TIMED_DESPAWN, 3600000);
|
||||
if (GameObject* gobject = me->FindNearestGameObject(GO_CAGE, 100.0f))
|
||||
gobject->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
me->CallForHelp(10.0f);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CATACLYSMIC_BOLT, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SEAR_NOVA, 25000);
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_ENRAGE:
|
||||
me->CastSpell(me, SPELL_ENRAGE, true);
|
||||
break;
|
||||
case EVENT_SPELL_CATACLYSMIC_BOLT:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 50.0f, true)))
|
||||
me->CastSpell(target, SPELL_CATACLYSMIC_BOLT, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CATACLYSMIC_BOLT, 6000);
|
||||
break;
|
||||
case EVENT_SPELL_SEAR_NOVA:
|
||||
me->CastSpell(me, SPELL_SEAR_NOVA, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SEAR_NOVA, 20000 + urand(0, 20000));
|
||||
break;
|
||||
case EVENT_HEALTH_CHECK:
|
||||
if (me->HealthBelowPct(76))
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
{
|
||||
if (summon->GetMaxHealth() > 500000)
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
if (summon->GetMaxHealth() > 500000)
|
||||
summon->CastSpell(me, SPELL_BLESSING_OF_THE_TIDES, true);
|
||||
|
||||
if (me->HasAura(SPELL_BLESSING_OF_THE_TIDES))
|
||||
Talk(SAY_GAIN_BLESSING);
|
||||
break;
|
||||
summon->CastSpell(me, SPELL_BLESSING_OF_THE_TIDES, true);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HEALTH_CHECK, 1000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (me->HasAura(SPELL_BLESSING_OF_THE_TIDES))
|
||||
{
|
||||
Talk(SAY_GAIN_BLESSING);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == NPC_SEER_OLUM)
|
||||
{
|
||||
summon->SetWalk(true);
|
||||
summon->GetMotionMaster()->MovePoint(0, advisorsPosition[MAX_ADVISORS + 1], false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) override
|
||||
{
|
||||
summons.Despawn(summon);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_TIDALVESS)
|
||||
Talk(SAY_GAIN_ABILITY1);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_SHARKKIS)
|
||||
Talk(SAY_GAIN_ABILITY2);
|
||||
if (summon->GetEntry() == NPC_FATHOM_GUARD_CARIBDIS)
|
||||
Talk(SAY_GAIN_ABILITY3);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (!_recentlySpoken)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
_recentlySpoken = true;
|
||||
}
|
||||
scheduler.Schedule(6s, [this](TaskContext)
|
||||
{
|
||||
_recentlySpoken = false;
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
me->SummonCreature(NPC_SEER_OLUM, advisorsPosition[MAX_ADVISORS], TEMPSUMMON_TIMED_DESPAWN, 3600000);
|
||||
if (GameObject* gobject = me->FindNearestGameObject(GO_CAGE, 100.0f))
|
||||
{
|
||||
gobject->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
instance->DoForAllMinions(DATA_FATHOM_LORD_KARATHRESS, [&](Creature* fathomguard) {
|
||||
fathomguard->SetInCombatWithZone();
|
||||
});
|
||||
|
||||
scheduler.Schedule(10s, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 50.0f, true)))
|
||||
{
|
||||
me->CastSpell(target, SPELL_CATACLYSMIC_BOLT);
|
||||
}
|
||||
context.Repeat(6s);
|
||||
}).Schedule(25s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SEAR_NOVA);
|
||||
context.Repeat(20s, 40s);
|
||||
}).Schedule(10min, [this](TaskContext)
|
||||
{
|
||||
DoCastSelf(SPELL_ENRAGE, true);
|
||||
});
|
||||
}
|
||||
private:
|
||||
bool _recentlySpoken;
|
||||
};
|
||||
|
||||
struct LeechingThrowSelector
|
||||
{
|
||||
public:
|
||||
explicit LeechingThrowSelector(WorldObject const* source) : _source(source) { }
|
||||
|
||||
bool operator() (Unit* unit) const
|
||||
{
|
||||
return unit->getPowerType() == POWER_MANA && _source->GetDistance(unit) < 50.0f;
|
||||
}
|
||||
private:
|
||||
WorldObject const* _source;
|
||||
};
|
||||
|
||||
struct boss_fathomguard_sharkkis : public ScriptedAI
|
||||
{
|
||||
boss_fathomguard_sharkkis(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
{
|
||||
summons.clear();
|
||||
|
||||
_instance = creature->GetInstanceScript();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->SetInCombatWithZone();
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.Schedule(2500ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_HURL_TRIDENT);
|
||||
context.Repeat(5s);
|
||||
}).Schedule(20650ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_MULTI_TOSS);
|
||||
context.Repeat(12150ms, 26350ms);
|
||||
}).Schedule(6050ms, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, LeechingThrowSelector(me)))
|
||||
{
|
||||
me->CastSpell(target, SPELL_LEECHING_THROW);
|
||||
}
|
||||
context.Repeat(6050ms, 22250ms);
|
||||
}).Schedule(41250ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_THE_BEAST_WITHIN);
|
||||
summons.DoForAllSummons([&](WorldObject* summon)
|
||||
{
|
||||
me->CastSpell(summon->ToCreature(), SPELL_BESTIAL_WRATH, true);
|
||||
});
|
||||
context.Repeat(39950ms, 46050ms);
|
||||
}).Schedule(14550ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(urand(0, 1) ? SPELL_SUMMON_FATHOM_LURKER : SPELL_SUMMON_FATHOM_SPOREBAT);
|
||||
context.Repeat(30300ms);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS))
|
||||
{
|
||||
me->CastSpell(karathress, SPELL_POWER_OF_SHARKKIS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
enum NPCTotems
|
||||
{
|
||||
NPC_SPITFIRE_TOTEM = 22091,
|
||||
NPC_GREATER_EARTHBIND_TOTEM = 22486,
|
||||
NPC_GREATER_POISON_CLEANSING_TOTEM = 22487
|
||||
};
|
||||
|
||||
enum TidalActions
|
||||
{
|
||||
ACTION_REMOVE_SPITFIRE = 1,
|
||||
ACTION_REMOVE_EARTHBIND = 2,
|
||||
ACTION_REMOVE_CLEANSING = 3
|
||||
};
|
||||
|
||||
enum TotemChoice
|
||||
{
|
||||
SPITFIRE = 1,
|
||||
EARTHBIND = 2,
|
||||
CLEANSING = 3
|
||||
};
|
||||
|
||||
struct boss_fathomguard_tidalvess : public ScriptedAI
|
||||
{
|
||||
boss_fathomguard_tidalvess(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
{
|
||||
_instance = creature->GetInstanceScript();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
SummonList summons;
|
||||
|
||||
std::list<uint32> entryList;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
_choice = 0;
|
||||
|
||||
summons.DespawnAll();
|
||||
|
||||
entryList.clear();
|
||||
|
||||
entryList = {NPC_SPITFIRE_TOTEM, NPC_GREATER_EARTHBIND_TOTEM, NPC_GREATER_POISON_CLEANSING_TOTEM};
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
summon->Attack(me->GetVictim(), false);
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
|
||||
void ScheduleRemoval(uint32 entry)
|
||||
{
|
||||
std::chrono::seconds timer = 0s;
|
||||
int32 action = 0;
|
||||
uint8 group = 0;
|
||||
|
||||
switch(entry)
|
||||
{
|
||||
case NPC_SPITFIRE_TOTEM:
|
||||
timer = 59s;
|
||||
action = ACTION_REMOVE_SPITFIRE;
|
||||
group = SPITFIRE;
|
||||
break;
|
||||
case NPC_GREATER_EARTHBIND_TOTEM:
|
||||
timer = 44s;
|
||||
action = ACTION_REMOVE_EARTHBIND;
|
||||
group = EARTHBIND;
|
||||
break;
|
||||
case NPC_GREATER_POISON_CLEANSING_TOTEM:
|
||||
timer = 29s;
|
||||
action = ACTION_REMOVE_CLEANSING;
|
||||
group = CLEANSING;
|
||||
break;
|
||||
default:
|
||||
timer = 29s;
|
||||
}
|
||||
_totemScheduler.Schedule(timer, group, [this, action](TaskContext)
|
||||
{
|
||||
me->AI()->DoAction(action);
|
||||
});
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_REMOVE_SPITFIRE:
|
||||
_totemScheduler.CancelGroup(SPITFIRE);
|
||||
entryList.push_back(NPC_SPITFIRE_TOTEM);
|
||||
break;
|
||||
case ACTION_REMOVE_EARTHBIND:
|
||||
_totemScheduler.CancelGroup(EARTHBIND);
|
||||
entryList.push_back(NPC_GREATER_EARTHBIND_TOTEM);
|
||||
break;
|
||||
case ACTION_REMOVE_CLEANSING:
|
||||
_totemScheduler.CancelGroup(CLEANSING);
|
||||
entryList.push_back(NPC_GREATER_POISON_CLEANSING_TOTEM);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonTotem(uint32 entry)
|
||||
{
|
||||
switch(entry)
|
||||
{
|
||||
case NPC_SPITFIRE_TOTEM:
|
||||
DoCastSelf(SPELL_SPITFIRE_TOTEM);
|
||||
break;
|
||||
case NPC_GREATER_EARTHBIND_TOTEM:
|
||||
DoCastSelf(SPELL_EARTHBIND_TOTEM);
|
||||
break;
|
||||
case NPC_GREATER_POISON_CLEANSING_TOTEM:
|
||||
DoCastSelf(SPELL_POISON_CLEANSING_TOTEM);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.Schedule(10900ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_FROST_SHOCK);
|
||||
context.Repeat(10900ms, 14700ms);
|
||||
}).Schedule(15800ms, [this](TaskContext context)
|
||||
{
|
||||
if (entryList.size() != 0) //don't summon when all totems are up
|
||||
{
|
||||
uint32 totemEntry = entryList.front();
|
||||
entryList.pop_front();
|
||||
SummonTotem(totemEntry);
|
||||
ScheduleRemoval(totemEntry);
|
||||
}
|
||||
context.Repeat(13350ms, 24250ms);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS))
|
||||
{
|
||||
me->CastSpell(karathress, SPELL_POWER_OF_TIDALVESS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff);
|
||||
_totemScheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
TaskScheduler _totemScheduler;
|
||||
InstanceScript* _instance;
|
||||
uint8 _choice;
|
||||
};
|
||||
|
||||
struct boss_fathomguard_caribdis : public ScriptedAI
|
||||
{
|
||||
boss_fathomguard_caribdis(Creature* creature) : ScriptedAI(creature), summons(creature)
|
||||
{
|
||||
_instance = creature->GetInstanceScript();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
SummonList summons;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.Schedule(27900ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_WATER_BOLT_VOLLEY);
|
||||
context.Repeat(6050ms, 19750ms);
|
||||
}).Schedule(23050ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_TIDAL_SURGE);
|
||||
context.Repeat(24250ms, 33250ms);
|
||||
}).Schedule(15750ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_SUMMON_CYCLONE);
|
||||
context.Repeat(47250ms, 51550ms);
|
||||
}).Schedule(20s, [this](TaskContext context)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(60.0f, 150000))
|
||||
{
|
||||
DoCast(target, SPELL_HEALING_WAVE);
|
||||
}
|
||||
context.Repeat(20s);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
if (Creature* karathress = _instance->GetCreature(DATA_FATHOM_LORD_KARATHRESS))
|
||||
{
|
||||
me->CastSpell(karathress, SPELL_POWER_OF_CARIBDIS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_scheduler.Update(diff);
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
class spell_karathress_power_of_caribdis : public SpellScriptLoader
|
||||
@@ -213,6 +568,9 @@ public:
|
||||
|
||||
void AddSC_boss_fathomlord_karathress()
|
||||
{
|
||||
new boss_fathomlord_karathress();
|
||||
RegisterSerpentShrineAI(boss_fathomlord_karathress);
|
||||
RegisterSerpentShrineAI(boss_fathomguard_sharkkis);
|
||||
RegisterSerpentShrineAI(boss_fathomguard_tidalvess);
|
||||
RegisterSerpentShrineAI(boss_fathomguard_caribdis);
|
||||
new spell_karathress_power_of_caribdis();
|
||||
}
|
||||
|
||||
@@ -64,20 +64,6 @@ enum Misc
|
||||
ITEM_TAINTED_CORE = 31088,
|
||||
|
||||
POINT_HOME = 1,
|
||||
|
||||
EVENT_SPELL_SHOCK_BLAST = 1,
|
||||
EVENT_SPELL_STATIC_CHARGE = 2,
|
||||
EVENT_SPELL_ENTANGLE = 3,
|
||||
EVENT_CHECK_HEALTH = 4,
|
||||
EVENT_SPELL_FORKED_LIGHTNING = 5,
|
||||
EVENT_SUMMON_A = 6,
|
||||
EVENT_SUMMON_B = 7,
|
||||
EVENT_SUMMON_C = 8,
|
||||
EVENT_SUMMON_D = 9,
|
||||
EVENT_CHECK_HEALTH2 = 10,
|
||||
EVENT_SUMMON_SPOREBAT = 11,
|
||||
|
||||
EVENT_KILL_TALK = 20
|
||||
};
|
||||
|
||||
class startFollow : public BasicEvent
|
||||
@@ -88,215 +74,223 @@ public:
|
||||
bool Execute(uint64 /*execTime*/, uint32 /*diff*/) override
|
||||
{
|
||||
if (InstanceScript* instance = _owner->GetInstanceScript())
|
||||
{
|
||||
if (Creature* vashj = ObjectAccessor::GetCreature(*_owner, instance->GetGuidData(NPC_LADY_VASHJ)))
|
||||
{
|
||||
_owner->GetMotionMaster()->MoveFollow(vashj, 3.0f, vashj->GetAngle(_owner), MOTION_SLOT_CONTROLLED);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Unit* _owner;
|
||||
};
|
||||
|
||||
class boss_lady_vashj : public CreatureScript
|
||||
struct boss_lady_vashj : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_lady_vashj() : CreatureScript("boss_lady_vashj") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_lady_vashj(Creature* creature) : BossAI(creature, DATA_LADY_VASHJ)
|
||||
{
|
||||
return GetSerpentShrineAI<boss_lady_vashjAI>(creature);
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
|
||||
_intro = false;
|
||||
}
|
||||
|
||||
struct boss_lady_vashjAI : public BossAI
|
||||
void Reset() override
|
||||
{
|
||||
boss_lady_vashjAI(Creature* creature) : BossAI(creature, DATA_LADY_VASHJ)
|
||||
_count = 0;
|
||||
_recentlySpoken = false;
|
||||
_batTimer = 20s;
|
||||
BossAI::Reset();
|
||||
|
||||
ScheduleHealthCheckEvent(70, [&]{
|
||||
Talk(SAY_PHASE2);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MovePoint(POINT_HOME, me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY(), me->GetHomePosition().GetPositionZ(), true, true);
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if(!_recentlySpoken)
|
||||
{
|
||||
intro = false;
|
||||
Talk(SAY_SLAY);
|
||||
_recentlySpoken = true;
|
||||
}
|
||||
scheduler.Schedule(6s, [this](TaskContext)
|
||||
{
|
||||
_recentlySpoken = false;
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
DoCastSelf(SPELL_REMOVE_TAINTED_CORES, true);
|
||||
|
||||
ScheduleSpells();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == WORLD_TRIGGER)
|
||||
{
|
||||
summon->CastSpell(summon, SPELL_MAGIC_BARRIER);
|
||||
}
|
||||
else if (summon->GetEntry() == NPC_ENCHANTED_ELEMENTAL)
|
||||
{
|
||||
summon->SetWalk(true);
|
||||
summon->m_Events.AddEvent(new startFollow(summon), summon->m_Events.CalculateTime(0));
|
||||
}
|
||||
else if (summon->GetEntry() == NPC_TOXIC_SPOREBAT)
|
||||
{
|
||||
summon->GetMotionMaster()->MoveRandom(30.0f);
|
||||
}
|
||||
else if (summon->GetEntry() != NPC_TAINTED_ELEMENTAL)
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(POINT_HOME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleSpells()
|
||||
{
|
||||
scheduler.Schedule(14550ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SHOCK_BLAST);
|
||||
context.Repeat(10850ms, 25100ms);
|
||||
}).Schedule(18150ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_STATIC_CHARGE);
|
||||
context.Repeat(7250ms, 27050ms);
|
||||
}).Schedule(25450ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_ENTANGLE);
|
||||
context.Repeat(18200ms, 51500ms);
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!_intro && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
_intro = true;
|
||||
Talk(SAY_INTRO);
|
||||
}
|
||||
|
||||
bool intro;
|
||||
int32 count;
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || id != POINT_HOME)
|
||||
{
|
||||
count = 0;
|
||||
BossAI::Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
me->SetFacingTo(me->GetHomePosition().GetOrientation());
|
||||
instance->SetData(DATA_ACTIVATE_SHIELD, 0);
|
||||
scheduler.CancelAll();
|
||||
|
||||
scheduler.Schedule(2400ms, [this](TaskContext context)
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
DoCastRandomTarget(SPELL_FORKED_LIGHTNING);
|
||||
context.Repeat(2400ms, 12450ms);
|
||||
}).Schedule(0s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_ENCHANTED_ELEMENTAL, true);
|
||||
context.Repeat(2500ms);
|
||||
}).Schedule(45s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_COILFANG_ELITE, true);
|
||||
context.Repeat(45s);
|
||||
}).Schedule(60s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_COILFANG_STRIDER, true);
|
||||
context.Repeat(60s);
|
||||
}).Schedule(50s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_TAINTED_ELEMENTAL, true);
|
||||
context.Repeat(50s);
|
||||
}).Schedule(1s, [this](TaskContext context)
|
||||
{
|
||||
if (!me->HasAura(SPELL_MAGIC_BARRIER))
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6000);
|
||||
}
|
||||
}
|
||||
Talk(SAY_PHASE3);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
scheduler.CancelAll();
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
BossAI::JustDied(killer);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
me->CastSpell(me, SPELL_REMOVE_TAINTED_CORES, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 20000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (summon->GetEntry() == WORLD_TRIGGER)
|
||||
summon->CastSpell(summon, SPELL_MAGIC_BARRIER, false);
|
||||
else if (summon->GetEntry() == NPC_ENCHANTED_ELEMENTAL)
|
||||
{
|
||||
summon->SetWalk(true);
|
||||
summon->m_Events.AddEvent(new startFollow(summon), summon->m_Events.CalculateTime(0));
|
||||
}
|
||||
else if (summon->GetEntry() == NPC_TOXIC_SPOREBAT)
|
||||
summon->GetMotionMaster()->MoveRandom(30.0f);
|
||||
else if (summon->GetEntry() != NPC_TAINTED_ELEMENTAL)
|
||||
summon->GetMotionMaster()->MovePoint(POINT_HOME, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), true, true);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!intro && who->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
intro = true;
|
||||
Talk(SAY_INTRO);
|
||||
}
|
||||
|
||||
BossAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type != POINT_MOTION_TYPE || id != POINT_HOME)
|
||||
return;
|
||||
|
||||
me->SetFacingTo(me->GetHomePosition().GetOrientation());
|
||||
instance->SetData(DATA_ACTIVATE_SHIELD, 0);
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_FORKED_LIGHTNING, 3000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_A, 0);
|
||||
events.ScheduleEvent(EVENT_SUMMON_B, 45000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_C, 60000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_D, 50000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_SHOCK_BLAST:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SHOCK_BLAST, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, urand(10000, 20000));
|
||||
break;
|
||||
case EVENT_SPELL_STATIC_CHARGE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f))
|
||||
me->CastSpell(target, SPELL_STATIC_CHARGE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_ENTANGLE:
|
||||
me->CastSpell(me, SPELL_ENTANGLE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 30000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(71))
|
||||
{
|
||||
Talk(SAY_PHASE2);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->GetMotionMaster()->MovePoint(POINT_HOME, me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY(), me->GetHomePosition().GetPositionZ(), true, true);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
|
||||
break;
|
||||
case EVENT_SPELL_FORKED_LIGHTNING:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 60.0f))
|
||||
me->CastSpell(target, SPELL_FORKED_LIGHTNING, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_FORKED_LIGHTNING, urand(2500, 5000));
|
||||
break;
|
||||
case EVENT_SUMMON_A:
|
||||
me->CastSpell(me, SPELL_SUMMON_ENCHANTED_ELEMENTAL, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_A, 2500);
|
||||
break;
|
||||
case EVENT_SUMMON_B:
|
||||
me->CastSpell(me, SPELL_SUMMON_COILFANG_ELITE, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_B, 45000);
|
||||
break;
|
||||
case EVENT_SUMMON_C:
|
||||
me->CastSpell(me, SPELL_SUMMON_COILFANG_STRIDER, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_C, 60000);
|
||||
break;
|
||||
case EVENT_SUMMON_D:
|
||||
me->CastSpell(me, SPELL_SUMMON_TAINTED_ELEMENTAL, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_D, 50000);
|
||||
break;
|
||||
case EVENT_CHECK_HEALTH2:
|
||||
if (!me->HasAura(SPELL_MAGIC_BARRIER))
|
||||
{
|
||||
Talk(SAY_PHASE3);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->GetMotionMaster()->MoveChase(me->GetVictim());
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_SHOCK_BLAST, 10000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STATIC_CHARGE, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENTANGLE, 20000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 5000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH2, 1000);
|
||||
break;
|
||||
case EVENT_SUMMON_SPOREBAT:
|
||||
me->CastSpell(me, SPELL_SUMMON_TOXIC_SPOREBAT, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_SPOREBAT, 20000 - 1000 * std::min(count++, 16));
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->GetReactState() != REACT_AGGRESSIVE || !me->isAttackReady())
|
||||
return;
|
||||
|
||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
me->resetAttackTimer();
|
||||
me->SetSheath(SHEATH_STATE_RANGED);
|
||||
me->CastSpell(me->GetVictim(), roll_chance_i(33) ? SPELL_MULTI_SHOT : SPELL_SHOOT, false);
|
||||
if (roll_chance_i(15))
|
||||
Talk(SAY_BOWSHOT);
|
||||
ScheduleSpells();
|
||||
scheduler.Schedule(5s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SUMMON_TOXIC_SPOREBAT, true);
|
||||
_batTimer = 20s - static_cast<std::chrono::seconds>(std::min(_count++, 16));
|
||||
context.Repeat(_batTimer);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetSheath(SHEATH_STATE_MELEE);
|
||||
DoMeleeAttackIfReady();
|
||||
context.Repeat(1s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
scheduler.Update(diff);
|
||||
|
||||
if (me->GetReactState() != REACT_AGGRESSIVE || !me->isAttackReady())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
if (!me->IsWithinMeleeRange(me->GetVictim()))
|
||||
{
|
||||
return me->GetHomePosition().GetExactDist2d(me) > 80.0f || !SelectTargetFromPlayerList(100.0f);
|
||||
me->resetAttackTimer();
|
||||
me->SetSheath(SHEATH_STATE_RANGED);
|
||||
me->CastSpell(me->GetVictim(), roll_chance_i(33) ? SPELL_MULTI_SHOT : SPELL_SHOOT, false);
|
||||
if (roll_chance_i(15))
|
||||
{
|
||||
Talk(SAY_BOWSHOT);
|
||||
}
|
||||
}
|
||||
};
|
||||
else
|
||||
{
|
||||
me->SetSheath(SHEATH_STATE_MELEE);
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckEvadeIfOutOfCombatArea() const override
|
||||
{
|
||||
return me->GetHomePosition().GetExactDist2d(me) > 80.0f || !SelectTargetFromPlayerList(100.0f);
|
||||
}
|
||||
|
||||
private:
|
||||
bool _recentlySpoken;
|
||||
bool _intro;
|
||||
int32 _count;
|
||||
std::chrono::seconds _batTimer;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
//Toxic Sporebat
|
||||
//Toxic Spores: Used in Phase 3 by the Spore Bats, it creates a contaminated green patch of ground, dealing about 2775-3225 nature damage every second to anyone who stands in it.
|
||||
//deprecated -- adds do work
|
||||
class npc_toxic_sporebat : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -433,7 +427,9 @@ public:
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Player* target = GetHitPlayer())
|
||||
{
|
||||
target->DestroyItemCount(ITEM_TAINTED_CORE, -1, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -488,7 +484,9 @@ public:
|
||||
{
|
||||
PreventHitDefaultEffect(effIndex);
|
||||
if (Unit* target = GetHitUnit())
|
||||
{
|
||||
target->CastSpell(target, SPELL_TOXIC_SPORES, true, nullptr, nullptr, GetCaster()->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
@@ -505,7 +503,7 @@ public:
|
||||
|
||||
void AddSC_boss_lady_vashj()
|
||||
{
|
||||
new boss_lady_vashj();
|
||||
RegisterSerpentShrineAI(boss_lady_vashj);
|
||||
new spell_lady_vashj_magic_barrier();
|
||||
new spell_lady_vashj_remove_tainted_cores();
|
||||
new spell_lady_vashj_summon_sporebat();
|
||||
|
||||
@@ -29,6 +29,20 @@ DoorData const doorData[] =
|
||||
{ GO_COILFANG_BRIDGE3, DATA_BRIDGE_EMERGED, DOOR_TYPE_PASSAGE }
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_FATHOM_LORD_KARATHRESS, DATA_FATHOM_LORD_KARATHRESS },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MinionData const minionData[] =
|
||||
{
|
||||
{ NPC_FATHOM_GUARD_SHARKKIS, DATA_FATHOM_LORD_KARATHRESS },
|
||||
{ NPC_FATHOM_GUARD_TIDALVESS, DATA_FATHOM_LORD_KARATHRESS },
|
||||
{ NPC_FATHOM_GUARD_CARIBDIS, DATA_FATHOM_LORD_KARATHRESS },
|
||||
{ 0, 0, }
|
||||
};
|
||||
|
||||
class instance_serpent_shrine : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
@@ -45,6 +59,8 @@ public:
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
LoadMinionData(minionData);
|
||||
|
||||
AliveKeepersCount = 0;
|
||||
}
|
||||
|
||||
@@ -53,8 +53,13 @@ enum SSNPCs
|
||||
NPC_THE_LURKER_BELOW = 21217,
|
||||
NPC_LEOTHERAS_THE_BLIND = 21215,
|
||||
NPC_CYCLONE_KARATHRESS = 22104,
|
||||
NPC_FATHOM_LORD_KARATHRESS = 21214,
|
||||
NPC_LADY_VASHJ = 21212,
|
||||
|
||||
NPC_FATHOM_GUARD_SHARKKIS = 21966,
|
||||
NPC_FATHOM_GUARD_TIDALVESS = 21965,
|
||||
NPC_FATHOM_GUARD_CARIBDIS = 21964,
|
||||
|
||||
NPC_COILFANG_SHATTERER = 21301,
|
||||
NPC_COILFANG_PRIESTESS = 21220,
|
||||
|
||||
|
||||
@@ -23,8 +23,7 @@ enum Spells
|
||||
{
|
||||
SPELL_ACID_SPRAY = 38153,
|
||||
SPELL_CLEAVE = 40504,
|
||||
SPELL_POISON_BOLT_VOLLEY_N = 34780,
|
||||
SPELL_POISON_BOLT_VOLLEY_H = 39340,
|
||||
SPELL_POISON_BOLT_VOLLEY = 34780,
|
||||
SPELL_UPPERCUT = 32055
|
||||
};
|
||||
|
||||
@@ -38,11 +37,6 @@ struct boss_quagmirran : public BossAI
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
_JustEngagedWith();
|
||||
@@ -57,11 +51,11 @@ struct boss_quagmirran : public BossAI
|
||||
context.Repeat(21800ms);
|
||||
}).Schedule(25200ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_ACID_SPRAY);
|
||||
DoCastRandomTarget(SPELL_ACID_SPRAY);
|
||||
context.Repeat(25s);
|
||||
}).Schedule(31800ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(DUNGEON_MODE(SPELL_POISON_BOLT_VOLLEY_N, SPELL_POISON_BOLT_VOLLEY_H));
|
||||
DoCastAOE(SPELL_POISON_BOLT_VOLLEY);
|
||||
context.Repeat(24400ms);
|
||||
});
|
||||
}
|
||||
@@ -70,4 +64,4 @@ struct boss_quagmirran : public BossAI
|
||||
void AddSC_boss_quagmirran()
|
||||
{
|
||||
RegisterTheSlavePensCreatureAI(boss_quagmirran);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,12 @@ DoorData const doorData[] =
|
||||
{ 0, 0, DOOR_TYPE_ROOM } // END
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_MAULGAR, DATA_MAULGAR },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
MinionData const minionData[] =
|
||||
{
|
||||
{ NPC_MAULGAR, DATA_MAULGAR },
|
||||
@@ -46,64 +52,13 @@ public:
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTER);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
LoadDoorData(doorData);
|
||||
LoadMinionData(minionData);
|
||||
|
||||
_addsKilled = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_MAULGAR:
|
||||
_maulgarGUID = creature->GetGUID();
|
||||
[[fallthrough]];
|
||||
case NPC_KROSH_FIREHAND:
|
||||
case NPC_OLM_THE_SUMMONER:
|
||||
case NPC_KIGGLER_THE_CRAZED:
|
||||
case NPC_BLINDEYE_THE_SEER:
|
||||
AddMinion(creature, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureRemove(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_MAULGAR:
|
||||
case NPC_KROSH_FIREHAND:
|
||||
case NPC_OLM_THE_SUMMONER:
|
||||
case NPC_KIGGLER_THE_CRAZED:
|
||||
case NPC_BLINDEYE_THE_SEER:
|
||||
AddMinion(creature, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_MAULGAR_DOOR:
|
||||
case GO_GRUUL_DOOR:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_MAULGAR_DOOR:
|
||||
case GO_GRUUL_DOOR:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SetBossState(uint32 id, EncounterState state) override
|
||||
{
|
||||
if (!InstanceScript::SetBossState(id, state))
|
||||
@@ -117,8 +72,12 @@ public:
|
||||
void SetData(uint32 type, uint32 /*id*/) override
|
||||
{
|
||||
if (type == DATA_ADDS_KILLED)
|
||||
if (Creature* maulgar = instance->GetCreature(_maulgarGUID))
|
||||
{
|
||||
if (Creature* maulgar = GetCreature(DATA_MAULGAR))
|
||||
{
|
||||
maulgar->AI()->DoAction(++_addsKilled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
@@ -130,7 +89,6 @@ public:
|
||||
|
||||
protected:
|
||||
uint32 _addsKilled;
|
||||
ObjectGuid _maulgarGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const override
|
||||
|
||||
@@ -388,20 +388,25 @@ class spell_dru_treant_scaling : public AuraScript
|
||||
};
|
||||
|
||||
// -1850 - Dash
|
||||
class spell_dru_dash : public AuraScript
|
||||
class spell_dru_dash : public SpellScript
|
||||
{
|
||||
PrepareAuraScript(spell_dru_dash);
|
||||
PrepareSpellScript(spell_dru_dash);
|
||||
|
||||
void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& /*canBeRecalculated*/)
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
// do not set speed if not in cat form
|
||||
if (GetUnitOwner()->GetShapeshiftForm() != FORM_CAT)
|
||||
amount = 0;
|
||||
Unit* caster = GetCaster();
|
||||
if (caster->GetShapeshiftForm() != FORM_CAT)
|
||||
{
|
||||
SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_MUST_BE_IN_CAT_FORM);
|
||||
return SPELL_FAILED_CUSTOM_ERROR;
|
||||
}
|
||||
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_dru_dash::CalculateAmount, EFFECT_0, SPELL_AURA_MOD_INCREASE_SPEED);
|
||||
OnCheckCast += SpellCheckCastFn(spell_dru_dash::CheckCast);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1308,6 +1308,29 @@ class spell_hun_bestial_wrath : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_hun_furious_howl : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_hun_furious_howl);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
return GetCaster()->IsPet();
|
||||
}
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if([&](WorldObject const* target) -> bool
|
||||
{
|
||||
return target != GetCaster() && target != GetCaster()->ToPet()->GetOwner();
|
||||
});
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_hun_furious_howl::FilterTargets, EFFECT_ALL, TARGET_UNIT_CASTER_AREA_PARTY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_hunter_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_hun_check_pet_los);
|
||||
@@ -1338,4 +1361,5 @@ void AddSC_hunter_spell_scripts()
|
||||
RegisterSpellScript(spell_hun_lock_and_load);
|
||||
RegisterSpellScript(spell_hun_intimidation);
|
||||
RegisterSpellScript(spell_hun_bestial_wrath);
|
||||
RegisterSpellScript(spell_hun_furious_howl);
|
||||
}
|
||||
|
||||
@@ -3342,9 +3342,9 @@ class spell_item_rocket_boots : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_item_runic_healing_injector : public SpellScript
|
||||
class spell_item_healing_injector : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_item_runic_healing_injector);
|
||||
PrepareSpellScript(spell_item_healing_injector);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
@@ -3360,7 +3360,33 @@ class spell_item_runic_healing_injector : public SpellScript
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_item_runic_healing_injector::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_item_healing_injector::HandleHeal, EFFECT_0, SPELL_EFFECT_HEAL);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_item_mana_injector : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_item_mana_injector);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
return GetCaster()->GetTypeId() == TYPEID_PLAYER;
|
||||
}
|
||||
|
||||
void HandleEnergize(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Player* caster = GetCaster()->ToPlayer())
|
||||
{
|
||||
if (caster->HasSkill(SKILL_ENGINEERING))
|
||||
{
|
||||
SetEffectValue(GetEffectValue() * 1.25f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_item_mana_injector::HandleEnergize, EFFECT_0, SPELL_EFFECT_ENERGIZE);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3959,7 +3985,8 @@ void AddSC_item_spell_scripts()
|
||||
RegisterSpellScript(spell_item_nitro_boots);
|
||||
RegisterSpellScript(spell_item_teach_language);
|
||||
RegisterSpellScript(spell_item_rocket_boots);
|
||||
RegisterSpellScript(spell_item_runic_healing_injector);
|
||||
RegisterSpellScript(spell_item_healing_injector);
|
||||
RegisterSpellScript(spell_item_mana_injector);
|
||||
RegisterSpellScript(spell_item_pygmy_oil);
|
||||
RegisterSpellScript(spell_item_unusual_compass);
|
||||
RegisterSpellScript(spell_item_chicken_cover);
|
||||
|
||||
@@ -1267,6 +1267,45 @@ class spell_warl_glyph_of_felguard : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
class spell_warl_glyph_of_voidwalker : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_warl_glyph_of_voidwalker);
|
||||
|
||||
void HandleApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Player* player = GetCaster()->ToPlayer())
|
||||
{
|
||||
if (Pet* pet = player->GetPet())
|
||||
{
|
||||
if (pet->GetEntry() == NPC_VOIDWALKER)
|
||||
{
|
||||
pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Player* player = GetCaster()->ToPlayer())
|
||||
{
|
||||
if (Pet* pet = player->GetPet())
|
||||
{
|
||||
if (pet->GetEntry() == NPC_VOIDWALKER)
|
||||
{
|
||||
pet->HandleStatModifier(UNIT_MOD_STAT_STAMINA, TOTAL_PCT, aurEff->GetAmount(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectApply += AuraEffectApplyFn(spell_warl_glyph_of_voidwalker::HandleApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_warl_glyph_of_voidwalker::HandleRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_warlock_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_warl_eye_of_kilrogg);
|
||||
@@ -1299,4 +1338,5 @@ void AddSC_warlock_spell_scripts()
|
||||
RegisterSpellScript(spell_warl_drain_soul);
|
||||
RegisterSpellScript(spell_warl_shadowburn);
|
||||
RegisterSpellScript(spell_warl_glyph_of_felguard);
|
||||
RegisterSpellScript(spell_warl_glyph_of_voidwalker);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user