Big re-organization of repository [W.I.P]

This commit is contained in:
Yehonal
2016-08-11 20:25:27 +02:00
parent c62a72c0a8
commit 0f85ce1c54
3016 changed files with 1271 additions and 1 deletions

View File

@@ -1,161 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum Curator
{
SAY_AGGRO = 0,
SAY_SUMMON = 1,
SAY_EVOCATE = 2,
SAY_ENRAGE = 3,
SAY_KILL = 4,
SAY_DEATH = 5,
SPELL_HATEFUL_BOLT = 30383,
SPELL_EVOCATION = 30254,
SPELL_ARCANE_INFUSION = 30403,
SPELL_ASTRAL_DECONSTRUCTION = 30407,
SPELL_SUMMON_ASTRAL_FLARE1 = 30236,
SPELL_SUMMON_ASTRAL_FLARE2 = 30239,
SPELL_SUMMON_ASTRAL_FLARE3 = 30240,
SPELL_SUMMON_ASTRAL_FLARE4 = 30241,
EVENT_KILL_TALK = 1,
EVENT_SPELL_HATEFUL_BOLT = 2,
EVENT_SPELL_EVOCATION = 3,
EVENT_SPELL_ASTRAL_FLARE = 4,
EVENT_SPELL_BERSERK = 5,
EVENT_CHECK_HEALTH = 6
};
class boss_curator : public CreatureScript
{
public:
boss_curator() : CreatureScript("boss_curator") { }
struct boss_curatorAI : public BossAI
{
boss_curatorAI(Creature* creature) : BossAI(creature, TYPE_CURATOR) { }
void Reset()
{
BossAI::Reset();
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true);
}
void KilledUnit(Unit* victim)
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 5000);
}
}
void JustDied(Unit* killer)
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void EnterCombat(Unit* who)
{
BossAI::EnterCombat(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, 10000);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 6000);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
if (Unit* target = summon->SelectNearbyTarget(NULL, 40.0f))
{
summon->AI()->AttackStart(target);
summon->AddThreat(target, 1000.0f);
}
summon->SetInCombatWithZone();
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (me->HealthBelowPct(16))
{
events.CancelEvent(EVENT_SPELL_ASTRAL_FLARE);
me->CastSpell(me, SPELL_ARCANE_INFUSION, true);
Talk(SAY_ENRAGE);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
break;
case EVENT_SPELL_BERSERK:
Talk(SAY_ENRAGE);
me->InterruptNonMeleeSpells(true);
me->CastSpell(me, SPELL_ASTRAL_DECONSTRUCTION, true);
break;
case EVENT_SPELL_HATEFUL_BOLT:
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, urand(1, 2), 40.0f))
me->CastSpell(target, SPELL_HATEFUL_BOLT, false);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, urand(5000, 7500) * (events.GetNextEventTime(EVENT_SPELL_BERSERK) == 0 ? 1 : 2));
break;
case EVENT_SPELL_ASTRAL_FLARE:
{
me->CastSpell(me, RAND(SPELL_SUMMON_ASTRAL_FLARE1, SPELL_SUMMON_ASTRAL_FLARE2, SPELL_SUMMON_ASTRAL_FLARE3, SPELL_SUMMON_ASTRAL_FLARE4), false);
int32 mana = CalculatePct(me->GetMaxPower(POWER_MANA), 10);
me->ModifyPower(POWER_MANA, -mana);
if (me->GetPowerPct(POWER_MANA) < 10.0f)
{
Talk(SAY_EVOCATE);
me->CastSpell(me, SPELL_EVOCATION, false);
events.DelayEvents(20000);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 20000);
}
else
{
if (roll_chance_i(50))
Talk(SAY_SUMMON);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 10000);
}
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_curatorAI>(creature);
}
};
void AddSC_boss_curator()
{
new boss_curator();
}

View File

@@ -1,113 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum MaidenOfVirtue
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_REPENTANCE = 2,
SAY_DEATH = 3,
SPELL_REPENTANCE = 29511,
SPELL_HOLY_FIRE = 29522,
SPELL_HOLY_WRATH = 32445,
SPELL_HOLY_GROUND = 29523,
SPELL_BERSERK = 26662,
EVENT_SPELL_REPENTANCE = 1,
EVENT_SPELL_HOLY_FIRE = 2,
EVENT_SPELL_HOLY_WRATH = 3,
EVENT_SPELL_ENRAGE = 4,
EVENT_KILL_TALK = 5
};
class boss_maiden_of_virtue : public CreatureScript
{
public:
boss_maiden_of_virtue() : CreatureScript("boss_maiden_of_virtue") { }
struct boss_maiden_of_virtueAI : public BossAI
{
boss_maiden_of_virtueAI(Creature* creature) : BossAI(creature, TYPE_MAIDEN) { }
void Reset()
{
BossAI::Reset();
}
void KilledUnit(Unit* /*victim*/)
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_KILL_TALK, 5000);
}
}
void JustDied(Unit* killer)
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void EnterCombat(Unit* who)
{
BossAI::EnterCombat(who);
Talk(SAY_AGGRO);
me->CastSpell(me, SPELL_HOLY_GROUND, true);
events.ScheduleEvent(EVENT_SPELL_REPENTANCE, 25000);
events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, 8000);
events.ScheduleEvent(EVENT_SPELL_HOLY_WRATH, 15000);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000);
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_REPENTANCE:
me->CastSpell(me, SPELL_REPENTANCE, true);
events.ScheduleEvent(EVENT_SPELL_REPENTANCE, urand(25000, 35000));
break;
case EVENT_SPELL_HOLY_FIRE:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
me->CastSpell(target, SPELL_HOLY_FIRE, true);
events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, urand(8000, 18000));
break;
case EVENT_SPELL_HOLY_WRATH:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
me->CastSpell(target, SPELL_HOLY_WRATH, true);
events.ScheduleEvent(EVENT_SPELL_HOLY_WRATH, urand(20000, 25000));
break;
case EVENT_SPELL_ENRAGE:
me->CastSpell(me, SPELL_BERSERK, true);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_maiden_of_virtueAI>(creature);
}
};
void AddSC_boss_maiden_of_virtue()
{
new boss_maiden_of_virtue();
}

View File

