mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-22 10:05:32 +01:00
Scripts/Ahnkahet: implement Herald Volazj's Twisted Visage AI + small corrections to Herald's own AI
sorry about indentation timers are guessed summoning logic unchanged, remains not blizzlike visage's spells missing spelldifficulty_dbc entries
This commit is contained in:
1
sql/updates/world/3.3.5/2021_08_19_00_world.sql
Normal file
1
sql/updates/world/3.3.5/2021_08_19_00_world.sql
Normal file
@@ -0,0 +1 @@
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_twisted_visage' WHERE `entry`=30625;
|
||||
@@ -15,75 +15,127 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Comment: Missing AI for Twisted Visages
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ahnkahet.h"
|
||||
#include "CommonHelpers.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
enum VolazjTexts
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_INSANITY = 1,
|
||||
SAY_SLAY_1 = 2,
|
||||
SAY_SLAY_2 = 3,
|
||||
SAY_SLAY_3 = 4,
|
||||
SAY_DEATH_1 = 5,
|
||||
SAY_DEATH_2 = 6,
|
||||
SAY_AGGRO = 0,
|
||||
SAY_INSANITY = 1,
|
||||
SAY_SLAY_1 = 2,
|
||||
SAY_SLAY_2 = 3,
|
||||
SAY_SLAY_3 = 4,
|
||||
SAY_DEATH_1 = 5,
|
||||
SAY_DEATH_2 = 6,
|
||||
|
||||
WHISPER_AGGRO = 7,
|
||||
WHISPER_INSANITY = 8,
|
||||
WHISPER_SLAY_1 = 9,
|
||||
WHISPER_SLAY_2 = 10,
|
||||
WHISPER_SLAY_3 = 11,
|
||||
WHISPER_DEATH_1 = 12,
|
||||
WHISPER_DEATH_2 = 13
|
||||
WHISPER_AGGRO = 7,
|
||||
WHISPER_INSANITY = 8,
|
||||
WHISPER_SLAY_1 = 9,
|
||||
WHISPER_SLAY_2 = 10,
|
||||
WHISPER_SLAY_3 = 11,
|
||||
WHISPER_DEATH_1 = 12,
|
||||
WHISPER_DEATH_2 = 13
|
||||
};
|
||||
|
||||
enum VolazjSpells
|
||||
{
|
||||
SPELL_INSANITY = 57496, // Dummy
|
||||
INSANITY_VISUAL = 57561,
|
||||
SPELL_INSANITY_TARGET = 57508,
|
||||
SPELL_MIND_FLAY = 57941,
|
||||
SPELL_SHADOW_BOLT_VOLLEY = 57942,
|
||||
SPELL_SHIVER = 57949,
|
||||
SPELL_CLONE_PLAYER = 57507, // cast on player during insanity
|
||||
SPELL_INSANITY_PHASING_1 = 57508,
|
||||
SPELL_INSANITY_PHASING_2 = 57509,
|
||||
SPELL_INSANITY_PHASING_3 = 57510,
|
||||
SPELL_INSANITY_PHASING_4 = 57511,
|
||||
SPELL_INSANITY_PHASING_5 = 57512,
|
||||
SPELL_INSANITY = 57496, // Dummy
|
||||
INSANITY_VISUAL = 57561,
|
||||
SPELL_INSANITY_TARGET = 57508,
|
||||
SPELL_MIND_FLAY = 57941,
|
||||
SPELL_SHADOW_BOLT_VOLLEY = 57942,
|
||||
SPELL_SHIVER = 57949,
|
||||
SPELL_CLONE_PLAYER = 57507, // cast on player during insanity
|
||||
SPELL_INSANITY_PHASING_1 = 57508,
|
||||
SPELL_INSANITY_PHASING_2 = 57509,
|
||||
SPELL_INSANITY_PHASING_3 = 57510,
|
||||
SPELL_INSANITY_PHASING_4 = 57511,
|
||||
SPELL_INSANITY_PHASING_5 = 57512,
|
||||
|
||||
SPELL_WHISPER_AGGRO = 60291,
|
||||
SPELL_WHISPER_INSANITY = 60292,
|
||||
SPELL_WHISPER_SLAY_1 = 60293,
|
||||
SPELL_WHISPER_SLAY_2 = 60294,
|
||||
SPELL_WHISPER_SLAY_3 = 60295,
|
||||
SPELL_WHISPER_DEATH_1 = 60296,
|
||||
SPELL_WHISPER_DEATH_2 = 60297
|
||||
SPELL_WHISPER_AGGRO = 60291,
|
||||
SPELL_WHISPER_INSANITY = 60292,
|
||||
SPELL_WHISPER_SLAY_1 = 60293,
|
||||
SPELL_WHISPER_SLAY_2 = 60294,
|
||||
SPELL_WHISPER_SLAY_3 = 60295,
|
||||
SPELL_WHISPER_DEATH_1 = 60296,
|
||||
SPELL_WHISPER_DEATH_2 = 60297,
|
||||
|
||||
SPELL_TWISTED_VISAGE_VISUAL = 57551,
|
||||
SPELL_TWISTED_VISAGE_DEATH = 57555,
|
||||
|
||||
// Death Knight
|
||||
SPELL_TWISTED_VISAGE_DEATH_GRIP = 57602,
|
||||
SPELL_TWISTED_VISAGE_PLAGUE_STRIKE = 57599,
|
||||
// Druid
|
||||
SPELL_TWISTED_VISAGE_WRATH = 57648,
|
||||
SPELL_TWISTED_VISAGE_MOONFIRE = 57647,
|
||||
SPELL_TWISTED_VISAGE_LIFEBLOOM = 57762,
|
||||
SPELL_TWISTED_VISAGE_CAT_FORM = 57655,
|
||||
SPELL_TWISTED_VISAGE_MANGLE = 57657,
|
||||
SPELL_TWISTED_VISAGE_RIP = 57661,
|
||||
SPELL_TWISTED_VISAGE_NOURISH = 57765,
|
||||
// Hunter
|
||||
SPELL_TWISTED_VISAGE_SHOOT = 57589,
|
||||
SPELL_TWISTED_VISAGE_DISENGAGE = 57635,
|
||||
// Mage
|
||||
SPELL_TWISTED_VISAGE_FIREBALL = 57628,
|
||||
SPELL_TWISTED_VISAGE_FROST_NOVA = 57629,
|
||||
// Paladin
|
||||
SPELL_TWISTED_VISAGE_CONSECRATION = 57798,
|
||||
SPELL_TWISTED_VISAGE_AVENGER__S_SHIELD = 57799,
|
||||
SPELL_TWISTED_VISAGE_SEAL_OF_COMMAND = 57769,
|
||||
SPELL_TWISTED_VISAGE_JUDGEMENT_OF_LIGHT = 57774,
|
||||
// Priest
|
||||
SPELL_TWISTED_VISAGE_GREATER_HEAL = 57775,
|
||||
SPELL_TWISTED_VISAGE_RENEW = 57777,
|
||||
SPELL_TWISTED_VISAGE_SHADOW_WORD_PAIN = 57778,
|
||||
SPELL_TWISTED_VISAGE_MIND_FLAY = 57779,
|
||||
// Rogue
|
||||
SPELL_TWISTED_VISAGE_EVISCERATE = 57641,
|
||||
SPELL_TWISTED_VISAGE_SINISTER_STRIKE = 57640,
|
||||
// Shaman
|
||||
SPELL_TWISTED_VISAGE_EARTH_SHOCK = 57783,
|
||||
SPELL_TWISTED_VISAGE_LIGHTNING_BOLT = 57781,
|
||||
SPELL_TWISTED_VISAGE_EARTH_SHIELD = 57802,
|
||||
SPELL_TWISTED_VISAGE_HEALING_WEAVE = 57785,
|
||||
SPELL_TWISTED_VISAGE_THUNDERSTORM = 57784,
|
||||
// Warlock
|
||||
SPELL_TWISTED_VISAGE_CORRUPTION = 57645,
|
||||
SPELL_TWISTED_VISAGE_SHADOW_BOLT = 57644,
|
||||
// Warrior
|
||||
SPELL_TWISTED_VISAGE_THUNDER_CLAP = 57832,
|
||||
SPELL_TWISTED_VISAGE_DEVASTATE = 57795,
|
||||
SPELL_TWISTED_VISAGE_MORTAL_STRIKE = 57789,
|
||||
SPELL_TWISTED_VISAGE_INTERCEPT = 61490,
|
||||
SPELL_TWISTED_VISAGE_HAMSTRING = 9080,
|
||||
SPELL_TWISTED_VISAGE_BLOODTHIRST = 57790,
|
||||
};
|
||||
|
||||
enum VolazjAchievements
|
||||
{
|
||||
ACHIEV_QUICK_DEMISE_START_EVENT = 20382,
|
||||
ACHIEV_QUICK_DEMISE_START_EVENT = 20382,
|
||||
};
|
||||
|
||||
enum VolazjMisc
|
||||
{
|
||||
DATA_TWISTED_VISAGE_PLAYER_CLASS = 1,
|
||||
DATA_TWISTED_VISAGE_PLAYER_SPEC = 2,
|
||||
};
|
||||
|
||||
struct boss_volazj : public BossAI
|
||||
{
|
||||
boss_volazj(Creature* creature) : BossAI(creature, DATA_HERALD_VOLAZJ), _insanityHandled(0)
|
||||
boss_volazj(Creature* creature) : BossAI(creature, DATA_HERALD_VOLAZJ)
|
||||
{
|
||||
Initialize();
|
||||
_instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
@@ -92,7 +144,7 @@ struct boss_volazj : public BossAI
|
||||
|
||||
Initialize();
|
||||
|
||||
_instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
|
||||
// Visible for all players in insanity
|
||||
me->SetPhaseMask((1|16|32|64|128|256), true);
|
||||
@@ -113,21 +165,21 @@ struct boss_volazj : public BossAI
|
||||
void ScheduleTasks() override
|
||||
{
|
||||
scheduler.Schedule(8s, [this](TaskContext task)
|
||||
{
|
||||
DoCastVictim(SPELL_MIND_FLAY);
|
||||
task.Repeat(20s);
|
||||
})
|
||||
.Schedule(5s, [this](TaskContext task)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_BOLT_VOLLEY);
|
||||
task.Repeat();
|
||||
})
|
||||
.Schedule(15s, [this](TaskContext task)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_SHIVER);
|
||||
task.Repeat();
|
||||
});
|
||||
{
|
||||
DoCastVictim(SPELL_MIND_FLAY);
|
||||
task.Repeat(20s);
|
||||
})
|
||||
.Schedule(5s, [this](TaskContext task)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOW_BOLT_VOLLEY);
|
||||
task.Repeat();
|
||||
})
|
||||
.Schedule(15s, [this](TaskContext task)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_SHIVER);
|
||||
task.Repeat();
|
||||
});
|
||||
}
|
||||
|
||||
// returns the percentage of health after taking the given damage.
|
||||
@@ -143,14 +195,19 @@ struct boss_volazj : public BossAI
|
||||
if (me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))
|
||||
damage = 0;
|
||||
|
||||
if ((GetHealthPct(0) >= 66 && GetHealthPct(damage) < 66)||
|
||||
(GetHealthPct(0) >= 33 && GetHealthPct(damage) < 33))
|
||||
if ((GetHealthPct(0) >= 66 && GetHealthPct(damage) < 66) || (GetHealthPct(0) >= 33 && GetHealthPct(damage) < 33))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_INSANITY, false);
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon) override
|
||||
{
|
||||
summon->SetReactState(REACT_PASSIVE);
|
||||
summons.Summon(summon);
|
||||
}
|
||||
|
||||
void SpellHitTarget(WorldObject* target, SpellInfo const* spellInfo) override
|
||||
{
|
||||
if (spellInfo->Id == SPELL_INSANITY)
|
||||
@@ -173,18 +230,22 @@ struct boss_volazj : public BossAI
|
||||
target->CastSpell(target, SPELL_INSANITY_TARGET + _insanityHandled, true);
|
||||
// summon twisted party members for this target
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
for (auto i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
Player* player = i->GetSource();
|
||||
if (!player || !player->IsAlive())
|
||||
continue;
|
||||
// Summon clone
|
||||
if (Unit* summon = me->SummonCreature(NPC_TWISTED_VISAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN))
|
||||
if (TempSummon* summon = me->SummonCreature(NPC_TWISTED_VISAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN))
|
||||
{
|
||||
// clone
|
||||
player->CastSpell(summon, SPELL_CLONE_PLAYER, true);
|
||||
summon->GetAI()->SetData(DATA_TWISTED_VISAGE_PLAYER_CLASS, player->GetClass());
|
||||
summon->GetAI()->SetData(DATA_TWISTED_VISAGE_PLAYER_SPEC, Trinity::Helpers::Entity::GetPlayerSpecialization(player));
|
||||
summon->SetReactState(REACT_AGGRESSIVE);
|
||||
DoZoneInCombat(summon);
|
||||
// set phase
|
||||
summon->SetPhaseMask((1<<(4 + _insanityHandled)), true);
|
||||
summon->SetPhaseMask((1 << (4 + _insanityHandled)), true);
|
||||
}
|
||||
}
|
||||
++_insanityHandled;
|
||||
@@ -194,7 +255,7 @@ struct boss_volazj : public BossAI
|
||||
void ResetPlayersPhaseMask()
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
for (auto i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
Player* player = i->GetSource();
|
||||
player->RemoveAurasDueToSpell(GetSpellForPhaseMask(player->GetPhaseMask()));
|
||||
@@ -207,7 +268,7 @@ struct boss_volazj : public BossAI
|
||||
Talk(SAY_AGGRO);
|
||||
DoCastSelf(SPELL_WHISPER_AGGRO);
|
||||
|
||||
_instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT);
|
||||
}
|
||||
|
||||
uint32 GetSpellForPhaseMask(uint32 phase)
|
||||
@@ -257,19 +318,16 @@ struct boss_volazj : public BossAI
|
||||
// Roll Insanity
|
||||
uint32 spell = GetSpellForPhaseMask(phase);
|
||||
uint32 spell2 = GetSpellForPhaseMask(nextPhase);
|
||||
Map::PlayerList const& PlayerList = me->GetMap()->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
Map::PlayerList const& playerList = me->GetMap()->GetPlayers();
|
||||
for (auto itr = playerList.begin(); itr != playerList.end(); ++itr)
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
if (Player* player = itr->GetSource())
|
||||
{
|
||||
if (Player* player = i->GetSource())
|
||||
if (player->HasAura(spell))
|
||||
{
|
||||
if (player->HasAura(spell))
|
||||
{
|
||||
player->RemoveAurasDueToSpell(spell);
|
||||
if (spell2) // if there is still some different mask cast spell for it
|
||||
player->CastSpell(player, spell2, true);
|
||||
}
|
||||
player->RemoveAurasDueToSpell(spell);
|
||||
if (spell2) // if there is still some different mask cast spell for it
|
||||
player->CastSpell(player, spell2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -277,7 +335,6 @@ struct boss_volazj : public BossAI
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
@@ -339,11 +396,381 @@ struct boss_volazj : public BossAI
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* _instance;
|
||||
|
||||
uint32 _insanityHandled;
|
||||
};
|
||||
|
||||
struct npc_twisted_visage : public ScriptedAI
|
||||
{
|
||||
npc_twisted_visage(Creature* creature) : ScriptedAI(creature), _playerClass(CLASS_NONE), _playerSpec(0) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_VISUAL, true);
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
switch (_playerClass)
|
||||
{
|
||||
case CLASS_SHAMAN:
|
||||
switch (_playerSpec)
|
||||
{
|
||||
case SPEC_SHAMAN_ELEMENTAL:
|
||||
case SPEC_SHAMAN_RESTORATION:
|
||||
ScriptedAI::AttackStartCaster(who, 25.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
switch (_playerSpec)
|
||||
{
|
||||
case SPEC_DRUID_BALANCE:
|
||||
case SPEC_DRUID_RESTORATION:
|
||||
ScriptedAI::AttackStartCaster(who, 25.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_PRIEST:
|
||||
case CLASS_HUNTER:
|
||||
case CLASS_MAGE:
|
||||
case CLASS_WARLOCK:
|
||||
ScriptedAI::AttackStartCaster(who, 25.0f);
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
ScriptedAI::AttackStart(who);
|
||||
break;
|
||||
default:
|
||||
ScriptedAI::AttackStart(who);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
if (type == DATA_TWISTED_VISAGE_PLAYER_CLASS)
|
||||
{
|
||||
if (data > CLASS_NONE && data <= CLASS_DRUID)
|
||||
_playerClass = data;
|
||||
}
|
||||
else if (type == DATA_TWISTED_VISAGE_PLAYER_SPEC && _playerClass != CLASS_NONE)
|
||||
{
|
||||
if (data < 3)
|
||||
_playerSpec = data;
|
||||
|
||||
switch (_playerClass)
|
||||
{
|
||||
case CLASS_WARRIOR:
|
||||
switch (data)
|
||||
{
|
||||
case SPEC_WARRIOR_ARMS:
|
||||
_scheduler.Schedule(3s, [this](TaskContext mortalStrike)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_MORTAL_STRIKE);
|
||||
mortalStrike.Repeat(3s, 5s);
|
||||
}).Schedule(5s, [this](TaskContext harmstring)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_HAMSTRING);
|
||||
harmstring.Repeat(5s, 10s);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
case SPEC_WARRIOR_FURY:
|
||||
_scheduler.Schedule(2s, [this](TaskContext intercept)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, -8.f))
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_INTERCEPT);
|
||||
intercept.Repeat(12s);
|
||||
}
|
||||
else
|
||||
intercept.Repeat(1s);
|
||||
}).Schedule(3s, [this](TaskContext bloodthirst)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_BLOODTHIRST);
|
||||
bloodthirst.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case SPEC_WARRIOR_PROTECTION:
|
||||
_scheduler.Schedule(5s, [this](TaskContext thunderClap)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_THUNDER_CLAP);
|
||||
thunderClap.Repeat(5s, 10s);
|
||||
}).Schedule(3s, [this](TaskContext devastate)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_DEVASTATE);
|
||||
devastate.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_PALADIN:
|
||||
switch (data)
|
||||
{
|
||||
case SPEC_PALADIN_PROTECTION:
|
||||
_scheduler.Schedule(5s, [this](TaskContext consecration)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_CONSECRATION);
|
||||
consecration.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext avengersShield)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_AVENGER__S_SHIELD);
|
||||
avengersShield.Repeat(5s, 10s);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
case SPEC_PALADIN_RETRIBUTION:
|
||||
_scheduler.Schedule(5s, [this](TaskContext consecration)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_CONSECRATION);
|
||||
consecration.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext /*sealCommand*/)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_SEAL_OF_COMMAND);
|
||||
}).Schedule(3s, [this](TaskContext judgementLight)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_JUDGEMENT_OF_LIGHT);
|
||||
judgementLight.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_HUNTER:
|
||||
_scheduler.Schedule(2s, [this](TaskContext shoot)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_SHOOT);
|
||||
shoot.Repeat(1s, 4s);
|
||||
}).Schedule(5s, [this](TaskContext disengage)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, 4.f))
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_DISENGAGE);
|
||||
disengage.Repeat(10s, 20s);
|
||||
}
|
||||
else
|
||||
disengage.Repeat(1s);
|
||||
});
|
||||
break;
|
||||
case CLASS_ROGUE:
|
||||
me->SetCanDualWield(true);
|
||||
_scheduler.Schedule(5s, [this](TaskContext eviscerate)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_EVISCERATE);
|
||||
eviscerate.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext sinisterStrike)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_SINISTER_STRIKE);
|
||||
sinisterStrike.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case CLASS_PRIEST:
|
||||
switch (data)
|
||||
{
|
||||
case SPEC_PRIEST_SHADOW:
|
||||
_scheduler.Schedule(5s, [this](TaskContext shadowWordPain)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_SHADOW_WORD_PAIN);
|
||||
shadowWordPain.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext mindFlay)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_MIND_FLAY);
|
||||
mindFlay.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
_scheduler.Schedule(2s, [this](TaskContext renew)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_RENEW);
|
||||
renew.Repeat(2s, 5s);
|
||||
}
|
||||
else
|
||||
renew.Repeat(1s);
|
||||
}).Schedule(4s, [this](TaskContext greaterHeal)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_GREATER_HEAL);
|
||||
greaterHeal.Repeat(4s, 6s);
|
||||
}
|
||||
else
|
||||
greaterHeal.Repeat(1s);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_DEATH_KNIGHT:
|
||||
_scheduler.Schedule(5s, [this](TaskContext deathGrip)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, -3.f))
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_DEATH_GRIP);
|
||||
deathGrip.Repeat(12s);
|
||||
}
|
||||
else
|
||||
deathGrip.Repeat(1s);
|
||||
}).Schedule(2s, [this](TaskContext plagueStrike)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_PLAGUE_STRIKE);
|
||||
plagueStrike.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case CLASS_SHAMAN:
|
||||
switch (data)
|
||||
{
|
||||
default:
|
||||
case SPEC_SHAMAN_ELEMENTAL:
|
||||
_scheduler.Schedule(5s, [this](TaskContext thunderstorm)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_THUNDERSTORM);
|
||||
thunderstorm.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext lightningBolt)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_LIGHTNING_BOLT);
|
||||
lightningBolt.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case SPEC_SHAMAN_ENHANCEMENT:
|
||||
_scheduler.Schedule(2s, [this](TaskContext earthShock)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_EARTH_SHOCK);
|
||||
earthShock.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case SPEC_SHAMAN_RESTORATION:
|
||||
_scheduler.Schedule(2s, [this](TaskContext earthShield)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_EARTH_SHIELD);
|
||||
earthShield.Repeat(4s, 6s);
|
||||
}
|
||||
else
|
||||
earthShield.Repeat(1s);
|
||||
}).Schedule(4s, [this](TaskContext healingWave)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_HEALING_WEAVE);
|
||||
healingWave.Repeat(4s, 6s);
|
||||
}
|
||||
else
|
||||
healingWave.Repeat(1s);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
_scheduler.Schedule(5s, [this](TaskContext frostNova)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_FROST_NOVA);
|
||||
frostNova.Repeat(5s, 10s);
|
||||
}).Schedule(2s, [this](TaskContext fireball)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_FIREBALL);
|
||||
fireball.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case CLASS_WARLOCK:
|
||||
_scheduler.Schedule(2s, [this](TaskContext corruption)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_CORRUPTION);
|
||||
corruption.Repeat(6s, 10s);
|
||||
}).Schedule(3s, [this](TaskContext shadowBolt)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_SHADOW_BOLT);
|
||||
shadowBolt.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
switch (data)
|
||||
{
|
||||
case SPEC_DRUID_BALANCE:
|
||||
_scheduler.Schedule(2s, [this](TaskContext moonfire)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_MOONFIRE);
|
||||
moonfire.Repeat(3s, 5s);
|
||||
}).Schedule(3s, [this](TaskContext wrath)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_WRATH);
|
||||
wrath.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
case SPEC_DRUID_FERAL:
|
||||
_scheduler.Schedule(1ms, [this](TaskContext /*catForm*/)
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_CAT_FORM);
|
||||
}).Schedule(2s, [this](TaskContext mangle)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_MANGLE);
|
||||
mangle.Repeat(3s, 5s);
|
||||
}).Schedule(3s, [this](TaskContext rip)
|
||||
{
|
||||
DoCastVictim(SPELL_TWISTED_VISAGE_RIP);
|
||||
rip.Repeat(3s, 5s);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
case SPEC_DRUID_RESTORATION:
|
||||
_scheduler.Schedule(2s, [this](TaskContext lifebloom)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_LIFEBLOOM);
|
||||
lifebloom.Repeat(4s, 6s);
|
||||
}
|
||||
else
|
||||
lifebloom.Repeat(1s);
|
||||
}).Schedule(4s, [this](TaskContext nourish)
|
||||
{
|
||||
if (Unit* target = DoSelectLowestHpFriendly(40.f))
|
||||
{
|
||||
DoCast(target, SPELL_TWISTED_VISAGE_NOURISH);
|
||||
nourish.Repeat(4s, 6s);
|
||||
}
|
||||
else
|
||||
nourish.Repeat(1s);
|
||||
});
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
DoCastSelf(SPELL_TWISTED_VISAGE_DEATH, true);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff, [this]
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
uint32 _playerClass;
|
||||
uint32 _playerSpec;
|
||||
};
|
||||
|
||||
/* 60291 - Volazj Whisper: Aggro
|
||||
60292 - Volazj Whisper: Insanity
|
||||
60293 - Volazj Whisper: Slay 01
|
||||
@@ -400,5 +827,6 @@ class spell_volazj_whisper : public SpellScript
|
||||
void AddSC_boss_volazj()
|
||||
{
|
||||
RegisterAhnKahetCreatureAI(boss_volazj);
|
||||
RegisterAhnKahetCreatureAI(npc_twisted_visage);
|
||||
RegisterSpellScript(spell_volazj_whisper);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user