Implement Insanity phase for Herald Volazj encounter (still missing AI for adds)
--HG-- branch : trunk
This commit is contained in:
@@ -18,9 +18,9 @@
|
||||
|
||||
/* ScriptData
|
||||
SDName: boss_herald_volazj
|
||||
SDAuthor: Tartalo
|
||||
SD%Complete: 20
|
||||
SDComment: Coded all but Insanity
|
||||
SDAuthor: thenecromancer
|
||||
SD%Complete: ??
|
||||
SDComment: Missing AI for Twisted Visages
|
||||
SDCategory: Ahn'kahet
|
||||
EndScriptData */
|
||||
|
||||
@@ -31,6 +31,7 @@ enum Spells
|
||||
{
|
||||
SPELL_INSANITY = 57496, //Dummy
|
||||
INSANITY_VISUAL = 57561,
|
||||
SPELL_INSANITY_TARGET = 57508,
|
||||
SPELL_MIND_FLAY = 57941,
|
||||
H_SPELL_MIND_FLAY = 59974,
|
||||
SPELL_SHADOW_BOLT_VOLLEY = 57942,
|
||||
@@ -39,6 +40,8 @@ enum Spells
|
||||
H_SPELL_SHIVER = 59978
|
||||
};
|
||||
|
||||
#define MOB_TWISTED_VISAGE 30625
|
||||
|
||||
//not in db
|
||||
enum Yells
|
||||
{
|
||||
@@ -58,7 +61,7 @@ enum Achievements
|
||||
|
||||
struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
|
||||
{
|
||||
boss_volazjAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
boss_volazjAI(Creature* pCreature) : ScriptedAI(pCreature),Summons(m_creature)
|
||||
{
|
||||
pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
@@ -69,6 +72,69 @@ struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
|
||||
uint32 uiShadowBoltVolleyTimer;
|
||||
uint32 uiShiverTimer;
|
||||
uint32 uiEncounterTimer;
|
||||
uint32 insanityHandled;
|
||||
SummonList Summons;
|
||||
|
||||
uint32 GetHealthPct(uint32 damage)
|
||||
{
|
||||
if (damage > me->GetHealth())
|
||||
return 0;
|
||||
return 100*(me->GetHealth()-damage)/me->GetMaxHealth();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit *pAttacker, uint32 &damage)
|
||||
{
|
||||
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))
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_INSANITY, false);
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
|
||||
{
|
||||
if (spell->Id == SPELL_INSANITY)
|
||||
{
|
||||
// Not good target or too many players
|
||||
if (pTarget->GetTypeId() != TYPEID_PLAYER || insanityHandled > 4)
|
||||
return;
|
||||
// First target - start channel visual and set self as unnattackable
|
||||
if (!insanityHandled)
|
||||
{
|
||||
// Channel visual
|
||||
DoCast(me, INSANITY_VISUAL, true);
|
||||
// Unattackable
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(true, UNIT_STAT_STUNNED);
|
||||
}
|
||||
// phase mask
|
||||
pTarget->CastSpell(pTarget, SPELL_INSANITY_TARGET+insanityHandled, true);
|
||||
// summon twisted party members for this target
|
||||
Map::PlayerList const &players = m_creature->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
|
||||
{
|
||||
Player *plr = i->getSource();
|
||||
if (!plr || !plr->isAlive())
|
||||
continue;
|
||||
// Summon clone
|
||||
if (Unit *summon = me->SummonCreature(MOB_TWISTED_VISAGE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(),TEMPSUMMON_CORPSE_DESPAWN,0))
|
||||
{
|
||||
// required for correct visual
|
||||
// Fixme: allow mirror image query to send other guid to get rid of minion status
|
||||
summon->SetUInt64Value(UNIT_FIELD_CREATEDBY, plr->GetGUID());
|
||||
// clone
|
||||
plr->CastSpell(summon, 57507, true);
|
||||
// set phase
|
||||
summon->SetPhaseMask((1<<(4+insanityHandled)),true);
|
||||
}
|
||||
}
|
||||
++insanityHandled;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
@@ -79,6 +145,15 @@ struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_HERALD_VOLAZJ, NOT_STARTED);
|
||||
|
||||
// Visible for all players in insanity
|
||||
me->SetPhaseMask((1|16|32|64|128|256),true);
|
||||
// Used for Insanity handling
|
||||
insanityHandled = 0;
|
||||
|
||||
// Cleanup
|
||||
Summons.DespawnAll();
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
@@ -89,12 +164,96 @@ struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
|
||||
pInstance->SetData(DATA_HERALD_VOLAZJ, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
Summons.Summon(summon);
|
||||
}
|
||||
|
||||
uint32 GetSpellForPhaseMask(uint32 phase)
|
||||
{
|
||||
uint32 spell = 0;
|
||||
switch (phase)
|
||||
{
|
||||
case 16:
|
||||
spell = 57508;
|
||||
break;
|
||||
case 32:
|
||||
spell = 57509;
|
||||
break;
|
||||
case 64:
|
||||
spell = 57510;
|
||||
break;
|
||||
case 128:
|
||||
spell = 57511;
|
||||
break;
|
||||
case 256:
|
||||
spell = 57512;
|
||||
break;
|
||||
}
|
||||
return spell;
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature *summon)
|
||||
{
|
||||
uint32 phase= summon->GetPhaseMask();
|
||||
uint32 nextPhase = 0;
|
||||
Summons.Despawn(summon);
|
||||
|
||||
// Check if all summons in this phase killed
|
||||
for(SummonList::const_iterator iter = Summons.begin(); iter!=Summons.end(); iter++)
|
||||
{
|
||||
if(Creature *visage = Unit::GetCreature(*m_creature, *iter))
|
||||
{
|
||||
// Not all are dead
|
||||
if (phase == visage->GetPhaseMask())
|
||||
return;
|
||||
else
|
||||
nextPhase = visage->GetPhaseMask();
|
||||
}
|
||||
}
|
||||
|
||||
// Roll Insanity
|
||||
uint32 spell = GetSpellForPhaseMask(phase);
|
||||
uint32 spell2 = GetSpellForPhaseMask(nextPhase);
|
||||
Map* pMap = m_creature->GetMap();
|
||||
if (!pMap)
|
||||
return;
|
||||
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
{
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (Player* pPlayer = i->getSource())
|
||||
{
|
||||
if (pPlayer->HasAura(spell))
|
||||
{
|
||||
pPlayer->RemoveAurasDueToSpell(spell);
|
||||
if (spell2) // if there is still some different mask cast spell for it
|
||||
pPlayer->CastSpell(pPlayer, spell2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (insanityHandled)
|
||||
{
|
||||
if (!Summons.empty())
|
||||
return;
|
||||
|
||||
insanityHandled = 0;
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetControlled(false, UNIT_STAT_STUNNED);
|
||||
me->RemoveAurasDueToSpell(INSANITY_VISUAL);
|
||||
}
|
||||
|
||||
if (uiMindFlayTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_MIND_FLAY, H_SPELL_MIND_FLAY));
|
||||
@@ -134,6 +293,7 @@ struct TRINITY_DLL_DECL boss_volazjAI : public ScriptedAI
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
itr->getSource()->CompletedAchievement(AchievQuickDemise);
|
||||
}
|
||||
Summons.DespawnAll();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
|
||||
Reference in New Issue
Block a user