@@ -1,451 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
#include "karazhan.h"
enum eSay
{
SAY_ATTUMEN1_APPEAR = 0,
SAY_ATTUMEN1_MOUNT = 2,
SAY_ATTUMEN2_DEATH = 0,
SAY_ATTUMEN_KILL = 1,
SAY_ATTUMEN_DISARM = 3,
SAY_ATTUMEN_RANDOM = 4,
SAY_ATTUMEN_MIDNIGHT_KILL = 5,
SAY_MIDNIGHT_EMOTE = 0
};
enum eSpells
{
// Midnight
SPELL_KNOCKDOWN = 29711,
SPELL_SUMMON_ATTUMEN = 29714,
SPELL_SUMMON_ATTUMEN_MOUNTED = 29799,
// Attumen
SPELL_SHADOW_CLEAVE = 29832,
SPELL_INTANGIBLE_PRESENCE = 29833,
SPELL_SPAWN_SMOKE1 = 29802,
// Attumen 2
SPELL_CHARGE_MIDNIGHT = 29847,
SPELL_SPAWN_SMOKE2 = 10389,
// Generic
SPELL_MOUNT_TARGET_ATTUMEN = 29769,
SPELL_MOUNT_TARGET_MIDNIGHT = 29770
};
enum eEvents
{
EVENT_CHECK_HEALTH_95 = 1,
EVENT_CHECK_HEALTH_25 = 2,
EVENT_SPELL_KNOCKDOWN = 3,
EVENT_SUMMON_ATTUMEN_MOUNTED = 4,
EVENT_SPELL_SHADOW_CLEAVE = 10,
EVENT_SPELL_INTANGIBLE_PRESENCE = 11,
EVENT_RANDOM_YELL = 12,
EVENT_SPELL_CHARGE = 20,
EVENT_KILL_TALK = 30
};
enum eMisc
{
POINT_MOVE_TO_MIDNIGHT = 1,
DATA_ATTUMEN_READY = 1
};
class boss_midnight : public CreatureScript
{
public:
boss_midnight() : CreatureScript("boss_midnight") { }
struct boss_midnightAI : public BossAI
{
boss_midnightAI(Creature* creature) : BossAI(creature, TYPE_ATTUMEN) { }
void Reset()
{
BossAI::Reset();
me->SetVisible(true);
_healthPct = 100.0f;
}
void EnterCombat(Unit* who)
{
BossAI::EnterCombat(who);
events.ScheduleEvent(EVENT_CHECK_HEALTH_95, 0);
events.ScheduleEvent(EVENT_SPELL_KNOCKDOWN, 6000);
}
void KilledUnit(Unit* /*victim*/)
{
if (Creature* attumen = summons.GetCreatureWithEntry(NPC_ATTUMEN_THE_HUNTSMAN))
attumen->AI()->Talk(SAY_ATTUMEN_MIDNIGHT_KILL);
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
summon->SetInCombatWithZone();
if (summon->GetEntry() == NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED)
{
summon->SetHealth(summon->CountPctFromMaxHealth(_healthPct));
summon->CastSpell(summon, SPELL_SPAWN_SMOKE2, true);
}
else
summon->CastSpell(summon, SPELL_SPAWN_SMOKE1, true);
}
void SetData(uint32 type, uint32 /*data*/)
{
if (type == DATA_ATTUMEN_READY)
events.ScheduleEvent(EVENT_SUMMON_ATTUMEN_MOUNTED, 0);
}
void SummonedCreatureDies(Creature* summon, Unit* /*killer*/)
{
if (summon->GetEntry() == NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED)
{
summons.clear();
Unit::Kill(me, me);
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH_95:
if (me->HealthBelowPct(96))
{
me->CastSpell(me, SPELL_SUMMON_ATTUMEN, true);
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 0);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH_95, 500);
break;
case EVENT_CHECK_HEALTH_25:
if (me->HealthBelowPct(25))
{
Talk(SAY_MIDNIGHT_EMOTE);
me->CastSpell(me, SPELL_MOUNT_TARGET_ATTUMEN, true);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500);
break;
case EVENT_SPELL_KNOCKDOWN:
me->CastSpell(me->GetVictim(), SPELL_KNOCKDOWN, false);
events.ScheduleEvent(EVENT_SPELL_KNOCKDOWN, 20000);
break;
case EVENT_SUMMON_ATTUMEN_MOUNTED:
if (Creature* attumen = summons.GetCreatureWithEntry(NPC_ATTUMEN_THE_HUNTSMAN))
{
_healthPct = std::max<float>(me->GetHealthPct(), attumen->GetHealthPct());
attumen->DespawnOrUnsummon();
}
me->CastSpell(me, SPELL_SUMMON_ATTUMEN_MOUNTED, true);
me->SetVisible(false);
break;
}
if (me->IsVisible())
DoMeleeAttackIfReady();
EnterEvadeIfOutOfCombatArea();
}
bool CheckEvadeIfOutOfCombatArea() const
{
return me->GetHomePosition().GetExactDist2d(me) > 50.0f || me->GetPositionZ() > 60.0f;
}
private:
float _healthPct;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_midnightAI>(creature);
}
};
class boss_attumen : public CreatureScript
{
public:
boss_attumen() : CreatureScript("boss_attumen") { }
struct boss_attumenAI : public ScriptedAI
{
boss_attumenAI(Creature* creature) : ScriptedAI(creature)
{
}
void Reset()
{
_events.Reset();
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_ATTUMEN1_APPEAR);
_events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 0);
_events.ScheduleEvent(EVENT_SPELL_SHADOW_CLEAVE, 6000);
_events.ScheduleEvent(EVENT_SPELL_INTANGIBLE_PRESENCE, 15000);
_events.ScheduleEvent(EVENT_RANDOM_YELL, urand(25000, 45000));
}
void KilledUnit(Unit* /*victim*/)
{
if (_events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
_events.ScheduleEvent(EVENT_KILL_TALK, 5000);
Talk(SAY_ATTUMEN_KILL);
}
}
void SpellHit(Unit* caster, const SpellInfo* spellInfo)
{
if (spellInfo->Mechanic == MECHANIC_DISARM && _events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
_events.ScheduleEvent(EVENT_KILL_TALK, 5000);
Talk(SAY_ATTUMEN_DISARM);
}
else if (spellInfo->Id == SPELL_MOUNT_TARGET_ATTUMEN)
{
me->CastSpell(me, SPELL_MOUNT_TARGET_MIDNIGHT, true);
}
}
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
{
if (spellInfo->Id == SPELL_MOUNT_TARGET_MIDNIGHT)
{
Talk(SAY_ATTUMEN1_MOUNT);
_events.Reset();
me->GetMotionMaster()->MovePoint(POINT_MOVE_TO_MIDNIGHT, target->GetPositionX() + 2.0f*cos(target->GetAngle(me)), target->GetPositionY() + 2.0f*sin(target->GetAngle(me)), target->GetPositionZ()+0.2f, true, true, MOTION_SLOT_CONTROLLED);
}
}
void MovementInform(uint32 type, uint32 point)
{
if (type == POINT_MOTION_TYPE && point == POINT_MOVE_TO_MIDNIGHT)
{
if (TempSummon* summon = me->ToTempSummon())
if (Unit* midnight = summon->GetSummoner())
midnight->GetAI()->SetData(DATA_ATTUMEN_READY, 0);
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (_events.ExecuteEvent())
{
case EVENT_SPELL_SHADOW_CLEAVE:
me->CastSpell(me->GetVictim(), SPELL_SHADOW_CLEAVE, false);
_events.ScheduleEvent(EVENT_SPELL_SHADOW_CLEAVE, urand(9000, 14000));
break;
case EVENT_SPELL_INTANGIBLE_PRESENCE:
me->CastSpell(me->GetVictim(), SPELL_INTANGIBLE_PRESENCE, false);
_events.ScheduleEvent(EVENT_SPELL_INTANGIBLE_PRESENCE, 30000);
break;
case EVENT_RANDOM_YELL:
Talk(SAY_ATTUMEN_RANDOM);
_events.ScheduleEvent(EVENT_RANDOM_YELL, urand(30000, 70000));
break;
case EVENT_CHECK_HEALTH_25:
if (me->HealthBelowPct(25))
{
me->CastSpell(me, SPELL_MOUNT_TARGET_MIDNIGHT, true);
break;
}
_events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_attumenAI>(creature);
}
};
class boss_attumen_midnight : public CreatureScript
{
public:
boss_attumen_midnight() : CreatureScript("boss_attumen_midnight") { }
struct boss_attumen_midnightAI : public ScriptedAI
{
boss_attumen_midnightAI(Creature* creature) : ScriptedAI(creature)
{
}
void Reset()
{
_events.Reset();
}
void EnterCombat(Unit* /*who*/)
{
_events.ScheduleEvent(EVENT_SPELL_SHADOW_CLEAVE, 6000);
_events.ScheduleEvent(EVENT_SPELL_INTANGIBLE_PRESENCE, 15000);
_events.ScheduleEvent(EVENT_RANDOM_YELL, urand(25000, 45000));
_events.ScheduleEvent(EVENT_SPELL_CHARGE, 20000);
_events.ScheduleEvent(EVENT_SPELL_KNOCKDOWN, 11000);
}
void KilledUnit(Unit* /*victim*/)
{
if (_events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
_events.ScheduleEvent(EVENT_KILL_TALK, 5000);
Talk(SAY_ATTUMEN_KILL);
}
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_ATTUMEN2_DEATH);
}
void SpellHit(Unit* caster, const SpellInfo* spellInfo)
{
if (spellInfo->Mechanic == MECHANIC_DISARM && _events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
_events.ScheduleEvent(EVENT_KILL_TALK, 5000);
Talk(SAY_ATTUMEN_DISARM);
}
}
void MovementInform(uint32 type, uint32 point)
{
if (type == POINT_MOTION_TYPE && point == POINT_MOVE_TO_MIDNIGHT)
{
if (TempSummon* summon = me->ToTempSummon())
if (Unit* midnight = summon->GetSummoner())
midnight->GetAI()->SetData(DATA_ATTUMEN_READY, 0);
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
_events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (_events.ExecuteEvent())
{
case EVENT_SPELL_SHADOW_CLEAVE:
me->CastSpell(me->GetVictim(), SPELL_SHADOW_CLEAVE, false);
_events.ScheduleEvent(EVENT_SPELL_SHADOW_CLEAVE, urand(9000, 14000));
break;
case EVENT_SPELL_INTANGIBLE_PRESENCE:
me->CastSpell(me->GetVictim(), SPELL_INTANGIBLE_PRESENCE, false);
_events.ScheduleEvent(EVENT_SPELL_INTANGIBLE_PRESENCE, 30000);
break;
case EVENT_RANDOM_YELL:
Talk(SAY_ATTUMEN_RANDOM);
_events.ScheduleEvent(EVENT_RANDOM_YELL, urand(30000, 70000));
break;
case EVENT_SPELL_CHARGE:
if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, 24.0f, true))
me->CastSpell(target, SPELL_CHARGE_MIDNIGHT, false);
_events.ScheduleEvent(EVENT_SPELL_CHARGE, 20000);
break;
case EVENT_SPELL_KNOCKDOWN:
me->CastSpell(me->GetVictim(), SPELL_KNOCKDOWN, false);
_events.ScheduleEvent(EVENT_SPELL_KNOCKDOWN, 20000);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap _events;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_attumen_midnightAI>(creature);
}
};
class spell_midnight_fixate : public SpellScriptLoader
{
public:
spell_midnight_fixate() : SpellScriptLoader("spell_midnight_fixate") { }
class spell_midnight_fixate_AuraScript : public AuraScript
{
PrepareAuraScript(spell_midnight_fixate_AuraScript);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
if (Unit* caster = GetCaster())
caster->TauntApply(target);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
if (Unit* caster = GetCaster())
caster->TauntFadeOut(target);
}
void Register()
{
OnEffectApply += AuraEffectApplyFn(spell_midnight_fixate_AuraScript::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_midnight_fixate_AuraScript::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_midnight_fixate_AuraScript();
}
};
void AddSC_boss_attumen()
{
new boss_midnight();
new boss_attumen();
new boss_attumen_midnight();
}

View File

@@ -1,278 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum Yells
{
SAY_AGGRO = 0,
SAY_SPECIAL = 1,
SAY_KILL = 2,
SAY_DEATH = 3,
SAY_OUT_OF_COMBAT = 4,
SAY_GUEST = 0
};
enum Spells
{
SPELL_VANISH = 29448,
SPELL_GARROTE_DUMMY = 29433,
SPELL_GARROTE = 37066,
SPELL_BLIND = 34694,
SPELL_GOUGE = 29425,
SPELL_FRENZY = 37023,
SPELL_DUAL_WIELD = 29651,
SPELL_BERSERK = 26662,
SPELL_VANISH_TELEPORT = 29431,
};
enum Misc
{
EVENT_GUEST_TALK = 1,
EVENT_GUEST_TALK2 = 2,
EVENT_SPELL_VANISH = 3,
EVENT_SPELL_GARROTE = 4,
EVENT_SPELL_BLIND = 5,
EVENT_SPELL_GOUGE = 6,
EVENT_CHECK_HEALTH = 7,
EVENT_SPELL_ENRAGE = 8,
EVENT_KILL_TALK = 9,
ACTIVE_GUEST_COUNT = 4,
MAX_GUEST_COUNT = 6
};
const Position GuestsPosition[4] =
{
{-10987.38f, -1883.38f, 81.73f, 1.50f},
{-10989.60f, -1881.27f, 81.73f, 0.73f},
{-10978.81f, -1884.08f, 81.73f, 1.50f},
{-10976.38f, -1882.59f, 81.73f, 2.31f},
};
const uint32 GuestEntries[6]=
{
17007,
19872,
19873,
19874,
19875,
19876,
};
class boss_moroes : public CreatureScript
{
public:
boss_moroes() : CreatureScript("boss_moroes") { }
struct boss_moroesAI : public BossAI
{
boss_moroesAI(Creature* creature) : BossAI(creature, TYPE_MOROES)
{
_activeGuests = 0;
}
void InitializeAI()
{
BossAI::InitializeAI();
InitializeGuests();
}
void JustReachedHome()
{
BossAI::JustReachedHome();
InitializeGuests();
}
void InitializeGuests()
{
if (!me->IsAlive())
return;
if (_activeGuests == 0)
{
_activeGuests |= 0x3F;
uint8 rand1 = RAND(0x01, 0x02, 0x04);
uint8 rand2 = RAND(0x08, 0x10, 0x20);
_activeGuests &= ~(rand1|rand2);
}
for (uint8 i = 0; i < MAX_GUEST_COUNT; ++i)
if ((1 << i) & _activeGuests)
me->SummonCreature(GuestEntries[i], GuestsPosition[summons.size()], TEMPSUMMON_MANUAL_DESPAWN);
_events2.Reset();
_events2.ScheduleEvent(EVENT_GUEST_TALK, 10000);
}
void Reset()
{
BossAI::Reset();
me->CastSpell(me, SPELL_DUAL_WIELD, true);
}
void EnterCombat(Unit* who)
{
BossAI::EnterCombat(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_VANISH, 30000);
events.ScheduleEvent(EVENT_SPELL_BLIND, 20000);
events.ScheduleEvent(EVENT_SPELL_GOUGE, 13000);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 5000);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 600000);
_events2.Reset();
me->CallForHelp(20.0f);
}
void KilledUnit(Unit* /*victim*/)
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 5000);
}
}
void JustDied(Unit* killer)
{
summons.clear();
BossAI::JustDied(killer);
Talk(SAY_DEATH);
instance->DoRemoveAurasDueToSpellOnPlayers(SPELL_GARROTE);
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
}
Creature* GetRandomGuest()
{
std::list<Creature*> guestList;
for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ++i)
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
guestList.push_back(summon);
return Trinity::Containers::SelectRandomContainerElement(guestList);
}
void UpdateAI(uint32 diff)
{
_events2.Update(diff);
switch (_events2.ExecuteEvent())
{
case EVENT_GUEST_TALK:
if (Creature* guest = GetRandomGuest())
guest->AI()->Talk(SAY_GUEST);
_events2.ScheduleEvent(EVENT_GUEST_TALK2, 5000);
break;
case EVENT_GUEST_TALK2:
Talk(SAY_OUT_OF_COMBAT);
_events2.ScheduleEvent(EVENT_GUEST_TALK, urand(60000, 120000));
break;
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (me->HealthBelowPct(31))
{
me->CastSpell(me, SPELL_FRENZY, true);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
break;
case EVENT_SPELL_ENRAGE:
me->CastSpell(me, SPELL_BERSERK, true);
break;
case EVENT_SPELL_BLIND:
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 10.0f, true))
me->CastSpell(target, SPELL_BLIND, false);
events.ScheduleEvent(EVENT_SPELL_BLIND, urand(25000, 40000));
break;
case EVENT_SPELL_GOUGE:
me->CastSpell(me->GetVictim(), SPELL_GOUGE, false);
events.ScheduleEvent(EVENT_SPELL_GOUGE, urand(25000, 40000));
return;
case EVENT_SPELL_VANISH:
events.DelayEvents(9000);
events.SetPhase(1);
me->CastSpell(me, SPELL_VANISH, false);
events.ScheduleEvent(EVENT_SPELL_VANISH, 30000);
events.ScheduleEvent(EVENT_SPELL_GARROTE, urand(5000, 7000));
return;
case EVENT_SPELL_GARROTE:
me->CastSpell(me, SPELL_VANISH_TELEPORT, false);
break;
}
// Xinef: not in vanish
if (events.GetPhaseMask() == 0)
DoMeleeAttackIfReady();
}
private:
EventMap _events2;
uint8 _activeGuests;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_moroesAI>(creature);
}
};
class spell_moroes_vanish : public SpellScriptLoader
{
public:
spell_moroes_vanish() : SpellScriptLoader("spell_moroes_vanish") { }
class spell_moroes_vanish_SpellScript : public SpellScript
{
PrepareSpellScript(spell_moroes_vanish_SpellScript);
void HandleDummy(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
{
Position pos;
target->GetFirstCollisionPosition(pos, 5.0f, M_PI);
GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true);
GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH);
GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
}
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_moroes_vanish_SpellScript();
}
};
void AddSC_boss_moroes()
{
new boss_moroes();
new spell_moroes_vanish();
}

View File

