Implement Insanity phase for Herald Volazj encounter (still missing AI for adds)

--HG--
branch : trunk
This commit is contained in:
thenecromancer
2010-01-28 14:42:05 +01:00
parent b31c11bf03
commit 984a47b541
@@ -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)