mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-26 07:06:23 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -244,7 +244,8 @@ public:
|
||||
enum MograineEvents
|
||||
{
|
||||
EVENT_SPELL_CRUSADER_STRIKE = 1,
|
||||
EVENT_SPELL_HAMMER_OF_JUSTICE = 2
|
||||
EVENT_SPELL_HAMMER_OF_JUSTICE = 2,
|
||||
EVENT_PULL_CATHEDRAL = 3
|
||||
};
|
||||
|
||||
enum WhitemaneEvents
|
||||
@@ -285,6 +286,8 @@ enum Says
|
||||
SAY_WH_RESURRECT = 2,
|
||||
};
|
||||
|
||||
float const CATHEDRAL_PULL_RANGE = 80.0f; // Distance from the Cathedral doors to where Mograine is standing
|
||||
|
||||
class npc_mograine : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -357,6 +360,22 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void PullCathedral() // CallForHelp will ignore any npcs without LOS
|
||||
{
|
||||
std::list<Creature*> creatureList;
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_MONK, CATHEDRAL_PULL_RANGE);
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_ABBOT, CATHEDRAL_PULL_RANGE);
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CHAMPION, CATHEDRAL_PULL_RANGE);
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CENTURION, CATHEDRAL_PULL_RANGE);
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_WIZARD, CATHEDRAL_PULL_RANGE);
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_SCARLET_CHAPLAIN, CATHEDRAL_PULL_RANGE);
|
||||
for (std::list<Creature*>::iterator itr = creatureList.begin(); itr != creatureList.end(); ++itr)
|
||||
{
|
||||
if (Creature* creature = *itr)
|
||||
creature->AI()->AttackStart(me->GetVictim());
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
//Incase wipe during phase that mograine fake death
|
||||
@@ -392,8 +411,8 @@ public:
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_MO_AGGRO);
|
||||
me->CallForHelp(150.0f);
|
||||
me->CastSpell(me, SPELL_RETRIBUTION_AURA, true);
|
||||
events.ScheduleEvent(EVENT_PULL_CATHEDRAL, 1000); // Has to be done via event, otherwise mob aggroing Mograine DOES NOT aggro the room
|
||||
events.ScheduleEvent(EVENT_SPELL_CRUSADER_STRIKE, urand(1000, 5000));
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, urand(6000, 11000));
|
||||
}
|
||||
@@ -496,6 +515,9 @@ public:
|
||||
me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, true);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER_OF_JUSTICE, 60000);
|
||||
break;
|
||||
case EVENT_PULL_CATHEDRAL:
|
||||
PullCathedral();
|
||||
break;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -30,7 +30,8 @@ enum Spells
|
||||
{
|
||||
SPELL_FROSTBREATH = 16099,
|
||||
SPELL_MASSIVEGEYSER = 22421,
|
||||
SPELL_SLAM = 24326
|
||||
SPELL_SLAM = 24326,
|
||||
SPELL_THRASH = 3417 // Triggers 3391
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -40,7 +41,7 @@ enum Events
|
||||
EVENT_SLAM = 3
|
||||
};
|
||||
|
||||
class boss_gahzranka : public CreatureScript // gahzranka
|
||||
class boss_gahzranka : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_gahzranka() : CreatureScript("boss_gahzranka") { }
|
||||
@@ -62,9 +63,10 @@ public:
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
me->AddAura(SPELL_THRASH, me);
|
||||
events.ScheduleEvent(EVENT_FROSTBREATH, 8000);
|
||||
events.ScheduleEvent(EVENT_MASSIVEGEYSER, 25000);
|
||||
events.ScheduleEvent(EVENT_SLAM, 17000);
|
||||
events.ScheduleEvent(EVENT_SLAM, 15000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -82,11 +84,11 @@ public:
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FROSTBREATH:
|
||||
DoCastVictim(SPELL_FROSTBREATH, true);
|
||||
events.ScheduleEvent(EVENT_FROSTBREATH, urand(7000, 11000));
|
||||
DoCastVictim(SPELL_FROSTBREATH);
|
||||
events.ScheduleEvent(EVENT_FROSTBREATH, urand(8000, 20000));
|
||||
break;
|
||||
case EVENT_MASSIVEGEYSER:
|
||||
DoCastVictim(SPELL_MASSIVEGEYSER, true);
|
||||
DoCastVictim(SPELL_MASSIVEGEYSER);
|
||||
events.ScheduleEvent(EVENT_MASSIVEGEYSER, urand(22000, 32000));
|
||||
break;
|
||||
case EVENT_SLAM:
|
||||
|
||||
@@ -29,13 +29,16 @@ EndScriptData */
|
||||
enum Spells
|
||||
{
|
||||
SPELL_AVATAR = 24646, // Enrage Spell
|
||||
SPELL_GROUND_TREMOR = 6524
|
||||
SPELL_GROUND_TREMOR = 6524,
|
||||
SPELL_ENTANGLING_ROOTS = 24648
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_AVATAR = 1,
|
||||
EVENT_GROUND_TREMOR = 2
|
||||
EVENT_GROUND_TREMOR = 2,
|
||||
EVENT_START_PURSUIT = 3,
|
||||
EVENT_ENTANGLING_ROOTS = 4
|
||||
};
|
||||
|
||||
class boss_grilek : public CreatureScript // grilek
|
||||
@@ -45,23 +48,16 @@ public:
|
||||
|
||||
struct boss_grilekAI : public BossAI
|
||||
{
|
||||
boss_grilekAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
void Reset() override
|
||||
boss_grilekAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS)
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_AVATAR, urand(15000, 25000));
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(15000, 25000));
|
||||
events.ScheduleEvent(EVENT_AVATAR, 20s, 30s);
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, 15s, 25s);
|
||||
events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, 5s, 15s);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
@@ -80,19 +76,21 @@ public:
|
||||
{
|
||||
case EVENT_AVATAR:
|
||||
DoCast(me, SPELL_AVATAR);
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (DoGetThreat(victim))
|
||||
DoModifyThreatPercent(victim, -50);
|
||||
}
|
||||
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
AttackStart(target);
|
||||
events.ScheduleEvent(EVENT_AVATAR, urand(25000, 35000));
|
||||
DoResetThreat();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
events.ScheduleEvent(EVENT_START_PURSUIT, 2s);
|
||||
events.ScheduleEvent(EVENT_AVATAR, 45s, 50s);
|
||||
break;
|
||||
case EVENT_GROUND_TREMOR:
|
||||
DoCastVictim(SPELL_GROUND_TREMOR, true);
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(12000, 16000));
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, 12s, 16s);
|
||||
break;
|
||||
case EVENT_START_PURSUIT:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
break;
|
||||
case EVENT_ENTANGLING_ROOTS:
|
||||
DoCastVictim(SPELL_ENTANGLING_ROOTS);
|
||||
events.ScheduleEvent(EVENT_ENTANGLING_ROOTS, 10s, 20s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -34,15 +34,15 @@ enum Say
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BRAINWASHTOTEM = 24262,
|
||||
SPELL_POWERFULLHEALINGWARD = 24309, // HACKED Totem summoned by script because the spell totems will not cast.
|
||||
SPELL_POWERFULLHEALINGWARD = 24309,
|
||||
SPELL_HEX = 24053,
|
||||
SPELL_DELUSIONSOFJINDO = 24306,
|
||||
SPELL_SHADEOFJINDO = 24308, // HACKED
|
||||
//Healing Ward Spell
|
||||
SPELL_HEAL = 38588, // HACKED Totems are not working right. Right heal spell ID is 24311 but this spell is not casting...
|
||||
SPELL_HEAL = 24311,
|
||||
//Shade of Jindo Spell
|
||||
SPELL_SHADOWSHOCK = 19460,
|
||||
SPELL_INVISIBLE = 24699
|
||||
SPELL_SHADEOFJINDO_PASSIVE = 24307,
|
||||
SPELL_SHADEOFJINDO_VISUAL = 24313,
|
||||
SPELL_SHADOWSHOCK = 19460
|
||||
};
|
||||
|
||||
enum Events
|
||||
@@ -104,9 +104,8 @@ public:
|
||||
DoCast(me, SPELL_BRAINWASHTOTEM);
|
||||
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, urand(18000, 26000));
|
||||
break;
|
||||
case EVENT_POWERFULLHEALINGWARD: // HACK
|
||||
//DoCast(me, SPELL_POWERFULLHEALINGWARD);
|
||||
me->SummonCreature(14987, me->GetPositionX() + 3, me->GetPositionY() - 2, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
|
||||
case EVENT_POWERFULLHEALINGWARD:
|
||||
DoCastSelf(SPELL_POWERFULLHEALINGWARD, true);
|
||||
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
|
||||
break;
|
||||
case EVENT_HEX:
|
||||
@@ -251,7 +250,8 @@ public:
|
||||
void Reset() override
|
||||
{
|
||||
ShadowShock_Timer = 1000;
|
||||
DoCast(me, SPELL_INVISIBLE, true);
|
||||
DoCastSelf(SPELL_SHADEOFJINDO_PASSIVE, true);
|
||||
DoCastSelf(SPELL_SHADEOFJINDO_VISUAL, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override { }
|
||||
|
||||
@@ -15,34 +15,32 @@
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss_Thekal
|
||||
SD%Complete: 95
|
||||
SDComment: Almost finished.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1
|
||||
SAY_DEATH = 1,
|
||||
|
||||
EMOTE_ZEALOT_DIES = 0,
|
||||
EMOTE_THEKAL_DIES = 2
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTALCLEAVE = 22859, // Phase 1
|
||||
SPELL_SILENCE = 22666, // Phase 1
|
||||
SPELL_TIGER_FORM = 24169, // Phase 1
|
||||
SPELL_RESURRECT = 24173, // Phase 1 // Not used in script.
|
||||
SPELL_FRENZY = 8269, // Phase 2
|
||||
SPELL_FORCEPUNCH = 24189, // Phase 2
|
||||
SPELL_CHARGE = 24193, // Phase 2
|
||||
SPELL_ENRAGE = 8269, // Phase 2
|
||||
SPELL_SUMMONTIGERS = 24183, // Phase 2
|
||||
SPELL_MORTALCLEAVE = 22859,
|
||||
SPELL_SILENCE = 22666,
|
||||
SPELL_TIGER_FORM = 24169,
|
||||
SPELL_RESURRECT = 24173,
|
||||
SPELL_FRENZY = 8269,
|
||||
SPELL_FORCEPUNCH = 24189,
|
||||
SPELL_CHARGE = 24193,
|
||||
SPELL_ENRAGE = 8269,
|
||||
SPELL_SUMMONTIGERS = 24183,
|
||||
|
||||
// Zealot Lor'Khan Spells
|
||||
SPELL_SHIELD = 20545,
|
||||
SPELL_BLOODLUST = 24185,
|
||||
@@ -56,23 +54,9 @@ enum Spells
|
||||
SPELL_BLIND = 21060
|
||||
};
|
||||
|
||||
enum Events
|
||||
enum Actions
|
||||
{
|
||||
EVENT_MORTALCLEAVE = 1, // Phase 1
|
||||
EVENT_SILENCE = 2, // Phase 1
|
||||
EVENT_CHECK_TIMER = 3, // Phase 1
|
||||
EVENT_RESURRECT_TIMER = 4, // Phase 1
|
||||
EVENT_FRENZY = 5, // Phase 2
|
||||
EVENT_FORCEPUNCH = 6, // Phase 2
|
||||
EVENT_SPELL_CHARGE = 7, // Phase 2
|
||||
EVENT_ENRAGE = 8, // Phase 2
|
||||
EVENT_SUMMONTIGERS = 9 // Phase 2
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2
|
||||
ACTION_RESSURRECT = 1
|
||||
};
|
||||
|
||||
class boss_thekal : public CreatureScript
|
||||
@@ -82,170 +66,240 @@ public:
|
||||
|
||||
struct boss_thekalAI : public BossAI
|
||||
{
|
||||
boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL) { }
|
||||
boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
bool Enraged;
|
||||
bool WasDead;
|
||||
|
||||
void Reset() override
|
||||
void Initialize()
|
||||
{
|
||||
if (events.IsInPhase(PHASE_TWO))
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
_Reset();
|
||||
Enraged = false;
|
||||
WasDead = false;
|
||||
_lorkhanDied = false;
|
||||
_zathDied = false;
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
Initialize();
|
||||
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_LORKHAN))
|
||||
{
|
||||
zealot->AI()->Reset();
|
||||
zealot->ResetFaction();
|
||||
}
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_ZATH))
|
||||
{
|
||||
zealot->AI()->Reset();
|
||||
zealot->ResetFaction();
|
||||
}
|
||||
|
||||
// TODO: do this in formations, once a flag is added to prevent leaders from respawning as well.
|
||||
std::list<Creature*> creatureList;
|
||||
GetCreatureListWithEntryInGrid(creatureList, me, NPC_ZULGURUB_TIGER, 15.0f);
|
||||
|
||||
if (_catGuids.empty())
|
||||
{
|
||||
for (Creature* creature : creatureList)
|
||||
{
|
||||
_catGuids.push_back(creature->GetGUID());
|
||||
if (!creature->IsAlive())
|
||||
{
|
||||
creature->Respawn(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ObjectGuid guid : _catGuids)
|
||||
{
|
||||
if (Creature* creature = ObjectAccessor::GetCreature(*me, guid))
|
||||
{
|
||||
if (!creature->IsAlive())
|
||||
{
|
||||
creature->Respawn(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_LORKHAN))
|
||||
{
|
||||
zealot->Kill(zealot, zealot);
|
||||
}
|
||||
|
||||
if (Creature* zealot = instance->GetCreature(DATA_ZATH))
|
||||
{
|
||||
zealot->Kill(zealot, zealot);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 4000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_SILENCE, 9000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_CHECK_TIMER, 10000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); // Phase 1
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
_scheduler.CancelAll();
|
||||
_scheduler.Schedule(4s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_MORTALCLEAVE);
|
||||
context.Repeat(15s, 20s);
|
||||
}).Schedule(9s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_SILENCE);
|
||||
context.Repeat(20s, 25s);
|
||||
}).Schedule(16s, [this](TaskContext context) {
|
||||
DoCastSelf(SPELL_BLOODLUST);
|
||||
context.Repeat(20s, 28s);
|
||||
});
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
void SetData(uint32 /*type*/, uint32 data) override
|
||||
{
|
||||
instance->SetBossState(DATA_THEKAL, NOT_STARTED);
|
||||
UpdateZealotStatus(data, true);
|
||||
CheckPhaseTransition();
|
||||
|
||||
_scheduler.Schedule(10s, [this, data](TaskContext /*context*/) {
|
||||
if ((!_lorkhanDied || !_zathDied) && !WasDead)
|
||||
{
|
||||
ReviveZealot(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (!WasDead && damage >= me->GetHealth())
|
||||
{
|
||||
damage = me->GetHealth() - 1;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->AttackStop();
|
||||
WasDead = true;
|
||||
CheckPhaseTransition();
|
||||
Talk(EMOTE_THEKAL_DIES);
|
||||
}
|
||||
|
||||
if (!Enraged && me->HealthBelowPctDamaged(20, damage) && me->GetEntry() != NPC_HIGH_PRIEST_THEKAL)
|
||||
{
|
||||
DoCastSelf(SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
if (action == ACTION_RESSURRECT)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->ResetFaction();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->SetFullHealth();
|
||||
WasDead = false;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (me->GetReactState() != REACT_PASSIVE && !UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MORTALCLEAVE:
|
||||
DoCastVictim(SPELL_MORTALCLEAVE, true);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SILENCE:
|
||||
DoCastVictim(SPELL_SILENCE, true);
|
||||
events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RESURRECT_TIMER:
|
||||
//Thekal will transform to Tiger if he died and was not resurrected after 10 seconds.
|
||||
if (WasDead)
|
||||
{
|
||||
DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM
|
||||
me->SetObjectScale(2.00f);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
/*
|
||||
const CreatureTemplate* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40)));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40)));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 40.0f, true); // hack
|
||||
DoResetThreat();
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2
|
||||
events.SetPhase(PHASE_TWO);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_CHECK_TIMER:
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!WasDead)
|
||||
{
|
||||
if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
|
||||
{
|
||||
//Resurrect LorKhan
|
||||
if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LORKHAN)))
|
||||
{
|
||||
pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pLorKhan->SetFaction(FACTION_MONSTER);
|
||||
pLorKhan->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pLorKhan->SetFullHealth();
|
||||
instance->SetData(DATA_LORKHAN, DONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_ZATH) == SPECIAL)
|
||||
{
|
||||
//Resurrect Zath
|
||||
if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ZATH)))
|
||||
{
|
||||
pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pZath->SetFaction(FACTION_MONSTER);
|
||||
pZath->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pZath->SetFullHealth();
|
||||
instance->SetBossState(DATA_ZATH, DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_FORCEPUNCH:
|
||||
DoCastVictim(SPELL_FORCEPUNCH, true);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_CHARGE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
DoResetThreat();
|
||||
AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
if (HealthBelowPct(11) && !Enraged)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 30000);
|
||||
break;
|
||||
case EVENT_SUMMONTIGERS:
|
||||
DoCastVictim(SPELL_SUMMONTIGERS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->IsFullHealth() && WasDead)
|
||||
WasDead = false;
|
||||
|
||||
if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->AttackStop();
|
||||
instance->SetBossState(DATA_THEKAL, SPECIAL);
|
||||
WasDead = true;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
_scheduler.Update(diff,
|
||||
std::bind(&BossAI::DoMeleeAttackIfReady, this));
|
||||
}
|
||||
|
||||
void ReviveZealot(uint32 zealotData)
|
||||
{
|
||||
if (Creature* zealot = instance->GetCreature(zealotData))
|
||||
{
|
||||
zealot->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
zealot->ResetFaction();
|
||||
zealot->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
zealot->SetReactState(REACT_AGGRESSIVE);
|
||||
zealot->SetFullHealth();
|
||||
UpdateZealotStatus(zealotData, false);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateZealotStatus(uint32 data, bool dead)
|
||||
{
|
||||
if (data == DATA_LORKHAN)
|
||||
{
|
||||
_lorkhanDied = dead;
|
||||
}
|
||||
else if (data == DATA_ZATH)
|
||||
{
|
||||
_zathDied = dead;
|
||||
}
|
||||
}
|
||||
|
||||
void CheckPhaseTransition()
|
||||
{
|
||||
if (WasDead && _lorkhanDied && _zathDied)
|
||||
{
|
||||
_scheduler.Schedule(3s, [this](TaskContext /*context*/) {
|
||||
Talk(SAY_AGGRO);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoResetThreat();
|
||||
|
||||
_scheduler.Schedule(6s, [this](TaskContext /*context*/) {
|
||||
DoCastSelf(SPELL_TIGER_FORM);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.Schedule(30s, [this](TaskContext context) {
|
||||
DoCastSelf(SPELL_FRENZY);
|
||||
context.Repeat();
|
||||
}).Schedule(4s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_FORCEPUNCH);
|
||||
context.Repeat(16s, 21s);
|
||||
}).Schedule(12s, [this](TaskContext context) {
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
DoResetThreat();
|
||||
AttackStart(target);
|
||||
}
|
||||
context.Repeat(15s, 22s);
|
||||
}).Schedule(25s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_SUMMONTIGERS, true);
|
||||
context.Repeat(10s, 14s);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
_scheduler.Schedule(10s, [this](TaskContext /*context*/) {
|
||||
DoAction(ACTION_RESSURRECT);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
GuidVector _catGuids;
|
||||
bool _lorkhanDied;
|
||||
bool _zathDied;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -254,7 +308,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//Zealot Lor'Khan
|
||||
class npc_zealot_lorkhan : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -267,138 +320,86 @@ public:
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 Shield_Timer;
|
||||
uint32 BloodLust_Timer;
|
||||
uint32 GreaterHeal_Timer;
|
||||
uint32 Disarm_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool FakeDeath;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Shield_Timer = 1000;
|
||||
BloodLust_Timer = 16000;
|
||||
GreaterHeal_Timer = 32000;
|
||||
Disarm_Timer = 6000;
|
||||
Check_Timer = 10000;
|
||||
|
||||
FakeDeath = false;
|
||||
|
||||
instance->SetBossState(DATA_LORKHAN, NOT_STARTED);
|
||||
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.CancelAll();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING) && !me->HasReactState(REACT_PASSIVE);
|
||||
});
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.Schedule(1s, [this](TaskContext context) {
|
||||
DoCastSelf(SPELL_SHIELD);
|
||||
context.Repeat(1min);
|
||||
}).Schedule(32s, [this](TaskContext context) {
|
||||
Unit* thekal = instance->GetCreature(DATA_THEKAL);
|
||||
Unit* zath = instance->GetCreature(DATA_ZATH);
|
||||
|
||||
if (!thekal || !zath)
|
||||
return;
|
||||
|
||||
if ((me->GetHealthPct() <= thekal->GetHealthPct()) || (me->GetHealthPct() <= zath->GetHealthPct()))
|
||||
{
|
||||
DoCastSelf(SPELL_GREATERHEAL);
|
||||
}
|
||||
else if (zath->GetHealthPct() <= thekal->GetHealthPct())
|
||||
{
|
||||
DoCast(zath, SPELL_GREATERHEAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
DoCast(thekal, SPELL_GREATERHEAL);
|
||||
}
|
||||
|
||||
context.Repeat(15s, 20s);
|
||||
}).Schedule(6s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
context.Repeat(15s, 25s);
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && me->HasReactState(REACT_AGGRESSIVE))
|
||||
{
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
me->AttackStop();
|
||||
|
||||
damage = 0;
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_LORKHAN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (me->GetReactState() != REACT_PASSIVE && !UpdateVictim())
|
||||
return;
|
||||
|
||||
//Shield_Timer
|
||||
if (Shield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SHIELD);
|
||||
Shield_Timer = 61000;
|
||||
}
|
||||
else Shield_Timer -= diff;
|
||||
|
||||
//BloodLust_Timer
|
||||
if (BloodLust_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BLOODLUST);
|
||||
BloodLust_Timer = 20000 + rand() % 8000;
|
||||
}
|
||||
else BloodLust_Timer -= diff;
|
||||
|
||||
//Casting Greaterheal to Thekal or Zath if they are in meele range.
|
||||
if (GreaterHeal_Timer <= diff)
|
||||
{
|
||||
Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_THEKAL));
|
||||
Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ZATH));
|
||||
|
||||
if (!pThekal || !pZath)
|
||||
return;
|
||||
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
if (me->IsWithinMeleeRange(pThekal))
|
||||
DoCast(pThekal, SPELL_GREATERHEAL);
|
||||
break;
|
||||
case 1:
|
||||
if (me->IsWithinMeleeRange(pZath))
|
||||
DoCast(pZath, SPELL_GREATERHEAL);
|
||||
break;
|
||||
}
|
||||
|
||||
GreaterHeal_Timer = 15000 + rand() % 5000;
|
||||
}
|
||||
else GreaterHeal_Timer -= diff;
|
||||
|
||||
//Disarm_Timer
|
||||
if (Disarm_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
Disarm_Timer = 15000 + rand() % 10000;
|
||||
}
|
||||
else Disarm_Timer -= diff;
|
||||
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!FakeDeath && Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
|
||||
{
|
||||
//Resurrect Thekal
|
||||
if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_THEKAL)))
|
||||
{
|
||||
pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pThekal->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pThekal->SetFaction(FACTION_MONSTER);
|
||||
pThekal->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_ZATH) == SPECIAL)
|
||||
{
|
||||
//Resurrect Zath
|
||||
if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_ZATH)))
|
||||
{
|
||||
pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pZath->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pZath->SetFaction(FACTION_MONSTER);
|
||||
pZath->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
Check_Timer = 5000;
|
||||
}
|
||||
else Check_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
me->AttackStop();
|
||||
|
||||
instance->SetBossState(DATA_LORKHAN, SPECIAL);
|
||||
|
||||
FakeDeath = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
_scheduler.Update(diff,
|
||||
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -407,14 +408,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
//Zealot Zath
|
||||
class npc_zealot_zath : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_zealot_zath()
|
||||
: CreatureScript("npc_zealot_zath")
|
||||
{
|
||||
}
|
||||
npc_zealot_zath() : CreatureScript("npc_zealot_zath") { }
|
||||
|
||||
struct npc_zealot_zathAI : public ScriptedAI
|
||||
{
|
||||
@@ -423,135 +420,82 @@ public:
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 SweepingStrikes_Timer;
|
||||
uint32 SinisterStrike_Timer;
|
||||
uint32 Gouge_Timer;
|
||||
uint32 Kick_Timer;
|
||||
uint32 Blind_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool FakeDeath;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
SweepingStrikes_Timer = 13000;
|
||||
SinisterStrike_Timer = 8000;
|
||||
Gouge_Timer = 25000;
|
||||
Kick_Timer = 18000;
|
||||
Blind_Timer = 5000;
|
||||
Check_Timer = 10000;
|
||||
|
||||
FakeDeath = false;
|
||||
|
||||
instance->SetBossState(DATA_ZATH, NOT_STARTED);
|
||||
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
|
||||
_scheduler.CancelAll();
|
||||
|
||||
_scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING) && !me->HasReactState(REACT_PASSIVE);
|
||||
});
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) override
|
||||
{
|
||||
_scheduler.Schedule(13s, [this](TaskContext context) {
|
||||
DoCastSelf(SPELL_SWEEPINGSTRIKES);
|
||||
context.Repeat(1min);
|
||||
}).Schedule(16s, [this](TaskContext context) {
|
||||
DoCastSelf(SPELL_BLOODLUST);
|
||||
context.Repeat(22s, 26s);
|
||||
}).Schedule(8s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_SINISTERSTRIKE);
|
||||
context.Repeat(8s, 16s);
|
||||
}).Schedule(25s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_GOUGE);
|
||||
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
{
|
||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
||||
}
|
||||
|
||||
context.Repeat(17s, 27s);
|
||||
}).Schedule(18s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_KICK);
|
||||
context.Repeat(15s, 25s);
|
||||
}).Schedule(5s, [this](TaskContext context) {
|
||||
DoCastVictim(SPELL_BLIND);
|
||||
context.Repeat(10s, 20s);
|
||||
});
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& damage, DamageEffectType, SpellSchoolMask) override
|
||||
{
|
||||
if (damage >= me->GetHealth() && me->HasReactState(REACT_AGGRESSIVE))
|
||||
{
|
||||
Talk(EMOTE_ZEALOT_DIES);
|
||||
me->RemoveAllAuras();
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->AttackStop();
|
||||
|
||||
damage = 0;
|
||||
|
||||
if (Creature* thekal = instance->GetCreature(DATA_THEKAL))
|
||||
{
|
||||
thekal->AI()->SetData(ACTION_RESSURRECT, DATA_ZATH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
if (me->GetReactState() != REACT_PASSIVE && !UpdateVictim())
|
||||
return;
|
||||
|
||||
//SweepingStrikes_Timer
|
||||
if (SweepingStrikes_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SWEEPINGSTRIKES);
|
||||
SweepingStrikes_Timer = 22000 + rand() % 4000;
|
||||
}
|
||||
else SweepingStrikes_Timer -= diff;
|
||||
|
||||
//SinisterStrike_Timer
|
||||
if (SinisterStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SINISTERSTRIKE);
|
||||
SinisterStrike_Timer = 8000 + rand() % 8000;
|
||||
}
|
||||
else SinisterStrike_Timer -= diff;
|
||||
|
||||
//Gouge_Timer
|
||||
if (Gouge_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_GOUGE);
|
||||
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
||||
|
||||
Gouge_Timer = 17000 + rand() % 10000;
|
||||
}
|
||||
else Gouge_Timer -= diff;
|
||||
|
||||
//Kick_Timer
|
||||
if (Kick_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_KICK);
|
||||
Kick_Timer = 15000 + rand() % 10000;
|
||||
}
|
||||
else Kick_Timer -= diff;
|
||||
|
||||
//Blind_Timer
|
||||
if (Blind_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_BLIND);
|
||||
Blind_Timer = 10000 + rand() % 10000;
|
||||
}
|
||||
else Blind_Timer -= diff;
|
||||
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!FakeDeath && Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
|
||||
{
|
||||
//Resurrect LorKhan
|
||||
if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_LORKHAN)))
|
||||
{
|
||||
pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pLorKhan->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pLorKhan->SetFaction(FACTION_MONSTER);
|
||||
pLorKhan->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
|
||||
{
|
||||
//Resurrect Thekal
|
||||
if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_THEKAL)))
|
||||
{
|
||||
pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pThekal->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
pThekal->SetFaction(FACTION_MONSTER);
|
||||
pThekal->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
Check_Timer = 5000;
|
||||
}
|
||||
else Check_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
me->AttackStop();
|
||||
|
||||
instance->SetBossState(DATA_ZATH, SPECIAL);
|
||||
|
||||
FakeDeath = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
_scheduler.Update(diff,
|
||||
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -29,7 +29,14 @@ EndScriptData */
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM },
|
||||
{ 0, 0, DOOR_TYPE_ROOM } // END
|
||||
{ 0, 0, DOOR_TYPE_ROOM }
|
||||
};
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_HIGH_PRIEST_THEKAL, DATA_THEKAL },
|
||||
{ NPC_ZEALOT_LORKHAN, DATA_LORKHAN },
|
||||
{ NPC_ZEALOT_ZATH, DATA_ZATH }
|
||||
};
|
||||
|
||||
class instance_zulgurub : public InstanceMapScript
|
||||
@@ -43,21 +50,15 @@ public:
|
||||
{
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ZEALOT_LORKHAN:
|
||||
_zealotLorkhanGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ZEALOT_ZATH:
|
||||
_zealotZathGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HIGH_PRIEST_THEKAL:
|
||||
_highPriestTekalGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_JINDO_THE_HEXXER:
|
||||
_jindoTheHexxerGUID = creature->GetGUID();
|
||||
break;
|
||||
@@ -75,11 +76,10 @@ public:
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
InstanceScript::OnGameObjectCreate(go);
|
||||
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FORCEFIELD:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
case GO_GONG_OF_BETHEKK:
|
||||
_goGongOfBethekkGUID = go->GetGUID();
|
||||
if (GetBossState(DATA_ARLOKK) == DONE)
|
||||
@@ -92,28 +92,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FORCEFIELD:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGuid GetGuidData(uint32 uiData) const override
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case DATA_LORKHAN:
|
||||
return _zealotLorkhanGUID;
|
||||
case DATA_ZATH:
|
||||
return _zealotZathGUID;
|
||||
case DATA_THEKAL:
|
||||
return _highPriestTekalGUID;
|
||||
case DATA_JINDO:
|
||||
return _jindoTheHexxerGUID;
|
||||
case NPC_ARLOKK:
|
||||
@@ -170,12 +152,9 @@ public:
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
private:
|
||||
//If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too.
|
||||
//Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too.
|
||||
// If all High Priest bosses were killed. Ohgan is added too.
|
||||
// Jindo is needed for healfunction.
|
||||
|
||||
ObjectGuid _zealotLorkhanGUID;
|
||||
ObjectGuid _zealotZathGUID;
|
||||
ObjectGuid _highPriestTekalGUID;
|
||||
ObjectGuid _jindoTheHexxerGUID;
|
||||
ObjectGuid _vilebranchSpeakerGUID;
|
||||
ObjectGuid _arlokkGUID;
|
||||
|
||||
@@ -58,7 +58,8 @@ enum CreatureIds
|
||||
NPC_OHGAN = 14988, // Mandokir Event
|
||||
NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event
|
||||
NPC_CHAINED_SPIRT = 15117, // Mandokir Event
|
||||
NPC_HAKKAR = 14834
|
||||
NPC_HAKKAR = 14834,
|
||||
NPC_ZULGURUB_TIGER = 11361
|
||||
};
|
||||
|
||||
enum GameobjectIds
|
||||
|
||||
@@ -1045,9 +1045,9 @@ public:
|
||||
if (reportUse)
|
||||
{
|
||||
uint32 gossipId = me->GetGOInfo()->GetGossipMenuId();
|
||||
bool _twilightSetAura = (player->HasAura(AURA_TWILIGHT_SET, player->GetGUID()) ? true : false);
|
||||
bool _medallionAura = (player->HasAura(AURA_MEDALLION, player->GetGUID()) ? true : false);
|
||||
bool _ringAura = (player->HasAura(AURA_RING, player->GetGUID()) ? true : false);
|
||||
bool _twilightSetAura = (player->HasAura(AURA_TWILIGHT_SET, player->GetGUID()));
|
||||
bool _medallionAura = (player->HasAura(AURA_MEDALLION, player->GetGUID()));
|
||||
bool _ringAura = (player->HasAura(AURA_RING, player->GetGUID()));
|
||||
|
||||
switch (gossipId)
|
||||
{
|
||||
|
||||
@@ -34,157 +34,155 @@
|
||||
enum LeviathanSpells
|
||||
{
|
||||
// Leviathan basic
|
||||
SPELL_PURSUED = 62374,
|
||||
SPELL_GATHERING_SPEED = 62375,
|
||||
SPELL_BATTERING_RAM = 62376,
|
||||
SPELL_FLAME_VENTS = 62396,
|
||||
SPELL_MISSILE_BARRAGE = 62400,
|
||||
SPELL_NAPALM_10 = 63666,
|
||||
SPELL_NAPALM_25 = 65026,
|
||||
SPELL_INVIS_AND_STEALTH_DETECT = 18950,
|
||||
SPELL_TRANSITUS_SHIELD_IMPACT = 48387,
|
||||
SPELL_PURSUED = 62374,
|
||||
SPELL_GATHERING_SPEED = 62375,
|
||||
SPELL_BATTERING_RAM = 62376,
|
||||
SPELL_FLAME_VENTS = 62396,
|
||||
SPELL_MISSILE_BARRAGE = 62400,
|
||||
SPELL_NAPALM_10 = 63666,
|
||||
SPELL_NAPALM_25 = 65026,
|
||||
SPELL_INVIS_AND_STEALTH_DETECT = 18950,
|
||||
SPELL_TRANSITUS_SHIELD_IMPACT = 48387,
|
||||
|
||||
// Shutdown spells
|
||||
SPELL_SYSTEMS_SHUTDOWN = 62475,
|
||||
SPELL_OVERLOAD_CIRCUIT = 62399,
|
||||
SPELL_SYSTEMS_SHUTDOWN = 62475,
|
||||
SPELL_OVERLOAD_CIRCUIT = 62399,
|
||||
|
||||
// hard mode
|
||||
SPELL_TOWER_OF_STORMS = 65076,
|
||||
SPELL_TOWER_OF_FLAMES = 65075,
|
||||
SPELL_TOWER_OF_FROST = 65077,
|
||||
SPELL_TOWER_OF_LIFE = 64482,
|
||||
SPELL_TOWER_OF_STORMS = 65076,
|
||||
SPELL_TOWER_OF_FLAMES = 65075,
|
||||
SPELL_TOWER_OF_FROST = 65077,
|
||||
SPELL_TOWER_OF_LIFE = 64482,
|
||||
|
||||
SPELL_HODIRS_FURY = 62533,
|
||||
SPELL_FREYA_WARD = 62906, // removed spawn effect
|
||||
SPELL_MIMIRONS_INFERNO = 62909,
|
||||
SPELL_THORIMS_HAMMER = 62911,
|
||||
SPELL_HODIRS_FURY = 62533,
|
||||
SPELL_FREYA_WARD = 62906, // removed spawn effect
|
||||
SPELL_MIMIRONS_INFERNO = 62909,
|
||||
SPELL_THORIMS_HAMMER = 62911,
|
||||
|
||||
SPELL_FREYA_DUMMY_BLUE = 63294,
|
||||
SPELL_FREYA_DUMMY_GREEN = 63295,
|
||||
SPELL_FREYA_DUMMY_YELLOW = 63292,
|
||||
SPELL_FREYA_DUMMY_BLUE = 63294,
|
||||
SPELL_FREYA_DUMMY_GREEN = 63295,
|
||||
SPELL_FREYA_DUMMY_YELLOW = 63292,
|
||||
|
||||
// Leviathan turret spell
|
||||
SPELL_SEARING_FLAME = 62402,
|
||||
SPELL_SEARING_FLAME = 62402,
|
||||
// On turret Destory
|
||||
SPELL_SMOKE_TRAIL = 63575,
|
||||
SPELL_SMOKE_TRAIL = 63575,
|
||||
|
||||
// Pool of tar blaze
|
||||
SPELL_BLAZE = 62292,
|
||||
SPELL_BLAZE = 62292,
|
||||
|
||||
// Pyrite
|
||||
SPELL_LIQUID_PYRITE = 62494,
|
||||
SPELL_DUSTY_EXPLOSION = 63360,
|
||||
SPELL_DUST_CLOUD_IMPACT = 54740,
|
||||
SPELL_LIQUID_PYRITE = 62494,
|
||||
SPELL_DUSTY_EXPLOSION = 63360,
|
||||
SPELL_DUST_CLOUD_IMPACT = 54740,
|
||||
};
|
||||
|
||||
enum GosNpcs
|
||||
{
|
||||
NPC_FLAME_LEVIATHAN_TURRET = 33139,
|
||||
NPC_SEAT = 33114,
|
||||
NPC_MECHANOLIFT = 33214,
|
||||
NPC_LIQUID = 33189,
|
||||
NPC_FLAME_LEVIATHAN_TURRET = 33139,
|
||||
NPC_SEAT = 33114,
|
||||
NPC_MECHANOLIFT = 33214,
|
||||
NPC_LIQUID = 33189,
|
||||
|
||||
// Starting event
|
||||
NPC_ULDUAR_COLOSSUS = 33237,
|
||||
NPC_BRANN_RADIO = 34054,
|
||||
NPC_ULDUAR_GAUNTLET_GENERATOR = 33571,
|
||||
NPC_DEFENDER_GENERATED = 33572,
|
||||
NPC_ULDUAR_COLOSSUS = 33237,
|
||||
NPC_BRANN_RADIO = 34054,
|
||||
NPC_ULDUAR_GAUNTLET_GENERATOR = 33571,
|
||||
NPC_DEFENDER_GENERATED = 33572,
|
||||
|
||||
// Hard Mode
|
||||
NPC_THORIM_HAMMER_TARGET = 33364,
|
||||
NPC_THORIM_HAMMER = 33365,
|
||||
NPC_FREYA_WARD_TARGET = 33366,
|
||||
NPC_FREYA_WARD = 33367,
|
||||
NPC_MIMIRONS_INFERNO_TARGET = 33369,
|
||||
NPC_MIMIRONS_INFERNO = 33370,
|
||||
NPC_HODIRS_FURY_TARGET = 33108,
|
||||
NPC_HODIRS_FURY = 33212,
|
||||
NPC_THORIM_HAMMER_TARGET = 33364,
|
||||
NPC_THORIM_HAMMER = 33365,
|
||||
NPC_FREYA_WARD_TARGET = 33366,
|
||||
NPC_FREYA_WARD = 33367,
|
||||
NPC_MIMIRONS_INFERNO_TARGET = 33369,
|
||||
NPC_MIMIRONS_INFERNO = 33370,
|
||||
NPC_HODIRS_FURY_TARGET = 33108,
|
||||
NPC_HODIRS_FURY = 33212,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_PURSUE = 1,
|
||||
EVENT_MISSILE,
|
||||
EVENT_VENT,
|
||||
EVENT_SPEED,
|
||||
EVENT_SUMMON,
|
||||
EVENT_REINSTALL,
|
||||
EVENT_HODIRS_FURY,
|
||||
EVENT_FREYA,
|
||||
EVENT_MIMIRONS_INFERNO,
|
||||
EVENT_THORIMS_HAMMER,
|
||||
EVENT_SOUND_BEGINNING,
|
||||
EVENT_POSITION_CHECK,
|
||||
EVENT_PURSUE = 1,
|
||||
EVENT_MISSILE = 2,
|
||||
EVENT_VENT = 3,
|
||||
EVENT_SPEED = 4,
|
||||
EVENT_SUMMON = 5,
|
||||
EVENT_REINSTALL = 6,
|
||||
EVENT_HODIRS_FURY = 7,
|
||||
EVENT_FREYA = 8,
|
||||
EVENT_MIMIRONS_INFERNO = 9,
|
||||
EVENT_THORIMS_HAMMER = 10,
|
||||
EVENT_SOUND_BEGINNING = 11,
|
||||
EVENT_POSITION_CHECK = 12,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
FLAME_LEVIATHAN_SAY_AGGRO = 0,
|
||||
FLAME_LEVIATHAN_SAY_SLAY,
|
||||
FLAME_LEVIATHAN_SAY_DEATH,
|
||||
FLAME_LEVIATHAN_SAY_PURSUE,
|
||||
FLAME_LEVIATHAN_SAY_HARDMODE,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_NONE,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_FROST,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_FLAME,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_NATURE,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_STORM,
|
||||
FLAME_LEVIATHAN_SAY_PLAYER_RIDING,
|
||||
FLAME_LEVIATHAN_SAY_OVERLOAD,
|
||||
FLAME_LEVIATHAN_EMOTE_PURSUE,
|
||||
FLAME_LEVIATHAN_EMOTE_OVERLOAD,
|
||||
FLAME_LEVIATHAN_EMOTE_REPAIR
|
||||
};
|
||||
FLAME_LEVIATHAN_SAY_AGGRO = 0,
|
||||
FLAME_LEVIATHAN_SAY_SLAY = 1,
|
||||
FLAME_LEVIATHAN_SAY_DEATH = 2,
|
||||
FLAME_LEVIATHAN_SAY_PURSUE = 3,
|
||||
FLAME_LEVIATHAN_SAY_HARDMODE = 4,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_NONE = 5,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_FROST = 6,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_FLAME = 7,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_NATURE = 8,
|
||||
FLAME_LEVIATHAN_SAY_TOWER_STORM = 9,
|
||||
FLAME_LEVIATHAN_SAY_PLAYER_RIDING = 10,
|
||||
FLAME_LEVIATHAN_SAY_OVERLOAD = 11,
|
||||
FLAME_LEVIATHAN_EMOTE_PURSUE = 12,
|
||||
FLAME_LEVIATHAN_EMOTE_OVERLOAD = 13,
|
||||
FLAME_LEVIATHAN_EMOTE_REPAIR = 14,
|
||||
FLAME_LEVIATHAN_EMOTE_FROST = 15,
|
||||
FLAME_LEVIATHAN_EMOTE_FLAME = 16,
|
||||
FLAME_LEVIATHAN_EMOTE_NATURE = 17,
|
||||
FLAME_LEVIATHAN_EMOTE_STORM = 18,
|
||||
FLAME_LEVIATHAN_EMOTE_REACTIVATE = 19,
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
RSOUND_L0 = 15807,
|
||||
RSOUND_L1 = 15804,
|
||||
RSOUND_L2 = 15805,
|
||||
RSOUND_L3 = 15806,
|
||||
RSOUND_ENGAGE = 15794,
|
||||
RSOUND_SILOS = 15795,
|
||||
RSOUND_GENERATORS = 15796,
|
||||
RSOUND_HODIR = 15797,
|
||||
RSOUND_FREYA = 15798,
|
||||
RSOUND_MIMIRON = 15799,
|
||||
RSOUND_THORIM = 15801,
|
||||
RSOUND_STATION = 15803,
|
||||
// NPC_BRANN_RADIO
|
||||
BRANN_RADIO_SAY_FL_START_0 = 0,
|
||||
BRANN_RADIO_SAY_FL_START_1 = 1,
|
||||
BRANN_RADIO_SAY_FL_START_2 = 2,
|
||||
BRANN_RADIO_SAY_GENERATORS = 3,
|
||||
BRANN_RADIO_SAY_STATIONS = 4,
|
||||
BRANN_RADIO_SAY_TOWER_THORIM = 5,
|
||||
BRANN_RADIO_SAY_TOWER_HODIR = 6,
|
||||
BRANN_RADIO_SAY_TOWER_FREYA = 7,
|
||||
BRANN_RADIO_SAY_TOWER_MIMIRON = 8,
|
||||
|
||||
// Vehicle Repair - Said by a spell, BroadcastTextID, same as FLAME_LEVIATHAN_EMOTE_REPAIR
|
||||
VEHICLE_EMOTE_REPAIR = 33538,
|
||||
};
|
||||
|
||||
enum Seats
|
||||
{
|
||||
SEAT_PLAYER = 0,
|
||||
SEAT_TURRET = 1,
|
||||
SEAT_DEVICE = 2,
|
||||
SEAT_CANNON = 7,
|
||||
SEAT_PLAYER = 0,
|
||||
SEAT_TURRET = 1,
|
||||
SEAT_DEVICE = 2,
|
||||
SEAT_CANNON = 7,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
DATA_EVENT_STARTED = 1,
|
||||
DATA_GET_TOWER_COUNT = 2,
|
||||
DATA_GET_SHUTDOWN = 3,
|
||||
DATA_EVENT_STARTED = 1,
|
||||
DATA_GET_TOWER_COUNT = 2,
|
||||
DATA_GET_SHUTDOWN = 3,
|
||||
|
||||
TOWER_OF_STORMS = 2,
|
||||
TOWER_OF_FLAMES = 1,
|
||||
TOWER_OF_FROST = 3,
|
||||
TOWER_OF_LIFE = 0,
|
||||
TOWER_OF_STORMS = 2,
|
||||
TOWER_OF_FLAMES = 1,
|
||||
TOWER_OF_FROST = 3,
|
||||
TOWER_OF_LIFE = 0,
|
||||
|
||||
ACTION_START_NORGANNON_EVENT = 1,
|
||||
ACTION_START_NORGANNON_BRANN = 2,
|
||||
ACTION_START_BRANN_EVENT = 3,
|
||||
ACTION_DESPAWN_ADDS = 4,
|
||||
ACTION_DELAY_CANNON = 5,
|
||||
ACTION_DESTROYED_TURRET = 6,
|
||||
ACTION_START_NORGANNON_EVENT = 1,
|
||||
ACTION_START_NORGANNON_BRANN = 2,
|
||||
ACTION_START_BRANN_EVENT = 3,
|
||||
ACTION_DESPAWN_ADDS = 4,
|
||||
ACTION_DELAY_CANNON = 5,
|
||||
ACTION_DESTROYED_TURRET = 6,
|
||||
};
|
||||
const Position homePos = {322.39f, -14.5f, 409.8f, 3.14f};
|
||||
|
||||
///////////////////////////////////////////
|
||||
//
|
||||
// BOSS CODE
|
||||
//
|
||||
///////////////////////////////////////////
|
||||
const Position homePos = {322.39f, -14.5f, 409.8f, 3.14f};
|
||||
|
||||
class boss_flame_leviathan : public CreatureScript
|
||||
{
|
||||
@@ -217,7 +215,7 @@ public:
|
||||
|
||||
// Custom
|
||||
void BindPlayers();
|
||||
void RadioSay(const char* text, uint32 soundId);
|
||||
void RadioSay(uint8 textid);
|
||||
void ActivateTowers();
|
||||
void TurnGates(bool _start, bool _death);
|
||||
void TurnHealStations(bool _apply);
|
||||
@@ -357,18 +355,18 @@ public:
|
||||
_speakTimer += diff;
|
||||
if (_speakTimer <= 10000)
|
||||
{
|
||||
RadioSay("You've done it! You've broken the defenses of Ulduar. In a few moments, we will be dropping in to...", RSOUND_L1);
|
||||
_speakTimer = 10000;
|
||||
RadioSay(BRANN_RADIO_SAY_FL_START_0);
|
||||
}
|
||||
else if (_speakTimer > 16000 && _speakTimer < 20000)
|
||||
{
|
||||
_speakTimer = 20000;
|
||||
RadioSay("What is that? Be careful! Something's headed your way!", RSOUND_L2);
|
||||
RadioSay(BRANN_RADIO_SAY_FL_START_1);
|
||||
}
|
||||
else if (_speakTimer > 24000 && _speakTimer < 40000)
|
||||
{
|
||||
_speakTimer = 40000;
|
||||
RadioSay("Quicly! Evasive action! Evasive act--", RSOUND_L3);
|
||||
RadioSay(BRANN_RADIO_SAY_FL_START_2);
|
||||
}
|
||||
else if (_speakTimer > 41000 && _speakTimer < 60000)
|
||||
{
|
||||
@@ -443,27 +441,27 @@ public:
|
||||
if (Unit* seat = vehicle->GetPassenger(i))
|
||||
if (seat->GetTypeId() == TYPEID_UNIT)
|
||||
seat->ToCreature()->AI()->EnterEvadeMode();
|
||||
me->TextEmote("Flame Leviathan reactivated. Resumming combat functions.", nullptr, true);
|
||||
Talk(FLAME_LEVIATHAN_EMOTE_REACTIVATE);
|
||||
return;
|
||||
case EVENT_THORIMS_HAMMER:
|
||||
SummonTowerHelpers(TOWER_OF_STORMS);
|
||||
events.RepeatEvent(60000 + rand() % 60000);
|
||||
me->TextEmote("Flame Leviathan activates Thorim's Hammer.", nullptr, true);
|
||||
Talk(FLAME_LEVIATHAN_EMOTE_STORM);
|
||||
Talk(FLAME_LEVIATHAN_SAY_TOWER_STORM);
|
||||
return;
|
||||
case EVENT_FREYA:
|
||||
SummonTowerHelpers(TOWER_OF_LIFE);
|
||||
me->TextEmote("Flame Leviathan activates Freya's Ward.", nullptr, true);
|
||||
Talk(FLAME_LEVIATHAN_EMOTE_NATURE);
|
||||
Talk(FLAME_LEVIATHAN_SAY_TOWER_NATURE);
|
||||
return;
|
||||
case EVENT_MIMIRONS_INFERNO:
|
||||
SummonTowerHelpers(TOWER_OF_FLAMES);
|
||||
me->TextEmote("Flame Leviathan activates Mimiron's Inferno.", nullptr, true);
|
||||
Talk(FLAME_LEVIATHAN_EMOTE_FLAME);
|
||||
Talk(FLAME_LEVIATHAN_SAY_TOWER_FLAME);
|
||||
return;
|
||||
case EVENT_HODIRS_FURY:
|
||||
SummonTowerHelpers(TOWER_OF_FROST);
|
||||
me->TextEmote("Flame Leviathan activates Hodir's Fury.", nullptr, true);
|
||||
Talk(FLAME_LEVIATHAN_EMOTE_FROST);
|
||||
Talk(FLAME_LEVIATHAN_SAY_TOWER_FROST);
|
||||
return;
|
||||
}
|
||||
@@ -499,14 +497,11 @@ void boss_flame_leviathan::boss_flame_leviathanAI::BindPlayers()
|
||||
me->GetMap()->ToInstanceMap()->PermBindAllPlayers();
|
||||
}
|
||||
|
||||
void boss_flame_leviathan::boss_flame_leviathanAI::RadioSay(const char* text, uint32 soundId)
|
||||
void boss_flame_leviathan::boss_flame_leviathanAI::RadioSay(uint8 textid)
|
||||
{
|
||||
if (Creature* r = me->SummonCreature(NPC_BRANN_RADIO, me->GetPositionX() - 150, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 5000))
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, r, nullptr, text);
|
||||
r->SendMessageToSetInRange(&data, 200, true);
|
||||
r->PlayDirectSound(soundId);
|
||||
r->AI()->Talk(textid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,13 +1218,6 @@ public:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void Say(const char* text)
|
||||
{
|
||||
WorldPacket data;
|
||||
ChatHandler::BuildChatPacket(data, CHAT_MSG_MONSTER_SAY, LANG_UNIVERSAL, me, nullptr, text);
|
||||
me->SendMessageToSetInRange(&data, 100.0f, true);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!_lock)
|
||||
@@ -1242,8 +1230,7 @@ public:
|
||||
{
|
||||
if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() > 430.0f)
|
||||
{
|
||||
Say("This generator powers Mimiron's Gaze. In moments, it can turn earth to ash, stone to magma--we cannot let it reach full power!");
|
||||
me->PlayDirectSound(RSOUND_MIMIRON);
|
||||
Talk(BRANN_RADIO_SAY_TOWER_MIMIRON);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1252,8 +1239,7 @@ public:
|
||||
{
|
||||
if (me->GetDistance2d(who) <= 60.0f && who->GetPositionZ() < 380.0f)
|
||||
{
|
||||
Say("You're approaching the tower of Freya. It contains the power to turn barren wastelands into jungles teeming with life overnight");
|
||||
me->PlayDirectSound(RSOUND_FREYA);
|
||||
Talk(BRANN_RADIO_SAY_TOWER_FREYA);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1262,8 +1248,7 @@ public:
|
||||
{
|
||||
if (me->GetDistance2d(who) <= 40.0f)
|
||||
{
|
||||
Say("It appears you are near a repair station. Drive your vehicle on to the platform and it should be automatically repaired.");
|
||||
me->PlayDirectSound(RSOUND_STATION);
|
||||
Talk(BRANN_RADIO_SAY_STATIONS);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1272,8 +1257,7 @@ public:
|
||||
{
|
||||
if (me->GetDistance2d(who) <= 40.0f)
|
||||
{
|
||||
Say("This tower powers the hammer of Hodir. It is said to have the power to turn entire armies to ice!");
|
||||
me->PlayDirectSound(RSOUND_HODIR);
|
||||
Talk(BRANN_RADIO_SAY_TOWER_HODIR);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1282,8 +1266,7 @@ public:
|
||||
{
|
||||
if (me->GetDistance2d(who) <= 60.0f)
|
||||
{
|
||||
Say("Aaaah, the tower of Krolmir. It is said that the power of Thorim has been used only once. And that it turned an entire continent to dust...");
|
||||
me->PlayDirectSound(RSOUND_THORIM);
|
||||
Talk(BRANN_RADIO_SAY_TOWER_THORIM);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1292,8 +1275,7 @@ public:
|
||||
{
|
||||
if (who->GetPositionX() >= -480.0f)
|
||||
{
|
||||
Say("There are four generators powering the defense structures. If you sabotage the generators, the missile attacks will stop!");
|
||||
me->PlayDirectSound(RSOUND_GENERATORS);
|
||||
Talk(BRANN_RADIO_SAY_GENERATORS);
|
||||
_lock = true;
|
||||
}
|
||||
}
|
||||
@@ -1533,7 +1515,7 @@ public:
|
||||
if (!driver)
|
||||
return;
|
||||
|
||||
driver->TextEmote("Automatic repair sequence initiated.", driver, true);
|
||||
//driver->TextEmote(VEHICLE_EMOTE_REPAIR, driver, true); // No source
|
||||
|
||||
// Actually should/could use basepoints (100) for this spell effect as percentage of health, but oh well.
|
||||
vehicle->GetBase()->SetFullHealth();
|
||||
|
||||
@@ -25,6 +25,31 @@
|
||||
#include "SpellScript.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
// Freya
|
||||
GOSSIP_MENU_FREYA = 10324,
|
||||
NPC_TEXT_FREYA = 14332,
|
||||
|
||||
// Hodir
|
||||
GOSSIP_MENU_HODIR = 10335,
|
||||
NPC_TEXT_HODIR = 14326,
|
||||
|
||||
// Mimiron
|
||||
GOSSIP_MENU_MIMIRON = 10336,
|
||||
NPC_TEXT_MIMIRON = 14334,
|
||||
|
||||
// Thorim
|
||||
GOSSIP_MENU_THORIM = 10337,
|
||||
NPC_TEXT_THORIM = 14333,
|
||||
|
||||
// Confirm assistance
|
||||
GOSSIP_MENU_CONFIRM = 10333,
|
||||
NPC_TEXT_CONFIRM = 14325,
|
||||
|
||||
SAY_KEEPER_SELECTED = 1,
|
||||
};
|
||||
|
||||
class npc_ulduar_keeper : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -32,45 +57,75 @@ public:
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature) override
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Lend us your aid, keeper. Together we shall defeat Yogg-Saron.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* /*player*/, Creature* creature, uint32 /*uiSender*/, uint32 /*uiAction*/) override
|
||||
{
|
||||
creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
|
||||
uint8 _keeper = 0;
|
||||
uint32 gossipMenuId = 0;
|
||||
uint32 gossipTextId = 0;
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_FREYA_GOSSIP:
|
||||
creature->Yell("Eonar, your servant calls for your blessing!", LANG_UNIVERSAL);
|
||||
creature->PlayDirectSound(15535);
|
||||
_keeper = KEEPER_FREYA;
|
||||
gossipMenuId = GOSSIP_MENU_FREYA;
|
||||
gossipTextId = NPC_TEXT_FREYA;
|
||||
break;
|
||||
case NPC_HODIR_GOSSIP:
|
||||
creature->Yell("The veil of winter will protect you, champions!", LANG_UNIVERSAL);
|
||||
creature->PlayDirectSound(15559);
|
||||
_keeper = KEEPER_HODIR;
|
||||
gossipMenuId = GOSSIP_MENU_HODIR;
|
||||
gossipTextId = NPC_TEXT_HODIR;
|
||||
break;
|
||||
case NPC_MIMIRON_GOSSIP:
|
||||
creature->Yell("Combat matrix enhanced. Behold wonderous rapidity!", LANG_UNIVERSAL);
|
||||
creature->PlayDirectSound(15630);
|
||||
_keeper = KEEPER_MIMIRON;
|
||||
gossipMenuId = GOSSIP_MENU_MIMIRON;
|
||||
gossipTextId = NPC_TEXT_MIMIRON;
|
||||
break;
|
||||
case NPC_THORIM_GOSSIP:
|
||||
creature->Yell("Golganneth, lend me your strengh! Grant my mortal allies the power of thunder!", LANG_UNIVERSAL);
|
||||
creature->PlayDirectSound(15750);
|
||||
_keeper = KEEPER_THORIM;
|
||||
gossipMenuId = GOSSIP_MENU_THORIM;
|
||||
gossipTextId = NPC_TEXT_THORIM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (creature->GetInstanceScript())
|
||||
{
|
||||
creature->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper);
|
||||
creature->DespawnOrUnsummon(6000);
|
||||
}
|
||||
AddGossipItemFor(player, gossipMenuId, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, gossipTextId, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
|
||||
{
|
||||
ClearGossipMenuFor(player);
|
||||
uint8 _keeper = 0;
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF+1:
|
||||
AddGossipItemFor(player, GOSSIP_MENU_CONFIRM, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, NPC_TEXT_CONFIRM, creature);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF+2:
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_FREYA_GOSSIP:
|
||||
creature->AI()->Talk(SAY_KEEPER_SELECTED);
|
||||
_keeper = KEEPER_FREYA;
|
||||
break;
|
||||
case NPC_HODIR_GOSSIP:
|
||||
creature->AI()->Talk(SAY_KEEPER_SELECTED);
|
||||
_keeper = KEEPER_HODIR;
|
||||
break;
|
||||
case NPC_MIMIRON_GOSSIP:
|
||||
creature->AI()->Talk(SAY_KEEPER_SELECTED);
|
||||
_keeper = KEEPER_MIMIRON;
|
||||
break;
|
||||
case NPC_THORIM_GOSSIP:
|
||||
creature->AI()->Talk(SAY_KEEPER_SELECTED);
|
||||
_keeper = KEEPER_THORIM;
|
||||
break;
|
||||
}
|
||||
|
||||
creature->ReplaceAllNpcFlags(UNIT_NPC_FLAG_NONE);
|
||||
CloseGossipMenuFor(player);
|
||||
|
||||
if (creature->GetInstanceScript())
|
||||
{
|
||||
creature->GetInstanceScript()->SetData(TYPE_WATCHERS, _keeper);
|
||||
creature->DespawnOrUnsummon(6000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -127,8 +127,13 @@ public:
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, me);
|
||||
if (killer)
|
||||
{
|
||||
if (Player* player = killer->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
{
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, me);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -294,28 +294,52 @@ public:
|
||||
|
||||
enum hourglass
|
||||
{
|
||||
NPC_FUTURE_HOURGLASS = 27840,
|
||||
NPC_FUTURE_YOU = 27899,
|
||||
NPC_FUTURE_HOURGLASS = 27840,
|
||||
NPC_FUTURE_YOU = 27899,
|
||||
|
||||
NPC_PAST_HOURGLASS = 32327,
|
||||
NPC_PAST_YOU = 32331,
|
||||
NPC_PAST_HOURGLASS = 32327,
|
||||
NPC_PAST_YOU = 32331,
|
||||
|
||||
NPC_INFINITE_ASSAILANT = 27896,
|
||||
NPC_INFINITE_CHRONO_MAGUS = 27898,
|
||||
NPC_INFINITE_DESTROYER = 27897,
|
||||
NPC_INFINITE_TIMERENDER = 27900,
|
||||
NPC_INFINITE_ASSAILANT = 27896,
|
||||
NPC_INFINITE_CHRONO_MAGUS = 27898,
|
||||
NPC_INFINITE_DESTROYER = 27897,
|
||||
NPC_INFINITE_TIMERENDER = 27900,
|
||||
NPC_NOZDORMU = 27925,
|
||||
|
||||
SPELL_CLONE_CASTER = 49889,
|
||||
SPELL_TELEPORT_EFFECT = 52096,
|
||||
SPELL_NOZDORMU_INVIS = 50013,
|
||||
SPELL_CLONE_CASTER = 49889,
|
||||
SPELL_TELEPORT_EFFECT = 52096,
|
||||
|
||||
EVENT_START_EVENT = 1,
|
||||
EVENT_FIGHT_1 = 2,
|
||||
EVENT_FIGHT_2 = 3,
|
||||
EVENT_CHECK_FINISH = 4,
|
||||
EVENT_FINISH_EVENT = 5,
|
||||
EVENT_START_EVENT = 1,
|
||||
EVENT_FIGHT_1 = 2,
|
||||
EVENT_FIGHT_2 = 3,
|
||||
EVENT_CHECK_FINISH = 4,
|
||||
EVENT_FINISH_EVENT = 5,
|
||||
|
||||
QUEST_MYSTERY_OF_THE_INFINITE = 12470,
|
||||
QUEST_MYSTERY_OF_THE_INFINITE_REDUX = 13343,
|
||||
QUEST_MYSTERY_OF_THE_INFINITE = 12470,
|
||||
QUEST_MYSTERY_OF_THE_INFINITE_REDUX = 13343,
|
||||
};
|
||||
|
||||
enum hourglassText
|
||||
{
|
||||
// (All are whispers) Both NPC_PAST_YOU and NPC_FUTURE_YOU share the same creature_text GroupIDs
|
||||
// Start
|
||||
SAY_HOURGLASS_START_1 = 1,
|
||||
SAY_HOURGLASS_START_2 = 2,
|
||||
|
||||
// Random whispers during the fight
|
||||
SAY_HOURGLASS_RANDOM_1 = 3,
|
||||
SAY_HOURGLASS_RANDOM_2 = 4,
|
||||
SAY_HOURGLASS_RANDOM_3 = 5,
|
||||
SAY_HOURGLASS_RANDOM_4 = 6,
|
||||
SAY_HOURGLASS_RANDOM_5 = 7,
|
||||
SAY_HOURGLASS_RANDOM_6 = 8,
|
||||
SAY_HOURGLASS_RANDOM_7 = 9,
|
||||
SAY_HOURGLASS_RANDOM_8 = 10,
|
||||
|
||||
// End
|
||||
SAY_HOURGLASS_END_1 = 11,
|
||||
SAY_HOURGLASS_END_2 = 12,
|
||||
};
|
||||
|
||||
class npc_hourglass_of_eternity : public CreatureScript
|
||||
@@ -332,24 +356,26 @@ public:
|
||||
{
|
||||
npc_hourglass_of_eternityAI(Creature* c) : ScriptedAI(c) {}
|
||||
|
||||
ObjectGuid summonerGUID;
|
||||
ObjectGuid futureGUID;
|
||||
ObjectGuid pGUID;
|
||||
ObjectGuid copyGUID;
|
||||
EventMap events;
|
||||
uint8 count[3];
|
||||
uint8 phase;
|
||||
uint8 randomTalk;
|
||||
uint8 lastRandomTalk;
|
||||
|
||||
bool IsFuture() { return me->GetEntry() == NPC_FUTURE_HOURGLASS; }
|
||||
bool IsFuture() {return me->GetEntry() == NPC_FUTURE_HOURGLASS;}
|
||||
void InitializeAI() override
|
||||
{
|
||||
if (me->ToTempSummon())
|
||||
if (Unit* summoner = me->ToTempSummon()->GetSummonerUnit())
|
||||
{
|
||||
summonerGUID = summoner->GetGUID();
|
||||
pGUID = summoner->GetGUID();
|
||||
float x, y, z;
|
||||
me->GetNearPoint(summoner, x, y, z, me->GetCombatReach(), 0.0f, rand_norm() * 2 * M_PI);
|
||||
if (Creature* cr = summoner->SummonCreature((IsFuture() ? NPC_FUTURE_YOU : NPC_PAST_YOU), x, y, z, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 210000))
|
||||
{
|
||||
futureGUID = cr->GetGUID();
|
||||
copyGUID = cr->GetGUID();
|
||||
summoner->CastSpell(cr, SPELL_CLONE_CASTER, true);
|
||||
cr->SetFaction(summoner->GetFaction());
|
||||
cr->SetReactState(REACT_AGGRESSIVE);
|
||||
@@ -365,27 +391,39 @@ public:
|
||||
events.ScheduleEvent(EVENT_START_EVENT, 4000);
|
||||
}
|
||||
|
||||
Player* getSummoner() { return ObjectAccessor::GetPlayer(*me, summonerGUID); }
|
||||
Creature* getFuture() { return ObjectAccessor::GetCreature(*me, futureGUID); }
|
||||
Player* GetPlayer() {return ObjectAccessor::GetPlayer(*me, pGUID);}
|
||||
Creature* GetCopy() {return ObjectAccessor::GetCreature(*me, copyGUID);}
|
||||
|
||||
uint32 randEntry()
|
||||
{
|
||||
return NPC_INFINITE_ASSAILANT + urand(0, 2);
|
||||
}
|
||||
|
||||
void ShowNozdormu()
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_NOZDORMU, 100.0f, true))
|
||||
cr->RemoveAura(SPELL_NOZDORMU_INVIS);
|
||||
}
|
||||
|
||||
void HideNozdormu()
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_NOZDORMU, 100.0f, true))
|
||||
cr->AddAura(SPELL_NOZDORMU_INVIS, cr);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_START_EVENT:
|
||||
if (Creature* cr = getFuture())
|
||||
cr->Whisper(IsFuture() ? "Hey there, $N, don't be alarmed. It's me... you... from the future. I'm here to help." : "Whoa! You're me, but from the future! Hey, my equipment got an upgrade! Cool!", LANG_UNIVERSAL, getSummoner());
|
||||
if (Creature* cr = GetCopy())
|
||||
cr->AI()->Talk(SAY_HOURGLASS_START_1, GetPlayer());
|
||||
events.ScheduleEvent(EVENT_FIGHT_1, 7000);
|
||||
break;
|
||||
case EVENT_FIGHT_1:
|
||||
if (Creature* cr = getFuture())
|
||||
cr->Whisper(IsFuture() ? "Heads up... here they come. I'll help as much as I can. Let's just keep them off the hourglass!" : "Here come the Infinites! I've got to keep the hourglass safe. Can you help?", LANG_UNIVERSAL, getSummoner());
|
||||
if (Creature* cr = GetCopy())
|
||||
cr->AI()->Talk(SAY_HOURGLASS_START_2, GetPlayer());
|
||||
events.ScheduleEvent(EVENT_FIGHT_2, 6000);
|
||||
break;
|
||||
case EVENT_FIGHT_2:
|
||||
@@ -433,57 +471,44 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
if (Player* player = getSummoner())
|
||||
ShowNozdormu();
|
||||
if (Player* player = GetPlayer())
|
||||
player->GroupEventHappens(IsFuture() ? QUEST_MYSTERY_OF_THE_INFINITE : QUEST_MYSTERY_OF_THE_INFINITE_REDUX, me);
|
||||
|
||||
me->Whisper(IsFuture() ? "Look, $N, the hourglass has revealed Nozdormu!" : "What the heck? Nozdormu is up there!", LANG_UNIVERSAL, getSummoner());
|
||||
if (Creature* cr = GetCopy())
|
||||
{
|
||||
cr->SetFacingToObject(me->FindNearestCreature(NPC_NOZDORMU, 100.0f, true));
|
||||
cr->AI()->Talk(SAY_HOURGLASS_END_1, GetPlayer());
|
||||
}
|
||||
events.ScheduleEvent(EVENT_FINISH_EVENT, 6000);
|
||||
break;
|
||||
}
|
||||
case EVENT_FINISH_EVENT:
|
||||
{
|
||||
me->Whisper(IsFuture() ? "Farewell, $N. Keep us alive and get some better equipment!" : "I feel like I'm being pulled away through time. Thanks for the help....", LANG_UNIVERSAL, getSummoner());
|
||||
HideNozdormu();
|
||||
if (Creature* cr = GetCopy())
|
||||
cr->AI()->Talk(SAY_HOURGLASS_END_2, GetPlayer());
|
||||
me->DespawnOrUnsummon(500);
|
||||
if (getFuture())
|
||||
getFuture()->DespawnOrUnsummon(500);
|
||||
if (GetCopy())
|
||||
GetCopy()->DespawnOrUnsummon(500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void randomWhisper()
|
||||
void randomWhisper() // Do not repeat the same line
|
||||
{
|
||||
std::string text = "";
|
||||
switch(urand(0, IsFuture() ? 7 : 5))
|
||||
randomTalk = urand(SAY_HOURGLASS_RANDOM_1, SAY_HOURGLASS_RANDOM_8); // 3 to 10
|
||||
if (randomTalk == lastRandomTalk)
|
||||
{
|
||||
case 0:
|
||||
text = IsFuture() ? "What? Am I here alone. We both have a stake at this, you know!" : "This equipment looks cool and all, but couldn't we have done a little better? Are you even raiding?";
|
||||
break;
|
||||
case 1:
|
||||
text = IsFuture() ? "No matter what, you can't die, because would mean that I would cease to exist, right? But, I was here before when I was you. I'm so confused!" : "Chromie said that if I don't do this just right, I might wink out of existence. If I go, then you go!";
|
||||
break;
|
||||
case 2:
|
||||
text = IsFuture() ? "Sorry, but Chromie said that I couldn't reveal anything about your future to you. She said that if I did, I would cease to exist." : "I just want you to know that if we get through this alive, I'm making sure that we turn out better than you. No offense.";
|
||||
break;
|
||||
case 3:
|
||||
text = IsFuture() ? "Look at you fight; no wonder I turned to drinking." : "Looks like I'm an underachiever.";
|
||||
break;
|
||||
case 4:
|
||||
text = IsFuture() ? "Wow, I'd forgotten how inexperienced I used to be." : "Wait a minute! If you're here, then that means that in the not-so-distant future I'm going to be you helping me? Are we stuck in a time loop?!";
|
||||
break;
|
||||
case 5:
|
||||
text = IsFuture() ? "I can't believe that I used to wear that." : "I think I'm going to turn to drinking after this.";
|
||||
break;
|
||||
case 6:
|
||||
text = "Listen. I'm not supposed to tell you this, but there's going to be this party that you're invited to. Whatever you do, DO NOT DRINK THE PUNCH!";
|
||||
break;
|
||||
case 7:
|
||||
text = "Wish I could remember how many of the Infinite Dragonflight were going to try to stop you. This fight was so long ago.";
|
||||
break;
|
||||
randomWhisper();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Creature* cr = GetCopy())
|
||||
cr->AI()->Talk(randomTalk, GetPlayer());
|
||||
lastRandomTalk = randomTalk;
|
||||
}
|
||||
|
||||
if (Creature* cr = getFuture())
|
||||
cr->Whisper(text, LANG_UNIVERSAL, getSummoner());
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -516,7 +541,7 @@ public:
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!me->GetVictim() && who->GetEntry() >= NPC_INFINITE_ASSAILANT && who->GetEntry() <= NPC_INFINITE_TIMERENDER)
|
||||
if (!me->GetVictim() && !who->IsFlying() && who->GetEntry() >= NPC_INFINITE_ASSAILANT && who->GetEntry() <= NPC_INFINITE_TIMERENDER)
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
|
||||
@@ -220,7 +220,9 @@ class spell_pal_sacred_shield_base : public AuraScript
|
||||
|
||||
bool CheckProc(ProcEventInfo& eventInfo)
|
||||
{
|
||||
return !(eventInfo.GetHitMask() & PROC_EX_INTERNAL_HOT) && eventInfo.GetDamageInfo() && eventInfo.GetDamageInfo()->GetDamage() > 0;
|
||||
HealInfo* healinfo = eventInfo.GetHealInfo();
|
||||
DamageInfo* damageinfo = eventInfo.GetDamageInfo();
|
||||
return !(eventInfo.GetHitMask() & PROC_EX_INTERNAL_HOT) && ((healinfo && healinfo->GetHeal() > 0) || (damageinfo && damageinfo->GetDamage() > 0));
|
||||
}
|
||||
|
||||
void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
|
||||
@@ -231,14 +233,14 @@ class spell_pal_sacred_shield_base : public AuraScript
|
||||
{
|
||||
Unit* caster = eventInfo.GetActor();
|
||||
|
||||
DamageInfo* damageInfo = eventInfo.GetDamageInfo();
|
||||
HealInfo* healinfo = eventInfo.GetHealInfo();
|
||||
|
||||
if (!damageInfo || !damageInfo->GetDamage())
|
||||
if (!healinfo || !healinfo->GetHeal())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SpellInfo const* procSpell = damageInfo->GetSpellInfo();
|
||||
SpellInfo const* procSpell = healinfo->GetSpellInfo();
|
||||
if (!procSpell)
|
||||
{
|
||||
return;
|
||||
@@ -247,12 +249,12 @@ class spell_pal_sacred_shield_base : public AuraScript
|
||||
if (caster && procSpell->SpellFamilyName == SPELLFAMILY_PALADIN &&
|
||||
procSpell->SpellFamilyFlags.HasFlag(0x40000000) && caster->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_PALADIN, 3021, 0)) // need infusion of light
|
||||
{
|
||||
int32 basepoints = int32(float(damageInfo->GetDamage()) / 12.0f);
|
||||
int32 basepoints = int32(float(healinfo->GetHeal()) / 12.0f);
|
||||
// Item - Paladin T9 Holy 4P Bonus (Flash of Light)
|
||||
if (AuraEffect const* aurEffect = caster->GetAuraEffect(67191, EFFECT_0))
|
||||
AddPct(basepoints, aurEffect->GetAmount());
|
||||
|
||||
caster->CastCustomSpell(eventInfo.GetActionTarget(), 66922, &basepoints, nullptr, nullptr, true, 0, aurEff, caster->GetGUID());
|
||||
caster->CastCustomSpell(eventInfo.GetActionTarget(), 66922, &basepoints, nullptr, nullptr, true, nullptr, aurEff, caster->GetGUID());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user