@@ -1,346 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Netherspite
SD%Complete: 90
SDComment: Not sure about timing and portals placing
SDCategory: Karazhan
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
#include "Player.h"
enum Netherspite
{
EMOTE_PHASE_PORTAL = 0,
EMOTE_PHASE_BANISH = 1,
SPELL_NETHERBURN_AURA = 30522,
SPELL_VOIDZONE = 37063,
SPELL_NETHER_INFUSION = 38688,
SPELL_NETHERBREATH = 38523,
SPELL_BANISH_VISUAL = 39833,
SPELL_BANISH_ROOT = 42716,
SPELL_EMPOWERMENT = 38549,
SPELL_NETHERSPITE_ROAR = 38684,
};
const float PortalCoord[3][3] =
{
{-11195.353516f, -1613.237183f, 278.237258f}, // Left side
{-11137.846680f, -1685.607422f, 278.239258f}, // Right side
{-11094.493164f, -1591.969238f, 279.949188f} // Back side
};
enum Netherspite_Portal{
RED_PORTAL = 0, // Perseverence
GREEN_PORTAL = 1, // Serenity
BLUE_PORTAL = 2 // Dominance
};
const uint32 PortalID[3] = {17369, 17367, 17368};
const uint32 PortalVisual[3] = {30487, 30490, 30491};
const uint32 PortalBeam[3] = {30465, 30464, 30463};
const uint32 PlayerBuff[3] = {30421, 30422, 30423};
const uint32 NetherBuff[3] = {30466, 30467, 30468};
const uint32 PlayerDebuff[3] = {38637, 38638, 38639};
class boss_netherspite : public CreatureScript
{
public:
boss_netherspite() : CreatureScript("boss_netherspite") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_netherspiteAI>(creature);
}
struct boss_netherspiteAI : public ScriptedAI
{
boss_netherspiteAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
for (int i=0; i<3; ++i)
{
PortalGUID[i] = 0;
BeamTarget[i] = 0;
BeamerGUID[i] = 0;
}
}
InstanceScript* instance;
bool PortalPhase;
bool Berserk;
uint32 PhaseTimer; // timer for phase switching
uint32 VoidZoneTimer;
uint32 NetherInfusionTimer; // berserking timer
uint32 NetherbreathTimer;
uint32 EmpowermentTimer;
uint32 PortalTimer; // timer for beam checking
uint64 PortalGUID[3]; // guid's of portals
uint64 BeamerGUID[3]; // guid's of auxiliary beaming portals
uint64 BeamTarget[3]; // guid's of portals' current targets
bool IsBetween(WorldObject* u1, WorldObject* target, WorldObject* u2) // the in-line checker
{
if (!u1 || !u2 || !target)
return false;
float xn, yn, xp, yp, xh, yh;
xn = u1->GetPositionX();
yn = u1->GetPositionY();
xp = u2->GetPositionX();
yp = u2->GetPositionY();
xh = target->GetPositionX();
yh = target->GetPositionY();
// check if target is between (not checking distance from the beam yet)
if (dist(xn, yn, xh, yh) >= dist(xn, yn, xp, yp) || dist(xp, yp, xh, yh) >= dist(xn, yn, xp, yp))
return false;
// check distance from the beam
return (abs((xn-xp)*yh+(yp-yn)*xh-xn*yp+xp*yn)/dist(xn, yn, xp, yp) < 1.5f);
}
float dist(float xa, float ya, float xb, float yb) // auxiliary method for distance
{
return sqrt((xa-xb)*(xa-xb) + (ya-yb)*(ya-yb));
}
void Reset()
{
Berserk = false;
NetherInfusionTimer = 540000;
VoidZoneTimer = 15000;
NetherbreathTimer = 3000;
HandleDoors(true);
DestroyPortals();
}
void SummonPortals()
{
uint8 r = rand()%4;
uint8 pos[3];
pos[RED_PORTAL] = ((r % 2) ? (r > 1 ? 2 : 1) : 0);
pos[GREEN_PORTAL] = ((r % 2) ? 0 : (r > 1 ? 2 : 1));
pos[BLUE_PORTAL] = (r > 1 ? 1 : 2); // Blue Portal not on the left side (0)
for (int i=0; i<3; ++i)
if (Creature* portal = me->SummonCreature(PortalID[i], PortalCoord[pos[i]][0], PortalCoord[pos[i]][1], PortalCoord[pos[i]][2], 0, TEMPSUMMON_TIMED_DESPAWN, 60000))
{
PortalGUID[i] = portal->GetGUID();
portal->AddAura(PortalVisual[i], portal);
}
}
void DestroyPortals()
{
for (int i=0; i<3; ++i)
{
if (Creature* portal = ObjectAccessor::GetCreature(*me, PortalGUID[i]))
portal->DisappearAndDie();
if (Creature* portal = ObjectAccessor::GetCreature(*me, BeamerGUID[i]))
portal->DisappearAndDie();
PortalGUID[i] = 0;
BeamTarget[i] = 0;
}
}
void UpdatePortals() // Here we handle the beams' behavior
{
for (int j=0; j<3; ++j) // j = color
if (Creature* portal = ObjectAccessor::GetCreature(*me, PortalGUID[j]))
{
// the one who's been cast upon before
Unit* current = ObjectAccessor::GetUnit(*portal, BeamTarget[j]);
// temporary store for the best suitable beam reciever
Unit* target = me;
if (Map* map = me->GetMap())
{
Map::PlayerList const& players = map->GetPlayers();
// get the best suitable target
for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i)
{
Player* p = i->GetSource();
if (p && p->IsAlive() // alive
&& (!target || target->GetDistance2d(portal)>p->GetDistance2d(portal)) // closer than current best
&& !p->HasAura(PlayerDebuff[j], 0) // not exhausted
&& !p->HasAura(PlayerBuff[(j+1)%3], 0) // not on another beam
&& !p->HasAura(PlayerBuff[(j+2)%3], 0)
&& IsBetween(me, p, portal)) // on the beam
target = p;
}
}
// buff the target
if (target->GetTypeId() == TYPEID_PLAYER)
target->AddAura(PlayerBuff[j], target);
else
target->AddAura(NetherBuff[j], target);
// cast visual beam on the chosen target if switched
// simple target switching isn't working -> using BeamerGUID to cast (workaround)
if (!current || target != current)
{
BeamTarget[j] = target->GetGUID();
// remove currently beaming portal
if (Creature* beamer = ObjectAccessor::GetCreature(*portal, BeamerGUID[j]))
{
beamer->CastSpell(target, PortalBeam[j], false);
beamer->DisappearAndDie();
BeamerGUID[j] = 0;
}
// create new one and start beaming on the target
if (Creature* beamer = portal->SummonCreature(PortalID[j], portal->GetPositionX(), portal->GetPositionY(), portal->GetPositionZ(), portal->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN, 60000))
{
beamer->CastSpell(target, PortalBeam[j], false);
BeamerGUID[j] = beamer->GetGUID();
}
}
// aggro target if Red Beam
if (j == RED_PORTAL && me->GetVictim() != target && target->GetTypeId() == TYPEID_PLAYER)
me->getThreatManager().addThreat(target, 100000.0f+DoGetThreat(me->GetVictim()));
}
}
void SwitchToPortalPhase()
{
me->RemoveAurasDueToSpell(SPELL_BANISH_ROOT);
me->RemoveAurasDueToSpell(SPELL_BANISH_VISUAL);
SummonPortals();
PhaseTimer = 60000;
PortalPhase = true;
PortalTimer = 10000;
EmpowermentTimer = 10000;
Talk(EMOTE_PHASE_PORTAL);
}
void SwitchToBanishPhase()
{
me->RemoveAurasDueToSpell(SPELL_EMPOWERMENT);
me->RemoveAurasDueToSpell(SPELL_NETHERBURN_AURA);
DoCast(me, SPELL_BANISH_VISUAL, true);
DoCast(me, SPELL_BANISH_ROOT, true);
DestroyPortals();
PhaseTimer = 30000;
PortalPhase = false;
Talk(EMOTE_PHASE_BANISH);
for (uint8 i = 0; i < 3; ++i)
me->RemoveAurasDueToSpell(NetherBuff[i]);
}
void HandleDoors(bool open) // Massive Door switcher
{
if (GameObject* Door = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_GO_MASSIVE_DOOR) ))
Door->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY);
}
void EnterCombat(Unit* /*who*/)
{
HandleDoors(false);
SwitchToPortalPhase();
}
void JustDied(Unit* /*killer*/)
{
HandleDoors(true);
DestroyPortals();
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
// Void Zone
if (VoidZoneTimer <= diff)
{
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true), SPELL_VOIDZONE, true);
VoidZoneTimer = 15000;
} else VoidZoneTimer -= diff;
// NetherInfusion Berserk
if (!Berserk && NetherInfusionTimer <= diff)
{
me->AddAura(SPELL_NETHER_INFUSION, me);
DoCast(me, SPELL_NETHERSPITE_ROAR);
Berserk = true;
} else NetherInfusionTimer -= diff;
if (PortalPhase) // PORTAL PHASE
{
// Distribute beams and buffs
if (PortalTimer <= diff)
{
UpdatePortals();
PortalTimer = 1000;
} else PortalTimer -= diff;
// Empowerment & Nether Burn
if (EmpowermentTimer <= diff)
{
DoCast(me, SPELL_EMPOWERMENT);
me->AddAura(SPELL_NETHERBURN_AURA, me);
EmpowermentTimer = 90000;
} else EmpowermentTimer -= diff;
if (PhaseTimer <= diff)
{
if (!me->IsNonMeleeSpellCast(false))
{
SwitchToBanishPhase();
return;
}
} else PhaseTimer -= diff;
}
else // BANISH PHASE
{
// Netherbreath
if (NetherbreathTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true))
DoCast(target, SPELL_NETHERBREATH);
NetherbreathTimer = urand(5000, 7000);
} else NetherbreathTimer -= diff;
if (PhaseTimer <= diff)
{
if (!me->IsNonMeleeSpellCast(false))
{
SwitchToPortalPhase();
return;
}
} else PhaseTimer -= diff;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_netherspite()
{
new boss_netherspite();
}

View File

@@ -1,434 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Nightbane
SD%Complete: 80
SDComment: SDComment: Timers may incorrect
SDCategory: Karazhan
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum Spells
{
// phase 1
SPELL_BELLOWING_ROAR = 39427,
SPELL_CHARRED_EARTH = 30129,
SPELL_DISTRACTING_ASH = 30130,
SPELL_SMOLDERING_BREATH = 30210,
SPELL_TAIL_SWEEP = 25653,
// phase 2
SPELL_RAIN_OF_BONES = 37098,
SPELL_SMOKING_BLAST = 37057,
SPELL_FIREBALL_BARRAGE = 30282,
SPELL_SEARING_CINDERS = 30127,
SPELL_SUMMON_SKELETON = 30170
};
enum Says
{
EMOTE_SUMMON = 0, // Not used in script
YELL_AGGRO = 1,
YELL_FLY_PHASE = 2,
YELL_LAND_PHASE = 3,
EMOTE_BREATH = 4
};
float IntroWay[8][3] =
{
{-11053.37f, -1794.48f, 149.00f},
{-11141.07f, -1841.40f, 125.00f},
{-11187.28f, -1890.23f, 125.00f},
{-11189.20f, -1931.25f, 125.00f},
{-11153.76f, -1948.93f, 125.00f},
{-11128.73f, -1929.75f, 125.00f},
{-11140.00f, -1915.00f, 122.00f},
{-11163.00f, -1903.00f, 91.473f}
};
class boss_nightbane : public CreatureScript
{
public:
boss_nightbane() : CreatureScript("boss_nightbane") { }
CreatureAI* GetAI(Creature* creature) const
{
return new boss_nightbaneAI (creature);
}
struct boss_nightbaneAI : public ScriptedAI
{
boss_nightbaneAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
Intro = true;
}
InstanceScript* instance;
uint32 Phase;
bool RainBones;
bool Skeletons;
uint32 BellowingRoarTimer;
uint32 CharredEarthTimer;
uint32 DistractingAshTimer;
uint32 SmolderingBreathTimer;
uint32 TailSweepTimer;
uint32 RainofBonesTimer;
uint32 SmokingBlastTimer;
uint32 FireballBarrageTimer;
uint32 SearingCindersTimer;
uint32 FlyCount;
uint32 FlyTimer;
bool Intro;
bool Flying;
bool Movement;
uint32 MovePhase;
void Reset()
{
BellowingRoarTimer = 30000;
CharredEarthTimer = 15000;
DistractingAshTimer = 20000;
SmolderingBreathTimer = 10000;
TailSweepTimer = 12000;
RainofBonesTimer = 10000;
SmokingBlastTimer = 20000;
FireballBarrageTimer = 13000;
SearingCindersTimer = 14000;
Phase = 1;
FlyCount = 0;
MovePhase = 0;
me->SetSpeed(MOVE_RUN, 2.0f);
me->SetDisableGravity(Intro);
me->SetWalk(false);
me->setActive(true);
if (instance)
{
if (instance->GetData(TYPE_NIGHTBANE) == DONE)
me->DisappearAndDie();
else
instance->SetData(TYPE_NIGHTBANE, NOT_STARTED);
}
HandleTerraceDoors(true);
Flying = false;
Movement = false;
if (!Intro)
{
me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0);
me->GetMotionMaster()->MoveTargetedHome();
}
}
void HandleTerraceDoors(bool open)
{
if (instance)
{
instance->HandleGameObject(instance->GetData64(DATA_MASTERS_TERRACE_DOOR_1), open);
instance->HandleGameObject(instance->GetData64(DATA_MASTERS_TERRACE_DOOR_2), open);
}
}
void EnterCombat(Unit* /*who*/)
{
if (instance)
instance->SetData(TYPE_NIGHTBANE, IN_PROGRESS);
HandleTerraceDoors(false);
Talk(YELL_AGGRO);
}
void AttackStart(Unit* who)
{
if (!Intro && !Flying)
ScriptedAI::AttackStart(who);
}
void JustDied(Unit* /*killer*/)
{
if (instance)
instance->SetData(TYPE_NIGHTBANE, DONE);
HandleTerraceDoors(true);
}
void MoveInLineOfSight(Unit* who)
{
if (!Intro && !Flying)
ScriptedAI::MoveInLineOfSight(who);
}
void MovementInform(uint32 type, uint32 id)
{
if (type != POINT_MOTION_TYPE)
return;
if (Intro)
{
if (id >= 8)
{
Intro = false;
me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0);
return;
}
MovePhase = id+1;
return;
}
if (Flying)
{
if (id == 0)
{
Talk(EMOTE_BREATH);
Flying = false;
Phase = 2;
return;
}
if (id < 8)
MovePhase = id+1;
else
{
Phase = 1;
Flying = false;
Movement = true;
return;
}
}
}
void JustSummoned(Creature* summoned)
{
summoned->AI()->AttackStart(me->GetVictim());
}
void TakeOff()
{
Talk(YELL_FLY_PHASE);
me->InterruptSpell(CURRENT_GENERIC_SPELL);
me->HandleEmoteCommand(EMOTE_ONESHOT_LIFTOFF);
me->SetDisableGravity(true);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MovePoint(0, IntroWay[2][0], IntroWay[2][1], IntroWay[2][2]);
Flying = true;
FlyTimer = urand(45000, 60000); //timer wrong between 45 and 60 seconds
++FlyCount;
RainofBonesTimer = 5000; //timer wrong (maybe)
RainBones = false;
Skeletons = false;
}
void UpdateAI(uint32 diff)
{
if (Intro)
{
if (MovePhase)
{
if (MovePhase >= 7)
{
me->SetDisableGravity(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
}
else
{
me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]);
}
MovePhase = 0;
}
return;
}
if (Flying && MovePhase)
{
if (MovePhase >= 7)
{
me->SetDisableGravity(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
}
else
me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]);
MovePhase = 0;
}
if (!UpdateVictim())
return;
if (Flying)
return;
// Phase 1 "GROUND FIGHT"
if (Phase == 1)
{
if (Movement)
{
DoStartMovement(me->GetVictim());
Movement = false;
}
if (BellowingRoarTimer <= diff)
{
DoCastVictim(SPELL_BELLOWING_ROAR);
BellowingRoarTimer = urand(30000, 40000);
} else BellowingRoarTimer -= diff;
if (SmolderingBreathTimer <= diff)
{
DoCastVictim(SPELL_SMOLDERING_BREATH);
SmolderingBreathTimer = 20000;
} else SmolderingBreathTimer -= diff;
if (CharredEarthTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_CHARRED_EARTH);
CharredEarthTimer = 20000;
} else CharredEarthTimer -= diff;
if (TailSweepTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
if (!me->HasInArc(M_PI, target))
DoCast(target, SPELL_TAIL_SWEEP);
TailSweepTimer = 15000;
} else TailSweepTimer -= diff;
if (SearingCindersTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_SEARING_CINDERS);
SearingCindersTimer = 10000;
} else SearingCindersTimer -= diff;
uint32 Prozent = uint32(me->GetHealthPct());
if (Prozent < 75 && FlyCount == 0) // first take off 75%
TakeOff();
if (Prozent < 50 && FlyCount == 1) // secound take off 50%
TakeOff();
if (Prozent < 25 && FlyCount == 2) // third take off 25%
TakeOff();
DoMeleeAttackIfReady();
}
//Phase 2 "FLYING FIGHT"
if (Phase == 2)
{
if (!RainBones)
{
if (!Skeletons)
{
for (uint8 i = 0; i <= 3; ++i)
{
DoCastVictim(SPELL_SUMMON_SKELETON);
Skeletons = true;
}
}
if (RainofBonesTimer < diff && !RainBones) // only once at the beginning of phase 2
{
DoCastVictim(SPELL_RAIN_OF_BONES);
RainBones = true;
SmokingBlastTimer = 20000;
} else RainofBonesTimer -= diff;
if (DistractingAshTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_DISTRACTING_ASH);
DistractingAshTimer = 2000; //timer wrong
} else DistractingAshTimer -= diff;
}
if (RainBones)
{
if (SmokingBlastTimer <= diff)
{
DoCastVictim(SPELL_SMOKING_BLAST);
SmokingBlastTimer = 1500; //timer wrong
} else SmokingBlastTimer -= diff;
}
if (FireballBarrageTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0))
DoCast(target, SPELL_FIREBALL_BARRAGE);
FireballBarrageTimer = 20000;
} else FireballBarrageTimer -= diff;
if (FlyTimer <= diff) //landing
{
Talk(YELL_LAND_PHASE);
me->GetMotionMaster()->Clear(false);
me->GetMotionMaster()->MovePoint(3, IntroWay[3][0], IntroWay[3][1], IntroWay[3][2]);
Flying = true;
} else FlyTimer -= diff;
}
}
};
};
class go_blackened_urn : public GameObjectScript
{
public:
go_blackened_urn() : GameObjectScript("go_blackened_urn") { }
bool OnGossipHello(Player* pPlayer, GameObject *pGo)
{
if (InstanceScript* pInstance = pGo->GetInstanceScript())
{
if (pInstance->GetData(TYPE_NIGHTBANE) != DONE && !pGo->FindNearestCreature(17225, 40.0f))
if (Creature *cr = ObjectAccessor::GetCreature(*pPlayer, pInstance->GetData64(DATA_NIGHTBANE)))
cr->GetMotionMaster()->MovePoint(0, IntroWay[0][0], IntroWay[0][1], IntroWay[0][2]);
}
return false;
}
};
void AddSC_boss_nightbane()
{
new boss_nightbane();
new go_blackened_urn();
}

