aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp3
-rw-r--r--src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp343
2 files changed, 170 insertions, 176 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 67417ca809b..b7c713dd49c 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -6507,7 +6507,8 @@ bool Unit::HandleAuraProc(Unit* victim, uint32 /*damage*/, Aura* triggeredByAura
// Blood of the North
// Reaping
// Death Rune Mastery
- if (dummySpell->SpellIconID == 3041 || dummySpell->SpellIconID == 22 || dummySpell->SpellIconID == 2622)
+ /// @todo move those to spell scripts
+ if (dummySpell->SpellIconID == 3041 || (dummySpell->SpellIconID == 22 && dummySpell->Id != 62459) || dummySpell->SpellIconID == 2622)
{
*handled = true;
// Convert recently used Blood Rune to Death Rune
diff --git a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
index e090f3db7c0..efca060b67c 100644
--- a/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
+++ b/src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp
@@ -17,29 +17,48 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
-#include "drak_tharon_keep.h"
+#include "SpellScript.h"
+#include "SpellAuraEffects.h"
#include "Player.h"
+#include "drak_tharon_keep.h"
+
+/*
+ * Known Issues: Spell 49356 and 53463 will be interrupted for an unknown reason
+ */
enum Spells
{
- //skeletal spells (phase 1)
+ // Skeletal Spells (phase 1)
SPELL_CURSE_OF_LIFE = 49527,
- H_SPELL_CURSE_OF_LIFE = 59972,
SPELL_RAIN_OF_FIRE = 49518,
- H_SPELL_RAIN_OF_FIRE = 59971,
SPELL_SHADOW_VOLLEY = 49528,
- H_SPELL_SHADOW_VOLLEY = 59973,
- SPELL_DECAY_FLESH = 49356, //casted at end of phase 1, starts phase 2
- //flesh spells (phase 2)
+ SPELL_DECAY_FLESH = 49356, // casted at end of phase 1, starts phase 2
+ // Flesh Spells (phase 2)
SPELL_GIFT_OF_THARON_JA = 52509,
+ SPELL_CLEAR_GIFT_OF_THARON_JA = 53242,
SPELL_EYE_BEAM = 49544,
- H_SPELL_EYE_BEAM = 59965,
SPELL_LIGHTNING_BREATH = 49537,
- H_SPELL_LIGHTNING_BREATH = 59963,
SPELL_POISON_CLOUD = 49548,
- H_SPELL_POISON_CLOUD = 59969,
- SPELL_RETURN_FLESH = 53463, //Channeled spell ending phase two and returning to phase 1. This ability will stun the party for 6 seconds.
+ SPELL_RETURN_FLESH = 53463, // Channeled spell ending phase two and returning to phase 1. This ability will stun the party for 6 seconds.
SPELL_ACHIEVEMENT_CHECK = 61863,
+ SPELL_FLESH_VISUAL = 52582,
+ SPELL_DUMMY = 49551
+};
+
+enum Events
+{
+ EVENT_CURSE_OF_LIFE = 1,
+ EVENT_RAIN_OF_FIRE,
+ EVENT_SHADOW_VOLLEY,
+
+ EVENT_EYE_BEAM,
+ EVENT_LIGHTNING_BREATH,
+ EVENT_POISON_CLOUD,
+
+ EVENT_DECAY_FLESH,
+ EVENT_GOING_FLESH,
+ EVENT_RETURN_FLESH,
+ EVENT_GOING_SKELETAL
};
enum Yells
@@ -50,204 +69,178 @@ enum Yells
SAY_SKELETON = 3,
SAY_DEATH = 4
};
+
enum Models
{
- MODEL_FLESH = 27073,
- MODEL_SKELETON = 27511
-};
-enum CombatPhase
-{
- SKELETAL,
- GOING_FLESH,
- FLESH,
- GOING_SKELETAL
+ MODEL_FLESH = 27073
};
class boss_tharon_ja : public CreatureScript
{
-public:
- boss_tharon_ja() : CreatureScript("boss_tharon_ja") { }
+ public:
+ boss_tharon_ja() : CreatureScript("boss_tharon_ja") { }
- struct boss_tharon_jaAI : public ScriptedAI
- {
- boss_tharon_jaAI(Creature* creature) : ScriptedAI(creature)
+ struct boss_tharon_jaAI : public BossAI
{
- instance = creature->GetInstanceScript();
- }
-
- uint32 uiPhaseTimer;
- uint32 uiCurseOfLifeTimer;
- uint32 uiRainOfFireTimer;
- uint32 uiShadowVolleyTimer;
- uint32 uiEyeBeamTimer;
- uint32 uiLightningBreathTimer;
- uint32 uiPoisonCloudTimer;
+ boss_tharon_jaAI(Creature* creature) : BossAI(creature, DATA_THARON_JA) { }
- CombatPhase Phase;
-
- InstanceScript* instance;
-
- void Reset() OVERRIDE
- {
- uiPhaseTimer = 20*IN_MILLISECONDS;
- uiCurseOfLifeTimer = 1*IN_MILLISECONDS;
- uiRainOfFireTimer = urand(14*IN_MILLISECONDS, 18*IN_MILLISECONDS);
- uiShadowVolleyTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- Phase = SKELETAL;
- me->SetDisplayId(me->GetNativeDisplayId());
- instance->SetBossState(DATA_THARON_JA, NOT_STARTED);
- }
+ void Reset() OVERRIDE
+ {
+ _Reset();
+ me->RestoreDisplayId();
+ }
- void EnterCombat(Unit* /*who*/) OVERRIDE
- {
- Talk(SAY_AGGRO);
- instance->SetBossState(DATA_THARON_JA, IN_PROGRESS);
- }
+ void EnterCombat(Unit* /*who*/) OVERRIDE
+ {
+ Talk(SAY_AGGRO);
+ _EnterCombat();
- void UpdateAI(uint32 diff) OVERRIDE
- {
- //Return since we have no target
- if (!UpdateVictim())
- return;
+ events.ScheduleEvent(EVENT_DECAY_FLESH, 20000);
+ events.ScheduleEvent(EVENT_CURSE_OF_LIFE, 1000);
+ events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(14000, 18000));
+ events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(8000, 10000));
+ }
- switch (Phase)
+ void KilledUnit(Unit* who) OVERRIDE
{
- case SKELETAL:
- if (uiCurseOfLifeTimer < diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_CURSE_OF_LIFE);
- uiCurseOfLifeTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
- } else uiCurseOfLifeTimer -= diff;
+ if (who->GetTypeId() == TYPEID_PLAYER)
+ Talk(SAY_KILL);
+ }
- if (uiShadowVolleyTimer < diff)
- {
- DoCastVictim(SPELL_SHADOW_VOLLEY);
- uiShadowVolleyTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
- } else uiShadowVolleyTimer -= diff;
+ void JustDied(Unit* /*killer*/) OVERRIDE
+ {
+ _JustDied();
- if (uiRainOfFireTimer < diff)
- {
- DoCastAOE(SPELL_RAIN_OF_FIRE);
- uiRainOfFireTimer = urand(14*IN_MILLISECONDS, 18*IN_MILLISECONDS);
- } else uiRainOfFireTimer -= diff;
+ Talk(SAY_DEATH);
+ DoCastAOE(SPELL_CLEAR_GIFT_OF_THARON_JA, true);
+ DoCastAOE(SPELL_ACHIEVEMENT_CHECK, true);
+ }
- if (uiPhaseTimer < diff)
- {
- DoCast(SPELL_DECAY_FLESH);
- Phase = GOING_FLESH;
- uiPhaseTimer = 6*IN_MILLISECONDS;
- } else uiPhaseTimer -= diff;
-
- DoMeleeAttackIfReady();
- break;
- case GOING_FLESH:
- if (uiPhaseTimer < diff)
- {
- Talk(SAY_FLESH);
- me->SetDisplayId(MODEL_FLESH);
-
- std::list<Unit*> playerList;
- SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true);
- for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
- {
- Unit* temp = (*itr);
- me->AddAura(SPELL_GIFT_OF_THARON_JA, temp);
- temp->SetDisplayId(MODEL_SKELETON);
- }
- uiPhaseTimer = 20*IN_MILLISECONDS;
- uiLightningBreathTimer = urand(3*IN_MILLISECONDS, 4*IN_MILLISECONDS);
- uiEyeBeamTimer = urand(4*IN_MILLISECONDS, 8*IN_MILLISECONDS);
- uiPoisonCloudTimer = urand(6*IN_MILLISECONDS, 7*IN_MILLISECONDS);
- Phase = FLESH;
- } else uiPhaseTimer -= diff;
- break;
- case FLESH:
- if (uiLightningBreathTimer < diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_LIGHTNING_BREATH);
- uiLightningBreathTimer = urand(6*IN_MILLISECONDS, 7*IN_MILLISECONDS);
- } else uiLightningBreathTimer -= diff;
+ void UpdateAI(uint32 diff) OVERRIDE
+ {
+ if (!UpdateVictim())
+ return;
- if (uiEyeBeamTimer < diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
- DoCast(target, SPELL_EYE_BEAM);
- uiEyeBeamTimer = urand(4*IN_MILLISECONDS, 6*IN_MILLISECONDS);
- } else uiEyeBeamTimer -= diff;
+ events.Update(diff);
- if (uiPoisonCloudTimer < diff)
- {
- DoCastAOE(SPELL_POISON_CLOUD);
- uiPoisonCloudTimer = urand(10*IN_MILLISECONDS, 12*IN_MILLISECONDS);
- } else uiPoisonCloudTimer -= diff;
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- if (uiPhaseTimer < diff)
- {
- DoCast(SPELL_RETURN_FLESH);
- Phase = GOING_SKELETAL;
- uiPhaseTimer = 6*IN_MILLISECONDS;
- } else uiPhaseTimer -= diff;
- DoMeleeAttackIfReady();
- break;
- case GOING_SKELETAL:
- if (uiPhaseTimer < diff)
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
{
- Talk(SAY_SKELETON);
- me->DeMorph();
- Phase = SKELETAL;
- uiPhaseTimer = 20*IN_MILLISECONDS;
- uiCurseOfLifeTimer = 1*IN_MILLISECONDS;
- uiRainOfFireTimer = urand(14*IN_MILLISECONDS, 18*IN_MILLISECONDS);
- uiShadowVolleyTimer = urand(8*IN_MILLISECONDS, 10*IN_MILLISECONDS);
-
- std::list<Unit*> playerList;
- SelectTargetList(playerList, 5, SELECT_TARGET_TOPAGGRO, 0, true);
- for (std::list<Unit*>::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
- {
- Unit* temp = (*itr);
- if (temp->HasAura(SPELL_GIFT_OF_THARON_JA))
- temp->RemoveAura(SPELL_GIFT_OF_THARON_JA);
- temp->DeMorph();
- }
- } else uiPhaseTimer -= diff;
- break;
+ case EVENT_CURSE_OF_LIFE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_CURSE_OF_LIFE);
+ events.ScheduleEvent(EVENT_CURSE_OF_LIFE, urand(10000, 15000));
+ return;
+ case EVENT_SHADOW_VOLLEY:
+ DoCastVictim(SPELL_SHADOW_VOLLEY);
+ events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(8000, 10000));
+ return;
+ case EVENT_RAIN_OF_FIRE:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_RAIN_OF_FIRE);
+ events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(14000, 18000));
+ return;
+ case EVENT_LIGHTNING_BREATH:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_LIGHTNING_BREATH);
+ events.ScheduleEvent(EVENT_LIGHTNING_BREATH, urand(6000, 7000));
+ return;
+ case EVENT_EYE_BEAM:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
+ DoCast(target, SPELL_EYE_BEAM);
+ events.ScheduleEvent(EVENT_EYE_BEAM, urand(4000, 6000));
+ return;
+ case EVENT_POISON_CLOUD:
+ DoCastAOE(SPELL_POISON_CLOUD);
+ events.ScheduleEvent(EVENT_POISON_CLOUD, urand(10000, 12000));
+ return;
+ case EVENT_DECAY_FLESH:
+ DoCastAOE(SPELL_DECAY_FLESH);
+ events.ScheduleEvent(EVENT_GOING_FLESH, 6000);
+ return;
+ case EVENT_GOING_FLESH:
+ Talk(SAY_FLESH);
+ me->SetDisplayId(MODEL_FLESH);
+ DoCastAOE(SPELL_GIFT_OF_THARON_JA, true);
+ DoCast(me, SPELL_FLESH_VISUAL, true);
+ DoCast(me, SPELL_DUMMY, true);
+
+ events.Reset();
+ events.ScheduleEvent(EVENT_RETURN_FLESH, 20000);
+ events.ScheduleEvent(EVENT_LIGHTNING_BREATH, urand(3000, 4000));
+ events.ScheduleEvent(EVENT_EYE_BEAM, urand(4000, 8000));
+ events.ScheduleEvent(EVENT_POISON_CLOUD, urand(6000, 7000));
+ break;
+ case EVENT_RETURN_FLESH:
+ DoCastAOE(SPELL_RETURN_FLESH);
+ events.ScheduleEvent(EVENT_GOING_SKELETAL, 6000);
+ return;
+ case EVENT_GOING_SKELETAL:
+ Talk(SAY_SKELETON);
+ me->RestoreDisplayId();
+ DoCastAOE(SPELL_CLEAR_GIFT_OF_THARON_JA, true);
+
+ events.Reset();
+ events.ScheduleEvent(EVENT_DECAY_FLESH, 20000);
+ events.ScheduleEvent(EVENT_CURSE_OF_LIFE, 1000);
+ events.ScheduleEvent(EVENT_RAIN_OF_FIRE, urand(14000, 18000));
+ events.ScheduleEvent(EVENT_SHADOW_VOLLEY, urand(8000, 10000));
+ break;
+ default:
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
}
- }
+ };
- void KilledUnit(Unit* /*victim*/) OVERRIDE
+ CreatureAI* GetAI(Creature* creature) const OVERRIDE
{
- Talk(SAY_KILL);
+ return GetDrakTharonKeepAI<boss_tharon_jaAI>(creature);
}
+};
+
+class spell_tharon_ja_clear_gift_of_tharon_ja : public SpellScriptLoader
+{
+ public:
+ spell_tharon_ja_clear_gift_of_tharon_ja() : SpellScriptLoader("spell_tharon_ja_clear_gift_of_tharon_ja") { }
- void JustDied(Unit* /*killer*/) OVERRIDE
+ class spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript : public SpellScript
{
- Talk(SAY_DEATH);
+ PrepareSpellScript(spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript);
- if (instance)
+ bool Validate(SpellInfo const* /*spellInfo*/) OVERRIDE
{
- // clean morph on players
- Map::PlayerList const &PlayerList = instance->instance->GetPlayers();
-
- for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
- if (Player* player = i->GetSource())
- player->DeMorph();
+ if (!sSpellMgr->GetSpellInfo(SPELL_GIFT_OF_THARON_JA))
+ return false;
+ return true;
+ }
- DoCast(me, SPELL_ACHIEVEMENT_CHECK);
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ if (Unit* target = GetHitUnit())
+ target->RemoveAura(SPELL_GIFT_OF_THARON_JA);
+ }
- instance->SetBossState(DATA_THARON_JA, DONE);
+ void Register() OVERRIDE
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
- }
- };
+ };
- CreatureAI* GetAI(Creature* creature) const OVERRIDE
- {
- return GetDrakTharonKeepAI<boss_tharon_jaAI>(creature);
- }
+ SpellScript* GetSpellScript() const OVERRIDE
+ {
+ return new spell_tharon_ja_clear_gift_of_tharon_ja_SpellScript();
+ }
};
void AddSC_boss_tharon_ja()
{
- new boss_tharon_ja;
+ new boss_tharon_ja();
+ new spell_tharon_ja_clear_gift_of_tharon_ja();
}