mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 21:26:23 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,441 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
TCName: Boss_Arlokk
|
||||
TC%Complete: 95
|
||||
TCComment: Wrong cleave and red aura is missing not yet added.
|
||||
TCComment: Prowlers moving through wall hopefully mmaps will fix.
|
||||
TCComment: Can't test LOS until mmaps.
|
||||
TCCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_FEAST_PROWLER = 1,
|
||||
SAY_DEATH = 2
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SHADOW_WORD_PAIN = 24212, // Corrected
|
||||
SPELL_GOUGE = 12540, // Corrected
|
||||
SPELL_MARK_OF_ARLOKK = 24210, // triggered spell 24211 Added to spell_dbc
|
||||
SPELL_RAVAGE = 24213, // Corrected
|
||||
SPELL_CLEAVE = 25174, // Searching for right spell
|
||||
SPELL_PANTHER_TRANSFORM = 24190, // Transform to panther now used
|
||||
SPELL_SUMMON_PROWLER = 24246, // Added to Spell_dbc
|
||||
SPELL_VANISH_VISUAL = 24222, // Added
|
||||
SPELL_VANISH = 24223, // Added
|
||||
SPELL_SUPER_INVIS = 24235 // Added to Spell_dbc
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SHADOW_WORD_PAIN = 1,
|
||||
EVENT_GOUGE = 2,
|
||||
EVENT_MARK_OF_ARLOKK = 3,
|
||||
EVENT_RAVAGE = 4,
|
||||
EVENT_TRANSFORM = 5,
|
||||
EVENT_VANISH = 6,
|
||||
EVENT_VANISH_2 = 7,
|
||||
EVENT_TRANSFORM_BACK = 8,
|
||||
EVENT_VISIBLE = 9,
|
||||
EVENT_SUMMON_PROWLERS = 10
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ALL = 0,
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2
|
||||
};
|
||||
|
||||
enum Weapon
|
||||
{
|
||||
WEAPON_DAGGER = 10616
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
MAX_PROWLERS_PER_SIDE = 15
|
||||
};
|
||||
|
||||
Position const PosMoveOnSpawn[1] =
|
||||
{
|
||||
{ -11561.9f, -1627.868f, 41.29941f, 0.0f }
|
||||
};
|
||||
|
||||
class boss_arlokk : public CreatureScript
|
||||
{
|
||||
public: boss_arlokk() : CreatureScript("boss_arlokk") { }
|
||||
|
||||
struct boss_arlokkAI : public BossAI
|
||||
{
|
||||
boss_arlokkAI(Creature* creature) : BossAI(creature, DATA_ARLOKK) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (events.IsInPhase(PHASE_TWO))
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
_Reset();
|
||||
_summonCountA = 0;
|
||||
_summonCountB = 0;
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER));
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER));
|
||||
me->SetWalk(false);
|
||||
me->GetMotionMaster()->MovePoint(0, PosMoveOnSpawn[0]);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(7000, 9000), 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL);
|
||||
events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(9000, 11000), 0, PHASE_ALL);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, urand(15000, 20000), 0, PHASE_ONE);
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
// Sets up list of Panther spawners to cast on
|
||||
std::list<Creature*> triggerList;
|
||||
GetCreatureListWithEntryInGrid(triggerList, me, NPC_PANTHER_TRIGGER, 100.0f);
|
||||
if (!triggerList.empty())
|
||||
{
|
||||
uint8 sideA = 0;
|
||||
uint8 sideB = 0;
|
||||
for (std::list<Creature*>::const_iterator itr = triggerList.begin(); itr != triggerList.end(); ++itr)
|
||||
{
|
||||
if (Creature* trigger = *itr)
|
||||
{
|
||||
if (trigger->GetPositionY() < -1625.0f)
|
||||
{
|
||||
_triggersSideAGUID[sideA] = trigger->GetGUID();
|
||||
++sideA;
|
||||
}
|
||||
else
|
||||
{
|
||||
_triggersSideBGUID[sideB] = trigger->GetGUID();
|
||||
++sideB;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnterEvadeMode()
|
||||
{
|
||||
BossAI::EnterEvadeMode();
|
||||
if (GameObject* object = ObjectAccessor::GetGameObject(*me, instance->GetData64(GO_GONG_OF_BETHEKK)))
|
||||
object->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
me->DespawnOrUnsummon(4000);
|
||||
}
|
||||
|
||||
void SetData(uint32 id, uint32 /*value*/)
|
||||
{
|
||||
if (id == 1)
|
||||
--_summonCountA;
|
||||
else if (id == 2)
|
||||
--_summonCountB;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SHADOW_WORD_PAIN:
|
||||
DoCastVictim(SPELL_SHADOW_WORD_PAIN, true);
|
||||
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(5000, 7000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_GOUGE:
|
||||
DoCastVictim(SPELL_GOUGE, true);
|
||||
break;
|
||||
case EVENT_SUMMON_PROWLERS:
|
||||
if (_summonCountA < MAX_PROWLERS_PER_SIDE)
|
||||
{
|
||||
if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideAGUID[urand(0, 4)]))
|
||||
{
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER);
|
||||
++_summonCountA;
|
||||
}
|
||||
}
|
||||
if (_summonCountB < MAX_PROWLERS_PER_SIDE)
|
||||
{
|
||||
if (Unit* trigger = ObjectAccessor::GetUnit(*me, _triggersSideBGUID[urand(0, 4)]))
|
||||
{
|
||||
trigger->CastSpell(trigger, SPELL_SUMMON_PROWLER);
|
||||
++_summonCountB;
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SUMMON_PROWLERS, 6000, 0, PHASE_ALL);
|
||||
break;
|
||||
case EVENT_MARK_OF_ARLOKK:
|
||||
{
|
||||
Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, urand(1, 3), 0.0f, false, -SPELL_MARK_OF_ARLOKK);
|
||||
if (!target)
|
||||
target = me->GetVictim();
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_MARK_OF_ARLOKK, true);
|
||||
Talk(SAY_FEAST_PROWLER, target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_MARK_OF_ARLOKK, urand(120000, 130000));
|
||||
break;
|
||||
}
|
||||
case EVENT_TRANSFORM:
|
||||
{
|
||||
DoCast(me, SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(EQUIP_UNEQUIP));
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(EQUIP_UNEQUIP));
|
||||
/*
|
||||
const CreatureTemplate* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->AttackStop();
|
||||
DoResetThreat();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
DoCast(me, SPELL_VANISH_VISUAL);
|
||||
DoCast(me, SPELL_VANISH);
|
||||
events.ScheduleEvent(EVENT_VANISH, 1000, 0, PHASE_ONE);
|
||||
break;
|
||||
}
|
||||
case EVENT_VANISH:
|
||||
DoCast(me, SPELL_SUPER_INVIS);
|
||||
me->SetWalk(false);
|
||||
me->GetMotionMaster()->MovePoint(0, frand(-11551.0f, -11508.0f), frand(-1638.0f, -1617.0f), me->GetPositionZ());
|
||||
events.ScheduleEvent(EVENT_VANISH_2, 9000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_VANISH_2:
|
||||
DoCast(me, SPELL_VANISH);
|
||||
DoCast(me, SPELL_SUPER_INVIS);
|
||||
events.ScheduleEvent(EVENT_VISIBLE, urand(7000, 10000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_VISIBLE:
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_NOT_SELECTABLE);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
AttackStart(target);
|
||||
me->RemoveAura(SPELL_SUPER_INVIS);
|
||||
me->RemoveAura(SPELL_VANISH);
|
||||
events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM_BACK, urand(15000, 18000), 0, PHASE_TWO);
|
||||
events.SetPhase(PHASE_TWO);
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
|
||||
break;
|
||||
case EVENT_RAVAGE:
|
||||
DoCastVictim(SPELL_RAVAGE, true);
|
||||
events.ScheduleEvent(EVENT_RAVAGE, urand(10000, 14000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_TRANSFORM_BACK:
|
||||
{
|
||||
me->RemoveAura(SPELL_PANTHER_TRANSFORM); // SPELL_AURA_TRANSFORM
|
||||
DoCast(me, SPELL_VANISH_VISUAL);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_DAGGER));
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, uint32(WEAPON_DAGGER));
|
||||
/*
|
||||
const CreatureTemplate* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(4000, 7000), 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_GOUGE, urand(12000, 15000), 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, urand(16000, 20000), 0, PHASE_ONE);
|
||||
events.SetPhase(PHASE_ONE);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _summonCountA;
|
||||
uint8 _summonCountB;
|
||||
uint64 _triggersSideAGUID[5];
|
||||
uint64 _triggersSideBGUID[5];
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetZulGurubAI<boss_arlokkAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## npc_zulian_prowler
|
||||
######*/
|
||||
|
||||
enum ZulianProwlerSpells
|
||||
{
|
||||
SPELL_SNEAK_RANK_1_1 = 22766,
|
||||
SPELL_SNEAK_RANK_1_2 = 7939, // Added to Spell_dbc
|
||||
SPELL_MARK_OF_ARLOKK_TRIGGER = 24211 // Added to Spell_dbc
|
||||
};
|
||||
|
||||
enum ZulianProwlerEvents
|
||||
{
|
||||
EVENT_ATTACK = 1
|
||||
};
|
||||
|
||||
Position const PosProwlerCenter[1] =
|
||||
{
|
||||
{ -11556.7f, -1631.344f, 41.2994f, 0.0f }
|
||||
};
|
||||
|
||||
class npc_zulian_prowler : public CreatureScript
|
||||
{
|
||||
public: npc_zulian_prowler() : CreatureScript("npc_zulian_prowler") { }
|
||||
|
||||
struct npc_zulian_prowlerAI : public ScriptedAI
|
||||
{
|
||||
npc_zulian_prowlerAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (me->GetPositionY() < -1625.0f)
|
||||
_sideData = 1;
|
||||
else
|
||||
_sideData = 2;
|
||||
|
||||
DoCast(me, SPELL_SNEAK_RANK_1_1);
|
||||
DoCast(me, SPELL_SNEAK_RANK_1_2);
|
||||
|
||||
if (Unit* arlokk = ObjectAccessor::GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
|
||||
me->GetMotionMaster()->MovePoint(0, arlokk->GetPositionX(), arlokk->GetPositionY(), arlokk->GetPositionZ());
|
||||
_events.ScheduleEvent(EVENT_ATTACK, 6000);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->RemoveAura(SPELL_SNEAK_RANK_1_1);
|
||||
me->RemoveAura(SPELL_SNEAK_RANK_1_2);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell)
|
||||
{
|
||||
if (spell->Id == SPELL_MARK_OF_ARLOKK_TRIGGER) // Should only hit if line of sight
|
||||
me->Attack(caster, true);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
if (Unit* arlokk = ObjectAccessor::GetUnit(*me, _instance->GetData64(NPC_ARLOKK)))
|
||||
{
|
||||
if (arlokk->IsAlive())
|
||||
arlokk->GetAI()->SetData(_sideData, 0);
|
||||
}
|
||||
me->DespawnOrUnsummon(4000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (UpdateVictim())
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
return;
|
||||
}
|
||||
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ATTACK:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0.0f, 100, false))
|
||||
me->Attack(target, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int32 _sideData;
|
||||
EventMap _events;
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetZulGurubAI<npc_zulian_prowlerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## go_gong_of_bethekk
|
||||
######*/
|
||||
|
||||
Position const PosSummonArlokk[1] =
|
||||
{
|
||||
{ -11507.22f, -1628.062f, 41.38264f, 3.159046f }
|
||||
};
|
||||
|
||||
class go_gong_of_bethekk : public GameObjectScript
|
||||
{
|
||||
public: go_gong_of_bethekk() : GameObjectScript("go_gong_of_bethekk") { }
|
||||
|
||||
bool OnGossipHello(Player* /*player*/, GameObject* go)
|
||||
{
|
||||
if (go->GetInstanceScript())
|
||||
{
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
go->SendCustomAnim(0);
|
||||
go->SummonCreature(NPC_ARLOKK, PosSummonArlokk[0], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 600000);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_arlokk()
|
||||
{
|
||||
new boss_arlokk();
|
||||
new npc_zulian_prowler();
|
||||
new go_gong_of_bethekk();
|
||||
}
|
||||
@@ -1,114 +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_Gahz'ranka
|
||||
SD%Complete: 85
|
||||
SDComment: Massive Geyser with knockback not working. Spell buggy.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FROSTBREATH = 16099,
|
||||
SPELL_MASSIVEGEYSER = 22421, // Not working. (summon)
|
||||
SPELL_SLAM = 24326
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_FROSTBREATH = 1,
|
||||
EVENT_MASSIVEGEYSER = 2,
|
||||
EVENT_SLAM = 3
|
||||
};
|
||||
|
||||
class boss_gahzranka : public CreatureScript // gahzranka
|
||||
{
|
||||
public: boss_gahzranka() : CreatureScript("boss_gahzranka") { }
|
||||
|
||||
struct boss_gahzrankaAI : public BossAI
|
||||
{
|
||||
boss_gahzrankaAI(Creature* creature) : BossAI(creature, DATA_GAHZRANKA) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_FROSTBREATH, 8000);
|
||||
events.ScheduleEvent(EVENT_MASSIVEGEYSER, 25000);
|
||||
events.ScheduleEvent(EVENT_SLAM, 17000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_FROSTBREATH:
|
||||
DoCastVictim(SPELL_FROSTBREATH, true);
|
||||
events.ScheduleEvent(EVENT_FROSTBREATH, urand(7000, 11000));
|
||||
break;
|
||||
case EVENT_MASSIVEGEYSER:
|
||||
DoCastVictim(SPELL_MASSIVEGEYSER, true);
|
||||
events.ScheduleEvent(EVENT_MASSIVEGEYSER, urand(22000, 32000));
|
||||
break;
|
||||
case EVENT_SLAM:
|
||||
DoCastVictim(SPELL_SLAM, true);
|
||||
events.ScheduleEvent(EVENT_SLAM, urand(12000, 20000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_gahzrankaAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_gahzranka()
|
||||
{
|
||||
new boss_gahzranka();
|
||||
}
|
||||
@@ -1,116 +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_Grilek
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_AVATAR = 24646, // Enrage Spell
|
||||
SPELL_GROUND_TREMOR = 6524
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_AVATAR = 1,
|
||||
EVENT_GROUND_TREMOR = 2
|
||||
};
|
||||
|
||||
class boss_grilek : public CreatureScript // grilek
|
||||
{
|
||||
public: boss_grilek() : CreatureScript("boss_grilek") { }
|
||||
|
||||
struct boss_grilekAI : public BossAI
|
||||
{
|
||||
boss_grilekAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_AVATAR, urand(15000, 25000));
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(15000, 25000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_AVATAR:
|
||||
DoCast(me, SPELL_AVATAR);
|
||||
if (Unit* victim = me->GetVictim())
|
||||
{
|
||||
if (DoGetThreat(victim))
|
||||
DoModifyThreatPercent(victim, -50);
|
||||
}
|
||||
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1))
|
||||
AttackStart(target);
|
||||
events.ScheduleEvent(EVENT_AVATAR, urand(25000, 35000));
|
||||
break;
|
||||
case EVENT_GROUND_TREMOR:
|
||||
DoCastVictim(SPELL_GROUND_TREMOR, true);
|
||||
events.ScheduleEvent(EVENT_GROUND_TREMOR, urand(12000, 16000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_grilekAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_grilek()
|
||||
{
|
||||
new boss_grilek();
|
||||
}
|
||||
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
Name: Boss_Hakkar
|
||||
%Complete: 95
|
||||
Comment: Blood siphon spell buggy cause of Core Issue.
|
||||
Category: Zul'Gurub
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_FLEEING = 1,
|
||||
SAY_MINION_DESTROY = 2, // Where does it belong?
|
||||
SAY_PROTECT_ALTAR = 3 // Where does it belong?
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BLOOD_SIPHON = 24322, // Buggy ?
|
||||
SPELL_CORRUPTED_BLOOD = 24328,
|
||||
SPELL_CAUSE_INSANITY = 24327, // Spell needs scripting.
|
||||
SPELL_WILL_OF_HAKKAR = 24178,
|
||||
SPELL_ENRAGE = 24318,
|
||||
// The Aspects of all High Priests spells
|
||||
SPELL_ASPECT_OF_JEKLIK = 24687,
|
||||
SPELL_ASPECT_OF_VENOXIS = 24688,
|
||||
SPELL_ASPECT_OF_MARLI = 24686,
|
||||
SPELL_ASPECT_OF_THEKAL = 24689,
|
||||
SPELL_ASPECT_OF_ARLOKK = 24690
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_BLOOD_SIPHON = 1,
|
||||
EVENT_CORRUPTED_BLOOD = 2,
|
||||
EVENT_CAUSE_INSANITY = 3, // Spell needs scripting. Event disabled
|
||||
EVENT_WILL_OF_HAKKAR = 4,
|
||||
EVENT_ENRAGE = 5,
|
||||
// The Aspects of all High Priests events
|
||||
EVENT_ASPECT_OF_JEKLIK = 6,
|
||||
EVENT_ASPECT_OF_VENOXIS = 7,
|
||||
EVENT_ASPECT_OF_MARLI = 8,
|
||||
EVENT_ASPECT_OF_THEKAL = 9,
|
||||
EVENT_ASPECT_OF_ARLOKK = 10
|
||||
};
|
||||
|
||||
class boss_hakkar : public CreatureScript
|
||||
{
|
||||
public: boss_hakkar() : CreatureScript("boss_hakkar") { }
|
||||
|
||||
struct boss_hakkarAI : public BossAI
|
||||
{
|
||||
boss_hakkarAI(Creature* creature) : BossAI(creature, DATA_HAKKAR) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, 25000);
|
||||
events.ScheduleEvent(EVENT_CAUSE_INSANITY, 17000);
|
||||
events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, 17000);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 600000);
|
||||
if (instance->GetBossState(DATA_JEKLIK) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, 4000);
|
||||
if (instance->GetBossState(DATA_VENOXIS) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 7000);
|
||||
if (instance->GetBossState(DATA_MARLI) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000);
|
||||
if (instance->GetBossState(DATA_THEKAL) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 8000);
|
||||
if (instance->GetBossState(DATA_ARLOKK) != DONE)
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, 18000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BLOOD_SIPHON:
|
||||
DoCastVictim(SPELL_BLOOD_SIPHON, true);
|
||||
events.ScheduleEvent(EVENT_BLOOD_SIPHON, 90000);
|
||||
break;
|
||||
case EVENT_CORRUPTED_BLOOD:
|
||||
DoCastVictim(SPELL_CORRUPTED_BLOOD, true);
|
||||
events.ScheduleEvent(EVENT_CORRUPTED_BLOOD, urand(30000, 45000));
|
||||
break;
|
||||
case EVENT_CAUSE_INSANITY:
|
||||
// DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CAUSE_INSANITY);
|
||||
// events.ScheduleEvent(EVENT_CAUSE_INSANITY, urand(35000, 45000));
|
||||
break;
|
||||
case EVENT_WILL_OF_HAKKAR:
|
||||
// Xinef: Skip Tank
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true), SPELL_WILL_OF_HAKKAR);
|
||||
events.ScheduleEvent(EVENT_WILL_OF_HAKKAR, urand(25000, 35000));
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
if (!me->HasAura(SPELL_ENRAGE))
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 90000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_JEKLIK:
|
||||
DoCastVictim(SPELL_ASPECT_OF_JEKLIK, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_JEKLIK, urand(10000, 14000));
|
||||
break;
|
||||
case EVENT_ASPECT_OF_VENOXIS:
|
||||
DoCastVictim(SPELL_ASPECT_OF_VENOXIS, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_VENOXIS, 8000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_MARLI:
|
||||
DoCastVictim(SPELL_ASPECT_OF_MARLI, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 10000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_THEKAL:
|
||||
DoCastVictim(SPELL_ASPECT_OF_THEKAL, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_THEKAL, 15000);
|
||||
break;
|
||||
case EVENT_ASPECT_OF_ARLOKK:
|
||||
DoCastVictim(SPELL_ASPECT_OF_ARLOKK, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_ARLOKK, urand(10000, 15000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_hakkarAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_hakkar()
|
||||
{
|
||||
new boss_hakkar();
|
||||
}
|
||||
|
||||
@@ -1,123 +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_Hazzarah
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MANABURN = 26046,
|
||||
SPELL_SLEEP = 24664
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MANABURN = 1,
|
||||
EVENT_SLEEP = 2,
|
||||
EVENT_ILLUSIONS = 3
|
||||
};
|
||||
|
||||
class boss_hazzarah : public CreatureScript
|
||||
{
|
||||
public: boss_hazzarah() : CreatureScript("boss_hazzarah") { }
|
||||
|
||||
struct boss_hazzarahAI : public BossAI
|
||||
{
|
||||
boss_hazzarahAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_MANABURN, urand(4000, 10000));
|
||||
events.ScheduleEvent(EVENT_SLEEP, urand(10000, 18000));
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, urand(10000, 18000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MANABURN:
|
||||
DoCastVictim(SPELL_MANABURN, true);
|
||||
events.ScheduleEvent(EVENT_MANABURN, urand(8000, 16000));
|
||||
break;
|
||||
case EVENT_SLEEP:
|
||||
DoCastVictim(SPELL_SLEEP, true);
|
||||
events.ScheduleEvent(EVENT_SLEEP, urand(12000, 20000));
|
||||
break;
|
||||
case EVENT_ILLUSIONS:
|
||||
// We will summon 3 illusions that will spawn on a random gamer and attack this gamer
|
||||
// We will just use one model for the beginning
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
Creature* Illusion = me->SummonCreature(NPC_NIGHTMARE_ILLUSION, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000);
|
||||
if (Illusion)
|
||||
Illusion->AI()->AttackStart(target);
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ILLUSIONS, urand(15000, 25000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_hazzarahAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_hazzarah()
|
||||
{
|
||||
new boss_hazzarah();
|
||||
}
|
||||
@@ -1,257 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_RAIN_FIRE = 1,
|
||||
SAY_DEATH = 2
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CHARGE = 22911,
|
||||
SPELL_SONICBURST = 23918,
|
||||
SPELL_SCREECH = 6605,
|
||||
SPELL_SHADOW_WORD_PAIN = 23952,
|
||||
SPELL_MIND_FLAY = 23953,
|
||||
SPELL_CHAIN_MIND_FLAY = 26044, // Right ID unknown. So disabled
|
||||
SPELL_GREATERHEAL = 23954,
|
||||
SPELL_BAT_FORM = 23966,
|
||||
|
||||
// Batriders Spell
|
||||
SPELL_BOMB = 40332 // Wrong ID but Magmadars bomb is not working...
|
||||
};
|
||||
|
||||
enum BatIds
|
||||
{
|
||||
NPC_BLOODSEEKER_BAT = 11368,
|
||||
NPC_FRENZIED_BAT = 14965
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CHARGE_JEKLIK = 1,
|
||||
EVENT_SONIC_BURST,
|
||||
EVENT_SCREECH,
|
||||
EVENT_SPAWN_BATS,
|
||||
EVENT_SHADOW_WORD_PAIN,
|
||||
EVENT_MIND_FLAY,
|
||||
EVENT_CHAIN_MIND_FLAY,
|
||||
EVENT_GREATER_HEAL,
|
||||
EVENT_SPAWN_FLYING_BATS
|
||||
};
|
||||
|
||||
enum Phase
|
||||
{
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2
|
||||
};
|
||||
|
||||
Position const SpawnBat[6] =
|
||||
{
|
||||
{ -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
|
||||
{ -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
|
||||
{ -12293.6220f, -1380.2640f, 144.8304f, 5.483f },
|
||||
{ -12291.6220f, -1380.2640f, 144.8304f, 5.483f },
|
||||
{ -12289.6220f, -1380.2640f, 144.8304f, 5.483f },
|
||||
{ -12293.6220f, -1380.2640f, 144.8304f, 5.483f }
|
||||
};
|
||||
|
||||
class boss_jeklik : public CreatureScript
|
||||
{
|
||||
public: boss_jeklik() : CreatureScript("boss_jeklik") { }
|
||||
|
||||
struct boss_jeklikAI : public BossAI
|
||||
{
|
||||
boss_jeklikAI(Creature* creature) : BossAI(creature, DATA_JEKLIK) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
Talk(SAY_AGGRO);
|
||||
events.SetPhase(PHASE_ONE);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHARGE_JEKLIK, 20000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SONIC_BURST, 8000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SCREECH, 13000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
|
||||
|
||||
me->SetCanFly(true);
|
||||
DoCast(me, SPELL_BAT_FORM);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (events.IsInPhase(PHASE_ONE) && !HealthAbovePct(50))
|
||||
{
|
||||
me->RemoveAurasDueToSpell(SPELL_BAT_FORM);
|
||||
me->SetCanFly(false);
|
||||
DoResetThreat();
|
||||
events.SetPhase(PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, 6000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_MIND_FLAY, 11000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, 26000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_GREATER_HEAL, 50000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, 10000, 0, PHASE_TWO);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHARGE_JEKLIK:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE_JEKLIK, urand(15000, 30000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SONIC_BURST:
|
||||
DoCastVictim(SPELL_SONICBURST);
|
||||
events.ScheduleEvent(EVENT_SONIC_BURST, urand(8000, 13000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SCREECH:
|
||||
DoCastVictim(SPELL_SCREECH);
|
||||
events.ScheduleEvent(EVENT_SCREECH, urand(18000, 26000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SPAWN_BATS:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
if (Creature* bat = me->SummonCreature(NPC_BLOODSEEKER_BAT, SpawnBat[i], TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
|
||||
bat->AI()->AttackStart(target);
|
||||
events.ScheduleEvent(EVENT_SPAWN_BATS, 60000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SHADOW_WORD_PAIN:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(target, SPELL_SHADOW_WORD_PAIN);
|
||||
events.ScheduleEvent(EVENT_SHADOW_WORD_PAIN, urand(12000, 18000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_MIND_FLAY:
|
||||
DoCastVictim(SPELL_MIND_FLAY);
|
||||
events.ScheduleEvent(EVENT_MIND_FLAY, 16000, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_CHAIN_MIND_FLAY:
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastVictim(SPELL_CHAIN_MIND_FLAY);
|
||||
events.ScheduleEvent(EVENT_CHAIN_MIND_FLAY, urand(15000, 30000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_GREATER_HEAL:
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_GREATERHEAL);
|
||||
events.ScheduleEvent(EVENT_GREATER_HEAL, urand(25000, 35000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_SPAWN_FLYING_BATS:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
if (Creature* flyingBat = me->SummonCreature(NPC_FRENZIED_BAT, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + 15.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000))
|
||||
flyingBat->AI()->AttackStart(target);
|
||||
events.ScheduleEvent(EVENT_SPAWN_FLYING_BATS, urand(10000, 15000), 0, PHASE_TWO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetZulGurubAI<boss_jeklikAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Flying Bat
|
||||
class npc_batrider : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_batrider() : CreatureScript("npc_batrider") { }
|
||||
|
||||
struct npc_batriderAI : public ScriptedAI
|
||||
{
|
||||
npc_batriderAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 Bomb_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Bomb_Timer = 2000;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (Bomb_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_BOMB);
|
||||
Bomb_Timer = 5000;
|
||||
}
|
||||
}
|
||||
else
|
||||
Bomb_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_batriderAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_jeklik()
|
||||
{
|
||||
new boss_jeklik();
|
||||
new npc_batrider();
|
||||
}
|
||||
@@ -1,285 +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_Jin'do the Hexxer
|
||||
SD%Complete: 85
|
||||
SDComment: Mind Control not working because of core bug. Shades visible for all.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Say
|
||||
{
|
||||
SAY_AGGRO = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BRAINWASHTOTEM = 24262,
|
||||
SPELL_POWERFULLHEALINGWARD = 24309, // HACKED Totem summoned by script because the spell totems will not cast.
|
||||
SPELL_HEX = 24053,
|
||||
SPELL_DELUSIONSOFJINDO = 24306,
|
||||
SPELL_SHADEOFJINDO = 24308, // HACKED
|
||||
//Healing Ward Spell
|
||||
SPELL_HEAL = 38588, // HACKED Totems are not working right. Right heal spell ID is 24311 but this spell is not casting...
|
||||
//Shade of Jindo Spell
|
||||
SPELL_SHADOWSHOCK = 19460,
|
||||
SPELL_INVISIBLE = 24699
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_BRAINWASHTOTEM = 1,
|
||||
EVENT_POWERFULLHEALINGWARD = 2,
|
||||
EVENT_HEX = 3,
|
||||
EVENT_DELUSIONSOFJINDO = 4,
|
||||
EVENT_TELEPORT = 5
|
||||
};
|
||||
|
||||
Position const TeleportLoc = {-11583.7783f, -1249.4278f, 77.5471f, 4.745f};
|
||||
|
||||
class boss_jindo : public CreatureScript
|
||||
{
|
||||
public: boss_jindo() : CreatureScript("boss_jindo") { }
|
||||
|
||||
struct boss_jindoAI : public BossAI
|
||||
{
|
||||
boss_jindoAI(Creature* creature) : BossAI(creature, DATA_JINDO) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, 20000);
|
||||
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, 16000);
|
||||
events.ScheduleEvent(EVENT_HEX, 8000);
|
||||
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, 10000);
|
||||
events.ScheduleEvent(EVENT_TELEPORT, 5000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_BRAINWASHTOTEM:
|
||||
DoCast(me, SPELL_BRAINWASHTOTEM);
|
||||
events.ScheduleEvent(EVENT_BRAINWASHTOTEM, urand(18000, 26000));
|
||||
break;
|
||||
case EVENT_POWERFULLHEALINGWARD: // HACK
|
||||
//DoCast(me, SPELL_POWERFULLHEALINGWARD);
|
||||
me->SummonCreature(14987, me->GetPositionX()+3, me->GetPositionY()-2, me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000);
|
||||
events.ScheduleEvent(EVENT_POWERFULLHEALINGWARD, urand(14000, 20000));
|
||||
break;
|
||||
case EVENT_HEX:
|
||||
if (Unit* target = me->GetVictim())
|
||||
{
|
||||
DoCast(target, SPELL_HEX, true);
|
||||
if (DoGetThreat(target))
|
||||
DoModifyThreatPercent(target, -80);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_HEX, urand(12000, 20000));
|
||||
break;
|
||||
case EVENT_DELUSIONSOFJINDO: // HACK
|
||||
// Casting the delusion curse with a shade so shade will attack the same target with the curse.
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_DELUSIONSOFJINDO);
|
||||
Creature* Shade = me->SummonCreature(NPC_SHADE_OF_JINDO, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Shade)
|
||||
Shade->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_DELUSIONSOFJINDO, urand(4000, 12000));
|
||||
break;
|
||||
case EVENT_TELEPORT: // Possible HACK
|
||||
// Teleports a random player and spawns 9 Sacrificed Trolls to attack player
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoTeleportPlayer(target, TeleportLoc.m_positionX, TeleportLoc.m_positionY, TeleportLoc.m_positionZ, TeleportLoc.m_orientation);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(target, -100);
|
||||
Creature* SacrificedTroll;
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()-2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()-4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()+2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()-2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()+4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX(), target->GetPositionY()-4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
SacrificedTroll = me->SummonCreature(NPC_SACRIFICED_TROLL, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (SacrificedTroll)
|
||||
SacrificedTroll->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_TELEPORT, urand(15000, 23000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_jindoAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
//Healing Ward
|
||||
class npc_healing_ward : public CreatureScript
|
||||
{
|
||||
public:
|
||||
|
||||
npc_healing_ward()
|
||||
: CreatureScript("npc_healing_ward")
|
||||
{
|
||||
}
|
||||
|
||||
struct npc_healing_wardAI : public ScriptedAI
|
||||
{
|
||||
npc_healing_wardAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 Heal_Timer;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Heal_Timer = 2000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Heal_Timer
|
||||
if (Heal_Timer <= diff)
|
||||
{
|
||||
Unit* pJindo = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JINDO));
|
||||
if (pJindo)
|
||||
DoCast(pJindo, SPELL_HEAL);
|
||||
Heal_Timer = 3000;
|
||||
} else Heal_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_healing_wardAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
//Shade of Jindo
|
||||
class npc_shade_of_jindo : public CreatureScript
|
||||
{
|
||||
public:
|
||||
|
||||
npc_shade_of_jindo()
|
||||
: CreatureScript("npc_shade_of_jindo")
|
||||
{
|
||||
}
|
||||
|
||||
struct npc_shade_of_jindoAI : public ScriptedAI
|
||||
{
|
||||
npc_shade_of_jindoAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 ShadowShock_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ShadowShock_Timer = 1000;
|
||||
DoCast(me, SPELL_INVISIBLE, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
|
||||
//ShadowShock_Timer
|
||||
if (ShadowShock_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SHADOWSHOCK);
|
||||
ShadowShock_Timer = 2000;
|
||||
} else ShadowShock_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_shade_of_jindoAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_jindo()
|
||||
{
|
||||
new boss_jindo();
|
||||
new npc_healing_ward();
|
||||
new npc_shade_of_jindo();
|
||||
}
|
||||
@@ -1,435 +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_Mandokir
|
||||
SD%Complete: 90
|
||||
SDComment: Ohgan function needs improvements.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Spell.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellScript.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DING_KILL = 1,
|
||||
SAY_WATCH = 2,
|
||||
SAY_WATCH_WHISPER = 3,
|
||||
SAY_OHGAN_DEAD = 4,
|
||||
SAY_GRATS_JINDO = 0,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CHARGE = 24408, // seen
|
||||
SPELL_OVERPOWER = 24407, // Seen
|
||||
SPELL_FEAR = 29321,
|
||||
SPELL_WHIRLWIND = 13736, // Triggers 15589
|
||||
SPELL_MORTAL_STRIKE = 16856, // Seen
|
||||
SPELL_FRENZY = 24318, // seen
|
||||
SPELL_WATCH = 24314, // seen 24315, 24316
|
||||
SPELL_WATCH_CHARGE = 24315, // Triggers 24316
|
||||
SPELL_LEVEL_UP = 24312 //
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_CHECK_SPEAKER = 1,
|
||||
EVENT_CHECK_START = 2,
|
||||
EVENT_STARTED = 3,
|
||||
EVENT_OVERPOWER = 4,
|
||||
EVENT_MORTAL_STRIKE = 5,
|
||||
EVENT_WHIRLWIND = 6,
|
||||
EVENT_CHECK_OHGAN = 7,
|
||||
EVENT_WATCH_PLAYER = 8,
|
||||
EVENT_CHARGE_PLAYER = 9
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
MODEL_OHGAN_MOUNT = 15271,
|
||||
PATH_MANDOKIR = 492861,
|
||||
POINT_MANDOKIR_END = 24,
|
||||
CHAINED_SPIRT_COUNT = 20
|
||||
};
|
||||
|
||||
Position const PosSummonChainedSpirits[CHAINED_SPIRT_COUNT] =
|
||||
{
|
||||
{ -12167.17f, -1979.330f, 133.0992f, 2.268928f },
|
||||
{ -12262.74f, -1953.394f, 133.5496f, 0.593412f },
|
||||
{ -12176.89f, -1983.068f, 133.7841f, 2.129302f },
|
||||
{ -12226.45f, -1977.933f, 132.7982f, 1.466077f },
|
||||
{ -12204.74f, -1890.431f, 135.7569f, 4.415683f },
|
||||
{ -12216.70f, -1891.806f, 136.3496f, 4.677482f },
|
||||
{ -12236.19f, -1892.034f, 134.1041f, 5.044002f },
|
||||
{ -12248.24f, -1893.424f, 134.1182f, 5.270895f },
|
||||
{ -12257.36f, -1897.663f, 133.1484f, 5.462881f },
|
||||
{ -12265.84f, -1903.077f, 133.1649f, 5.654867f },
|
||||
{ -12158.69f, -1972.707f, 133.8751f, 2.408554f },
|
||||
{ -12178.82f, -1891.974f, 134.1786f, 3.944444f },
|
||||
{ -12193.36f, -1890.039f, 135.1441f, 4.188790f },
|
||||
{ -12275.59f, -1932.845f, 134.9017f, 0.174533f },
|
||||
{ -12273.51f, -1941.539f, 136.1262f, 0.314159f },
|
||||
{ -12247.02f, -1963.497f, 133.9476f, 0.872665f },
|
||||
{ -12238.68f, -1969.574f, 133.6273f, 1.134464f },
|
||||
{ -12192.78f, -1982.116f, 132.6966f, 1.919862f },
|
||||
{ -12210.81f, -1979.316f, 133.8700f, 1.797689f },
|
||||
{ -12283.51f, -1924.839f, 133.5170f, 0.069813f }
|
||||
};
|
||||
|
||||
Position const PosMandokir[2] =
|
||||
{
|
||||
{ -12167.8f, -1927.25f, 153.73f, 3.76991f },
|
||||
{ -12197.86f, -1949.392f, 130.2745f, 0.0f }
|
||||
};
|
||||
|
||||
class boss_mandokir : public CreatureScript
|
||||
{
|
||||
public: boss_mandokir() : CreatureScript("boss_mandokir") { }
|
||||
|
||||
struct boss_mandokirAI : public BossAI
|
||||
{
|
||||
boss_mandokirAI(Creature* creature) : BossAI(creature, DATA_MANDOKIR) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (me->GetPositionZ() > 140.0f)
|
||||
{
|
||||
_Reset();
|
||||
killCount = 0;
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
events.ScheduleEvent(EVENT_CHECK_START, 1000);
|
||||
if (Creature* speaker = ObjectAccessor::GetCreature(*me, instance->GetData64(NPC_VILEBRANCH_SPEAKER)))
|
||||
if (!speaker->IsAlive())
|
||||
speaker->Respawn(true);
|
||||
}
|
||||
summons.DespawnAll();
|
||||
me->Mount(MODEL_OHGAN_MOUNT);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
// Do not want to unsummon Ohgan
|
||||
for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
|
||||
if (Creature* unsummon = ObjectAccessor::GetCreature(*me, chainedSpirtGUIDs[i]))
|
||||
unsummon->DespawnOrUnsummon();
|
||||
instance->SetBossState(DATA_MANDOKIR, DONE);
|
||||
instance->SaveToDB();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_OVERPOWER, urand(7000, 9000));
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, urand(24000, 30000));
|
||||
events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
|
||||
events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(13000, 15000));
|
||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(33000, 38000));
|
||||
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation());
|
||||
Talk(SAY_AGGRO);
|
||||
me->Dismount();
|
||||
// Summon Ohgan (Spell missing) TEMP HACK
|
||||
me->SummonCreature(NPC_OHGAN, me->GetPositionX()-3, me->GetPositionY(), me->GetPositionZ(), me->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 35000);
|
||||
// Summon Chained Spirits
|
||||
for (int i = 0; i < CHAINED_SPIRT_COUNT; ++i)
|
||||
{
|
||||
Creature* chainedSpirt = me->SummonCreature(NPC_CHAINED_SPIRT, PosSummonChainedSpirits[i], TEMPSUMMON_CORPSE_DESPAWN);
|
||||
chainedSpirtGUIDs[i] = chainedSpirt->GetGUID();
|
||||
}
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (++killCount == 3)
|
||||
{
|
||||
Talk(SAY_DING_KILL);
|
||||
if (Creature* jindo = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_JINDO)))
|
||||
if (jindo->IsAlive())
|
||||
jindo->AI()->Talk(SAY_GRATS_JINDO);
|
||||
DoCast(me, SPELL_LEVEL_UP, true);
|
||||
killCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type == WAYPOINT_MOTION_TYPE)
|
||||
{
|
||||
me->SetWalk(false);
|
||||
if (id == POINT_MANDOKIR_END)
|
||||
{
|
||||
me->SetHomePosition(PosMandokir[0]);
|
||||
instance->SetBossState(DATA_MANDOKIR, NOT_STARTED);
|
||||
me->DespawnOrUnsummon(6000); // No idea how to respawn on wipe.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
{
|
||||
if (instance->GetBossState(DATA_MANDOKIR) == NOT_STARTED || instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
|
||||
{
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_CHECK_START:
|
||||
if (instance->GetBossState(DATA_MANDOKIR) == SPECIAL)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(0, PosMandokir[1].m_positionX, PosMandokir[1].m_positionY, PosMandokir[1].m_positionZ);
|
||||
events.ScheduleEvent(EVENT_STARTED, 6000);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_CHECK_START, 1000);
|
||||
break;
|
||||
case EVENT_STARTED:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->GetMotionMaster()->MovePath(PATH_MANDOKIR, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_OVERPOWER:
|
||||
DoCastVictim(SPELL_OVERPOWER, true);
|
||||
events.ScheduleEvent(EVENT_OVERPOWER, urand(6000, 12000));
|
||||
break;
|
||||
case EVENT_MORTAL_STRIKE:
|
||||
if (me->GetVictim() && me->GetVictim()->HealthBelowPct(50))
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE, true);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(12000, 18000));
|
||||
break;
|
||||
case EVENT_WHIRLWIND:
|
||||
DoCast(me, SPELL_WHIRLWIND);
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, urand(22000, 26000));
|
||||
break;
|
||||
case EVENT_CHECK_OHGAN:
|
||||
if (instance->GetBossState(DATA_OHGAN) == DONE)
|
||||
{
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
Talk(SAY_OHGAN_DEAD);
|
||||
}
|
||||
else
|
||||
events.ScheduleEvent(EVENT_CHECK_OHGAN, 1000);
|
||||
break;
|
||||
case EVENT_WATCH_PLAYER:
|
||||
if (Unit* player = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
DoCast(player, SPELL_WATCH);
|
||||
Talk(SAY_WATCH, player);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_WATCH_PLAYER, urand(12000, 15000));
|
||||
break;
|
||||
case EVENT_CHARGE_PLAYER:
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_CHARGE);
|
||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, urand(22000, 30000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 killCount;
|
||||
uint64 chainedSpirtGUIDs[CHAINED_SPIRT_COUNT];
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetZulGurubAI<boss_mandokirAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Ohgan
|
||||
|
||||
enum OhganSpells
|
||||
{
|
||||
SPELL_SUNDERARMOR = 24317
|
||||
};
|
||||
|
||||
class npc_ohgan : public CreatureScript
|
||||
{
|
||||
public: npc_ohgan() : CreatureScript("npc_ohgan") { }
|
||||
|
||||
struct npc_ohganAI : public ScriptedAI
|
||||
{
|
||||
npc_ohganAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SunderArmor_Timer = 5000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
instance->SetBossState(DATA_OHGAN, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (SunderArmor_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SUNDERARMOR, true);
|
||||
SunderArmor_Timer = urand(10000, 15000);
|
||||
} else SunderArmor_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 SunderArmor_Timer;
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetZulGurubAI<npc_ohganAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
enum VilebranchSpells
|
||||
{
|
||||
SPELL_DEMORALIZING_SHOUT = 13730,
|
||||
SPELL_CLEAVE = 15284
|
||||
};
|
||||
|
||||
class npc_vilebranch_speaker : public CreatureScript
|
||||
{
|
||||
public: npc_vilebranch_speaker() : CreatureScript("npc_vilebranch_speaker") { }
|
||||
|
||||
struct npc_vilebranch_speakerAI : public ScriptedAI
|
||||
{
|
||||
npc_vilebranch_speakerAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
demoralizing_Shout_Timer = urand(2000, 4000);
|
||||
cleave_Timer = urand(5000, 8000);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
instance->SetBossState(DATA_MANDOKIR, SPECIAL);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (demoralizing_Shout_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_DEMORALIZING_SHOUT);
|
||||
demoralizing_Shout_Timer = urand(22000, 30000);
|
||||
} else demoralizing_Shout_Timer -= diff;
|
||||
|
||||
if (cleave_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE, true);
|
||||
cleave_Timer = urand(6000, 9000);
|
||||
} else cleave_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 demoralizing_Shout_Timer;
|
||||
uint32 cleave_Timer;
|
||||
InstanceScript* instance;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_vilebranch_speakerAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_threatening_gaze : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_threatening_gaze() : SpellScriptLoader("spell_threatening_gaze") { }
|
||||
|
||||
class spell_threatening_gaze_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_threatening_gaze_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
if (Unit* caster = GetCaster())
|
||||
if (Unit* target = GetTarget())
|
||||
if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEATH)
|
||||
caster->CastSpell(target, SPELL_WATCH_CHARGE);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectRemove += AuraEffectRemoveFn(spell_threatening_gaze_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_threatening_gaze_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_mandokir()
|
||||
{
|
||||
new boss_mandokir();
|
||||
new npc_ohgan();
|
||||
new npc_vilebranch_speaker();
|
||||
new spell_threatening_gaze();
|
||||
}
|
||||
@@ -1,269 +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_Marli
|
||||
SD%Complete: 80
|
||||
SDComment: Charging healers and casters not working. Perhaps wrong Spell Timers.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_TRANSFORM = 1,
|
||||
SAY_SPIDER_SPAWN = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CHARGE = 22911,
|
||||
SPELL_ASPECT_OF_MARLI = 24686, // A stun spell
|
||||
SPELL_ENVOLWINGWEB = 24110,
|
||||
SPELL_POISON_VOLLEY = 24099,
|
||||
SPELL_SPIDER_FORM = 24084,
|
||||
// The Spider Spell
|
||||
SPELL_LEVELUP = 24312 // Not right Spell.
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPAWN_START_SPIDERS = 1, // Phase 1
|
||||
EVENT_POISON_VOLLEY = 2, // Phase All
|
||||
EVENT_SPAWN_SPIDER = 3, // Phase All
|
||||
EVENT_CHARGE_PLAYER = 4, // Phase 3
|
||||
EVENT_ASPECT_OF_MARLI = 5, // Phase 2
|
||||
EVENT_TRANSFORM = 6, // Phase 2
|
||||
EVENT_TRANSFORM_BACK = 7 // Phase 3
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2,
|
||||
PHASE_THREE = 3
|
||||
};
|
||||
|
||||
class boss_marli : public CreatureScript
|
||||
{
|
||||
public: boss_marli() : CreatureScript("boss_marli") { }
|
||||
|
||||
struct boss_marliAI : public BossAI
|
||||
{
|
||||
boss_marliAI(Creature* creature) : BossAI(creature, DATA_MARLI) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (events.IsInPhase(PHASE_THREE))
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_SPAWN_START_SPIDERS, 1000, 0, PHASE_ONE);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SPAWN_START_SPIDERS:
|
||||
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
Talk(SAY_SPIDER_SPAWN);
|
||||
Creature* Spider = NULL;
|
||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Spider)
|
||||
Spider->AI()->AttackStart(target);
|
||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Spider)
|
||||
Spider->AI()->AttackStart(target);
|
||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Spider)
|
||||
Spider->AI()->AttackStart(target);
|
||||
Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Spider)
|
||||
Spider->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
|
||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
||||
events.SetPhase(PHASE_TWO);
|
||||
break;
|
||||
case EVENT_POISON_VOLLEY:
|
||||
DoCastVictim(SPELL_POISON_VOLLEY, true);
|
||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, urand(10000, 20000));
|
||||
break;
|
||||
case EVENT_ASPECT_OF_MARLI:
|
||||
DoCastVictim(SPELL_ASPECT_OF_MARLI, true);
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, urand(13000, 18000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_SPAWN_SPIDER:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
Creature* Spider = me->SummonCreature(15041, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
if (Spider)
|
||||
Spider->AI()->AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, urand(12000, 17000));
|
||||
break;
|
||||
case EVENT_TRANSFORM:
|
||||
{
|
||||
Talk(SAY_TRANSFORM);
|
||||
DoCast(me, SPELL_SPIDER_FORM); // SPELL_AURA_TRANSFORM
|
||||
/*
|
||||
CreatureTemplate const* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, true); // hack
|
||||
DoCastVictim(SPELL_ENVOLWINGWEB);
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 1500, 0, PHASE_THREE);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM_BACK, 25000, 0, PHASE_THREE);
|
||||
events.SetPhase(PHASE_THREE);
|
||||
break;
|
||||
}
|
||||
case EVENT_CHARGE_PLAYER:
|
||||
{
|
||||
Unit* target = NULL;
|
||||
int i = 0;
|
||||
while (i++ < 3) // max 3 tries to get a random target with power_mana
|
||||
{
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true); // not aggro leader
|
||||
if (target && target->getPowerType() == POWER_MANA)
|
||||
break;
|
||||
}
|
||||
if (target)
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE_PLAYER, 8000, 0, PHASE_THREE);
|
||||
break;
|
||||
}
|
||||
case EVENT_TRANSFORM_BACK:
|
||||
{
|
||||
me->RemoveAura(SPELL_SPIDER_FORM);
|
||||
/*
|
||||
CreatureTemplate const* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
events.ScheduleEvent(EVENT_ASPECT_OF_MARLI, 12000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 45000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_POISON_VOLLEY, 15000);
|
||||
events.ScheduleEvent(EVENT_SPAWN_SPIDER, 30000);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, urand(35000, 60000), 0, PHASE_TWO);
|
||||
events.SetPhase(PHASE_TWO);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_marliAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
// Spawn of Marli
|
||||
class npc_spawn_of_marli : public CreatureScript
|
||||
{
|
||||
public: npc_spawn_of_marli() : CreatureScript("npc_spawn_of_marli") { }
|
||||
|
||||
struct npc_spawn_of_marliAI : public ScriptedAI
|
||||
{
|
||||
npc_spawn_of_marliAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint32 LevelUp_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
LevelUp_Timer = 3000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//LevelUp_Timer
|
||||
if (LevelUp_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_LEVELUP);
|
||||
LevelUp_Timer = 3000;
|
||||
} else LevelUp_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_spawn_of_marliAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_marli()
|
||||
{
|
||||
new boss_marli();
|
||||
new npc_spawn_of_marli();
|
||||
}
|
||||
@@ -1,171 +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_Renataki
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_AMBUSH = 34794,
|
||||
SPELL_THOUSANDBLADES = 34799
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
EQUIP_ID_MAIN_HAND = 0 //was item display id 31818, but this id does not exist
|
||||
};
|
||||
|
||||
class boss_renataki : public CreatureScript
|
||||
{
|
||||
public: boss_renataki() : CreatureScript("boss_renataki") { }
|
||||
|
||||
struct boss_renatakiAI : public BossAI
|
||||
{
|
||||
boss_renatakiAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
uint32 Invisible_Timer;
|
||||
uint32 Ambush_Timer;
|
||||
uint32 Visible_Timer;
|
||||
uint32 Aggro_Timer;
|
||||
uint32 ThousandBlades_Timer;
|
||||
|
||||
bool Invisible;
|
||||
bool Ambushed;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
Invisible_Timer = urand(8000, 18000);
|
||||
Ambush_Timer = 3000;
|
||||
Visible_Timer = 4000;
|
||||
Aggro_Timer = urand(15000, 25000);
|
||||
ThousandBlades_Timer = urand(4000, 8000);
|
||||
|
||||
Invisible = false;
|
||||
Ambushed = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Invisible_Timer
|
||||
if (Invisible_Timer <= diff)
|
||||
{
|
||||
me->InterruptSpell(CURRENT_GENERIC_SPELL);
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_UNEQUIP, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
||||
me->SetDisplayId(11686);
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
Invisible = true;
|
||||
|
||||
Invisible_Timer = urand(15000, 30000);
|
||||
} else Invisible_Timer -= diff;
|
||||
|
||||
if (Invisible)
|
||||
{
|
||||
if (Ambush_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 0);
|
||||
if (target)
|
||||
{
|
||||
me->NearTeleportTo(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), me->GetOrientation());
|
||||
DoCast(target, SPELL_AMBUSH);
|
||||
}
|
||||
|
||||
Ambushed = true;
|
||||
Ambush_Timer = 3000;
|
||||
} else Ambush_Timer -= diff;
|
||||
}
|
||||
|
||||
if (Ambushed)
|
||||
{
|
||||
if (Visible_Timer <= diff)
|
||||
{
|
||||
me->InterruptSpell(CURRENT_GENERIC_SPELL);
|
||||
|
||||
me->SetDisplayId(15268);
|
||||
SetEquipmentSlots(false, EQUIP_ID_MAIN_HAND, EQUIP_NO_CHANGE, EQUIP_NO_CHANGE);
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
Invisible = false;
|
||||
|
||||
Visible_Timer = 4000;
|
||||
} else Visible_Timer -= diff;
|
||||
}
|
||||
|
||||
//Resetting some aggro so he attacks other gamers
|
||||
if (!Invisible)
|
||||
{
|
||||
if (Aggro_Timer <= diff)
|
||||
{
|
||||
Unit* target = NULL;
|
||||
target = SelectTarget(SELECT_TARGET_RANDOM, 1);
|
||||
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -50);
|
||||
|
||||
if (target)
|
||||
AttackStart(target);
|
||||
|
||||
Aggro_Timer = urand(7000, 20000);
|
||||
} else Aggro_Timer -= diff;
|
||||
|
||||
if (ThousandBlades_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_THOUSANDBLADES);
|
||||
ThousandBlades_Timer = urand(7000, 12000);
|
||||
} else ThousandBlades_Timer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_renatakiAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_renataki()
|
||||
{
|
||||
new boss_renataki();
|
||||
}
|
||||
|
||||
@@ -1,557 +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_Thekal
|
||||
SD%Complete: 95
|
||||
SDComment: Almost finished.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_MORTALCLEAVE = 22859, // Phase 1
|
||||
SPELL_SILENCE = 22666, // Phase 1
|
||||
SPELL_TIGER_FORM = 24169, // Phase 1
|
||||
SPELL_RESURRECT = 24173, // Phase 1 // Not used in script.
|
||||
SPELL_FRENZY = 8269, // Phase 2
|
||||
SPELL_FORCEPUNCH = 24189, // Phase 2
|
||||
SPELL_CHARGE = 24193, // Phase 2
|
||||
SPELL_ENRAGE = 8269, // Phase 2
|
||||
SPELL_SUMMONTIGERS = 24183, // Phase 2
|
||||
// Zealot Lor'Khan Spells
|
||||
SPELL_SHIELD = 20545,
|
||||
SPELL_BLOODLUST = 24185,
|
||||
SPELL_GREATERHEAL = 24208,
|
||||
SPELL_DISARM = 6713,
|
||||
// Zealot Zath Spells
|
||||
SPELL_SWEEPINGSTRIKES = 18765,
|
||||
SPELL_SINISTERSTRIKE = 15581,
|
||||
SPELL_GOUGE = 12540,
|
||||
SPELL_KICK = 15614,
|
||||
SPELL_BLIND = 21060
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_MORTALCLEAVE = 1, // Phase 1
|
||||
EVENT_SILENCE = 2, // Phase 1
|
||||
EVENT_CHECK_TIMER = 3, // Phase 1
|
||||
EVENT_RESURRECT_TIMER = 4, // Phase 1
|
||||
EVENT_FRENZY = 5, // Phase 2
|
||||
EVENT_FORCEPUNCH = 6, // Phase 2
|
||||
EVENT_SPELL_CHARGE = 7, // Phase 2
|
||||
EVENT_ENRAGE = 8, // Phase 2
|
||||
EVENT_SUMMONTIGERS = 9 // Phase 2
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ONE = 1,
|
||||
PHASE_TWO = 2
|
||||
};
|
||||
|
||||
class boss_thekal : public CreatureScript
|
||||
{
|
||||
public: boss_thekal() : CreatureScript("boss_thekal") { }
|
||||
|
||||
struct boss_thekalAI : public BossAI
|
||||
{
|
||||
boss_thekalAI(Creature* creature) : BossAI(creature, DATA_THEKAL) { }
|
||||
|
||||
bool Enraged;
|
||||
bool WasDead;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (events.IsInPhase(PHASE_TWO))
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 35.0f, false); // hack
|
||||
_Reset();
|
||||
Enraged = false;
|
||||
WasDead = false;
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, 4000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_SILENCE, 9000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_CHECK_TIMER, 10000, 0, PHASE_ONE); // Phase 1
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE); // Phase 1
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
instance->SetBossState(DATA_THEKAL, NOT_STARTED);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_MORTALCLEAVE:
|
||||
DoCastVictim(SPELL_MORTALCLEAVE, true);
|
||||
events.ScheduleEvent(EVENT_MORTALCLEAVE, urand(15000, 20000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_SILENCE:
|
||||
DoCastVictim(SPELL_SILENCE, true);
|
||||
events.ScheduleEvent(EVENT_SILENCE, urand(20000, 25000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RESURRECT_TIMER:
|
||||
//Thekal will transform to Tiger if he died and was not resurrected after 10 seconds.
|
||||
if (WasDead)
|
||||
{
|
||||
DoCast(me, SPELL_TIGER_FORM); // SPELL_AURA_TRANSFORM
|
||||
me->SetObjectScale(2.00f);
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
/*
|
||||
const CreatureTemplate* cinfo = me->GetCreatureTemplate();
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 40)));
|
||||
me->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 40)));
|
||||
me->UpdateDamagePhysical(BASE_ATTACK);
|
||||
*/
|
||||
me->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, 40.0f, true); // hack
|
||||
DoResetThreat();
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, 4000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_SPELL_CHARGE, 12000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 32000, 0, PHASE_TWO); // Phase 2
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, 25000, 0, PHASE_TWO); // Phase 2
|
||||
events.SetPhase(PHASE_TWO);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_RESURRECT_TIMER, 10000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_CHECK_TIMER:
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!WasDead)
|
||||
{
|
||||
if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
|
||||
{
|
||||
//Resurrect LorKhan
|
||||
if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
|
||||
{
|
||||
pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pLorKhan->setFaction(14);
|
||||
pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pLorKhan->SetFullHealth();
|
||||
instance->SetData(DATA_LORKHAN, DONE);
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_ZATH) == SPECIAL)
|
||||
{
|
||||
//Resurrect Zath
|
||||
if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH)))
|
||||
{
|
||||
pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pZath->setFaction(14);
|
||||
pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pZath->SetFullHealth();
|
||||
instance->SetBossState(DATA_ZATH, DONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_TIMER, 5000, 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
DoCast(me, SPELL_FRENZY);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_FORCEPUNCH:
|
||||
DoCastVictim(SPELL_FORCEPUNCH, true);
|
||||
events.ScheduleEvent(EVENT_FORCEPUNCH, urand(16000, 21000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_CHARGE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
|
||||
{
|
||||
DoCast(target, SPELL_CHARGE);
|
||||
DoResetThreat();
|
||||
AttackStart(target);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHARGE, urand(15000, 22000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
if (HealthBelowPct(11) && !Enraged)
|
||||
{
|
||||
DoCast(me, SPELL_ENRAGE);
|
||||
Enraged = true;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 30000);
|
||||
break;
|
||||
case EVENT_SUMMONTIGERS:
|
||||
DoCastVictim(SPELL_SUMMONTIGERS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMONTIGERS, urand(10000, 14000), 0, PHASE_TWO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->IsFullHealth() && WasDead)
|
||||
WasDead = false;
|
||||
|
||||
if ((events.IsInPhase(PHASE_ONE)) && !WasDead && !HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->AttackStop();
|
||||
instance->SetBossState(DATA_THEKAL, SPECIAL);
|
||||
WasDead=true;
|
||||
}
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_thekalAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
//Zealot Lor'Khan
|
||||
class npc_zealot_lorkhan : public CreatureScript
|
||||
{
|
||||
public: npc_zealot_lorkhan() : CreatureScript("npc_zealot_lorkhan") { }
|
||||
|
||||
struct npc_zealot_lorkhanAI : public ScriptedAI
|
||||
{
|
||||
npc_zealot_lorkhanAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 Shield_Timer;
|
||||
uint32 BloodLust_Timer;
|
||||
uint32 GreaterHeal_Timer;
|
||||
uint32 Disarm_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool FakeDeath;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Shield_Timer = 1000;
|
||||
BloodLust_Timer = 16000;
|
||||
GreaterHeal_Timer = 32000;
|
||||
Disarm_Timer = 6000;
|
||||
Check_Timer = 10000;
|
||||
|
||||
FakeDeath = false;
|
||||
|
||||
instance->SetBossState(DATA_LORKHAN, NOT_STARTED);
|
||||
|
||||
me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Shield_Timer
|
||||
if (Shield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_SHIELD);
|
||||
Shield_Timer = 61000;
|
||||
} else Shield_Timer -= diff;
|
||||
|
||||
//BloodLust_Timer
|
||||
if (BloodLust_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_BLOODLUST);
|
||||
BloodLust_Timer = 20000+rand()%8000;
|
||||
} else BloodLust_Timer -= diff;
|
||||
|
||||
//Casting Greaterheal to Thekal or Zath if they are in meele range.
|
||||
if (GreaterHeal_Timer <= diff)
|
||||
{
|
||||
Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL));
|
||||
Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH));
|
||||
|
||||
if (!pThekal || !pZath)
|
||||
return;
|
||||
|
||||
switch (urand(0, 1))
|
||||
{
|
||||
case 0:
|
||||
if (me->IsWithinMeleeRange(pThekal))
|
||||
DoCast(pThekal, SPELL_GREATERHEAL);
|
||||
break;
|
||||
case 1:
|
||||
if (me->IsWithinMeleeRange(pZath))
|
||||
DoCast(pZath, SPELL_GREATERHEAL);
|
||||
break;
|
||||
}
|
||||
|
||||
GreaterHeal_Timer = 15000+rand()%5000;
|
||||
} else GreaterHeal_Timer -= diff;
|
||||
|
||||
//Disarm_Timer
|
||||
if (Disarm_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DISARM);
|
||||
Disarm_Timer = 15000+rand()%10000;
|
||||
} else Disarm_Timer -= diff;
|
||||
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!FakeDeath && Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
|
||||
{
|
||||
//Resurrect Thekal
|
||||
if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
|
||||
{
|
||||
pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pThekal->setFaction(14);
|
||||
pThekal->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_ZATH) == SPECIAL)
|
||||
{
|
||||
//Resurrect Zath
|
||||
if (Unit* pZath = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_ZATH)))
|
||||
{
|
||||
pZath->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pZath->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pZath->setFaction(14);
|
||||
pZath->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
Check_Timer = 5000;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->setFaction(35);
|
||||
me->AttackStop();
|
||||
|
||||
instance->SetBossState(DATA_LORKHAN, SPECIAL);
|
||||
|
||||
FakeDeath = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_zealot_lorkhanAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
//Zealot Zath
|
||||
class npc_zealot_zath : public CreatureScript
|
||||
{
|
||||
public:
|
||||
|
||||
npc_zealot_zath()
|
||||
: CreatureScript("npc_zealot_zath")
|
||||
{
|
||||
}
|
||||
|
||||
struct npc_zealot_zathAI : public ScriptedAI
|
||||
{
|
||||
npc_zealot_zathAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
uint32 SweepingStrikes_Timer;
|
||||
uint32 SinisterStrike_Timer;
|
||||
uint32 Gouge_Timer;
|
||||
uint32 Kick_Timer;
|
||||
uint32 Blind_Timer;
|
||||
uint32 Check_Timer;
|
||||
|
||||
bool FakeDeath;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SweepingStrikes_Timer = 13000;
|
||||
SinisterStrike_Timer = 8000;
|
||||
Gouge_Timer = 25000;
|
||||
Kick_Timer = 18000;
|
||||
Blind_Timer = 5000;
|
||||
Check_Timer = 10000;
|
||||
|
||||
FakeDeath = false;
|
||||
|
||||
instance->SetBossState(DATA_ZATH, NOT_STARTED);
|
||||
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//SweepingStrikes_Timer
|
||||
if (SweepingStrikes_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SWEEPINGSTRIKES);
|
||||
SweepingStrikes_Timer = 22000+rand()%4000;
|
||||
} else SweepingStrikes_Timer -= diff;
|
||||
|
||||
//SinisterStrike_Timer
|
||||
if (SinisterStrike_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SINISTERSTRIKE);
|
||||
SinisterStrike_Timer = 8000+rand()%8000;
|
||||
} else SinisterStrike_Timer -= diff;
|
||||
|
||||
//Gouge_Timer
|
||||
if (Gouge_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_GOUGE);
|
||||
|
||||
if (DoGetThreat(me->GetVictim()))
|
||||
DoModifyThreatPercent(me->GetVictim(), -100);
|
||||
|
||||
Gouge_Timer = 17000+rand()%10000;
|
||||
} else Gouge_Timer -= diff;
|
||||
|
||||
//Kick_Timer
|
||||
if (Kick_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_KICK);
|
||||
Kick_Timer = 15000+rand()%10000;
|
||||
} else Kick_Timer -= diff;
|
||||
|
||||
//Blind_Timer
|
||||
if (Blind_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_BLIND);
|
||||
Blind_Timer = 10000+rand()%10000;
|
||||
} else Blind_Timer -= diff;
|
||||
|
||||
//Check_Timer for the death of LorKhan and Zath.
|
||||
if (!FakeDeath && Check_Timer <= diff)
|
||||
{
|
||||
if (instance->GetBossState(DATA_LORKHAN) == SPECIAL)
|
||||
{
|
||||
//Resurrect LorKhan
|
||||
if (Unit* pLorKhan = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_LORKHAN)))
|
||||
{
|
||||
pLorKhan->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pLorKhan->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pLorKhan->setFaction(14);
|
||||
pLorKhan->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_THEKAL) == SPECIAL)
|
||||
{
|
||||
//Resurrect Thekal
|
||||
if (Unit* pThekal = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THEKAL)))
|
||||
{
|
||||
pThekal->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
|
||||
pThekal->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
pThekal->setFaction(14);
|
||||
pThekal->SetFullHealth();
|
||||
}
|
||||
}
|
||||
|
||||
Check_Timer = 5000;
|
||||
} else Check_Timer -= diff;
|
||||
|
||||
if (!HealthAbovePct(5))
|
||||
{
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE_PERCENT);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||
me->RemoveAurasByType(SPELL_AURA_PERIODIC_LEECH);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetStandState(UNIT_STAND_STATE_SLEEP);
|
||||
me->setFaction(35);
|
||||
me->AttackStop();
|
||||
|
||||
instance->SetBossState(DATA_ZATH, SPECIAL);
|
||||
|
||||
FakeDeath = true;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_zealot_zathAI>(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_thekal()
|
||||
{
|
||||
new boss_thekal();
|
||||
new npc_zealot_lorkhan();
|
||||
new npc_zealot_zath();
|
||||
}
|
||||
@@ -1,274 +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/>.
|
||||
*/
|
||||
|
||||
#include "ObjectMgr.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Spell.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
/*
|
||||
* @todo
|
||||
* - Fix timers (research some more)
|
||||
*/
|
||||
|
||||
enum Says
|
||||
{
|
||||
SAY_VENOXIS_TRANSFORM = 1, // Let the coils of hate unfurl!
|
||||
SAY_VENOXIS_DEATH = 2 // Ssserenity.. at lassst!
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
// troll form
|
||||
SPELL_THRASH = 3391,
|
||||
SPELL_DISPEL_MAGIC = 23859,
|
||||
SPELL_RENEW = 23895,
|
||||
SPELL_HOLY_NOVA = 23858,
|
||||
SPELL_HOLY_FIRE = 23860,
|
||||
SPELL_HOLY_WRATH = 23979,
|
||||
// snake form
|
||||
SPELL_POISON_CLOUD = 23861,
|
||||
SPELL_VENOM_SPIT = 23862,
|
||||
|
||||
SPELL_PARASITIC_SERPENT = 23865,
|
||||
SPELL_SUMMON_PARASITIC_SERPENT = 23866,
|
||||
SPELL_PARASITIC_SERPENT_TRIGGER = 23867,
|
||||
// used when swapping event-stages
|
||||
SPELL_VENOXIS_TRANSFORM = 23849, // 50% health - shapechange to cobra
|
||||
SPELL_FRENZY = 8269 // 20% health - frenzy
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
// troll form
|
||||
EVENT_THRASH = 1,
|
||||
EVENT_DISPEL_MAGIC = 2,
|
||||
EVENT_RENEW = 3,
|
||||
EVENT_HOLY_NOVA = 4,
|
||||
EVENT_HOLY_FIRE = 5,
|
||||
EVENT_HOLY_WRATH = 6,
|
||||
// phase-changing
|
||||
EVENT_TRANSFORM = 7,
|
||||
// snake form events
|
||||
EVENT_POISON_CLOUD = 8,
|
||||
EVENT_VENOM_SPIT = 9,
|
||||
EVENT_PARASITIC_SERPENT = 10,
|
||||
EVENT_FRENZY = 11,
|
||||
};
|
||||
|
||||
enum Phases
|
||||
{
|
||||
PHASE_ONE = 1, // troll form
|
||||
PHASE_TWO = 2 // snake form
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_PARASITIC_SERPENT = 14884
|
||||
};
|
||||
|
||||
class boss_venoxis : public CreatureScript
|
||||
{
|
||||
public: boss_venoxis() : CreatureScript("boss_venoxis") { }
|
||||
|
||||
struct boss_venoxisAI : public BossAI
|
||||
{
|
||||
boss_venoxisAI(Creature* creature) : BossAI(creature, DATA_VENOXIS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
// remove all spells and auras from previous attempts
|
||||
me->RemoveAllAuras();
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
// set some internally used variables to their defaults
|
||||
_inMeleeRange = 0;
|
||||
_transformed = false;
|
||||
_frenzied = false;
|
||||
events.SetPhase(PHASE_ONE);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_VENOXIS_DEATH);
|
||||
me->RemoveAllAuras();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
// Always running events
|
||||
events.ScheduleEvent(EVENT_THRASH, 5000);
|
||||
// Phase one events (regular form)
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, 5000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, 35000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, 10000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_RENEW, 30000, 0, PHASE_ONE);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, 60000, 0, PHASE_ONE);
|
||||
|
||||
events.SetPhase(PHASE_ONE);
|
||||
|
||||
// Set zone in combat
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
// check if venoxis is ready to transform
|
||||
if (!_transformed && !HealthAbovePct(50))
|
||||
{
|
||||
_transformed = true;
|
||||
// schedule the event that changes our phase
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 100);
|
||||
}
|
||||
// we're losing health, bad, go frenzy
|
||||
else if (!_frenzied && !HealthAbovePct(20))
|
||||
{
|
||||
_frenzied = true;
|
||||
events.ScheduleEvent(EVENT_FRENZY, 100);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
// return back to main code if we're still casting
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
// thrash is available in all phases
|
||||
case EVENT_THRASH:
|
||||
DoCast(me, SPELL_THRASH, true);
|
||||
events.ScheduleEvent(EVENT_THRASH, urand(10000, 20000));
|
||||
break;
|
||||
|
||||
// troll form spells and Actions (first part)
|
||||
case EVENT_DISPEL_MAGIC:
|
||||
DoCast(me, SPELL_DISPEL_MAGIC);
|
||||
events.ScheduleEvent(EVENT_DISPEL_MAGIC, urand(15000, 20000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_RENEW:
|
||||
DoCast(me, SPELL_RENEW);
|
||||
events.ScheduleEvent(EVENT_RENEW, urand(25000, 30000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_NOVA:
|
||||
_inMeleeRange = 0;
|
||||
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_TOPAGGRO, i))
|
||||
// check if target is within melee-distance
|
||||
if (me->IsWithinMeleeRange(target))
|
||||
++_inMeleeRange;
|
||||
}
|
||||
|
||||
// trigger spellcast only if we have 3 or more targets to affect
|
||||
if (_inMeleeRange >= 3)
|
||||
DoCastVictim(SPELL_HOLY_NOVA);
|
||||
|
||||
events.ScheduleEvent(EVENT_HOLY_NOVA, urand(45000, 75000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_FIRE:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_HOLY_FIRE);
|
||||
events.ScheduleEvent(EVENT_HOLY_FIRE, urand(45000, 60000), 0, PHASE_ONE);
|
||||
break;
|
||||
case EVENT_HOLY_WRATH:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_HOLY_WRATH);
|
||||
events.ScheduleEvent(EVENT_HOLY_WRATH, urand(45000, 60000), 0, PHASE_ONE);
|
||||
break;
|
||||
|
||||
//
|
||||
// snake form spells and Actions
|
||||
//
|
||||
|
||||
case EVENT_VENOM_SPIT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_VENOM_SPIT);
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, urand(5000, 15000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_POISON_CLOUD:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_POISON_CLOUD);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, urand(15000, 20000), 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_PARASITIC_SERPENT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM))
|
||||
DoCast(target, SPELL_SUMMON_PARASITIC_SERPENT);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 15000, 0, PHASE_TWO);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
// frenzy at 20% health
|
||||
DoCast(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
|
||||
//
|
||||
// shape and phase-changing
|
||||
//
|
||||
|
||||
case EVENT_TRANSFORM:
|
||||
// shapeshift at 50% health
|
||||
DoCast(me, SPELL_VENOXIS_TRANSFORM);
|
||||
Talk(SAY_VENOXIS_TRANSFORM);
|
||||
DoResetThreat();
|
||||
|
||||
// phase two events (snakeform)
|
||||
events.ScheduleEvent(EVENT_VENOM_SPIT, 5000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_POISON_CLOUD, 10000, 0, PHASE_TWO);
|
||||
events.ScheduleEvent(EVENT_PARASITIC_SERPENT, 30000, 0, PHASE_TWO);
|
||||
|
||||
// transformed, start phase two
|
||||
events.SetPhase(PHASE_TWO);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
uint8 _inMeleeRange;
|
||||
bool _transformed;
|
||||
bool _frenzied;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_venoxisAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_venoxis()
|
||||
{
|
||||
new boss_venoxis();
|
||||
}
|
||||
@@ -1,108 +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_Wushoolay
|
||||
SD%Complete: 100
|
||||
SDComment:
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_LIGHTNINGCLOUD = 25033,
|
||||
SPELL_LIGHTNINGWAVE = 24819
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_LIGHTNINGCLOUD = 1,
|
||||
EVENT_LIGHTNINGWAVE = 2
|
||||
};
|
||||
|
||||
class boss_wushoolay : public CreatureScript
|
||||
{
|
||||
public: boss_wushoolay() : CreatureScript("boss_wushoolay") { }
|
||||
|
||||
struct boss_wushoolayAI : public BossAI
|
||||
{
|
||||
boss_wushoolayAI(Creature* creature) : BossAI(creature, DATA_EDGE_OF_MADNESS) { }
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(5000, 10000));
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(8000, 16000));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_LIGHTNINGCLOUD:
|
||||
DoCastVictim(SPELL_LIGHTNINGCLOUD, true);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGCLOUD, urand(15000, 20000));
|
||||
break;
|
||||
case EVENT_LIGHTNINGWAVE:
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_LIGHTNINGWAVE);
|
||||
events.ScheduleEvent(EVENT_LIGHTNINGWAVE, urand(12000, 16000));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_wushoolayAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_wushoolay()
|
||||
{
|
||||
new boss_wushoolay();
|
||||
}
|
||||
|
||||
@@ -1,211 +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: Instance_ZulGurub
|
||||
SD%Complete: 80
|
||||
SDComment: Missing reset function after killing a boss for Ohgan, Thekal.
|
||||
SDCategory: Zul'Gurub
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "zulgurub.h"
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_FORCEFIELD, DATA_ARLOKK, DOOR_TYPE_ROOM, BOUNDARY_NONE },
|
||||
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
|
||||
};
|
||||
|
||||
class instance_zulgurub : public InstanceMapScript
|
||||
{
|
||||
public: instance_zulgurub(): InstanceMapScript(ZGScriptName, 309) { }
|
||||
|
||||
struct instance_zulgurub_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_zulgurub_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadDoorData(doorData);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_zealotLorkhanGUID = 0;
|
||||
_zealotZathGUID = 0;
|
||||
_highPriestTekalGUID = 0;
|
||||
_jindoTheHexxerGUID = 0;
|
||||
_vilebranchSpeakerGUID = 0;
|
||||
_arlokkGUID = 0;
|
||||
_goGongOfBethekkGUID = 0;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
// not active in Zul'Gurub
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ZEALOT_LORKHAN:
|
||||
_zealotLorkhanGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ZEALOT_ZATH:
|
||||
_zealotZathGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_HIGH_PRIEST_THEKAL:
|
||||
_highPriestTekalGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_JINDO_THE_HEXXER:
|
||||
_jindoTheHexxerGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_VILEBRANCH_SPEAKER:
|
||||
_vilebranchSpeakerGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_ARLOKK:
|
||||
_arlokkGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FORCEFIELD:
|
||||
AddDoor(go, true);
|
||||
break;
|
||||
case GO_GONG_OF_BETHEKK:
|
||||
_goGongOfBethekkGUID = go->GetGUID();
|
||||
if (GetBossState(DATA_ARLOKK) == DONE)
|
||||
go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
else
|
||||
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_FORCEFIELD:
|
||||
AddDoor(go, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 uiData) const
|
||||
{
|
||||
switch (uiData)
|
||||
{
|
||||
case DATA_LORKHAN:
|
||||
return _zealotLorkhanGUID;
|
||||
break;
|
||||
case DATA_ZATH:
|
||||
return _zealotZathGUID;
|
||||
break;
|
||||
case DATA_THEKAL:
|
||||
return _highPriestTekalGUID;
|
||||
break;
|
||||
case DATA_JINDO:
|
||||
return _jindoTheHexxerGUID;
|
||||
break;
|
||||
case NPC_ARLOKK:
|
||||
return _arlokkGUID;
|
||||
break;
|
||||
case GO_GONG_OF_BETHEKK:
|
||||
return _goGongOfBethekkGUID;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "Z G " << GetBossSaveData();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* str)
|
||||
{
|
||||
if (!str)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(str);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(str);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
|
||||
if (dataHead1 == 'Z' && dataHead2 == 'G')
|
||||
{
|
||||
for (uint32 i = 0; i < EncounterCount; ++i)
|
||||
{
|
||||
uint32 tmpState;
|
||||
loadStream >> tmpState;
|
||||
if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
|
||||
tmpState = NOT_STARTED;
|
||||
SetBossState(i, EncounterState(tmpState));
|
||||
}
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
private:
|
||||
//If all High Priest bosses were killed. Lorkhan, Zath and Ohgan are added too.
|
||||
//Storing Lorkhan, Zath and Thekal because we need to cast on them later. Jindo is needed for healfunction too.
|
||||
|
||||
uint64 _zealotLorkhanGUID;
|
||||
uint64 _zealotZathGUID;
|
||||
uint64 _highPriestTekalGUID;
|
||||
uint64 _jindoTheHexxerGUID;
|
||||
uint64 _vilebranchSpeakerGUID;
|
||||
uint64 _arlokkGUID;
|
||||
uint64 _goGongOfBethekkGUID;
|
||||
};
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_zulgurub_InstanceMapScript(map);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_instance_zulgurub()
|
||||
{
|
||||
new instance_zulgurub();
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_ZULGURUB_H
|
||||
#define DEF_ZULGURUB_H
|
||||
|
||||
uint32 const EncounterCount = 13;
|
||||
|
||||
#define ZGScriptName "instance_zulgurub"
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_JEKLIK = 0, // Main boss
|
||||
DATA_VENOXIS = 1, // Main boss
|
||||
DATA_MARLI = 2, // Main boss
|
||||
DATA_ARLOKK = 3, // Main boss
|
||||
DATA_THEKAL = 4, // Main boss
|
||||
DATA_HAKKAR = 5, // End boss
|
||||
DATA_MANDOKIR = 6, // Optional boss
|
||||
DATA_JINDO = 7, // Optional boss
|
||||
DATA_GAHZRANKA = 8, // Optional boss
|
||||
DATA_EDGE_OF_MADNESS = 9, // Optional Event Edge of Madness - one of: Gri'lek, Renataki, Hazza'rah, or Wushoolay
|
||||
DATA_LORKHAN = 10, // Zealot Lor'Khan add to High priest Thekal!
|
||||
DATA_ZATH = 11, // Zealot Zath add to High priest Thekal!
|
||||
DATA_OHGAN = 12, // Bloodlord Mandokir's raptor mount
|
||||
TYPE_EDGE_OF_MADNESS = 13 // Boss storage
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_ARLOKK = 14515, // Arlokk Event
|
||||
NPC_PANTHER_TRIGGER = 15091, // Arlokk Event
|
||||
NPC_ZULIAN_PROWLER = 15101, // Arlokk Event
|
||||
NPC_ZEALOT_LORKHAN = 11347,
|
||||
NPC_ZEALOT_ZATH = 11348,
|
||||
NPC_HIGH_PRIEST_THEKAL = 14509,
|
||||
NPC_JINDO_THE_HEXXER = 11380,
|
||||
NPC_NIGHTMARE_ILLUSION = 15163,
|
||||
NPC_SHADE_OF_JINDO = 14986,
|
||||
NPC_SACRIFICED_TROLL = 14826,
|
||||
NPC_MANDOKIR = 11382, // Mandokir Event
|
||||
NPC_OHGAN = 14988, // Mandokir Event
|
||||
NPC_VILEBRANCH_SPEAKER = 11391, // Mandokir Event
|
||||
NPC_CHAINED_SPIRT = 15117 // Mandokir Event
|
||||
|
||||
};
|
||||
|
||||
enum GameobjectIds
|
||||
{
|
||||
GO_FORCEFIELD = 180497, // Arlokk Event
|
||||
GO_GONG_OF_BETHEKK = 180526 // Arlokk Event
|
||||
};
|
||||
|
||||
template<class AI>
|
||||
AI* GetZulGurubAI(Creature* creature)
|
||||
{
|
||||
return GetInstanceAI<AI>(creature, ZGScriptName);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user