View File

@@ -1,596 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Prince_Malchezzar
SD%Complete: 100
SDComment:
SDCategory: Karazhan
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
#include "SpellInfo.h"
// 18 Coordinates for Infernal spawns
struct InfernalPoint
{
float x, y;
};
#define INFERNAL_Z 275.5f
static InfernalPoint InfernalPoints[] =
{
{-10922.8f, -1985.2f},
{-10916.2f, -1996.2f},
{-10932.2f, -2008.1f},
{-10948.8f, -2022.1f},
{-10958.7f, -1997.7f},
{-10971.5f, -1997.5f},
{-10990.8f, -1995.1f},
{-10989.8f, -1976.5f},
{-10971.6f, -1973.0f},
{-10955.5f, -1974.0f},
{-10939.6f, -1969.8f},
{-10958.0f, -1952.2f},
{-10941.7f, -1954.8f},
{-10943.1f, -1988.5f},
{-10948.8f, -2005.1f},
{-10984.0f, -2019.3f},
{-10932.8f, -1979.6f},
{-10935.7f, -1996.0f}
};
//Enfeeble is supposed to reduce hp to 1 and then heal player back to full when it ends
//Along with reducing healing and regen while enfeebled to 0%
//This spell effect will only reduce healing
enum PrinceMalchezaar
{
SAY_AGGRO = 0,
SAY_AXE_TOSS1 = 1,
SAY_AXE_TOSS2 = 2,
// SAY_SPECIAL1 = 3, Not used, needs to be implemented, but I don't know where it should be used.
// SAY_SPECIAL2 = 4, Not used, needs to be implemented, but I don't know where it should be used.
// SAY_SPECIAL3 = 5, Not used, needs to be implemented, but I don't know where it should be used.
SAY_SLAY = 6,
SAY_SUMMON = 7,
SAY_DEATH = 8,
TOTAL_INFERNAL_POINTS = 18,
SPELL_ENFEEBLE = 30843, //Enfeeble during phase 1 and 2
SPELL_ENFEEBLE_EFFECT = 41624,
SPELL_SHADOWNOVA = 30852, //Shadownova used during all phases
SPELL_SW_PAIN = 30854, //Shadow word pain during phase 1 and 3 (different targeting rules though)
SPELL_THRASH_PASSIVE = 12787, //Extra attack chance during phase 2
SPELL_SUNDER_ARMOR = 30901, //Sunder armor during phase 2
SPELL_THRASH_AURA = 12787, //Passive proc chance for thrash
SPELL_EQUIP_AXES = 30857, //Visual for axe equiping
SPELL_AMPLIFY_DAMAGE = 39095, //Amplifiy during phase 3
SPELL_CLEAVE = 30131, //Same as Nightbane.
SPELL_HELLFIRE = 30859, //Infenals' hellfire aura
NETHERSPITE_INFERNAL = 17646, //The netherspite infernal creature
MALCHEZARS_AXE = 17650, //Malchezar's axes (creatures), summoned during phase 3
INFERNAL_MODEL_INVISIBLE = 11686, //Infernal Effects
SPELL_INFERNAL_RELAY = 30834,
EQUIP_ID_AXE = 33542 //Axes info
};
//---------Infernal code first
class netherspite_infernal : public CreatureScript
{
public:
netherspite_infernal() : CreatureScript("netherspite_infernal") { }
CreatureAI* GetAI(Creature* creature) const
{
return new netherspite_infernalAI(creature);
}
struct netherspite_infernalAI : public ScriptedAI
{
netherspite_infernalAI(Creature* creature) : ScriptedAI(creature),
HellfireTimer(0), CleanupTimer(0), malchezaar(0), point(NULL) { }
uint32 HellfireTimer;
uint32 CleanupTimer;
uint64 malchezaar;
InfernalPoint *point;
void Reset() { }
void EnterCombat(Unit* /*who*/) { }
void MoveInLineOfSight(Unit* /*who*/) { }
void UpdateAI(uint32 diff)
{
if (HellfireTimer)
{
if (HellfireTimer <= diff)
{
DoCast(me, SPELL_HELLFIRE);
HellfireTimer = 0;
}
else HellfireTimer -= diff;
}
if (CleanupTimer)
{
if (CleanupTimer <= diff)
{
Cleanup();
CleanupTimer = 0;
} else CleanupTimer -= diff;
}
}
void KilledUnit(Unit* who)
{
if (Unit* unit = ObjectAccessor::GetUnit(*me, malchezaar))
if (Creature* creature = unit->ToCreature())
creature->AI()->KilledUnit(who);
}
void SpellHit(Unit* /*who*/, const SpellInfo* spell)
{
if (spell->Id == SPELL_INFERNAL_RELAY)
{
me->SetDisplayId(me->GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID));
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
HellfireTimer = 4000;
CleanupTimer = 170000;
}
}
void DamageTaken(Unit* done_by, uint32 &damage, DamageEffectType, SpellSchoolMask)
{
if (!done_by || done_by->GetGUID() != malchezaar)
damage = 0;
}
void Cleanup();
};
};
class boss_malchezaar : public CreatureScript
{
public:
boss_malchezaar() : CreatureScript("boss_malchezaar") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_malchezaarAI>(creature);
}
struct boss_malchezaarAI : public ScriptedAI
{
boss_malchezaarAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
memset(axes, 0, sizeof(axes));
}
InstanceScript* instance;
uint32 EnfeebleTimer;
uint32 EnfeebleResetTimer;
uint32 ShadowNovaTimer;
uint32 SWPainTimer;
uint32 SunderArmorTimer;
uint32 AmplifyDamageTimer;
uint32 Cleave_Timer;
uint32 InfernalTimer;
uint32 AxesTargetSwitchTimer;
uint32 InfernalCleanupTimer;
std::vector<uint64> infernals;
std::vector<InfernalPoint*> positions;
uint64 axes[2];
uint64 enfeeble_targets[5];
uint32 enfeeble_health[5];
uint32 phase;
void Reset()
{
AxesCleanup();
ClearWeapons();
InfernalCleanup();
positions.clear();
for (uint8 i = 0; i < 5; ++i)
{
enfeeble_targets[i] = 0;
enfeeble_health[i] = 0;
}
for (uint8 i = 0; i < TOTAL_INFERNAL_POINTS; ++i)
positions.push_back(&InfernalPoints[i]);
EnfeebleTimer = 30000;
EnfeebleResetTimer = 38000;
ShadowNovaTimer = 35500;
SWPainTimer = 20000;
AmplifyDamageTimer = 5000;
Cleave_Timer = 8000;
InfernalTimer = 40000;
InfernalCleanupTimer = 47000;
AxesTargetSwitchTimer = urand(7500, 20000);
SunderArmorTimer = urand(5000, 10000);
phase = 1;
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), true);
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
AxesCleanup();
ClearWeapons();
InfernalCleanup();
positions.clear();
for (uint8 i = 0; i < TOTAL_INFERNAL_POINTS; ++i)
positions.push_back(&InfernalPoints[i]);
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), true);
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
instance->HandleGameObject(instance->GetData64(DATA_GO_NETHER_DOOR), false); // Open the door leading further in
}
void InfernalCleanup()
{
//Infernal Cleanup
for (std::vector<uint64>::const_iterator itr = infernals.begin(); itr != infernals.end(); ++itr)
if (Unit* pInfernal = ObjectAccessor::GetUnit(*me, *itr))
if (pInfernal->IsAlive())
{
pInfernal->SetVisible(false);
pInfernal->setDeathState(JUST_DIED);
}
infernals.clear();
}
void AxesCleanup()
{
for (uint8 i = 0; i < 2; ++i)
{
Unit* axe = ObjectAccessor::GetUnit(*me, axes[i]);
if (axe && axe->IsAlive())
Unit::Kill(axe, axe);
axes[i] = 0;
}
}
void ClearWeapons()
{
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
me->SetCanDualWield(false);
}
void EnfeebleHealthEffect()
{
const SpellInfo* info = sSpellMgr->GetSpellInfo(SPELL_ENFEEBLE_EFFECT);
if (!info)
return;
ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList();
std::vector<Unit*> targets;
if (t_list.empty())
return;
//begin + 1, so we don't target the one with the highest threat
ThreatContainer::StorageType::const_iterator itr = t_list.begin();
std::advance(itr, 1);
for (; itr != t_list.end(); ++itr) //store the threat list in a different container
if (Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid()))
if (target->IsAlive() && target->GetTypeId() == TYPEID_PLAYER)
targets.push_back(target);
//cut down to size if we have more than 5 targets
while (targets.size() > 5)
targets.erase(targets.begin()+rand()%targets.size());
uint32 i = 0;
for (std::vector<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter, ++i)
if (Unit* target = *iter)
{
enfeeble_targets[i] = target->GetGUID();
enfeeble_health[i] = target->GetHealth();
target->CastSpell(target, SPELL_ENFEEBLE, true, 0, 0, me->GetGUID());
target->SetHealth(1);
}
}
void EnfeebleResetHealth()
{
for (uint8 i = 0; i < 5; ++i)
{
Unit* target = ObjectAccessor::GetUnit(*me, enfeeble_targets[i]);
if (target && target->IsAlive())
target->SetHealth(enfeeble_health[i]);
enfeeble_targets[i] = 0;
enfeeble_health[i] = 0;
}
}
void SummonInfernal(const uint32 /*diff*/)
{
InfernalPoint *point = NULL;
Position pos;
if ((me->GetMapId() != 532) || positions.empty())
me->GetRandomNearPosition(pos, 60);
else
{
point = Trinity::Containers::SelectRandomContainerElement(positions);
pos.Relocate(point->x, point->y, INFERNAL_Z, frand(0.0f, float(M_PI * 2)));
}
Creature* infernal = me->SummonCreature(NETHERSPITE_INFERNAL, pos, TEMPSUMMON_TIMED_DESPAWN, 180000);
if (infernal)
{
infernal->SetDisplayId(INFERNAL_MODEL_INVISIBLE);
infernal->setFaction(me->getFaction());
if (point)
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->point=point;
CAST_AI(netherspite_infernal::netherspite_infernalAI, infernal->AI())->malchezaar=me->GetGUID();
infernals.push_back(infernal->GetGUID());
DoCast(infernal, SPELL_INFERNAL_RELAY);
}
Talk(SAY_SUMMON);
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
if (EnfeebleResetTimer && EnfeebleResetTimer <= diff) // Let's not forget to reset that
{
EnfeebleResetHealth();
EnfeebleResetTimer = 0;
} else EnfeebleResetTimer -= diff;
if (me->HasUnitState(UNIT_STATE_STUNNED)) // While shifting to phase 2 malchezaar stuns himself
return;
if (me->GetUInt64Value(UNIT_FIELD_TARGET) != me->GetVictim()->GetGUID())
me->SetTarget(me->GetVictim()->GetGUID());
if (phase == 1)
{
if (HealthBelowPct(60))
{
me->InterruptNonMeleeSpells(false);
phase = 2;
//animation
DoCast(me, SPELL_EQUIP_AXES);
//text
Talk(SAY_AXE_TOSS1);
//passive thrash aura
DoCast(me, SPELL_THRASH_AURA, true);
//models
SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE, EQUIP_NO_CHANGE);
me->SetAttackTime(OFF_ATTACK, (me->GetAttackTime(BASE_ATTACK)*150)/100);
me->SetCanDualWield(true);
}
}
else if (phase == 2)
{
if (HealthBelowPct(30))
{
InfernalTimer = 15000;
phase = 3;
ClearWeapons();
//remove thrash
me->RemoveAurasDueToSpell(SPELL_THRASH_AURA);
Talk(SAY_AXE_TOSS2);
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
for (uint8 i = 0; i < 2; ++i)
{
Creature* axe = me->SummonCreature(MALCHEZARS_AXE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);
if (axe)
{
axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
axe->setFaction(me->getFaction());
axes[i] = axe->GetGUID();
if (target)
{
axe->AI()->AttackStart(target);
//axe->getThreatManager().tauntApply(target); //Taunt Apply and fade out does not work properly
// So we'll use a hack to add a lot of threat to our target
axe->AddThreat(target, 10000000.0f);
}
}
}
if (ShadowNovaTimer > 35000)
ShadowNovaTimer = EnfeebleTimer + 5000;
return;
}
if (SunderArmorTimer <= diff)
{
DoCastVictim(SPELL_SUNDER_ARMOR);
SunderArmorTimer = urand(10000, 18000);
} else SunderArmorTimer -= diff;
if (Cleave_Timer <= diff)
{
DoCastVictim(SPELL_CLEAVE);
Cleave_Timer = urand(6000, 12000);
} else Cleave_Timer -= diff;
}
else
{
if (AxesTargetSwitchTimer <= diff)
{
AxesTargetSwitchTimer = urand(7500, 20000);
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
{
for (uint8 i = 0; i < 2; ++i)
{
if (Unit* axe = ObjectAccessor::GetUnit(*me, axes[i]))
{
if (axe->GetVictim())
DoModifyThreatPercent(axe->GetVictim(), -100);
if (target)
axe->AddThreat(target, 1000000.0f);
//axe->getThreatManager().tauntFadeOut(axe->GetVictim());
//axe->getThreatManager().tauntApply(target);
}
}
}
} else AxesTargetSwitchTimer -= diff;
if (AmplifyDamageTimer <= diff)
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_AMPLIFY_DAMAGE);
AmplifyDamageTimer = urand(20000, 30000);
} else AmplifyDamageTimer -= diff;
}
//Time for global and double timers
if (InfernalTimer <= diff)
{
SummonInfernal(diff);
InfernalTimer = phase == 3 ? 14500 : 44500; // 15 secs in phase 3, 45 otherwise
} else InfernalTimer -= diff;
if (ShadowNovaTimer <= diff)
{
DoCastVictim(SPELL_SHADOWNOVA);
ShadowNovaTimer = phase == 3 ? 31000 : uint32(-1);
} else ShadowNovaTimer -= diff;
if (phase != 2)
{
if (SWPainTimer <= diff)
{
Unit* target = NULL;
if (phase == 1)
target = me->GetVictim(); // the tank
else // anyone but the tank
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
if (target)
DoCast(target, SPELL_SW_PAIN);
SWPainTimer = 20000;
} else SWPainTimer -= diff;
}
if (phase != 3)
{
if (EnfeebleTimer <= diff)
{
EnfeebleHealthEffect();
EnfeebleTimer = 30000;
ShadowNovaTimer = 5000;
EnfeebleResetTimer = 9000;
} else EnfeebleTimer -= diff;
}
if (phase == 2)
DoMeleeAttacksIfReady();
else
DoMeleeAttackIfReady();
}
void DoMeleeAttacksIfReady()
{
if (me->IsWithinMeleeRange(me->GetVictim()) && !me->IsNonMeleeSpellCast(false))
{
//Check for base attack
if (me->isAttackReady() && me->GetVictim())
{
me->AttackerStateUpdate(me->GetVictim());
me->resetAttackTimer();
}
//Check for offhand attack
if (me->isAttackReady(OFF_ATTACK) && me->GetVictim())
{
me->AttackerStateUpdate(me->GetVictim(), OFF_ATTACK);
me->resetAttackTimer(OFF_ATTACK);
}
}
}
void Cleanup(Creature* infernal, InfernalPoint *point)
{
for (std::vector<uint64>::iterator itr = infernals.begin(); itr!= infernals.end(); ++itr)
if (*itr == infernal->GetGUID())
{
infernals.erase(itr);
break;
}
positions.push_back(point);
}
};
};
void netherspite_infernal::netherspite_infernalAI::Cleanup()
{
Creature* pMalchezaar = ObjectAccessor::GetCreature(*me, malchezaar);
if (pMalchezaar && pMalchezaar->IsAlive())
CAST_AI(boss_malchezaar::boss_malchezaarAI, pMalchezaar->AI())->Cleanup(me, point);
}
void AddSC_boss_malchezaar()
{
new boss_malchezaar();
new netherspite_infernal();
}

