rendered paste bodyIndex: scripts/zone/black_temple/boss_reliquary_of_souls.cpp===================================================================--- scripts/zone/black_temple/boss_reliquary_of_souls.cpp (revision 323)+++ scripts/zone/black_temple/boss_reliquary_of_souls.cpp (working copy)@@ -89,13 +89,33 @@ #define SPELL_SELF_SEETHE 41364 #define SPELL_ENEMY_SEETHE 41520 #define SPELL_SOUL_SCREAM 41545-#define SPELL_SPITE 41377+#define SPELL_SPITE 41376+#define SPELL_SPITE_DAMAGE 41377 #define ENSLAVED_SOUL_PASSIVE 41535 #define SPELL_SOUL_RELEASE 41542 #define SPELL_RESTORE_MANA 32848 #define SPELL_RESTORE_HEALTH 25329 +#define CREATURE_ENSLAVED_SOUL 23469+#define CREATURE_ESSENCE_OF_SUFFERING 23418+#define CREATURE_ESSENCE_OF_DESIRE 23419+#define CREATURE_ESSENCE_OF_ANGER 23420++#define EMOTE_RIBS_BRACE 375+#define EMOTE_RIBS_OPEN 373+#define EMOTE_RIBS_RELEASE 374+#define EMOTE_ESSENCE_SPIN 374++enum Phase+{+ PHASE_IDLE = 0,+ PHASE_SOULS = 1,+ PHASE_SUFFERING = 2,+ PHASE_DESIRE = 3,+ PHASE_ANGER = 4,+};+ struct Position { float x,y;@@ -133,13 +153,20 @@ if(done_by->GetTypeId() == TYPEID_PLAYER) { done_by->CastSpell(done_by, SPELL_RESTORE_HEALTH, true);- if(done_by->GetMaxPower(POWER_MANA) > 0)+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();++ if(m_threatlist.empty())+ return;++ std::list<HostilReference*>::iterator itr = m_threatlist.begin();+ for( ; itr != m_threatlist.end(); ++itr) {- if((done_by->GetPower(POWER_MANA) / done_by->GetMaxPower(POWER_MANA)) < 70)+ Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());+ if(pUnit && pUnit->isAlive() && (pUnit->GetMaxPower(POWER_MANA) > 0)) {- uint32 mana = done_by->GetPower(POWER_MANA) + (uint32)(done_by->GetMaxPower(POWER_MANA)*0.3);- done_by->SetPower(POWER_MANA, mana);- }else done_by->SetPower(POWER_MANA, done_by->GetMaxPower(POWER_MANA));+ uint32 mana = pUnit->GetPower(POWER_MANA) + ((uint32)(pUnit->GetMaxPower(POWER_MANA)*0.3));+ pUnit->SetPower(POWER_MANA, mana);+ } } } DoCast(done_by, SPELL_SOUL_RELEASE);@@ -151,7 +178,7 @@ struct MANGOS_DLL_DECL boss_reliquary_of_soulsAI : public ScriptedAI {- boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c) + boss_reliquary_of_soulsAI(Creature *c) : ScriptedAI(c) { pInstance = ((ScriptedInstance*)c->GetInstanceData()); Reset();@@ -159,47 +186,56 @@ ScriptedInstance* pInstance; - uint64 SufferingGUID;- uint64 DesireGUID;- uint64 AngerGUID;+ uint64 EssenceGUID; + uint32 SoulCount; uint32 SoulDeathCount;- uint32 Phase; // 0 = Out of Combat, 1 = Not started, 2 = Suffering, 3 = Souls, 4 = Desire, 5 = Souls, 6 = Anger+ uint32 Phase;+ uint32 NextPhase;++ uint32 AnimationTimer; uint32 SummonEssenceTimer; uint32 DespawnEssenceTimer;- uint32 SoulCount; uint32 SummonSoulTimer;- uint32 AnimationTimer;+ uint32 RaidCombatTimer; bool InCombat;- bool IsDead;- bool EndingPhase;+ bool HasSummonedEssence;+ bool DespawnEssence; + char* Yell[2];+ uint32 Sound[2];+ void Reset() {- if(pInstance)- pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, 0);+ EssenceGUID = 0; - SufferingGUID = 0;- DesireGUID = 0;- AngerGUID = 0;-+ SoulCount = 0; SoulDeathCount = 0;- Phase = 0;+ Phase = PHASE_IDLE;+ NextPhase = 0;+ SummonEssenceTimer = 8000; DespawnEssenceTimer = 2000;- SoulCount = 0; SummonSoulTimer = 1000; AnimationTimer = 8000;+ RaidCombatTimer = 5000; - IsDead = false;- EndingPhase = false; InCombat = false;+ HasSummonedEssence = false;+ DespawnEssence = false; + Yell[0] = NULL;+ Yell[1] = NULL;+ Sound[0] = NULL;+ Sound[1] = NULL;++ if(pInstance)+ pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, 0); // Not begun+ m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);- m_creature->GetMotionMaster()->Clear(false);+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); } void Aggro(Unit *who)@@ -208,26 +244,32 @@ void MoveInLineOfSight(Unit *who) {- if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))+ if(!who || who == m_creature || m_creature->getVictim())+ return;++ if(who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who)) { float attackRadius = m_creature->GetAttackDistance(who);- if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))+ if(m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who)) { if(who->HasStealthAura())- who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);+ who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH); - if(who && who->isAlive())- m_creature->AddThreat(who, 1.0f);+ DoZoneInCombat(); if(!InCombat) { if(pInstance)- pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, 1);+ pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, 1); // In Progress - Phase = 1;- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,375); // I R ANNNGRRRY!+ Phase = PHASE_SUFFERING;+ SummonEssenceTimer = 8000; AnimationTimer = 5100;++ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_RIBS_BRACE);++ HasSummonedEssence = false; InCombat = true; } }@@ -239,141 +281,109 @@ uint32 random = rand()%6; float x = Coords[random].x; float y = Coords[random].y;- Creature* Soul = m_creature->SummonCreature(23469, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);- Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);- if (target && Soul)+ if(!x || !y)+ return;++ Creature* Soul = m_creature->SummonCreature(CREATURE_ENSLAVED_SOUL, x, y, m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);+ if(Soul) { ((npc_enslaved_soulAI*)Soul->AI())->ReliquaryGUID = m_creature->GetGUID(); Soul->CastSpell(Soul, ENSLAVED_SOUL_PASSIVE, true);- Soul->AddThreat(target, 1.0f);+ DoZoneInCombat(Soul); SoulCount++; } } - void MergeThreatList(Creature* target)+ void MergeThreatList(Creature* Essence) {- if(!target) return;+ std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list<HostilReference*>& m_threatlist = target->getThreatManager().getThreatList();+ if(m_threatlist.empty())+ return;+ std::list<HostilReference*>::iterator itr = m_threatlist.begin();- for( ; itr != m_threatlist.end(); itr++)+ for( ; itr != m_threatlist.end(); ++itr) { Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid());- if(pUnit)+ if(pUnit && pUnit->isAlive()) {- m_creature->AddThreat(pUnit, 1.0f); // This is so that we make sure the unit is in Reliquary's threat list before we reset the unit's threat.- m_creature->getThreatManager().modifyThreatPercent(pUnit, -100);- float threat = target->getThreatManager().getThreat(pUnit);- m_creature->AddThreat(pUnit, threat); // This makes it so that the unit has the same amount of threat in Reliquary's threatlist as in the target creature's (One of the Essences).+ m_creature->AddThreat(pUnit, 1.0f); // In case pUnit is not in Reliquary's threatlist already+ m_creature->getThreatManager().modifyThreatPercent(pUnit, -100); // Reset threat for that victim before adding the threat from the Essence+ float threat = Essence->getThreatManager().getThreat(pUnit, true);+ m_creature->AddThreat(pUnit, threat); } } } - void JustDied(Unit* killer)+ void SummonEssence() {- InCombat = false;- }-- void UpdateAI(const uint32 diff)- {- if(!Phase)- return;-- if(Phase && m_creature->getThreatManager().getThreatList().empty()) // Reset if event is begun and we don't have a threatlist- EnterEvadeMode();-- if(Phase == 1)+ uint32 CreatureEntry = 0;+ char* YellFreed = NULL;+ uint32 SoundFreed = 0;+ + switch(Phase) {- if(AnimationTimer < diff)- {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); // Release teh cube- AnimationTimer = 8300;- }else AnimationTimer -= diff;+ case PHASE_SUFFERING:+ CreatureEntry = CREATURE_ESSENCE_OF_SUFFERING;+ YellFreed = SUFF_SAY_FREED;+ SoundFreed = SUFF_SOUND_FREED;+ Yell[0] = SUFF_SAY_RECAP;+ Sound[0] = SUFF_SOUND_RECAP;+ Yell[1] = SUFF_SAY_AFTER;+ Sound[1] = SUFF_SOUND_AFTER;+ break; - if(SummonEssenceTimer < diff)- {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); // Ribs: open- Creature* EssenceSuffering = NULL;- EssenceSuffering = m_creature->SummonCreature(23418, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);+ case PHASE_DESIRE:+ CreatureEntry = CREATURE_ESSENCE_OF_DESIRE;+ YellFreed = DESI_SAY_FREED;+ SoundFreed = DESI_SOUND_FREED;+ Yell[0] = DESI_SAY_RECAP;+ Sound[0] = DESI_SOUND_RECAP;+ Yell[1] = SUFF_SAY_AFTER;+ Sound[0] = SUFF_SOUND_AFTER;+ break; - if(EssenceSuffering)- {- EssenceSuffering->Yell(SUFF_SAY_FREED, LANG_UNIVERSAL, 0);- DoPlaySoundToSet(m_creature, SUFF_SOUND_FREED);- Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);- if(target)- {- EssenceSuffering->AddThreat(target, 1.0f);- EssenceSuffering->AI()->AttackStart(target);- }- SufferingGUID = EssenceSuffering->GetGUID();- }-- EndingPhase = false;- Phase = 2;- }else SummonEssenceTimer -= diff;+ case PHASE_ANGER:+ CreatureEntry = CREATURE_ESSENCE_OF_ANGER;+ YellFreed = ANGER_SAY_FREED;+ SoundFreed = ANGER_SOUND_FREED;+ Yell[0] = SUFF_SAY_AFTER;+ Sound[0] = SUFF_SOUND_AFTER;+ Yell[1] = SUFF_SAY_AFTER;+ Sound[1] = SUFF_SOUND_AFTER;+ break; } - if(Phase == 2)+ if(!CreatureEntry)+ return;++ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_RIBS_RELEASE);+ Creature* Essence = DoSpawnCreature(CreatureEntry, 0, 0, 0, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 45000);+ if(Essence) {- if(SufferingGUID)- {- Creature* EssenceSuffering = NULL;- EssenceSuffering = ((Creature*)Unit::GetUnit((*m_creature), SufferingGUID));+ if(YellFreed)+ Essence->MonsterYell(YellFreed, LANG_UNIVERSAL, 0);+ if(SoundFreed)+ DoPlaySoundToSet(Essence, SoundFreed);+ + Essence->AI()->AttackStart(Essence->getVictim()); - if(!EssenceSuffering || (!EssenceSuffering->isAlive()))- EnterEvadeMode();+ EssenceGUID = Essence->GetGUID(); - if(!EndingPhase)- {- if(EssenceSuffering)- {- if(EssenceSuffering->GetHealth() < (EssenceSuffering->GetMaxHealth()*0.1))- {- MergeThreatList(EssenceSuffering);- EssenceSuffering->RemoveAllAuras();- EssenceSuffering->DeleteThreatList();- EssenceSuffering->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));- EssenceSuffering->Yell(SUFF_SAY_RECAP,LANG_UNIVERSAL,0);- DoPlaySoundToSet(m_creature, SUFF_SOUND_RECAP);- EssenceSuffering->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- DespawnEssenceTimer = 4000;- AnimationTimer = 2200;- EndingPhase = true;- }- }- }+ HasSummonedEssence = true;+ DespawnEssence = false;+ }+ } - if((EndingPhase) && (EssenceSuffering) && (EssenceSuffering->isAlive()))- {- if(AnimationTimer < diff)- {- EssenceSuffering->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); // Return- AnimationTimer = 10000;- }else AnimationTimer -= diff;+ void UpdateAI(const uint32 diff)+ {+ if(!Phase)+ return; - if(DespawnEssenceTimer < diff)- {- EssenceSuffering->DeleteThreatList();- EssenceSuffering->Yell(SUFF_SAY_AFTER,LANG_UNIVERSAL,0);- DoPlaySoundToSet(m_creature, SUFF_SOUND_AFTER);- EssenceSuffering->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);- EssenceSuffering->setFaction(35);- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);- SummonEssenceTimer = 20000; //60000;- AnimationTimer = 18200; //58100;- SoulDeathCount = 0;- SoulCount = 0;- SummonSoulTimer = 1000;- EndingPhase = false;- Phase = 3;- SufferingGUID = 0;- }else DespawnEssenceTimer -= diff;- }- }- }+ if(Phase && m_creature->getThreatManager().getThreatList().empty()) // Reset if event is begun and we don't have a threatlist+ Reset(); - if(Phase == 3)+ if(Phase == PHASE_SOULS) { if(SoulCount < 36) {@@ -383,167 +393,112 @@ SummonSoulTimer = 500; }else SummonSoulTimer -= diff; }-+ if(SoulDeathCount >= SoulCount)- {- if(AnimationTimer < diff)- {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); // Release teh cube- AnimationTimer = 10000;- }else AnimationTimer -= diff;+ Phase = NextPhase; - if(SummonEssenceTimer < diff)- {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); // Ribs: open- Creature* EssenceDesire = NULL;- EssenceDesire = m_creature->SummonCreature(23419, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);-- if(EssenceDesire)- {- DoYell(DESI_SAY_FREED, LANG_UNIVERSAL, NULL);- DoPlaySoundToSet(m_creature, DESI_SOUND_FREED); - Unit* target = NULL;- target = SelectUnit(SELECT_TARGET_RANDOM, 0);- if(target)- {- EssenceDesire->AddThreat(target, 1.0f);- EssenceDesire->AI()->AttackStart(target);- }- DesireGUID = EssenceDesire->GetGUID();- SoulDeathCount = 0;- }-- Phase = 4;- }else SummonEssenceTimer -= diff;- }+ return; } - if(Phase == 4)+ if(RaidCombatTimer < diff) {- if(DesireGUID)+ DoZoneInCombat();+ RaidCombatTimer = 5000;+ }else RaidCombatTimer -= diff;++ if(!HasSummonedEssence)+ {+ if(AnimationTimer < diff) {- Creature* EssenceDesire = NULL;- EssenceDesire = ((Creature*)Unit::GetUnit((*m_creature), DesireGUID));+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_RIBS_OPEN);+ AnimationTimer = 8300;+ }else AnimationTimer -= diff; - if(!EssenceDesire || !EssenceDesire->isAlive())- EnterEvadeMode();-- if(!EndingPhase && EssenceDesire)+ if(SummonEssenceTimer < diff)+ SummonEssence();+ else SummonEssenceTimer -= diff;+ }+ else+ {+ if(!EssenceGUID)+ return;+ + Creature* Essence = ((Creature*)Unit::GetUnit((*m_creature), EssenceGUID));+ + if(Phase == PHASE_ANGER)+ {+ if(!Essence || Essence->isAlive()) {- if(EssenceDesire->GetHealth() < (EssenceDesire->GetMaxHealth()*0.1))- {- MergeThreatList(EssenceDesire);- EssenceDesire->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));- EssenceDesire->RemoveAllAuras();- EssenceDesire->DeleteThreatList();- EssenceDesire->Yell(DESI_SAY_RECAP,LANG_UNIVERSAL,0);- DoPlaySoundToSet(m_creature, DESI_SOUND_RECAP);- EssenceDesire->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);- DespawnEssenceTimer = 4000;- AnimationTimer = 2200;- EndingPhase = true;- }- } + if(pInstance)+ pInstance->SetData(DATA_RELIQUARYOFSOULSEVENT, 3); // Complete - if(EndingPhase && EssenceDesire)- {- if(EssenceDesire->isAlive())- {- if(AnimationTimer < diff)- {- EssenceDesire->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); // Return- AnimationTimer = 10000;- }else AnimationTimer -= diff;-- if(DespawnEssenceTimer < diff)- {- EssenceDesire->DeleteThreatList();- EssenceDesire->setFaction(35);- EssenceDesire->Yell(DESI_SAY_AFTER, LANG_UNIVERSAL, 0);- DoPlaySoundToSet(m_creature, DESI_SOUND_AFTER);- EssenceDesire->SetUInt32Value(UNIT_FIELD_DISPLAYID, 11686);- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,0);- SummonEssenceTimer = 20000;- AnimationTimer = 18200;- SoulDeathCount = 0;- SoulCount = 0;- SummonSoulTimer = 1000;- EndingPhase = false;- Phase = 5;- DesireGUID = 0;- }else DespawnEssenceTimer -= diff;- }+ m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false); } }- }-- if(Phase == 5)- {- if(SoulCount < 36)+ else {- if(SummonSoulTimer < diff)- {- SummonSoul();- SummonSoulTimer = 500;- }else SummonSoulTimer -= diff;+ if(!Essence || !Essence->isAlive())+ Reset(); } - if(SoulDeathCount >= SoulCount)- { - if(AnimationTimer < diff)+ if(!DespawnEssence)+ {+ if(Essence->GetHealth() < (Essence->GetMaxHealth() * 0.1)) {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,374); // Release teh cube- AnimationTimer = 10000;- }else AnimationTimer -= diff;+ MergeThreatList(Essence);+ Essence->RemoveAllAuras();+ Essence->DeleteThreatList();+ Essence->GetMotionMaster()->Mutate(new TargetedMovementGenerator<Creature>(*m_creature));+ + if(Yell[0])+ Essence->MonsterYell(Yell[0], LANG_UNIVERSAL, 0);+ if(Sound[0])+ DoPlaySoundToSet(Essence, Sound[0]); - if(SummonEssenceTimer < diff)+ Essence->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);+ Essence->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE);+ DespawnEssenceTimer = 4000;+ AnimationTimer = 2200;+ DespawnEssence = true;+ }+ else {- m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE,373); // Ribs: open- Creature* EssenceAnger = NULL;- EssenceAnger = m_creature->SummonCreature(23420, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 1.57, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 45000);+ if(AnimationTimer < diff)+ {+ Essence->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ESSENCE_SPIN);+ AnimationTimer = 10000;+ }else AnimationTimer -= diff; - if(EssenceAnger)+ if(DespawnEssenceTimer < diff) {- Unit* target = SelectUnit(SELECT_TARGET_TOPAGGRO, 0);- if(target)- {- EssenceAnger->AddThreat(target, 1.0f);- EssenceAnger->AI()->AttackStart(target);- }- AngerGUID = EssenceAnger->GetGUID();- DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED);- EssenceAnger->Yell(ANGER_SAY_FREED, LANG_UNIVERSAL, 0);- SoulDeathCount = 0;- }+ if(Yell[1])+ Essence->MonsterYell(Yell[1], LANG_UNIVERSAL, 0);+ if(Sound[1])+ DoPlaySoundToSet(Essence, Sound[1]); - Phase = 6;- }else SummonEssenceTimer -= diff;- }- }+ Essence->setDeathState(JUST_DIED);+ EssenceGUID = 0; - if(Phase == 6)- {- if(AngerGUID)- {- Creature* EssenceAnger = NULL;- EssenceAnger = ((Creature*)Unit::GetUnit((*m_creature), AngerGUID));+ m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - if(!EssenceAnger)- EnterEvadeMode();+ SummonEssenceTimer = 20000;+ AnimationTimer = 18200;+ SummonSoulTimer = 1000; - if(m_creature->isAlive() && EssenceAnger)- {- if(!EssenceAnger->isAlive())- {- AngerGUID = 0;- m_creature->DealDamage(m_creature, m_creature->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_NORMAL, NULL, false);- }+ SoulDeathCount = 0;+ SoulCount = 0;++ DespawnEssence = false;+ HasSummonedEssence = false;++ NextPhase = Phase++;+ Phase = PHASE_SOULS;+ }else DespawnEssenceTimer -= diff; } } } } };- //This is used to sort the players by distance in preparation for the Fixate cast. struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool> {@@ -590,15 +545,13 @@ { Unit* pUnit = Unit::GetUnit((*m_creature), StatAuraGUID); if(pUnit)- pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR);+ pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR); } } } void Aggro(Unit *who) {-- Reset(); DoCast(who, AURA_OF_SUFFERING, true); DoCast(m_creature, ESSENCE_OF_SUFFERING_PASSIVE, true); InCombat = true;@@ -608,41 +561,38 @@ { switch(rand()%3) {- case 0:- DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1);- break;- case 1:- DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2);- break;- case 2:- DoYell(SUFF_SAY_SLAY3,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY3);- break;+ case 0:+ DoYell(SUFF_SAY_SLAY1,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY1);+ break;+ case 1:+ DoYell(SUFF_SAY_SLAY2,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY2);+ break;+ case 2:+ DoYell(SUFF_SAY_SLAY3,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, SUFF_SOUND_SLAY3);+ break; } } - void JustDied(Unit* killer)- {- InCombat = false;- }- void CastFixate() { std::list<HostilReference*>& m_threatlist = m_creature->getThreatManager().getThreatList(); if(m_threatlist.empty())- return; // No point continuing if empty threatlist.+ return; // No point continuing if empty threatlist.+ std::list<Unit*> targets; std::list<HostilReference*>::iterator itr = m_threatlist.begin(); for( ; itr != m_threatlist.end(); ++itr) { Unit* pUnit = Unit::GetUnit((*m_creature), (*itr)->getUnitGuid()); if(pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER)) // Only alive players- targets.push_back(pUnit);+ targets.push_back(pUnit); } if(targets.empty())- return; // No targets added for some reason. No point continuing.+ return; // No targets added for some reason. No point continuing.+ targets.sort(TargetDistanceOrder(m_creature)); // Sort players by distance. targets.resize(1); // Only need closest target. Unit* target = targets.front(); // Get the first target.@@ -654,7 +604,7 @@ { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())- return;+ return; if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) {@@ -663,30 +613,30 @@ Unit* pUnit = NULL; pUnit = Unit::GetUnit((*m_creature), StatAuraGUID); if(pUnit)- pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR);+ pUnit->RemoveAurasDueToSpell(AURA_OF_SUFFERING_ARMOR); } } if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) { if(m_creature->getVictim())- m_creature->DeleteThreatList(); // Delete our threatlist if below 10% as we should no longer attack.+ m_creature->DeleteThreatList(); // Delete our threatlist if below 10% as we should no longer attack. return; } // Prevent overlapping yells if(AggroYellTimer)- if(AggroYellTimer < diff)- {- DoYell(SUFF_SAY_AGGRO, LANG_UNIVERSAL, NULL);- DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO);- AggroYellTimer = 0;- }else AggroYellTimer -= diff;+ if(AggroYellTimer < diff)+ {+ DoYell(SUFF_SAY_AGGRO, LANG_UNIVERSAL, NULL);+ DoPlaySoundToSet(m_creature, SUFF_SOUND_AGGRO);+ AggroYellTimer = 0;+ }else AggroYellTimer -= diff; //Supposed to be cast on nearest target if(FixateTimer < diff) {- //CastFixate();+ CastFixate(); FixateTimer = 5000; }else FixateTimer -= diff; @@ -702,8 +652,10 @@ target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target)- DoCast(target, SPELL_SOUL_DRAIN);- SoulDrainTimer = 60000;+ {+ DoCast(target, SPELL_SOUL_DRAIN);+ SoulDrainTimer = 60000;+ } }else SoulDrainTimer -= diff; DoMeleeAttackIfReady();@@ -745,67 +697,40 @@ void Aggro(Unit *who) {+ DoCast(who, AURA_OF_DESIRE, true);+ InCombat = true; } void KilledUnit(Unit *victim) { switch(rand()%3) {- case 0:- DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1);- break;- case 1:- DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2);- break;- case 2:- DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3);- break;+ case 0:+ DoYell(DESI_SAY_SLAY1,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY1);+ break;+ case 1:+ DoYell(DESI_SAY_SLAY2,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY2);+ break;+ case 2:+ DoYell(DESI_SAY_SLAY3,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, DESI_SOUND_SLAY3);+ break; } } - void MoveInLineOfSight(Unit *who)- {- if (!who || m_creature->getVictim())- return;-- if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))- {- float attackRadius = m_creature->GetAttackDistance(who);- if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))- {- if(who->HasStealthAura())- who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);-- //Begin melee attack if we are within range- DoStartMeleeAttack(who);-- if (!InCombat)- {- DoCast(who, AURA_OF_DESIRE);- InCombat = true;- }- }- }- }-- void JustDied(Unit* killer)- {- InCombat = false;- }- void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())- return;+ return; if(m_creature->GetHealth() <= (m_creature->GetMaxHealth()*0.1)) { if(m_creature->getVictim())- m_creature->DeleteThreatList(); // Delete our threatlist if below 10% as we should no longer attack.+ m_creature->DeleteThreatList(); // Delete our threatlist if below 10% as we should no longer attack.+ return; } @@ -842,11 +767,13 @@ boss_essence_of_angerAI(Creature *c) : ScriptedAI(c) {Reset();} uint64 AggroTargetGUID;+ uint64 SpiteTargetGUID[4]; uint32 AggroYellTimer; uint32 CheckTankTimer; uint32 SoulScreamTimer; uint32 SpiteTimer;+ uint32 SpiteDamageTimer; bool CheckedAggro; bool InCombat;@@ -855,10 +782,14 @@ { AggroTargetGUID = 0; - AggroYellTimer = 5000;- CheckTankTimer = 5000;- SoulScreamTimer = 10000;- SpiteTimer = 30000;+ for(uint8 i = 0; i < 4; ++i)+ SpiteTargetGUID[i] = 0;+ + AggroYellTimer = 5000;+ CheckTankTimer = 5000;+ SoulScreamTimer = 10000;+ SpiteTimer = 30000;+ SpiteDamageTimer = SpiteTimer + 6000; CheckedAggro = false; InCombat = false;@@ -866,37 +797,14 @@ void Aggro(Unit *who) {- DoCast(m_creature->getVictim(), AURA_OF_ANGER);+ DoCast(m_creature->getVictim(), AURA_OF_ANGER, true);+ DoCast(m_creature->getVictim(), SPELL_ENEMY_SEETHE, true);+ DoCast(m_creature, SPELL_SELF_SEETHE, true);+ InCombat = true; } - void MoveInLineOfSight(Unit *who)- {- if (!who || m_creature->getVictim())- return;-- if (who->isTargetableForAttack() && who->isInAccessablePlaceFor(m_creature) && m_creature->IsHostileTo(who))- {- float attackRadius = m_creature->GetAttackDistance(who);- if (m_creature->IsWithinDistInMap(who, attackRadius) && m_creature->GetDistanceZ(who) <= CREATURE_Z_ATTACK_RANGE && m_creature->IsWithinLOSInMap(who))- {- if(who->HasStealthAura())- who->RemoveSpellsCausingAura(SPELL_AURA_MOD_STEALTH);-- //Begin melee attack if we are within range- DoStartMeleeAttack(who);-- if (!InCombat)- {- DoCast(who, AURA_OF_ANGER);- InCombat = true;- }- }- }- }- void JustDied(Unit *victim) {- InCombat = false; DoYell(ANGER_SAY_DEATH, LANG_UNIVERSAL, NULL); DoPlaySoundToSet(m_creature,ANGER_SOUND_DEATH); }@@ -905,22 +813,33 @@ { switch(rand()%2) {- case 0:- DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1);- break;- case 1:- DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2);- break;+ case 0:+ DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY1);+ break;+ case 1:+ DoYell(ANGER_SAY_SLAY2,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, ANGER_SOUND_SLAY2);+ break; } } + void SpellHit(Unit *caster, const SpellEntry *spell)+ {+ for(uint8 i = 0; i < 3; ++i)+ {+ if(spell->EffectApplyAuraName[i] == SPELL_AURA_MOD_TAUNT)+ {+ DoCast(m_creature, SPELL_SELF_SEETHE, true);+ DoCast(m_creature->getVictim(), SPELL_ENEMY_SEETHE, true);+ }+ }+ } void UpdateAI(const uint32 diff) { //Return since we have no target if (!m_creature->SelectHostilTarget() || !m_creature->getVictim())- return;+ return; if(!CheckedAggro) {@@ -929,12 +848,12 @@ } if(AggroYellTimer)- if(AggroYellTimer < diff)- {- DoYell(ANGER_SAY_FREED2,LANG_UNIVERSAL,NULL);- DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED2);- AggroYellTimer = 0;- }else AggroYellTimer -= diff;+ if(AggroYellTimer < diff)+ {+ DoYell(ANGER_SAY_FREED2,LANG_UNIVERSAL,NULL);+ DoPlaySoundToSet(m_creature, ANGER_SOUND_FREED2);+ AggroYellTimer = 0;+ }else AggroYellTimer -= diff; if(CheckTankTimer < diff) {@@ -963,15 +882,34 @@ target = SelectUnit(SELECT_TARGET_RANDOM, 0); if(target)- DoCast(target, SPELL_SPITE);-+ {+ target->CastSpell(target, SPELL_SPITE, true);+ SpiteTargetGUID[i] = target->GetGUID();+ } } SpiteTimer = 30000;+ SpiteDamageTimer = 6000; DoYell(ANGER_SAY_SPEC,LANG_UNIVERSAL,NULL); DoPlaySoundToSet(m_creature, ANGER_SOUND_SPEC); }else SpiteTimer -= diff; + if(SpiteDamageTimer < diff)+ {+ for(uint8 i = 0; i < 4; ++i)+ {+ if(SpiteTargetGUID[i])+ {+ Unit* target = Unit::GetUnit((*m_creature), SpiteTargetGUID[i]);+ if(target && target->isAlive())+ target->CastSpell(target, SPELL_SPITE_DAMAGE, true);++ SpiteTargetGUID[i] = 0;+ }+ }+ SpiteDamageTimer = SpiteTimer + 6000;+ }else SpiteDamageTimer -= diff;+ DoMeleeAttackIfReady(); } };@@ -982,7 +920,7 @@ { Creature* Reliquary = ((Creature*)Unit::GetUnit((*m_creature), ReliquaryGUID)); if(Reliquary)- ((boss_reliquary_of_soulsAI*)Reliquary->AI())->SoulDeathCount++;+ ((boss_reliquary_of_soulsAI*)Reliquary->AI())->SoulDeathCount++; } }