Index: 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& m_threatlist = m_creature->getThreatManager().getThreatList(); + + if(m_threatlist.empty()) + return; + + std::list::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& m_threatlist = m_creature->getThreatManager().getThreatList(); - std::list& m_threatlist = target->getThreatManager().getThreatList(); + if(m_threatlist.empty()) + return; + std::list::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(*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(*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(*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 { @@ -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& 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 targets; std::list::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++; } }