View File

@@ -1,165 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
enum ServantQuartersSpells
{
SPELL_SNEAK = 22766,
SPELL_ACIDIC_FANG = 29901,
SPELL_HYAKISS_WEB = 29896,
SPELL_DIVE = 29903,
SPELL_SONIC_BURST = 29904,
SPELL_WING_BUFFET = 29905,
SPELL_FEAR = 29321,
SPELL_RAVAGE = 29906
};
enum ServantQuertersMisc
{
EVENT_SPELL_ACIDIC_FANG = 1,
EVENT_SPELL_HYAKISS_WEB = 2,
EVENT_SPELL_DIVE = 10,
EVENT_SPELL_SONIC_BURST = 11,
EVENT_SPELL_WING_BUFFET = 12,
EVENT_SPELL_FEAR = 13,
EVENT_SPELL_RAVAGE = 20,
EVENT_CHECK_VISIBILITY = 30
};
class boss_servant_quarters : public CreatureScript
{
public:
boss_servant_quarters() : CreatureScript("boss_servant_quarters") { }
struct boss_servant_quartersAI : public BossAI
{
boss_servant_quartersAI(Creature* creature) : BossAI(creature, TYPE_SERVANT_QUARTERS) { }
void Reset()
{
events.Reset();
me->SetVisible(false);
me->SetReactState(REACT_PASSIVE);
me->setFaction(35);
_events2.Reset();
_events2.ScheduleEvent(EVENT_CHECK_VISIBILITY, 5000);
if (me->GetEntry() == NPC_HYAKISS_THE_LURKER)
me->CastSpell(me, SPELL_SNEAK, true);
if (instance->GetData(DATA_SELECTED_RARE) != me->GetEntry())
me->DespawnOrUnsummon(1);
}
void EnterCombat(Unit* who)
{
me->setActive(true);
if (me->GetEntry() == NPC_HYAKISS_THE_LURKER)
{
events.ScheduleEvent(EVENT_SPELL_ACIDIC_FANG, 5000);
events.ScheduleEvent(EVENT_SPELL_HYAKISS_WEB, 9000);
}
else if (me->GetEntry() == NPC_SHADIKITH_THE_GLIDER)
{
events.ScheduleEvent(EVENT_SPELL_SONIC_BURST, 4000);
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 7000);
events.ScheduleEvent(EVENT_SPELL_DIVE, 10000);
}
else // if (me->GetEntry() == NPC_ROKAD_THE_RAVAGER)
{
events.ScheduleEvent(EVENT_SPELL_RAVAGE, 3000);
}
}
void JustDied(Unit* /*who*/)
{
}
void MovementInform(uint32 type, uint32 point)
{
if (type == POINT_MOTION_TYPE && point == EVENT_CHARGE)
events.ScheduleEvent(EVENT_SPELL_FEAR, 0);
}
void UpdateAI(uint32 diff)
{
_events2.Update(diff);
switch (_events2.ExecuteEvent())
{
case EVENT_CHECK_VISIBILITY:
if (instance->GetBossState(TYPE_SERVANT_QUARTERS) == DONE)
{
me->SetVisible(true);
me->SetReactState(REACT_AGGRESSIVE);
me->RestoreFaction();
}
else
_events2.ScheduleEvent(EVENT_CHECK_VISIBILITY, 5000);
break;
}
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_ACIDIC_FANG:
me->CastSpell(me->GetVictim(), SPELL_ACIDIC_FANG, false);
events.ScheduleEvent(EVENT_SPELL_ACIDIC_FANG, urand(12000, 18000));
break;
case EVENT_SPELL_HYAKISS_WEB:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 30.0f))
me->CastSpell(target, SPELL_HYAKISS_WEB, false);
events.ScheduleEvent(EVENT_SPELL_HYAKISS_WEB, 15000);
break;
case EVENT_SPELL_SONIC_BURST:
me->CastSpell(me, SPELL_SONIC_BURST, false);
events.ScheduleEvent(EVENT_SPELL_SONIC_BURST, urand(12000, 18000));
break;
case EVENT_SPELL_WING_BUFFET:
me->CastSpell(me, SPELL_WING_BUFFET, false);
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, urand(12000, 18000));
break;
case EVENT_SPELL_DIVE:
if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0, FarthestTargetSelector(me, 40.0f, false, true)))
me->CastSpell(target, SPELL_DIVE, false);
events.ScheduleEvent(EVENT_SPELL_DIVE, 20000);
break;
case EVENT_SPELL_FEAR:
me->CastSpell(me->GetVictim(), SPELL_FEAR, false);
break;
case EVENT_SPELL_RAVAGE:
me->CastSpell(me->GetVictim(), SPELL_RAVAGE, false);
events.ScheduleEvent(EVENT_SPELL_RAVAGE, 10500);
break;
}
DoMeleeAttackIfReady();
}
private:
EventMap _events2;
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_servant_quartersAI>(creature);
}
};
void AddSC_boss_servant_quarters()
{
new boss_servant_quarters();
}

View File

@@ -1,514 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
#include "GameObject.h"
#include "SpellInfo.h"
enum ShadeOfAran
{
SAY_AGGRO = 0,
SAY_FLAMEWREATH = 1,
SAY_BLIZZARD = 2,
SAY_EXPLOSION = 3,
SAY_DRINK = 4,
SAY_ELEMENTALS = 5,
SAY_KILL = 6,
SAY_TIMEOVER = 7,
SAY_DEATH = 8,
//Spells
SPELL_FROSTBOLT = 29954,
SPELL_FIREBALL = 29953,
SPELL_ARCMISSLE = 29955,
SPELL_CHAINSOFICE = 29991,
SPELL_DRAGONSBREATH = 29964,
SPELL_MASSSLOW = 30035,
SPELL_FLAME_WREATH = 29946,
SPELL_AOE_CS = 29961,
SPELL_PLAYERPULL = 32265,
SPELL_AEXPLOSION = 29973,
SPELL_MASS_POLY = 29963,
SPELL_BLINK_CENTER = 29967,
SPELL_ELEMENTALS = 29962,
SPELL_CONJURE = 29975,
SPELL_DRINK = 30024,
SPELL_POTION = 32453,
SPELL_AOE_PYROBLAST = 29978,
//Creature Spells
SPELL_CIRCULAR_BLIZZARD = 29951,
SPELL_WATERBOLT = 31012,
SPELL_SHADOW_PYRO = 29978,
//Creatures
CREATURE_WATER_ELEMENTAL = 17167,
CREATURE_SHADOW_OF_ARAN = 18254,
CREATURE_ARAN_BLIZZARD = 17161,
};
enum SuperSpell
{
SUPER_FLAME = 0,
SUPER_BLIZZARD,
SUPER_AE,
};
class boss_shade_of_aran : public CreatureScript
{
public:
boss_shade_of_aran() : CreatureScript("boss_shade_of_aran") { }
struct boss_aranAI : public BossAI
{
boss_aranAI(Creature* creature) : BossAI(creature, TYPE_ARAN)
{
}
uint32 SecondarySpellTimer;
uint32 NormalCastTimer;
uint32 SuperCastTimer;
uint32 BerserkTimer;
uint32 CloseDoorTimer; // Don't close the door right on aggro in case some people are still entering.
uint8 LastSuperSpell;
uint32 FlameWreathTimer;
uint32 FlameWreathCheckTime;
uint64 FlameWreathTarget[3];
float FWTargPosX[3];
float FWTargPosY[3];
uint32 CurrentNormalSpell;
uint32 ArcaneCooldown;
uint32 FireCooldown;
uint32 FrostCooldown;
uint32 DrinkInterruptTimer;
bool ElementalsSpawned;
bool Drinking;
bool DrinkInturrupted;
void Reset()
{
SecondarySpellTimer = 5000;
NormalCastTimer = 0;
SuperCastTimer = 35000;
BerserkTimer = 720000;
CloseDoorTimer = 15000;
LastSuperSpell = rand()%3;
FlameWreathTimer = 0;
FlameWreathCheckTime = 0;
CurrentNormalSpell = 0;
ArcaneCooldown = 0;
FireCooldown = 0;
FrostCooldown = 0;
DrinkInterruptTimer = 10000;
ElementalsSpawned = false;
Drinking = false;
DrinkInturrupted = false;
// Not in progress
instance->SetData(TYPE_ARAN, NOT_STARTED);
instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), true);
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_KILL);
}
void JustDied(Unit* /*killer*/)
{
Talk(SAY_DEATH);
instance->SetData(TYPE_ARAN, DONE);
instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), true);
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
instance->SetData(TYPE_ARAN, IN_PROGRESS);
instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), false);
}
void FlameWreathEffect()
{
std::vector<Unit*> targets;
ThreatContainer::StorageType const &t_list = me->getThreatManager().getThreatList();
if (t_list.empty())
return;
//store the threat list in a different container
for (ThreatContainer::StorageType::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
{
Unit* target = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
//only on alive players
if (target && target->IsAlive() && target->GetTypeId() == TYPEID_PLAYER)
targets.push_back(target);
}
//cut down to size if we have more than 3 targets
while (targets.size() > 3)
targets.erase(targets.begin()+rand()%targets.size());
uint32 i = 0;
for (std::vector<Unit*>::const_iterator itr = targets.begin(); itr!= targets.end(); ++itr)
{
if (*itr)
{
FlameWreathTarget[i] = (*itr)->GetGUID();
FWTargPosX[i] = (*itr)->GetPositionX();
FWTargPosY[i] = (*itr)->GetPositionY();
DoCast((*itr), SPELL_FLAME_WREATH, true);
++i;
}
}
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
if (CloseDoorTimer)
{
if (CloseDoorTimer <= diff)
{
instance->HandleGameObject(instance->GetData64(DATA_GO_LIBRARY_DOOR), false);
CloseDoorTimer = 0;
} else CloseDoorTimer -= diff;
}
//Cooldowns for casts
if (ArcaneCooldown)
{
if (ArcaneCooldown >= diff)
ArcaneCooldown -= diff;
else ArcaneCooldown = 0;
}
if (FireCooldown)
{
if (FireCooldown >= diff)
FireCooldown -= diff;
else FireCooldown = 0;
}
if (FrostCooldown)
{
if (FrostCooldown >= diff)
FrostCooldown -= diff;
else FrostCooldown = 0;
}
if (!Drinking && me->GetMaxPower(POWER_MANA) && (me->GetPower(POWER_MANA)*100 / me->GetMaxPower(POWER_MANA)) < 20)
{
Drinking = true;
me->InterruptNonMeleeSpells(false);
Talk(SAY_DRINK);
if (!DrinkInturrupted)
{
DoCast(me, SPELL_MASS_POLY, true);
DoCast(me, SPELL_CONJURE, false);
DoCast(me, SPELL_DRINK, false);
me->SetStandState(UNIT_STAND_STATE_SIT);
DrinkInterruptTimer = 10000;
}
}
//Drink Interrupt
if (Drinking && DrinkInturrupted)
{
Drinking = false;
me->RemoveAurasDueToSpell(SPELL_DRINK);
me->SetStandState(UNIT_STAND_STATE_STAND);
me->SetPower(POWER_MANA, me->GetMaxPower(POWER_MANA)-32000);
DoCast(me, SPELL_POTION, false);
}
//Drink Interrupt Timer
if (Drinking && !DrinkInturrupted)
{
if (DrinkInterruptTimer >= diff)
DrinkInterruptTimer -= diff;
else
{
me->SetStandState(UNIT_STAND_STATE_STAND);
DoCast(me, SPELL_POTION, true);
DoCast(me, SPELL_AOE_PYROBLAST, false);
DrinkInturrupted = true;
Drinking = false;
}
}
//Don't execute any more code if we are drinking
if (Drinking)
return;
//Normal casts
if (NormalCastTimer <= diff)
{
if (!me->IsNonMeleeSpellCast(false))
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
if (!target)
return;
uint32 Spells[3];
uint8 AvailableSpells = 0;
//Check for what spells are not on cooldown
if (!ArcaneCooldown)
{
Spells[AvailableSpells] = SPELL_ARCMISSLE;
++AvailableSpells;
}
if (!FireCooldown)
{
Spells[AvailableSpells] = SPELL_FIREBALL;
++AvailableSpells;
}
if (!FrostCooldown)
{
Spells[AvailableSpells] = SPELL_FROSTBOLT;
++AvailableSpells;
}
//If no available spells wait 1 second and try again
if (AvailableSpells)
{
CurrentNormalSpell = Spells[rand() % AvailableSpells];
DoCast(target, CurrentNormalSpell);
}
}
NormalCastTimer = 1000;
} else NormalCastTimer -= diff;
if (SecondarySpellTimer <= diff)
{
switch (urand(0, 1))
{
case 0:
DoCast(me, SPELL_AOE_CS);
break;
case 1:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_CHAINSOFICE);
break;
}
SecondarySpellTimer = urand(5000, 20000);
} else SecondarySpellTimer -= diff;
if (SuperCastTimer <= diff)
{
uint8 Available[2];
switch (LastSuperSpell)
{
case SUPER_AE:
Available[0] = SUPER_FLAME;
Available[1] = SUPER_BLIZZARD;
break;
case SUPER_FLAME:
Available[0] = SUPER_AE;
Available[1] = SUPER_BLIZZARD;
break;
case SUPER_BLIZZARD:
Available[0] = SUPER_FLAME;
Available[1] = SUPER_AE;
break;
}
LastSuperSpell = Available[urand(0, 1)];
switch (LastSuperSpell)
{
case SUPER_AE:
Talk(SAY_EXPLOSION);
DoCast(me, SPELL_BLINK_CENTER, true);
DoCast(me, SPELL_PLAYERPULL, true);
DoCast(me, SPELL_MASSSLOW, true);
DoCast(me, SPELL_AEXPLOSION, false);
break;
case SUPER_FLAME:
Talk(SAY_FLAMEWREATH);
FlameWreathTimer = 20000;
FlameWreathCheckTime = 500;
FlameWreathTarget[0] = 0;
FlameWreathTarget[1] = 0;
FlameWreathTarget[2] = 0;
FlameWreathEffect();
break;
case SUPER_BLIZZARD:
Talk(SAY_BLIZZARD);
if (Creature* pSpawn = me->SummonCreature(CREATURE_ARAN_BLIZZARD, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 25000))
{
pSpawn->setFaction(me->getFaction());
pSpawn->CastSpell(pSpawn, SPELL_CIRCULAR_BLIZZARD, false);
}
break;
}
SuperCastTimer = urand(35000, 40000);
} else SuperCastTimer -= diff;
if (!ElementalsSpawned && HealthBelowPct(40))
{
ElementalsSpawned = true;
for (uint32 i = 0; i < 4; ++i)
{
if (Creature* unit = me->SummonCreature(CREATURE_WATER_ELEMENTAL, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 90000))
{
unit->Attack(me->GetVictim(), true);
unit->setFaction(me->getFaction());
}
}
Talk(SAY_ELEMENTALS);
}
if (BerserkTimer <= diff)
{
for (uint32 i = 0; i < 5; ++i)
{
if (Creature* unit = me->SummonCreature(CREATURE_SHADOW_OF_ARAN, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000))
{
unit->Attack(me->GetVictim(), true);
unit->setFaction(me->getFaction());
}
}
Talk(SAY_TIMEOVER);
BerserkTimer = 60000;
} else BerserkTimer -= diff;
//Flame Wreath check
if (FlameWreathTimer)
{
if (FlameWreathTimer >= diff)
FlameWreathTimer -= diff;
else FlameWreathTimer = 0;
if (FlameWreathCheckTime <= diff)
{
for (uint8 i = 0; i < 3; ++i)
{
if (!FlameWreathTarget[i])
continue;
Unit* unit = ObjectAccessor::GetUnit(*me, FlameWreathTarget[i]);
if (unit && !unit->IsWithinDist2d(FWTargPosX[i], FWTargPosY[i], 3))
{
unit->CastSpell(unit, 20476, true, 0, 0, me->GetGUID());
unit->CastSpell(unit, 11027, true);
FlameWreathTarget[i] = 0;
}
}
FlameWreathCheckTime = 500;
} else FlameWreathCheckTime -= diff;
}
if (ArcaneCooldown && FireCooldown && FrostCooldown)
DoMeleeAttackIfReady();
}
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
{
if (!DrinkInturrupted && Drinking && damage)
DrinkInturrupted = true;
}
void SpellHit(Unit* /*pAttacker*/, const SpellInfo* Spell)
{
//We only care about interrupt effects and only if they are durring a spell currently being cast
if ((Spell->Effects[0].Effect != SPELL_EFFECT_INTERRUPT_CAST &&
Spell->Effects[1].Effect != SPELL_EFFECT_INTERRUPT_CAST &&
Spell->Effects[2].Effect != SPELL_EFFECT_INTERRUPT_CAST) || !me->IsNonMeleeSpellCast(false))
return;
//Interrupt effect
me->InterruptNonMeleeSpells(false);
//Normally we would set the cooldown equal to the spell duration
//but we do not have access to the DurationStore
switch (CurrentNormalSpell)
{
case SPELL_ARCMISSLE: ArcaneCooldown = 5000; break;
case SPELL_FIREBALL: FireCooldown = 5000; break;
case SPELL_FROSTBOLT: FrostCooldown = 5000; break;
}
}
};
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_aranAI>(creature);
}
};
class npc_aran_elemental : public CreatureScript
{
public:
npc_aran_elemental() : CreatureScript("npc_aran_elemental") { }
CreatureAI* GetAI(Creature* creature) const
{
return new water_elementalAI(creature);
}
struct water_elementalAI : public ScriptedAI
{
water_elementalAI(Creature* creature) : ScriptedAI(creature) { }
uint32 CastTimer;
void Reset()
{
CastTimer = 2000 + (rand()%3000);
}
void EnterCombat(Unit* /*who*/) { }
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
if (CastTimer <= diff)
{
DoCastVictim(SPELL_WATERBOLT);
CastTimer = urand(2000, 5000);
} else CastTimer -= diff;
}
};
};
void AddSC_boss_shade_of_aran()
{
new boss_shade_of_aran();
new npc_aran_elemental();
}

View File

@@ -1,426 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Terestian_Illhoof
SD%Complete: 95
SDComment: Complete! Needs adjustments to use spell though.
SDCategory: Karazhan
EndScriptData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "karazhan.h"
#include "PassiveAI.h"
enum TerestianIllhoof
{
SAY_SLAY = 1,
SAY_DEATH = 2,
SAY_AGGRO = 3,
SAY_SACRIFICE = 4,
SAY_SUMMON = 5
};
enum Spells
{
SPELL_SUMMON_DEMONCHAINS = 30120, // Summons demonic chains that maintain the ritual of sacrifice.
SPELL_DEMON_CHAINS = 30206, // Instant - Visual Effect
SPELL_ENRAGE = 23537, // Increases the caster's attack speed by 50% and the Physical damage it deals by 219 to 281 for 10 min.
SPELL_SHADOW_BOLT = 30055, // Hurls a bolt of dark magic at an enemy, inflicting Shadow damage.
SPELL_SACRIFICE = 30115, // Teleports and adds the debuff
SPELL_BERSERK = 32965, // Increases attack speed by 75%. Periodically casts Shadow Bolt Volley.
SPELL_SUMMON_FIENDISIMP = 30184, // Summons a Fiendish Imp.
SPELL_SUMMON_IMP = 30066, // Summons Kil'rek
SPELL_FIENDISH_PORTAL = 30171, // Opens portal and summons Fiendish Portal, 2 sec cast
SPELL_FIENDISH_PORTAL_1 = 30179, // Opens portal and summons Fiendish Portal, instant cast
SPELL_FIREBOLT = 30050, // Blasts a target for 150 Fire damage.
SPELL_BROKEN_PACT = 30065, // All damage taken increased by 25%.
SPELL_AMPLIFY_FLAMES = 30053, // Increases the Fire damage taken by an enemy by 500 for 25 sec.
};
enum Creatures
{
NPC_DEMONCHAINS = 17248,
NPC_FIENDISHIMP = 17267,
NPC_PORTAL = 17265,
NPC_KILREK = 17229
};
class npc_kilrek : public CreatureScript
{
public:
npc_kilrek() : CreatureScript("npc_kilrek") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<npc_kilrekAI>(creature);
}
struct npc_kilrekAI : public ScriptedAI
{
npc_kilrekAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint64 TerestianGUID;
uint32 AmplifyTimer;
void Reset()
{
TerestianGUID = 0;
AmplifyTimer = 2000;
}
void EnterCombat(Unit* /*who*/)
{
}
void JustDied(Unit* /*killer*/)
{
uint64 TerestianGUID = instance->GetData64(DATA_TERESTIAN);
if (TerestianGUID)
{
Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGUID);
if (Terestian && Terestian->IsAlive())
DoCast(Terestian, SPELL_BROKEN_PACT, true);
}
}
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (AmplifyTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCastVictim(SPELL_AMPLIFY_FLAMES);
AmplifyTimer = urand(10000, 20000);
} else AmplifyTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class npc_demon_chain : public CreatureScript
{
public:
npc_demon_chain() : CreatureScript("npc_demon_chain") { }
CreatureAI* GetAI(Creature* creature) const
{
return new npc_demon_chainAI(creature);
}
struct npc_demon_chainAI : public ScriptedAI
{
npc_demon_chainAI(Creature* creature) : ScriptedAI(creature) { }
uint64 SacrificeGUID;
void Reset()
{
SacrificeGUID = 0;
}
void EnterCombat(Unit* /*who*/) { }
void AttackStart(Unit* /*who*/) { }
void MoveInLineOfSight(Unit* /*who*/) { }
void JustDied(Unit* /*killer*/)
{
if (SacrificeGUID)
{
Unit* Sacrifice = ObjectAccessor::GetUnit(*me, SacrificeGUID);
if (Sacrifice)
Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE);
}
}
};
};
class npc_fiendish_portal : public CreatureScript
{
public:
npc_fiendish_portal() : CreatureScript("npc_fiendish_portal") { }
CreatureAI* GetAI(Creature* creature) const
{
return new npc_fiendish_portalAI(creature);
}
struct npc_fiendish_portalAI : public PassiveAI
{
npc_fiendish_portalAI(Creature* creature) : PassiveAI(creature), summons(me){ }
SummonList summons;
void Reset()
{
DespawnAllImp();
}
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
DoZoneInCombat(summon);
}
void DespawnAllImp()
{
summons.DespawnAll();
}
};
};
class npc_fiendish_imp : public CreatureScript
{
public:
npc_fiendish_imp() : CreatureScript("npc_fiendish_imp") { }
CreatureAI* GetAI(Creature* creature) const
{
return new npc_fiendish_impAI(creature);
}
struct npc_fiendish_impAI : public ScriptedAI
{
npc_fiendish_impAI(Creature* creature) : ScriptedAI(creature) { }
uint32 FireboltTimer;
void Reset()
{
FireboltTimer = 2000;
me->ApplySpellImmune(0, IMMUNITY_SCHOOL, SPELL_SCHOOL_MASK_FIRE, true);
}
void EnterCombat(Unit* /*who*/) { }
void UpdateAI(uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
if (FireboltTimer <= diff)
{
DoCastVictim(SPELL_FIREBOLT);
FireboltTimer = 2200;
} else FireboltTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class boss_terestian_illhoof : public CreatureScript
{
public:
boss_terestian_illhoof() : CreatureScript("boss_terestian_illhoof") { }
CreatureAI* GetAI(Creature* creature) const
{
return GetInstanceAI<boss_terestianAI>(creature);
}
struct boss_terestianAI : public ScriptedAI
{
boss_terestianAI(Creature* creature) : ScriptedAI(creature)
{
for (uint8 i = 0; i < 2; ++i)
PortalGUID[i] = 0;
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint64 PortalGUID[2];
uint8 PortalsCount;
uint32 SacrificeTimer;
uint32 ShadowboltTimer;
uint32 SummonTimer;
uint32 BerserkTimer;
bool SummonedPortals;
bool Berserk;
void Reset()
{
for (uint8 i = 0; i < 2; ++i)
{
if (PortalGUID[i])
{
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[i]))
{
CAST_AI(npc_fiendish_portal::npc_fiendish_portalAI, pPortal->AI())->DespawnAllImp();
pPortal->DespawnOrUnsummon();
}
PortalGUID[i] = 0;
}
}
PortalsCount = 0;
SacrificeTimer = 30000;
ShadowboltTimer = 5000;
SummonTimer = 10000;
BerserkTimer = 600000;
SummonedPortals = false;
Berserk = false;
instance->SetData(TYPE_TERESTIAN, NOT_STARTED);
me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);
if (Minion* Kilrek = me->GetFirstMinion())
{
if (!Kilrek->IsAlive())
{
Kilrek->UnSummon();
DoCast(me, SPELL_SUMMON_IMP, true);
}
}
else DoCast(me, SPELL_SUMMON_IMP, true);
}
void EnterCombat(Unit* /*who*/)
{
Talk(SAY_AGGRO);
}
void JustSummoned(Creature* summoned)
{
if (summoned->GetEntry() == NPC_PORTAL)
{
PortalGUID[PortalsCount] = summoned->GetGUID();
++PortalsCount;
if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1)
{
Talk(SAY_SUMMON);
SummonedPortals = true;
}
}
}
void KilledUnit(Unit* /*victim*/)
{
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/)
{
for (uint8 i = 0; i < 2; ++i)
{
if (PortalGUID[i])
{
if (Creature* pPortal = ObjectAccessor::GetCreature((*me), PortalGUID[i]))
pPortal->DespawnOrUnsummon();
PortalGUID[i] = 0;
}
}
Talk(SAY_DEATH);
instance->SetData(TYPE_TERESTIAN, DONE);
}
void UpdateAI(uint32 diff)
{
if (!UpdateVictim())
return;
if (SacrificeTimer <= diff)
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
if (target && target->IsAlive())
{
DoCast(target, SPELL_SACRIFICE, true);
DoCast(target, SPELL_SUMMON_DEMONCHAINS, true);
if (Creature* Chains = me->FindNearestCreature(NPC_DEMONCHAINS, 5000))
{
CAST_AI(npc_demon_chain::npc_demon_chainAI, Chains->AI())->SacrificeGUID = target->GetGUID();
Chains->CastSpell(Chains, SPELL_DEMON_CHAINS, true);
Talk(SAY_SACRIFICE);
SacrificeTimer = 30000;
}
}
} else SacrificeTimer -= diff;
if (ShadowboltTimer <= diff)
{
DoCast(SelectTarget(SELECT_TARGET_TOPAGGRO, 0), SPELL_SHADOW_BOLT);
ShadowboltTimer = 10000;
} else ShadowboltTimer -= diff;
if (SummonTimer <= diff)
{
if (!PortalGUID[0])
DoCastVictim(SPELL_FIENDISH_PORTAL, false);
if (!PortalGUID[1])
DoCastVictim(SPELL_FIENDISH_PORTAL_1, false);
if (PortalGUID[0] && PortalGUID[1])
{
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[urand(0, 1)]))
pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP, false);
SummonTimer = 5000;
}
} else SummonTimer -= diff;
if (!Berserk)
{
if (BerserkTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
Berserk = true;
} else BerserkTimer -= diff;
}
DoMeleeAttackIfReady();
}
};
};
void AddSC_boss_terestian_illhoof()
{
new boss_terestian_illhoof();
new npc_fiendish_imp();
new npc_fiendish_portal();
new npc_kilrek();
new npc_demon_chain();
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,301 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "karazhan.h"
class instance_karazhan : public InstanceMapScript
{
public:
instance_karazhan() : InstanceMapScript("instance_karazhan", 532) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const
{
return new instance_karazhan_InstanceMapScript(map);
}
struct instance_karazhan_InstanceMapScript : public InstanceScript
{
instance_karazhan_InstanceMapScript(Map* map) : InstanceScript(map) { }
void Initialize()
{
SetBossNumber(MAX_ENCOUNTERS);
_servantQuartersKills = 0;
_selectedRare = RAND(NPC_HYAKISS_THE_LURKER, NPC_SHADIKITH_THE_GLIDER, NPC_ROKAD_THE_RAVAGER);
}
void OnCreatureCreate(Creature* creature)
{
}
void SetData(uint32 type, uint32 uiData)
{
switch (type)
{
case DATA_COUNT_SERVANT_QUARTERS_KILLS:
if (++_servantQuartersKills > 52) // 56 in total, not all have to be killed, almost all
{
SetBossState(TYPE_SERVANT_QUARTERS, NOT_STARTED);
SetBossState(TYPE_SERVANT_QUARTERS, DONE);
}
SaveToDB();
break;
/*
case TYPE_ATTUMEN: m_auiEncounter[0] = uiData; break;
case TYPE_MOROES:
if (m_auiEncounter[1] == DONE)
break;
m_auiEncounter[1] = uiData;
break;
case TYPE_MAIDEN: m_auiEncounter[2] = uiData; break;
case TYPE_OPTIONAL_BOSS: m_auiEncounter[3] = uiData; break;
case TYPE_OPERA:
m_auiEncounter[4] = uiData;
if (uiData == DONE)
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, 16812, NULL);
break;
case TYPE_CURATOR: m_auiEncounter[5] = uiData; break;
case TYPE_ARAN: m_auiEncounter[6] = uiData; break;
case TYPE_TERESTIAN: m_auiEncounter[7] = uiData; break;
case TYPE_NETHERSPITE: m_auiEncounter[8] = uiData; break;
case TYPE_CHESS:
if (uiData == DONE)
DoRespawnGameObject(DustCoveredChest, DAY);
m_auiEncounter[9] = uiData;
break;
case TYPE_MALCHEZZAR: m_auiEncounter[10] = uiData; break;
case TYPE_NIGHTBANE:
if (m_auiEncounter[11] != DONE)
m_auiEncounter[11] = uiData;
break;
case DATA_OPERA_OZ_DEATHCOUNT:
if (uiData == SPECIAL)
++m_uiOzDeathCount;
else if (uiData == IN_PROGRESS)
m_uiOzDeathCount = 0;
break;
*/
}
}
void SetData64(uint32 identifier, uint64 data)
{
// switch (identifier)
// {
//case DATA_IMAGE_OF_MEDIVH: ImageGUID = data;
// }
}
void OnGameObjectCreate(GameObject* go)
{
/*switch (go->GetEntry())
{
case 183932: m_uiCurtainGUID = go->GetGUID(); break;
case 184278:
m_uiStageDoorLeftGUID = go->GetGUID();
if (m_auiEncounter[4] == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
case 184279:
m_uiStageDoorRightGUID = go->GetGUID();
if (m_auiEncounter[4] == DONE)
go->SetGoState(GO_STATE_ACTIVE);
break;
case 184517: m_uiLibraryDoor = go->GetGUID(); break;
case 185521: m_uiMassiveDoor = go->GetGUID(); break;
case 184276: m_uiGamesmansDoor = go->GetGUID(); break;
case 184277: m_uiGamesmansExitDoor = go->GetGUID(); break;
case 185134: m_uiNetherspaceDoor = go->GetGUID(); break;
case 184274: MastersTerraceDoor[0] = go->GetGUID(); break;
case 184280: MastersTerraceDoor[1] = go->GetGUID(); break;
case 184275:
m_uiSideEntranceDoor = go->GetGUID();
if (m_auiEncounter[4] == DONE)
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
else
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
break;
case 185119: DustCoveredChest = go->GetGUID(); break;
}*/
}
uint32 GetData(uint32 data) const
{
switch (data)
{
case DATA_SELECTED_RARE:
return _selectedRare;
}
return 0;
}
uint64 GetData64(uint32 data) const
{
/*switch (uiData)
{
case DATA_KILREK: return m_uiKilrekGUID;
case DATA_TERESTIAN: return m_uiTerestianGUID;
case DATA_MOROES: return m_uiMoroesGUID;
case DATA_GO_STAGEDOORLEFT: return m_uiStageDoorLeftGUID;
case DATA_GO_STAGEDOORRIGHT: return m_uiStageDoorRightGUID;
case DATA_GO_CURTAINS: return m_uiCurtainGUID;
case DATA_GO_LIBRARY_DOOR: return m_uiLibraryDoor;
case DATA_GO_MASSIVE_DOOR: return m_uiMassiveDoor;
case DATA_GO_SIDE_ENTRANCE_DOOR: return m_uiSideEntranceDoor;
case DATA_GO_GAME_DOOR: return m_uiGamesmansDoor;
case DATA_GO_GAME_EXIT_DOOR: return m_uiGamesmansExitDoor;
case DATA_GO_NETHER_DOOR: return m_uiNetherspaceDoor;
case DATA_MASTERS_TERRACE_DOOR_1: return MastersTerraceDoor[0];
case DATA_MASTERS_TERRACE_DOOR_2: return MastersTerraceDoor[1];
case DATA_IMAGE_OF_MEDIVH: return ImageGUID;
case DATA_NIGHTBANE: return m_uiNightbaneGUID;
}
*/
return 0;
}
std::string GetSaveData()
{
std::ostringstream saveStream;
saveStream << "K A " << GetBossSaveData() << _servantQuartersKills << ' ' << _selectedRare;
return saveStream.str();
}
void Load(char const* str)
{
if (!str)
return;
char dataHead1, dataHead2;
std::istringstream loadStream(str);
loadStream >> dataHead1 >> dataHead2;
if (dataHead1 == 'K' && dataHead2 == 'A')
{
for (uint32 i = 0; i < MAX_ENCOUNTERS; ++i)
{
uint32 tmpState;
loadStream >> tmpState;
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
tmpState = NOT_STARTED;
SetBossState(i, EncounterState(tmpState));
}
loadStream >> _servantQuartersKills;
loadStream >> _selectedRare;
}
}
private:
uint32 _servantQuartersKills;
uint32 _selectedRare;
};
};
class spell_karazhan_brittle_bones : public SpellScriptLoader
{
public:
spell_karazhan_brittle_bones() : SpellScriptLoader("spell_karazhan_brittle_bones") { }
class spell_karazhan_brittle_bones_AuraScript : public AuraScript
{
PrepareAuraScript(spell_karazhan_brittle_bones_AuraScript);
void CalcPeriodic(AuraEffect const* /*effect*/, bool& isPeriodic, int32& amplitude)
{
isPeriodic = true;
amplitude = 5000;
}
void Update(AuraEffect const* effect)
{
PreventDefaultAction();
if (roll_chance_i(35))
GetUnitOwner()->CastSpell(GetUnitOwner(), SPELL_RATTLED, true);
}
void Register()
{
DoEffectCalcPeriodic += AuraEffectCalcPeriodicFn(spell_karazhan_brittle_bones_AuraScript::CalcPeriodic, EFFECT_0, SPELL_AURA_DUMMY);
OnEffectPeriodic += AuraEffectPeriodicFn(spell_karazhan_brittle_bones_AuraScript::Update, EFFECT_0, SPELL_AURA_DUMMY);
}
};
AuraScript* GetAuraScript() const
{
return new spell_karazhan_brittle_bones_AuraScript();
}
};
class spell_karazhan_overload : public SpellScriptLoader
{
public:
spell_karazhan_overload() : SpellScriptLoader("spell_karazhan_overload") { }
class spell_karazhan_overload_AuraScript : public AuraScript
{
PrepareAuraScript(spell_karazhan_overload_AuraScript);
void PeriodicTick(AuraEffect const* auraEffect)
{
PreventDefaultAction();
GetUnitOwner()->CastCustomSpell(SPELL_OVERLOAD, SPELLVALUE_BASE_POINT0, int32(auraEffect->GetAmount() * (2.0, auraEffect->GetTickNumber())), GetUnitOwner(), true);
}
void Register()
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_karazhan_overload_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const
{
return new spell_karazhan_overload_AuraScript();
}
};
class spell_karazhan_blink : public SpellScriptLoader
{
public:
spell_karazhan_blink() : SpellScriptLoader("spell_karazhan_blink") { }
class spell_karazhan_blink_SpellScript : public SpellScript
{
PrepareSpellScript(spell_karazhan_blink_SpellScript);
void HandleDummy(SpellEffIndex effIndex)
{
PreventHitDefaultEffect(effIndex);
GetCaster()->getThreatManager().resetAllAggro();
if (Unit* target = GetHitUnit())
GetCaster()->CastSpell(target, SPELL_BLINK, true);
}
void Register()
{
OnEffectHitTarget += SpellEffectFn(spell_karazhan_blink_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const
{
return new spell_karazhan_blink_SpellScript();
}
};
void AddSC_instance_karazhan()
{
new instance_karazhan();
new spell_karazhan_brittle_bones();
new spell_karazhan_overload();
new spell_karazhan_blink();
}

View File

@@ -1,604 +0,0 @@
/*
* Copyright (C)
* Copyright (C)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Karazhan
SD%Complete: 100
SDComment: Support for Barnes (Opera controller) and Berthold (Doorman), Support for Quest 9645.
SDCategory: Karazhan
EndScriptData */
/* ContentData
npc_barnes
npc_berthold
npc_image_of_medivh
EndContentData */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "karazhan.h"
#include "ScriptedEscortAI.h"
#include "Player.h"
enum Spells
{
// Barnes
SPELL_SPOTLIGHT = 25824,
SPELL_TUXEDO = 32616,
// Berthold
SPELL_TELEPORT = 39567,
// Image of Medivh
SPELL_FIRE_BALL = 30967,
SPELL_UBER_FIREBALL = 30971,
SPELL_CONFLAGRATION_BLAST = 30977,
SPELL_MANA_SHIELD = 31635
};
enum Creatures
{
NPC_ARCANAGOS = 17652,
NPC_SPOTLIGHT = 19525
};
/*######
# npc_barnesAI
######*/
#define GOSSIP_READY "I'm not an actor."
#define SAY_READY "Splendid, I'm going to get the audience ready. Break a leg!"
#define SAY_OZ_INTRO1 "Finally, everything is in place. Are you ready for your big stage debut?"
#define OZ_GOSSIP1 "I'm not an actor."
#define SAY_OZ_INTRO2 "Don't worry, you'll be fine. You look like a natural!"
#define OZ_GOSSIP2 "Ok, I'll give it a try, then."
#define SAY_RAJ_INTRO1 "The romantic plays are really tough, but you'll do better this time. You have TALENT. Ready?"
#define RAJ_GOSSIP1 "I've never been more ready."
#define OZ_GM_GOSSIP1 "[GM] Change event to EVENT_OZ"
#define OZ_GM_GOSSIP2 "[GM] Change event to EVENT_HOOD"
#define OZ_GM_GOSSIP3 "[GM] Change event to EVENT_RAJ"
struct Dialogue
{
int32 textid;
uint32 timer;
};
static Dialogue OzDialogue[]=
{
{0, 6000},
{1, 18000},
{2, 9000},
{3, 15000}
};
static Dialogue HoodDialogue[]=
{
{4, 6000},
{5, 10000},
{6, 14000},
{7, 15000}
};
static Dialogue RAJDialogue[]=
{
{8, 5000},
{9, 7000},
{10, 14000},
{11, 14000}
};
// Entries and spawn locations for creatures in Oz event
float Spawns[6][2]=
{
{17535, -10896}, // Dorothee
{17546, -10891}, // Roar
{17547, -10884}, // Tinhead
{17543, -10902}, // Strawman
{17603, -10892}, // Grandmother
{17534, -10900}, // Julianne
};
#define SPAWN_Z 90.5f
#define SPAWN_Y -1758
#define SPAWN_O 4.738f
class npc_barnes : public CreatureScript
{
public:
npc_barnes() : CreatureScript("npc_barnes") { }
struct npc_barnesAI : public npc_escortAI
{
npc_barnesAI(Creature* creature) : npc_escortAI(creature)
{
RaidWiped = false;
m_uiEventId = 0;
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
uint64 m_uiSpotlightGUID;
uint32 TalkCount;
uint32 TalkTimer;
uint32 WipeTimer;
uint32 m_uiEventId;
bool PerformanceReady;
bool RaidWiped;
void Reset()
{
m_uiSpotlightGUID = 0;
TalkCount = 0;
TalkTimer = 2000;
WipeTimer = 5000;
PerformanceReady = false;
m_uiEventId = instance->GetData(DATA_OPERA_PERFORMANCE);
}
void StartEvent()
{
instance->SetData(TYPE_OPERA, IN_PROGRESS);
//resets count for this event, in case earlier failed
if (m_uiEventId == EVENT_OZ)
instance->SetData(DATA_OPERA_OZ_DEATHCOUNT, IN_PROGRESS);
Start(false, false);
}
void EnterCombat(Unit* /*who*/) { }
void WaypointReached(uint32 waypointId)
{
switch (waypointId)
{
case 0:
DoCast(me, SPELL_TUXEDO, false);
instance->DoUseDoorOrButton(instance->GetData64(DATA_GO_STAGEDOORLEFT));
break;
case 4:
TalkCount = 0;
SetEscortPaused(true);
if (Creature* spotlight = me->SummonCreature(NPC_SPOTLIGHT,
me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), 0.0f,
TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
{
spotlight->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
spotlight->CastSpell(spotlight, SPELL_SPOTLIGHT, false);
m_uiSpotlightGUID = spotlight->GetGUID();
}
break;
case 8:
instance->DoUseDoorOrButton(instance->GetData64(DATA_GO_STAGEDOORLEFT));
PerformanceReady = true;
break;
case 9:
PrepareEncounter();
instance->DoUseDoorOrButton(instance->GetData64(DATA_GO_CURTAINS));
break;
}
}
void Talk(uint32 count)
{
int32 text = 0;
switch (m_uiEventId)
{
case EVENT_OZ:
if (OzDialogue[count].textid)
text = OzDialogue[count].textid;
if (OzDialogue[count].timer)
TalkTimer = OzDialogue[count].timer;
break;
case EVENT_HOOD:
if (HoodDialogue[count].textid)
text = HoodDialogue[count].textid;
if (HoodDialogue[count].timer)
TalkTimer = HoodDialogue[count].timer;
break;
case EVENT_RAJ:
if (RAJDialogue[count].textid)
text = RAJDialogue[count].textid;
if (RAJDialogue[count].timer)
TalkTimer = RAJDialogue[count].timer;
break;
}
if (text)
CreatureAI::Talk(text);
}
void PrepareEncounter()
{
;//sLog->outDebug(LOG_FILTER_TSCR, "TSCR: Barnes Opera Event - Introduction complete - preparing encounter %d", m_uiEventId);
uint8 index = 0;
uint8 count = 0;
switch (m_uiEventId)
{
case EVENT_OZ:
index = 0;
count = 4;
break;
case EVENT_HOOD:
index = 4;
count = index+1;
break;
case EVENT_RAJ:
index = 5;
count = index+1;
break;
}
for (; index < count; ++index)
{
uint32 entry = ((uint32)Spawns[index][0]);
float PosX = Spawns[index][1];
if (Creature* creature = me->SummonCreature(entry, PosX, SPAWN_Y, SPAWN_Z, SPAWN_O, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, HOUR*2*IN_MILLISECONDS))
{
// In case database has bad flags
creature->SetUInt32Value(UNIT_FIELD_FLAGS, 0);
creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
}
RaidWiped = false;
}
void UpdateAI(uint32 diff)
{
npc_escortAI::UpdateAI(diff);
if (HasEscortState(STATE_ESCORT_PAUSED))
{
if (TalkTimer <= diff)
{
if (TalkCount > 3)
{
if (Creature* pSpotlight = ObjectAccessor::GetCreature(*me, m_uiSpotlightGUID))
pSpotlight->DespawnOrUnsummon();
SetEscortPaused(false);
return;
}
Talk(TalkCount);
++TalkCount;
} else TalkTimer -= diff;
}
if (PerformanceReady)
{
if (!RaidWiped)
{
if (WipeTimer <= diff)
{
Map* map = me->GetMap();
if (!map->IsDungeon())
return;
Map::PlayerList const &PlayerList = map->GetPlayers();
if (PlayerList.isEmpty())
return;
RaidWiped = true;
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (i->GetSource()->IsAlive() && !i->GetSource()->IsGameMaster())
{
RaidWiped = false;
break;
}
}
if (RaidWiped)
{
RaidWiped = true;
EnterEvadeMode();
return;
}
WipeTimer = 15000;
} else WipeTimer -= diff;
}
}
}
};
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
npc_barnesAI* pBarnesAI = CAST_AI(npc_barnes::npc_barnesAI, creature->AI());
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, OZ_GOSSIP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(8971, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->CLOSE_GOSSIP_MENU();
pBarnesAI->StartEvent();
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->CLOSE_GOSSIP_MENU();
pBarnesAI->m_uiEventId = EVENT_OZ;
break;
case GOSSIP_ACTION_INFO_DEF+4:
player->CLOSE_GOSSIP_MENU();
pBarnesAI->m_uiEventId = EVENT_HOOD;
break;
case GOSSIP_ACTION_INFO_DEF+5:
player->CLOSE_GOSSIP_MENU();
pBarnesAI->m_uiEventId = EVENT_RAJ;
break;
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature)
{
if (InstanceScript* instance = creature->GetInstanceScript())
{
// Check for death of Moroes and if opera event is not done already
if (instance->GetData(TYPE_MOROES) == DONE && instance->GetData(TYPE_OPERA) != DONE)
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, OZ_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (player->IsGameMaster())
{
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, OZ_GM_GOSSIP1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, OZ_GM_GOSSIP2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, OZ_GM_GOSSIP3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
}
if (npc_barnesAI* pBarnesAI = CAST_AI(npc_barnes::npc_barnesAI, creature->AI()))
{
if (!pBarnesAI->RaidWiped)
player->SEND_GOSSIP_MENU(8970, creature->GetGUID());
else
player->SEND_GOSSIP_MENU(8975, creature->GetGUID());
return true;
}
}
}
player->SEND_GOSSIP_MENU(8978, creature->GetGUID());
return true;
}
CreatureAI* GetAI(Creature* creature) const
{
return new npc_barnesAI(creature);
}
};
/*###
# npc_image_of_medivh
####*/
#define SAY_DIALOG_MEDIVH_1 "You've got my attention, dragon. You'll find I'm not as easily scared as the villagers below."
#define SAY_DIALOG_ARCANAGOS_2 "Your dabbling in the arcane has gone too far, Medivh. You've attracted the attention of powers beyond your understanding. You must leave Karazhan at once!"
#define SAY_DIALOG_MEDIVH_3 "You dare challenge me at my own dwelling? Your arrogance is astounding, even for a dragon!"
#define SAY_DIALOG_ARCANAGOS_4 "A dark power seeks to use you, Medivh! If you stay, dire days will follow. You must hurry, we don't have much time!"
#define SAY_DIALOG_MEDIVH_5 "I do not know what you speak of, dragon... but I will not be bullied by this display of insolence. I'll leave Karazhan when it suits me!"
#define SAY_DIALOG_ARCANAGOS_6 "You leave me no alternative. I will stop you by force if you won't listen to reason!"
#define EMOTE_DIALOG_MEDIVH_7 "begins to cast a spell of great power, weaving his own essence into the magic."
#define SAY_DIALOG_ARCANAGOS_8 "What have you done, wizard? This cannot be! I'm burning from... within!"
#define SAY_DIALOG_MEDIVH_9 "He should not have angered me. I must go... recover my strength now..."
static float MedivPos[4] = {-11161.49f, -1902.24f, 91.48f, 1.94f};
static float ArcanagosPos[4] = {-11169.75f, -1881.48f, 107.39f, 4.83f};
class npc_image_of_medivh : public CreatureScript
{
public:
npc_image_of_medivh() : CreatureScript("npc_image_of_medivh") { }
CreatureAI* GetAI(Creature* creature) const
{
return new npc_image_of_medivhAI(creature);
}
struct npc_image_of_medivhAI : public ScriptedAI
{
npc_image_of_medivhAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
Step = 1;
YellTimer = 5000;
}
InstanceScript* instance;
uint64 ArcanagosGUID;
uint32 YellTimer;
uint8 Step;
int32 MTimer;
int32 ATimer;
bool EventStarted;
void Reset()
{
ArcanagosGUID = 0;
MTimer = 0;
ATimer = 0;
if (instance && instance->GetData64(DATA_IMAGE_OF_MEDIVH) == 0)
{
Creature* Arcanagos = me->SummonCreature(NPC_ARCANAGOS, ArcanagosPos[0], ArcanagosPos[1], ArcanagosPos[2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 20000);
if (!Arcanagos)
{
me->DespawnOrUnsummon();
return;
}
instance->SetData64(DATA_IMAGE_OF_MEDIVH, me->GetGUID());
EventStarted = true;
ArcanagosGUID = Arcanagos->GetGUID();
Arcanagos->SetFacingToObject(me);
me->SetFacingToObject(Arcanagos);
Arcanagos->SetCanFly(true);
}
else
me->DespawnOrUnsummon();
}
void EnterCombat(Unit* /*who*/) {}
uint32 NextStep(uint32 Step)
{
switch(Step)
{
case 1:
me->MonsterYell(SAY_DIALOG_MEDIVH_1, LANG_UNIVERSAL, 0);
return 10000;
case 2:
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
arca->MonsterYell(SAY_DIALOG_ARCANAGOS_2, LANG_UNIVERSAL, 0);
return 20000;
case 3:
me->MonsterYell(SAY_DIALOG_MEDIVH_3, LANG_UNIVERSAL, 0);
return 10000;
case 4:
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
arca->MonsterYell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, 0);
return 20000;
case 5:
me->MonsterYell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, 0);
return 20000;
case 6:
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
arca->MonsterYell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, 0);
ATimer = 5500;
MTimer = 6600;
return 10000;
case 7:
return 1000;
case 8:
me->CastSpell(me, SPELL_MANA_SHIELD, true);
return 5500;
case 9:
me->MonsterTextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false);
me->CastSpell(me, 30972, true);
return 10000;
case 10:
me->RemoveAurasDueToSpell(30972);
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
me->CastSpell(arca, SPELL_CONFLAGRATION_BLAST, false);
return 1000;
case 11:
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
arca->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, 0);
return 5000;
case 12:
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
{
arca->SetSpeed(MOVE_RUN, 2.0f);
arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f);
arca->InterruptNonMeleeSpells(true);
}
return 10000;
case 13:
me->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, 0);
return 10000;
case 14:
if (me->GetMap()->IsDungeon())
{
InstanceMap::PlayerList const &PlayerList = me->GetMap()->GetPlayers();
for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
{
if (i->GetSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE)
{
i->GetSource()->GroupEventHappens(9645, me);
break;
}
}
}
me->DespawnOrUnsummon(100);
if (Creature* arca = ObjectAccessor::GetCreature((*me), ArcanagosGUID))
arca->DespawnOrUnsummon(100);
return 5000;
default:
return 2000;
}
}
void UpdateAI(uint32 diff)
{
if (YellTimer <= diff)
{
if (EventStarted)
YellTimer = NextStep(Step++);
} else YellTimer -= diff;
if (Step >= 7 && Step <= 8)
{
ATimer += diff;
MTimer += diff;
if (ATimer >= 6000)
{
if (Unit* arca = ObjectAccessor::GetUnit((*me), ArcanagosGUID))
arca->CastSpell(me, SPELL_FIRE_BALL, false);
ATimer = 0;
}
if (MTimer >= 6000)
{
if (Unit* arca = ObjectAccessor::GetUnit((*me), ArcanagosGUID))
me->CastSpell(arca, SPELL_FIRE_BALL, false);
MTimer = 0;
}
}
}
};
};
void AddSC_karazhan()
{
new npc_barnes();
new npc_image_of_medivh();
}

View File

@@ -1,76 +0,0 @@
/*
REWRITTEN BY XINEF
*/
#ifndef DEF_KARAZHAN_H
#define DEF_KARAZHAN_H
enum DataTypes
{
TYPE_SERVANT_QUARTERS = 0,
TYPE_ATTUMEN = 1,
TYPE_MOROES = 2,
TYPE_MAIDEN = 3,
TYPE_OPTIONAL_BOSS = 4,
TYPE_OPERA = 5,
TYPE_CURATOR = 6,
TYPE_ARAN = 7,
TYPE_TERESTIAN = 8,
TYPE_NETHERSPITE = 9,
TYPE_CHESS = 10,
TYPE_MALCHEZZAR = 11,
TYPE_NIGHTBANE = 12,
MAX_ENCOUNTERS = 13,
DATA_OPERA_PERFORMANCE = 13,
DATA_OPERA_OZ_DEATHCOUNT = 14,
DATA_KILREK = 15,
DATA_TERESTIAN = 16,
DATA_MOROES = 17,
DATA_GO_CURTAINS = 18,
DATA_GO_STAGEDOORLEFT = 19,
DATA_GO_STAGEDOORRIGHT = 20,
DATA_GO_LIBRARY_DOOR = 21,
DATA_GO_MASSIVE_DOOR = 22,
DATA_GO_NETHER_DOOR = 23,
DATA_GO_GAME_DOOR = 24,
DATA_GO_GAME_EXIT_DOOR = 25,
DATA_IMAGE_OF_MEDIVH = 26,
DATA_MASTERS_TERRACE_DOOR_1 = 27,
DATA_MASTERS_TERRACE_DOOR_2 = 28,
DATA_GO_SIDE_ENTRANCE_DOOR = 29,
DATA_NIGHTBANE = 30,
DATA_COUNT_SERVANT_QUARTERS_KILLS = 100,
DATA_SELECTED_RARE = 101,
};
enum OperaEvents
{
EVENT_OZ = 1,
EVENT_HOOD = 2,
EVENT_RAJ = 3
};
enum KarazhanNPCs
{
NPC_HYAKISS_THE_LURKER = 16179,
NPC_SHADIKITH_THE_GLIDER = 16180,
NPC_ROKAD_THE_RAVAGER = 16181,
NPC_ATTUMEN_THE_HUNTSMAN = 15550,
NPC_ATTUMEN_THE_HUNTSMAN_MOUNTED = 16152
};
enum KarazhanSpells
{
SPELL_RATTLED = 32437,
SPELL_OVERLOAD = 29766,
SPELL_BLINK = 29884
};
#endif