mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-22 13:16:23 +00:00
Big re-organization of repository [W.I.P]
This commit is contained in:
@@ -1,260 +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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_SWARM = 31306,
|
||||
SPELL_SLEEP = 31298,
|
||||
SPELL_VAMPIRIC_AURA = 38196,
|
||||
SPELL_INFERNO = 31299,
|
||||
SPELL_IMMOLATION = 31303,
|
||||
SPELL_INFERNO_EFFECT = 31302,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_SWARM = 2,
|
||||
SAY_SLEEP = 3,
|
||||
SAY_INFERNO = 4,
|
||||
SAY_ONAGGRO = 5,
|
||||
};
|
||||
|
||||
class boss_anetheron : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_anetheron() : CreatureScript("boss_anetheron") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_anetheronAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_anetheronAI : public hyjal_trashAI
|
||||
{
|
||||
boss_anetheronAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 SwarmTimer;
|
||||
uint32 SleepTimer;
|
||||
uint32 AuraTimer;
|
||||
uint32 InfernoTimer;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
SwarmTimer = 45000;
|
||||
SleepTimer = 60000;
|
||||
AuraTimer = 5000;
|
||||
InfernoTimer = 45000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_ANETHERONEVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 4896.08f, -1576.35f, 1333.65f);
|
||||
AddWaypoint(1, 4898.68f, -1615.02f, 1329.48f);
|
||||
AddWaypoint(2, 4907.12f, -1667.08f, 1321.00f);
|
||||
AddWaypoint(3, 4963.18f, -1699.35f, 1340.51f);
|
||||
AddWaypoint(4, 4989.16f, -1716.67f, 1335.74f);
|
||||
AddWaypoint(5, 5026.27f, -1736.89f, 1323.02f);
|
||||
AddWaypoint(6, 5037.77f, -1770.56f, 1324.36f);
|
||||
AddWaypoint(7, 5067.23f, -1789.95f, 1321.17f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (SwarmTimer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(target, SPELL_CARRION_SWARM);
|
||||
|
||||
SwarmTimer = urand(45000, 60000);
|
||||
Talk(SAY_SWARM);
|
||||
} else SwarmTimer -= diff;
|
||||
|
||||
if (SleepTimer <= diff)
|
||||
{
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
target->CastSpell(target, SPELL_SLEEP, true);
|
||||
}
|
||||
SleepTimer = 60000;
|
||||
Talk(SAY_SLEEP);
|
||||
} else SleepTimer -= diff;
|
||||
if (AuraTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_VAMPIRIC_AURA, true);
|
||||
AuraTimer = urand(10000, 20000);
|
||||
} else AuraTimer -= diff;
|
||||
if (InfernoTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_INFERNO);
|
||||
InfernoTimer = 45000;
|
||||
Talk(SAY_INFERNO);
|
||||
} else InfernoTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_towering_infernal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_towering_infernal() : CreatureScript("npc_towering_infernal") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_towering_infernalAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_towering_infernalAI : public ScriptedAI
|
||||
{
|
||||
npc_towering_infernalAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
AnetheronGUID = instance->GetData64(DATA_ANETHERON);
|
||||
}
|
||||
|
||||
uint32 ImmolationTimer;
|
||||
uint32 CheckTimer;
|
||||
uint64 AnetheronGUID;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
DoCast(me, SPELL_INFERNO_EFFECT);
|
||||
ImmolationTimer = 5000;
|
||||
CheckTimer = 5000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (me->IsWithinDist(who, 50) && !me->IsInCombat() && me->IsValidAttackTarget(who))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (AnetheronGUID)
|
||||
{
|
||||
Creature* boss = ObjectAccessor::GetCreature(*me, AnetheronGUID);
|
||||
if (!boss || (boss && boss->isDead()))
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->RemoveCorpse();
|
||||
return;
|
||||
}
|
||||
}
|
||||
CheckTimer = 5000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (ImmolationTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_IMMOLATION);
|
||||
ImmolationTimer = 5000;
|
||||
} else ImmolationTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_anetheron()
|
||||
{
|
||||
new boss_anetheron();
|
||||
new npc_towering_infernal();
|
||||
}
|
||||
@@ -1,644 +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_Archimonde
|
||||
SD%Complete: 85
|
||||
SDComment: Doomfires not completely offlike due to core limitations for random moving. Tyrande and second phase not fully implemented.
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "hyjal.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "hyjal_trash.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_AGGRO = 1,
|
||||
SAY_DOOMFIRE = 2,
|
||||
SAY_AIR_BURST = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_ENRAGE = 5,
|
||||
SAY_DEATH = 6,
|
||||
SAY_SOUL_CHARGE = 7,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_DENOUEMENT_WISP = 32124,
|
||||
SPELL_ANCIENT_SPARK = 39349,
|
||||
SPELL_PROTECTION_OF_ELUNE = 38528,
|
||||
|
||||
SPELL_DRAIN_WORLD_TREE = 39140,
|
||||
SPELL_DRAIN_WORLD_TREE_2 = 39141,
|
||||
|
||||
SPELL_FINGER_OF_DEATH = 31984,
|
||||
SPELL_HAND_OF_DEATH = 35354,
|
||||
SPELL_AIR_BURST = 32014,
|
||||
SPELL_GRIP_OF_THE_LEGION = 31972,
|
||||
SPELL_DOOMFIRE_STRIKE = 31903, //summons two creatures
|
||||
SPELL_DOOMFIRE_SPAWN = 32074,
|
||||
SPELL_DOOMFIRE = 31945,
|
||||
SPELL_SOUL_CHARGE_YELLOW = 32045,
|
||||
SPELL_SOUL_CHARGE_GREEN = 32051,
|
||||
SPELL_SOUL_CHARGE_RED = 32052,
|
||||
SPELL_UNLEASH_SOUL_YELLOW = 32054,
|
||||
SPELL_UNLEASH_SOUL_GREEN = 32057,
|
||||
SPELL_UNLEASH_SOUL_RED = 32053,
|
||||
SPELL_FEAR = 31970,
|
||||
};
|
||||
|
||||
enum Summons
|
||||
{
|
||||
CREATURE_DOOMFIRE = 18095,
|
||||
CREATURE_DOOMFIRE_SPIRIT = 18104,
|
||||
CREATURE_ANCIENT_WISP = 17946,
|
||||
CREATURE_CHANNEL_TARGET = 22418,
|
||||
};
|
||||
|
||||
Position const NordrassilLoc = {5503.713f, -3523.436f, 1608.781f, 0.0f};
|
||||
|
||||
class npc_ancient_wisp : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_ancient_wisp() : CreatureScript("npc_ancient_wisp") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_ancient_wispAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_ancient_wispAI : public ScriptedAI
|
||||
{
|
||||
npc_ancient_wispAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
ArchimondeGUID = 0;
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
uint64 ArchimondeGUID;
|
||||
uint32 CheckTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CheckTimer = 1000;
|
||||
|
||||
ArchimondeGUID = instance->GetData64(DATA_ARCHIMONDE);
|
||||
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (Unit* Archimonde = ObjectAccessor::GetUnit(*me, ArchimondeGUID))
|
||||
{
|
||||
if (Archimonde->HealthBelowPct(2) || !Archimonde->IsAlive())
|
||||
DoCast(me, SPELL_DENOUEMENT_WISP);
|
||||
else
|
||||
DoCast(Archimonde, SPELL_ANCIENT_SPARK);
|
||||
}
|
||||
CheckTimer = 1000;
|
||||
} else CheckTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* This script is merely a placeholder for the Doomfire that triggers Doomfire spell. It will
|
||||
MoveChase the Doomfire Spirit always, until despawn (AttackStart is called upon it's spawn) */
|
||||
class npc_doomfire : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_doomfire() : CreatureScript("npc_doomfire") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_doomfireAI(creature);
|
||||
}
|
||||
|
||||
struct npc_doomfireAI : public ScriptedAI
|
||||
{
|
||||
npc_doomfireAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) { }
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* This is the script for the Doomfire Spirit Mob. This mob simply follow players or
|
||||
travels in random directions if target cannot be found. */
|
||||
class npc_doomfire_targetting : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_doomfire_targetting() : CreatureScript("npc_doomfire_targetting") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_doomfire_targettingAI(creature);
|
||||
}
|
||||
|
||||
struct npc_doomfire_targettingAI : public ScriptedAI
|
||||
{
|
||||
npc_doomfire_targettingAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
uint64 TargetGUID;
|
||||
uint32 ChangeTargetTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TargetGUID = 0;
|
||||
ChangeTargetTimer = 5000;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
//will update once TargetGUID is 0. In case noone actually moves(not likely) and this is 0
|
||||
//when UpdateAI needs it, it will be forced to select randomPoint
|
||||
if (!TargetGUID && who->GetTypeId() == TYPEID_PLAYER)
|
||||
TargetGUID = who->GetGUID();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/) { }
|
||||
|
||||
void DamageTaken(Unit*, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (ChangeTargetTimer <= diff)
|
||||
{
|
||||
if (Unit* temp = ObjectAccessor::GetUnit(*me, TargetGUID))
|
||||
{
|
||||
me->GetMotionMaster()->MoveFollow(temp, 0.0f, 0.0f);
|
||||
TargetGUID = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Position pos;
|
||||
me->GetRandomNearPosition(pos, 40);
|
||||
me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
}
|
||||
|
||||
ChangeTargetTimer = 5000;
|
||||
} else ChangeTargetTimer -= diff;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/* Finally, Archimonde's script. His script isn't extremely complex, most are simply spells on timers.
|
||||
The only complicated aspect of the battle is Finger of Death and Doomfire, with Doomfire being the
|
||||
hardest bit to code. Finger of Death is simply a distance check - if no one is in melee range, then
|
||||
select a random target and cast the spell on them. However, if someone IS in melee range, and this
|
||||
is NOT the main tank (creature's victim), then we aggro that player and they become the new victim.
|
||||
For Doomfire, we summon a mob (Doomfire Spirit) for the Doomfire mob to follow. It's spirit will
|
||||
randomly select it's target to follow and then we create the random movement making it unpredictable. */
|
||||
|
||||
class boss_archimonde : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_archimonde() : CreatureScript("boss_archimonde") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_archimondeAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_archimondeAI : public hyjal_trashAI
|
||||
{
|
||||
boss_archimondeAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint64 DoomfireSpiritGUID;
|
||||
uint64 WorldTreeGUID;
|
||||
|
||||
uint32 DrainNordrassilTimer;
|
||||
uint32 FearTimer;
|
||||
uint32 AirBurstTimer;
|
||||
uint32 GripOfTheLegionTimer;
|
||||
uint32 DoomfireTimer;
|
||||
uint32 SoulChargeTimer;
|
||||
uint8 SoulChargeCount;
|
||||
uint32 MeleeRangeCheckTimer;
|
||||
uint32 HandOfDeathTimer;
|
||||
uint32 SummonWispTimer;
|
||||
uint8 WispCount;
|
||||
uint32 EnrageTimer;
|
||||
uint32 CheckDistanceTimer;
|
||||
|
||||
bool Enraged;
|
||||
bool BelowTenPercent;
|
||||
bool HasProtected;
|
||||
bool IsChanneling;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, NOT_STARTED);
|
||||
|
||||
DoomfireSpiritGUID = 0;
|
||||
damageTaken = 0;
|
||||
WorldTreeGUID = 0;
|
||||
|
||||
DrainNordrassilTimer = 0;
|
||||
FearTimer = 42000;
|
||||
AirBurstTimer = 30000;
|
||||
GripOfTheLegionTimer = urand(5000, 25000);
|
||||
DoomfireTimer = 20000;
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
SoulChargeCount = 0;
|
||||
MeleeRangeCheckTimer = 15000;
|
||||
HandOfDeathTimer = 2000;
|
||||
WispCount = 0; // When ~30 wisps are summoned, Archimonde dies
|
||||
EnrageTimer = 600000; // 10 minutes
|
||||
CheckDistanceTimer = 30000; // This checks if he's too close to the World Tree (75 yards from a point on the tree), if true then he will enrage
|
||||
SummonWispTimer = 0;
|
||||
|
||||
Enraged = false;
|
||||
BelowTenPercent = false;
|
||||
HasProtected = false;
|
||||
IsChanneling = false;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
Talk(SAY_AGGRO);
|
||||
DoZoneInCombat();
|
||||
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
|
||||
if (victim && victim->GetTypeId() == TYPEID_PLAYER)
|
||||
GainSoulCharge(victim->ToPlayer());
|
||||
}
|
||||
|
||||
void GainSoulCharge(Player* victim)
|
||||
{
|
||||
switch (victim->getClass())
|
||||
{
|
||||
case CLASS_PRIEST:
|
||||
case CLASS_PALADIN:
|
||||
case CLASS_WARLOCK:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_RED, true);
|
||||
break;
|
||||
case CLASS_MAGE:
|
||||
case CLASS_ROGUE:
|
||||
case CLASS_WARRIOR:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_YELLOW, true);
|
||||
break;
|
||||
case CLASS_DRUID:
|
||||
case CLASS_SHAMAN:
|
||||
case CLASS_HUNTER:
|
||||
victim->CastSpell(me, SPELL_SOUL_CHARGE_GREEN, true);
|
||||
break;
|
||||
}
|
||||
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
++SoulChargeCount;
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(DATA_ARCHIMONDEEVENT, DONE);
|
||||
instance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, me->GetEntry(), 1, me); }
|
||||
|
||||
bool CanUseFingerOfDeath()
|
||||
{
|
||||
// First we check if our current victim is in melee range or not.
|
||||
Unit* victim = me->GetVictim();
|
||||
if (victim && me->IsWithinDistInMap(victim, me->GetAggroRange(victim)))
|
||||
return false;
|
||||
|
||||
ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList();
|
||||
if (threatlist.empty())
|
||||
return false;
|
||||
|
||||
std::list<Unit*> targets;
|
||||
ThreatContainer::StorageType::const_iterator itr = threatlist.begin();
|
||||
for (; itr != threatlist.end(); ++itr)
|
||||
{
|
||||
Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid());
|
||||
if (unit && unit->IsAlive())
|
||||
targets.push_back(unit);
|
||||
}
|
||||
|
||||
if (targets.empty())
|
||||
return false;
|
||||
|
||||
targets.sort(Trinity::ObjectDistanceOrderPred(me));
|
||||
Unit* target = targets.front();
|
||||
if (target)
|
||||
{
|
||||
if (!me->IsWithinDistInMap(target, me->GetAggroRange(target)))
|
||||
return true; // Cast Finger of Death
|
||||
else // This target is closest, he is our new tank
|
||||
me->AddThreat(target, me->getThreatManager().getThreat(me->GetVictim()));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned)
|
||||
{
|
||||
if (summoned->GetEntry() == CREATURE_ANCIENT_WISP)
|
||||
summoned->AI()->AttackStart(me);
|
||||
else
|
||||
{
|
||||
summoned->setFaction(me->getFaction());
|
||||
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
summoned->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
if (summoned->GetEntry() == CREATURE_DOOMFIRE_SPIRIT)
|
||||
{
|
||||
DoomfireSpiritGUID = summoned->GetGUID();
|
||||
}
|
||||
|
||||
if (summoned->GetEntry() == CREATURE_DOOMFIRE)
|
||||
{
|
||||
summoned->CastSpell(summoned, SPELL_DOOMFIRE_SPAWN, false);
|
||||
summoned->CastSpell(summoned, SPELL_DOOMFIRE, true, 0, 0, me->GetGUID());
|
||||
|
||||
if (Unit* DoomfireSpirit = ObjectAccessor::GetUnit(*me, DoomfireSpiritGUID))
|
||||
{
|
||||
summoned->GetMotionMaster()->MoveFollow(DoomfireSpirit, 0.0f, 0.0f);
|
||||
DoomfireSpiritGUID = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//this is code doing close to what the summoning spell would do (spell 31903)
|
||||
void SummonDoomfire(Unit* target)
|
||||
{
|
||||
me->SummonCreature(CREATURE_DOOMFIRE_SPIRIT,
|
||||
target->GetPositionX()+15.0f, target->GetPositionY()+15.0f, target->GetPositionZ(), 0,
|
||||
TEMPSUMMON_TIMED_DESPAWN, 27000);
|
||||
|
||||
me->SummonCreature(CREATURE_DOOMFIRE,
|
||||
target->GetPositionX()-15.0f, target->GetPositionY()-15.0f, target->GetPositionZ(), 0,
|
||||
TEMPSUMMON_TIMED_DESPAWN, 27000);
|
||||
}
|
||||
|
||||
void UnleashSoulCharge()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
bool HasCast = false;
|
||||
uint32 chargeSpell = 0;
|
||||
uint32 unleashSpell = 0;
|
||||
|
||||
switch (urand(0, 2))
|
||||
{
|
||||
case 0:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_RED;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_RED;
|
||||
break;
|
||||
case 1:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_YELLOW;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_YELLOW;
|
||||
break;
|
||||
case 2:
|
||||
chargeSpell = SPELL_SOUL_CHARGE_GREEN;
|
||||
unleashSpell = SPELL_UNLEASH_SOUL_GREEN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (me->HasAura(chargeSpell))
|
||||
{
|
||||
me->RemoveAuraFromStack(chargeSpell);
|
||||
DoCastVictim(unleashSpell);
|
||||
HasCast = true;
|
||||
SoulChargeCount--;
|
||||
}
|
||||
|
||||
if (HasCast)
|
||||
SoulChargeTimer = urand(2000, 30000);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
{
|
||||
// Do not let the raid skip straight to Archimonde. Visible and hostile ONLY if Azagalor is finished.
|
||||
if ((instance->GetData(DATA_AZGALOREVENT) < DONE) && (me->IsVisible() || (me->getFaction() != 35)))
|
||||
{
|
||||
me->SetVisible(false);
|
||||
me->setFaction(35);
|
||||
}
|
||||
else if ((instance->GetData(DATA_AZGALOREVENT) >= DONE) && (!me->IsVisible() || (me->getFaction() == 35)))
|
||||
{
|
||||
me->setFaction(1720);
|
||||
me->SetVisible(true);
|
||||
}
|
||||
|
||||
if (DrainNordrassilTimer <= diff)
|
||||
{
|
||||
if (!IsChanneling)
|
||||
{
|
||||
Creature* temp = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 1200000);
|
||||
|
||||
if (temp)
|
||||
WorldTreeGUID = temp->GetGUID();
|
||||
|
||||
if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
|
||||
{
|
||||
Nordrassil->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
Nordrassil->SetDisplayId(11686);
|
||||
DoCast(Nordrassil, SPELL_DRAIN_WORLD_TREE);
|
||||
IsChanneling = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Unit* Nordrassil = ObjectAccessor::GetUnit(*me, WorldTreeGUID))
|
||||
{
|
||||
Nordrassil->CastSpell(me, SPELL_DRAIN_WORLD_TREE_2, true);
|
||||
DrainNordrassilTimer = 1000;
|
||||
}
|
||||
} else DrainNordrassilTimer -= diff;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HealthBelowPct(10) && !BelowTenPercent && !Enraged)
|
||||
BelowTenPercent = true;
|
||||
|
||||
if (!Enraged)
|
||||
{
|
||||
if (EnrageTimer <= diff)
|
||||
{
|
||||
if (HealthAbovePct(10))
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
Enraged = true;
|
||||
Talk(SAY_ENRAGE);
|
||||
}
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
if (CheckDistanceTimer <= diff)
|
||||
{
|
||||
// To simplify the check, we simply summon a Creature in the location and then check how far we are from the creature
|
||||
Creature* Check = me->SummonCreature(CREATURE_CHANNEL_TARGET, NordrassilLoc, TEMPSUMMON_TIMED_DESPAWN, 2000);
|
||||
if (Check)
|
||||
{
|
||||
Check->SetVisible(false);
|
||||
|
||||
if (me->IsWithinDistInMap(Check, 75))
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
Enraged = true;
|
||||
Talk(SAY_ENRAGE);
|
||||
}
|
||||
}
|
||||
CheckDistanceTimer = 5000;
|
||||
} else CheckDistanceTimer -= diff;
|
||||
}
|
||||
|
||||
if (BelowTenPercent)
|
||||
{
|
||||
if (!HasProtected)
|
||||
{
|
||||
me->GetMotionMaster()->Clear(false);
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
|
||||
//all members of raid must get this buff
|
||||
DoCastVictim(SPELL_PROTECTION_OF_ELUNE, true);
|
||||
HasProtected = true;
|
||||
Enraged = true;
|
||||
}
|
||||
|
||||
if (SummonWispTimer <= diff)
|
||||
{
|
||||
DoSpawnCreature(CREATURE_ANCIENT_WISP, float(rand()%40), float(rand()%40), 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
|
||||
SummonWispTimer = 1500;
|
||||
++WispCount;
|
||||
} else SummonWispTimer -= diff;
|
||||
|
||||
if (WispCount >= 30)
|
||||
Unit::DealDamage(me, me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
}
|
||||
|
||||
if (Enraged)
|
||||
{
|
||||
if (HandOfDeathTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_HAND_OF_DEATH);
|
||||
HandOfDeathTimer = 2000;
|
||||
} else HandOfDeathTimer -= diff;
|
||||
return; // Don't do anything after this point.
|
||||
}
|
||||
|
||||
if (SoulChargeCount)
|
||||
{
|
||||
if (SoulChargeTimer <= diff)
|
||||
UnleashSoulCharge();
|
||||
else SoulChargeTimer -= diff;
|
||||
}
|
||||
|
||||
if (GripOfTheLegionTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_GRIP_OF_THE_LEGION);
|
||||
GripOfTheLegionTimer = urand(5000, 25000);
|
||||
} else GripOfTheLegionTimer -= diff;
|
||||
|
||||
if (AirBurstTimer <= diff)
|
||||
{
|
||||
Talk(SAY_AIR_BURST);
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1), SPELL_AIR_BURST);//not on tank
|
||||
AirBurstTimer = urand(25000, 40000);
|
||||
} else AirBurstTimer -= diff;
|
||||
|
||||
if (FearTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FEAR);
|
||||
FearTimer = 42000;
|
||||
} else FearTimer -= diff;
|
||||
|
||||
if (DoomfireTimer <= diff)
|
||||
{
|
||||
Talk(SAY_DOOMFIRE);
|
||||
Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 1);
|
||||
if (!temp)
|
||||
temp = me->GetVictim();
|
||||
|
||||
//replace with spell cast 31903 once implicitTarget 73 implemented
|
||||
SummonDoomfire(temp);
|
||||
|
||||
//supposedly three doomfire can be up at the same time
|
||||
DoomfireTimer = 20000;
|
||||
} else DoomfireTimer -= diff;
|
||||
|
||||
if (MeleeRangeCheckTimer <= diff)
|
||||
{
|
||||
if (CanUseFingerOfDeath())
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0), SPELL_FINGER_OF_DEATH);
|
||||
MeleeRangeCheckTimer = 1000;
|
||||
}
|
||||
|
||||
MeleeRangeCheckTimer = 5000;
|
||||
} else MeleeRangeCheckTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
void WaypointReached(uint32 /*waypointId*/) { }
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_boss_archimonde()
|
||||
{
|
||||
new boss_archimonde();
|
||||
new npc_doomfire();
|
||||
new npc_doomfire_targetting();
|
||||
new npc_ancient_wisp();
|
||||
}
|
||||
@@ -1,278 +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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_RAIN_OF_FIRE = 31340,
|
||||
SPELL_DOOM = 31347,
|
||||
SPELL_HOWL_OF_AZGALOR = 31344,
|
||||
SPELL_CLEAVE = 31345,
|
||||
SPELL_BERSERK = 26662,
|
||||
|
||||
SPELL_THRASH = 12787,
|
||||
SPELL_CRIPPLE = 31406,
|
||||
SPELL_WARSTOMP = 31408,
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_DOOM = 2, // Not used?
|
||||
SAY_ONAGGRO = 3,
|
||||
};
|
||||
|
||||
class boss_azgalor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_azgalor() : CreatureScript("boss_azgalor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_azgalorAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_azgalorAI : public hyjal_trashAI
|
||||
{
|
||||
boss_azgalorAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 RainTimer;
|
||||
uint32 DoomTimer;
|
||||
uint32 HowlTimer;
|
||||
uint32 CleaveTimer;
|
||||
uint32 EnrageTimer;
|
||||
bool enraged;
|
||||
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
RainTimer = 20000;
|
||||
DoomTimer = 50000;
|
||||
HowlTimer = 30000;
|
||||
CleaveTimer = 10000;
|
||||
EnrageTimer = 600000;
|
||||
enraged = false;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THRALL));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_AZGALOREVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 5492.91f, -2404.61f, 1462.63f);
|
||||
AddWaypoint(1, 5531.76f, -2460.87f, 1469.55f);
|
||||
AddWaypoint(2, 5554.58f, -2514.66f, 1476.12f);
|
||||
AddWaypoint(3, 5554.16f, -2567.23f, 1479.90f);
|
||||
AddWaypoint(4, 5540.67f, -2625.99f, 1480.89f);
|
||||
AddWaypoint(5, 5508.16f, -2659.2f, 1480.15f);
|
||||
AddWaypoint(6, 5489.62f, -2704.05f, 1482.18f);
|
||||
AddWaypoint(7, 5457.04f, -2726.26f, 1485.10f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (RainTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 30, true), SPELL_RAIN_OF_FIRE);
|
||||
RainTimer = 20000+rand()%15000;
|
||||
} else RainTimer -= diff;
|
||||
|
||||
if (DoomTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true), SPELL_DOOM);//never on tank
|
||||
DoomTimer = 45000+rand()%5000;
|
||||
} else DoomTimer -= diff;
|
||||
|
||||
if (HowlTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOWL_OF_AZGALOR);
|
||||
HowlTimer = 30000;
|
||||
} else HowlTimer -= diff;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_CLEAVE);
|
||||
CleaveTimer = 10000+rand()%5000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
if (EnrageTimer < diff && !enraged)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCast(me, SPELL_BERSERK, true);
|
||||
enraged = true;
|
||||
EnrageTimer = 600000;
|
||||
} else EnrageTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class npc_lesser_doomguard : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_lesser_doomguard() : CreatureScript("npc_lesser_doomguard") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_lesser_doomguardAI>(creature);
|
||||
}
|
||||
|
||||
struct npc_lesser_doomguardAI : public hyjal_trashAI
|
||||
{
|
||||
npc_lesser_doomguardAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
AzgalorGUID = instance->GetData64(DATA_AZGALOR);
|
||||
}
|
||||
|
||||
uint32 CrippleTimer;
|
||||
uint32 WarstompTimer;
|
||||
uint32 CheckTimer;
|
||||
uint64 AzgalorGUID;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
CrippleTimer = 50000;
|
||||
WarstompTimer = 10000;
|
||||
DoCast(me, SPELL_THRASH);
|
||||
CheckTimer = 5000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 /*waypointId*/)
|
||||
{
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
|
||||
{
|
||||
if (me->IsWithinDist(who, 50) && !me->IsInCombat() && me->IsValidAttackTarget(who))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (CheckTimer <= diff)
|
||||
{
|
||||
if (AzgalorGUID)
|
||||
{
|
||||
Creature* boss = ObjectAccessor::GetCreature(*me, AzgalorGUID);
|
||||
if (!boss || (boss && boss->isDead()))
|
||||
{
|
||||
me->setDeathState(JUST_DIED);
|
||||
me->RemoveCorpse();
|
||||
return;
|
||||
}
|
||||
}
|
||||
CheckTimer = 5000;
|
||||
} else CheckTimer -= diff;
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (WarstompTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WARSTOMP);
|
||||
WarstompTimer = 10000+rand()%5000;
|
||||
} else WarstompTimer -= diff;
|
||||
|
||||
if (CrippleTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true), SPELL_CRIPPLE);
|
||||
CrippleTimer = 25000+rand()%5000;
|
||||
} else CrippleTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_azgalor()
|
||||
{
|
||||
new boss_azgalor();
|
||||
new npc_lesser_doomguard();
|
||||
}
|
||||
@@ -1,230 +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 "SpellAuraEffects.h"
|
||||
#include "SpellScript.h"
|
||||
#include "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CLEAVE = 31436,
|
||||
SPELL_WARSTOMP = 31480,
|
||||
SPELL_MARK = 31447,
|
||||
SPELL_MARK_DAMAGE = 31463
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONSLAY = 0,
|
||||
SAY_MARK = 1,
|
||||
SAY_ONAGGRO = 2,
|
||||
};
|
||||
|
||||
enum Sounds
|
||||
{
|
||||
SOUND_ONDEATH = 11018,
|
||||
};
|
||||
|
||||
class boss_kazrogal : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kazrogal() : CreatureScript("boss_kazrogal") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_kazrogalAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_kazrogalAI : public hyjal_trashAI
|
||||
{
|
||||
boss_kazrogalAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 CleaveTimer;
|
||||
uint32 WarStompTimer;
|
||||
uint32 MarkTimer;
|
||||
uint32 MarkTimerBase;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
CleaveTimer = 5000;
|
||||
WarStompTimer = 15000;
|
||||
MarkTimer = 45000;
|
||||
MarkTimerBase = 45000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, IN_PROGRESS);
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_THRALL));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_KAZROGALEVENT, DONE);
|
||||
DoPlaySoundToSet(me, SOUND_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 5492.91f, -2404.61f, 1462.63f);
|
||||
AddWaypoint(1, 5531.76f, -2460.87f, 1469.55f);
|
||||
AddWaypoint(2, 5554.58f, -2514.66f, 1476.12f);
|
||||
AddWaypoint(3, 5554.16f, -2567.23f, 1479.90f);
|
||||
AddWaypoint(4, 5540.67f, -2625.99f, 1480.89f);
|
||||
AddWaypoint(5, 5508.16f, -2659.2f, 1480.15f);
|
||||
AddWaypoint(6, 5489.62f, -2704.05f, 1482.18f);
|
||||
AddWaypoint(7, 5457.04f, -2726.26f, 1485.10f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (CleaveTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CLEAVE);
|
||||
CleaveTimer = 6000+rand()%15000;
|
||||
} else CleaveTimer -= diff;
|
||||
|
||||
if (WarStompTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_WARSTOMP);
|
||||
WarStompTimer = 60000;
|
||||
} else WarStompTimer -= diff;
|
||||
|
||||
if (MarkTimer <= diff)
|
||||
{
|
||||
DoCastAOE(SPELL_MARK);
|
||||
|
||||
MarkTimerBase -= 5000;
|
||||
if (MarkTimerBase < 5500)
|
||||
MarkTimerBase = 5500;
|
||||
MarkTimer = MarkTimerBase;
|
||||
Talk(SAY_MARK);
|
||||
} else MarkTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_mark_of_kazrogal : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_mark_of_kazrogal() : SpellScriptLoader("spell_mark_of_kazrogal") { }
|
||||
|
||||
class spell_mark_of_kazrogal_SpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_mark_of_kazrogal_SpellScript);
|
||||
|
||||
void FilterTargets(std::list<WorldObject*>& targets)
|
||||
{
|
||||
targets.remove_if(Trinity::PowerCheck(POWER_MANA, false));
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_mark_of_kazrogal_SpellScript::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ENEMY);
|
||||
}
|
||||
};
|
||||
|
||||
class spell_mark_of_kazrogal_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_mark_of_kazrogal_AuraScript);
|
||||
|
||||
bool Validate(SpellInfo const* /*spell*/)
|
||||
{
|
||||
if (!sSpellMgr->GetSpellInfo(SPELL_MARK_DAMAGE))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OnPeriodic(AuraEffect const* aurEff)
|
||||
{
|
||||
Unit* target = GetTarget();
|
||||
|
||||
if (target->GetPower(POWER_MANA) == 0)
|
||||
{
|
||||
target->CastSpell(target, SPELL_MARK_DAMAGE, true, NULL, aurEff);
|
||||
// Remove aura
|
||||
SetDuration(0);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_mark_of_kazrogal_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_MANA_LEECH);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_mark_of_kazrogal_SpellScript();
|
||||
}
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_mark_of_kazrogal_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_kazrogal()
|
||||
{
|
||||
new boss_kazrogal();
|
||||
new spell_mark_of_kazrogal();
|
||||
}
|
||||
@@ -1,164 +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 "hyjal.h"
|
||||
#include "hyjal_trash.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FROST_ARMOR = 31256,
|
||||
SPELL_DEATH_AND_DECAY = 31258,
|
||||
SPELL_FROST_NOVA = 31250,
|
||||
SPELL_ICEBOLT = 31249
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_ONDEATH = 0,
|
||||
SAY_ONSLAY = 1,
|
||||
SAY_DECAY = 2,
|
||||
SAY_NOVA = 3,
|
||||
SAY_ONAGGRO = 4
|
||||
};
|
||||
|
||||
class boss_rage_winterchill : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_rage_winterchill() : CreatureScript("boss_rage_winterchill") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_rage_winterchillAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_rage_winterchillAI : public hyjal_trashAI
|
||||
{
|
||||
boss_rage_winterchillAI(Creature* creature) : hyjal_trashAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
go = false;
|
||||
}
|
||||
|
||||
uint32 FrostArmorTimer;
|
||||
uint32 DecayTimer;
|
||||
uint32 NovaTimer;
|
||||
uint32 IceboltTimer;
|
||||
bool go;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
damageTaken = 0;
|
||||
FrostArmorTimer = 37000;
|
||||
DecayTimer = 45000;
|
||||
NovaTimer = 15000;
|
||||
IceboltTimer = 10000;
|
||||
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, IN_PROGRESS);
|
||||
Talk(SAY_ONAGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/)
|
||||
{
|
||||
Talk(SAY_ONSLAY);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7 && instance)
|
||||
{
|
||||
Unit* target = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_JAINAPROUDMOORE));
|
||||
if (target && target->IsAlive())
|
||||
me->AddThreat(target, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
hyjal_trashAI::JustDied(killer);
|
||||
if (IsEvent)
|
||||
instance->SetData(DATA_RAGEWINTERCHILLEVENT, DONE);
|
||||
Talk(SAY_ONDEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (IsEvent)
|
||||
{
|
||||
//Must update npc_escortAI
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
if (!go)
|
||||
{
|
||||
go = true;
|
||||
AddWaypoint(0, 4896.08f, -1576.35f, 1333.65f);
|
||||
AddWaypoint(1, 4898.68f, -1615.02f, 1329.48f);
|
||||
AddWaypoint(2, 4907.12f, -1667.08f, 1321.00f);
|
||||
AddWaypoint(3, 4963.18f, -1699.35f, 1340.51f);
|
||||
AddWaypoint(4, 4989.16f, -1716.67f, 1335.74f);
|
||||
AddWaypoint(5, 5026.27f, -1736.89f, 1323.02f);
|
||||
AddWaypoint(6, 5037.77f, -1770.56f, 1324.36f);
|
||||
AddWaypoint(7, 5067.23f, -1789.95f, 1321.17f);
|
||||
Start(false, true);
|
||||
SetDespawnAtEnd(false);
|
||||
}
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (FrostArmorTimer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_FROST_ARMOR);
|
||||
FrostArmorTimer = 40000+rand()%20000;
|
||||
} else FrostArmorTimer -= diff;
|
||||
if (DecayTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_DEATH_AND_DECAY);
|
||||
DecayTimer = 60000+rand()%20000;
|
||||
Talk(SAY_DECAY);
|
||||
} else DecayTimer -= diff;
|
||||
if (NovaTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FROST_NOVA);
|
||||
NovaTimer = 30000+rand()%15000;
|
||||
Talk(SAY_NOVA);
|
||||
} else NovaTimer -= diff;
|
||||
if (IceboltTimer <= diff)
|
||||
{
|
||||
DoCast(SelectTarget(SELECT_TARGET_RANDOM, 0, 40, true), SPELL_ICEBOLT);
|
||||
IceboltTimer = 11000+rand()%20000;
|
||||
} else IceboltTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_rage_winterchill()
|
||||
{
|
||||
new boss_rage_winterchill();
|
||||
}
|
||||
@@ -1,262 +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: Hyjal
|
||||
SD%Complete: 80
|
||||
SDComment: gossip text id's unknown
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
/* ContentData
|
||||
npc_jaina_proudmoore
|
||||
npc_thrall
|
||||
npc_tyrande_whisperwind
|
||||
EndContentData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "hyjalAI.h"
|
||||
#include "Player.h"
|
||||
|
||||
#define GOSSIP_ITEM_BEGIN_ALLY "My companions and I are with you, Lady Proudmoore."
|
||||
#define GOSSIP_ITEM_ANETHERON "We are ready for whatever Archimonde might send our way, Lady Proudmoore."
|
||||
|
||||
#define GOSSIP_ITEM_BEGIN_HORDE "I am with you, Thrall."
|
||||
#define GOSSIP_ITEM_AZGALOR "We have nothing to fear."
|
||||
|
||||
#define GOSSIP_ITEM_RETREAT "We can't keep this up. Let's retreat!"
|
||||
|
||||
#define GOSSIP_ITEM_TYRANDE "Aid us in defending Nordrassil"
|
||||
#define ITEM_TEAR_OF_GODDESS 24494
|
||||
|
||||
#define GOSSIP_ITEM_GM1 "[GM] Toggle Debug Timers"
|
||||
|
||||
class npc_jaina_proudmoore : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_jaina_proudmoore() : CreatureScript("npc_jaina_proudmoore") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
ai->FirstBossDead = true;
|
||||
ai->WaveCount = 9;
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
ai->Retreat();
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
ai->Debug = !ai->Debug;
|
||||
//TC_LOG_DEBUG("scripts", "HyjalAI - Debug mode has been toggled");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
if (ai->EventBegun)
|
||||
return false;
|
||||
|
||||
uint32 RageEncounter = ai->GetInstanceData(DATA_RAGEWINTERCHILLEVENT);
|
||||
uint32 AnetheronEncounter = ai->GetInstanceData(DATA_ANETHERONEVENT);
|
||||
if (RageEncounter == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_ALLY, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
else if (RageEncounter == DONE && AnetheronEncounter == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_ANETHERON, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
else if (RageEncounter == DONE && AnetheronEncounter == DONE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
|
||||
if (player->IsGameMaster())
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
|
||||
ai->Spells[0].SpellId = SPELL_BLIZZARD;
|
||||
ai->Spells[0].Cooldown = urand(15000, 35000);
|
||||
ai->Spells[0].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
ai->Spells[1].SpellId = SPELL_PYROBLAST;
|
||||
ai->Spells[1].Cooldown = urand(5500, 9500);
|
||||
ai->Spells[1].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
ai->Spells[2].SpellId = SPELL_SUMMON_ELEMENTALS;
|
||||
ai->Spells[2].Cooldown = urand(15000, 45000);
|
||||
ai->Spells[2].TargetType = TARGETTYPE_SELF;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class npc_thrall : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall() : CreatureScript("npc_thrall") { }
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
ai->DeSpawnVeins();//despawn the alliance veins
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
ai->FirstBossDead = true;
|
||||
ai->WaveCount = 9;
|
||||
ai->StartEvent(player);
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
ai->Retreat();
|
||||
break;
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
ai->Debug = !ai->Debug;
|
||||
//TC_LOG_DEBUG("scripts", "HyjalAI - Debug mode has been toggled");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
if (ai->EventBegun)
|
||||
return false;
|
||||
|
||||
uint32 AnetheronEvent = ai->GetInstanceData(DATA_ANETHERONEVENT);
|
||||
// Only let them start the Horde phases if Anetheron is dead.
|
||||
if (AnetheronEvent == DONE && ai->GetInstanceData(DATA_ALLIANCE_RETREAT))
|
||||
{
|
||||
uint32 KazrogalEvent = ai->GetInstanceData(DATA_KAZROGALEVENT);
|
||||
uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT);
|
||||
if (KazrogalEvent == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_BEGIN_HORDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
else if (KazrogalEvent == DONE && AzgalorEvent == NOT_STARTED)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_AZGALOR, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
else if (AzgalorEvent == DONE)
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_RETREAT, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
}
|
||||
|
||||
if (player->IsGameMaster())
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, GOSSIP_ITEM_GM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
|
||||
ai->Spells[0].SpellId = SPELL_CHAIN_LIGHTNING;
|
||||
ai->Spells[0].Cooldown = urand(3000, 8000);
|
||||
ai->Spells[0].TargetType = TARGETTYPE_VICTIM;
|
||||
|
||||
ai->Spells[1].SpellId = SPELL_SUMMON_DIRE_WOLF;
|
||||
ai->Spells[1].Cooldown = urand(6000, 41000);
|
||||
ai->Spells[1].TargetType = TARGETTYPE_RANDOM;
|
||||
|
||||
return ai;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class npc_tyrande_whisperwind : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_tyrande_whisperwind() : CreatureScript("npc_tyrande_whisperwind") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
if (!creature->GetInstanceScript())
|
||||
return NULL;
|
||||
|
||||
hyjalAI* ai = new hyjalAI(creature);
|
||||
ai->Reset();
|
||||
ai->EnterEvadeMode();
|
||||
return ai;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
|
||||
{
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
if (action == GOSSIP_ACTION_INFO_DEF)
|
||||
{
|
||||
ItemPosCountVec dest;
|
||||
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_TEAR_OF_GODDESS, 1);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
if (Item* item = player->StoreNewItem(dest, ITEM_TEAR_OF_GODDESS, true))
|
||||
player->SendNewItem(item, 1, true, false, true);
|
||||
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
hyjalAI* ai = CAST_AI(hyjalAI, creature->AI());
|
||||
uint32 AzgalorEvent = ai->GetInstanceData(DATA_AZGALOREVENT);
|
||||
|
||||
// Only let them get item if Azgalor is dead.
|
||||
if (AzgalorEvent == DONE && !player->HasItemCount(ITEM_TEAR_OF_GODDESS))
|
||||
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_TYRANDE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
player->SEND_GOSSIP_MENU(907, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void AddSC_hyjal()
|
||||
{
|
||||
new npc_jaina_proudmoore();
|
||||
new npc_thrall();
|
||||
new npc_tyrande_whisperwind();
|
||||
}
|
||||
@@ -1,93 +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/>.
|
||||
*/
|
||||
|
||||
#ifndef DEF_HYJAL_H
|
||||
#define DEF_HYJAL_H
|
||||
|
||||
#define ERROR_INST_DATA "TSCR: Instance data not set properly for Mount Hyjal. Encounters will be buggy."
|
||||
|
||||
uint32 const EncounterCount = 5;
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
DATA_ANETHERON = 1,
|
||||
DATA_ANETHERONEVENT = 2,
|
||||
DATA_ARCHIMONDE = 3,
|
||||
DATA_ARCHIMONDEEVENT = 4,
|
||||
DATA_AZGALOR = 5,
|
||||
DATA_AZGALOREVENT = 6,
|
||||
DATA_JAINAPROUDMOORE = 7,
|
||||
DATA_KAZROGAL = 8,
|
||||
DATA_KAZROGALEVENT = 9,
|
||||
DATA_RAGEWINTERCHILL = 10,
|
||||
DATA_RAGEWINTERCHILLEVENT = 11,
|
||||
DATA_THRALL = 12,
|
||||
DATA_TYRANDEWHISPERWIND = 13,
|
||||
DATA_TRASH = 14,
|
||||
DATA_RESET_TRASH_COUNT = 15,
|
||||
DATA_ALLIANCE_RETREAT = 16,
|
||||
DATA_HORDE_RETREAT = 17,
|
||||
DATA_RAIDDAMAGE = 18,
|
||||
DATA_RESET_RAIDDAMAGE = 19,
|
||||
TYPE_RETREAT = 20
|
||||
};
|
||||
|
||||
enum WorldStateIds
|
||||
{
|
||||
WORLD_STATE_WAVES = 2842,
|
||||
WORLD_STATE_ENEMY = 2453,
|
||||
WORLD_STATE_ENEMYCOUNT = 2454
|
||||
};
|
||||
|
||||
enum CreaturesIds
|
||||
{
|
||||
// Trash Mobs summoned in waves
|
||||
NECROMANCER = 17899,
|
||||
ABOMINATION = 17898,
|
||||
GHOUL = 17895,
|
||||
BANSHEE = 17905,
|
||||
CRYPT_FIEND = 17897,
|
||||
GARGOYLE = 17906,
|
||||
FROST_WYRM = 17907,
|
||||
GIANT_INFERNAL = 17908,
|
||||
FEL_STALKER = 17916,
|
||||
|
||||
JAINA = 17772,
|
||||
THRALL = 17852,
|
||||
TYRANDE = 17948,
|
||||
|
||||
// Bosses summoned after every 8 waves
|
||||
RAGE_WINTERCHILL = 17767,
|
||||
ANETHERON = 17808,
|
||||
KAZROGAL = 17888,
|
||||
AZGALOR = 17842,
|
||||
ARCHIMONDE = 17968,
|
||||
NPC_WORLD_TRIGGER_TINY = 21987
|
||||
};
|
||||
|
||||
enum GameobjectIds
|
||||
{
|
||||
GO_HORDE_ENCAMPMENT_PORTAL = 182060,
|
||||
GO_NIGHT_ELF_VILLAGE_PORTAL = 182061,
|
||||
GO_ANCIENT_GEM = 185557,
|
||||
GO_ANCIENT_VEIN = 185557,
|
||||
GO_ROARING_FLAME = 182592
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,208 +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/>.
|
||||
*/
|
||||
|
||||
#ifndef SC_HYJALAI_H
|
||||
#define SC_HYJALAI_H
|
||||
|
||||
#include "hyjal.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
|
||||
#define HYJAL_AI_MAX_SPELLS 3
|
||||
|
||||
enum SpellIds
|
||||
{
|
||||
SPELL_TELEPORT_VISUAL = 41232,
|
||||
SPELL_MASS_TELEPORT = 16807,
|
||||
|
||||
//Spells for Jaina
|
||||
SPELL_BRILLIANCE_AURA = 31260, // The database must handle this spell via creature_addon(it should, but is removed in evade..)
|
||||
SPELL_BLIZZARD = 31266,
|
||||
SPELL_PYROBLAST = 31263,
|
||||
SPELL_SUMMON_ELEMENTALS = 31264,
|
||||
|
||||
//Thrall spells
|
||||
SPELL_CHAIN_LIGHTNING = 31330,
|
||||
SPELL_SUMMON_DIRE_WOLF = 31331
|
||||
};
|
||||
|
||||
struct Wave
|
||||
{
|
||||
uint32 Mob[18]; // Stores Creature Entries to be summoned in Waves
|
||||
uint32 WaveTimer; // The timer before the next wave is summoned
|
||||
bool IsBoss; // Simply used to inform the wave summoner that the next wave contains a boss to halt all waves after that
|
||||
};
|
||||
|
||||
const Wave AllianceWaves[]= // Waves that will be summoned in the Alliance Base
|
||||
{ // Rage Winterchill Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
// All 8 Waves are summoned, summon Rage Winterchill, next few waves are for Anetheron
|
||||
{{RAGE_WINTERCHILL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true},
|
||||
// Anetheron Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, 0, 0, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 120000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, BANSHEE, BANSHEE, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, GHOUL, GHOUL, 0, 0, 0, 0}, 120000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
// All 8 Waves are summoned, summon Anatheron
|
||||
{{ANETHERON, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true}
|
||||
};
|
||||
|
||||
const Wave HordeWaves[]= // Waves that are summoned in the Horde base
|
||||
{ // Kaz'Rogal Wave 1-8
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, FROST_WYRM, 0, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0}, 240000, false},
|
||||
// All 8 Waves are summoned, summon Kaz'Rogal, next few waves are for Azgalor
|
||||
{{KAZROGAL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true},
|
||||
// Azgalor Wave 1-8
|
||||
{{ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, FROST_WYRM, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, GARGOYLE, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GHOUL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0}, 180000, false},
|
||||
{{GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, 0, 0, 0, 0}, 180000, false},
|
||||
{{FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, 0, 0, 0, 0}, 180000, false},
|
||||
{{NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, NECROMANCER, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, BANSHEE, 0, 0, 0, 0, 0, 0}, 180000, false},
|
||||
{{GHOUL, GHOUL, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, GIANT_INFERNAL, 0, 0, 0, 0}, 180000, false},
|
||||
{{CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, CRYPT_FIEND, FEL_STALKER, FEL_STALKER, ABOMINATION, ABOMINATION, ABOMINATION, ABOMINATION, BANSHEE, BANSHEE, BANSHEE, BANSHEE, NECROMANCER, NECROMANCER, 0, 0}, 240000, false},
|
||||
// All 8 Waves are summoned, summon Azgalor
|
||||
{{AZGALOR, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 0, true}
|
||||
};
|
||||
|
||||
enum TargetType // Used in the spell cast system for the AI
|
||||
{
|
||||
TARGETTYPE_SELF = 0,
|
||||
TARGETTYPE_RANDOM = 1,
|
||||
TARGETTYPE_VICTIM = 2,
|
||||
};
|
||||
|
||||
enum YellId
|
||||
{
|
||||
ATTACKED = 0, // Used when attacked and set in combat
|
||||
BEGIN = 1, // Used when the event is begun
|
||||
INCOMING = 2, // Used to warn the raid that another wave phase is coming
|
||||
RALLY = 3, // Used to rally the raid and warn that the next wave has been summoned
|
||||
FAILURE = 4, // Used when raid has failed (unsure where to place)
|
||||
SUCCESS = 5, // Used when the raid has sucessfully defeated a wave phase
|
||||
DEATH = 6, // Used on death
|
||||
};
|
||||
|
||||
struct hyjalAI : public npc_escortAI
|
||||
{
|
||||
hyjalAI(Creature* creature);
|
||||
|
||||
void Reset(); // Generically used to reset our variables. Do *not* call in EnterEvadeMode as this may make problems if the raid is still in combat
|
||||
|
||||
void EnterEvadeMode(); // Send creature back to spawn location and evade.
|
||||
|
||||
void EnterCombat(Unit* /*who*/); // Used to reset cooldowns for our spells and to inform the raid that we're under attack
|
||||
|
||||
void UpdateAI(uint32 diff); // Called to summon waves, check for boss deaths and to cast our spells.
|
||||
|
||||
void JustDied(Unit* /*killer*/); // Called on death, informs the raid that they have failed.
|
||||
|
||||
void SetFaction(uint32 _faction) // Set the faction to either Alliance or Horde in Hyjal
|
||||
{
|
||||
Faction = _faction;
|
||||
}
|
||||
|
||||
void Retreat(); // "Teleport" (teleport visual + set invisible) all friendly creatures away from the base.
|
||||
|
||||
void SpawnVeins();
|
||||
void DeSpawnVeins();
|
||||
void JustSummoned(Creature* summoned);
|
||||
void SummonedCreatureDespawn(Creature* summoned);
|
||||
void HideNearPos(float x, float y);
|
||||
void RespawnNearPos(float x, float y);
|
||||
void WaypointReached(uint32 waypointId);
|
||||
void DoOverrun(uint32 faction, const uint32 diff);
|
||||
void MoveInLineOfSight(Unit* who);
|
||||
|
||||
void SummonCreature(uint32 entry, float Base[4][3]); // Summons a creature for that wave in that base
|
||||
|
||||
// Summons the next wave, calls SummonCreature
|
||||
void SummonNextWave(const Wave wave[18], uint32 Count, float Base[4][3]);
|
||||
|
||||
void StartEvent(Player* player); // Begins the event by gossip click
|
||||
|
||||
uint32 GetInstanceData(uint32 Event); // Gets instance data for this instance, used to check if raid has gotten past a certain point and can access the next phase
|
||||
|
||||
public:
|
||||
InstanceScript* instance;
|
||||
|
||||
uint64 PlayerGUID;
|
||||
uint64 BossGUID[2];
|
||||
uint64 VeinGUID[14];
|
||||
|
||||
uint32 NextWaveTimer;
|
||||
uint32 WaveCount;
|
||||
uint32 CheckTimer;
|
||||
uint32 Faction;
|
||||
uint32 EnemyCount;
|
||||
uint32 RetreatTimer;
|
||||
|
||||
bool EventBegun;
|
||||
bool FirstBossDead;
|
||||
bool SecondBossDead;
|
||||
bool Summon;
|
||||
bool bRetreat;
|
||||
bool Debug;
|
||||
bool VeinsSpawned[2];
|
||||
uint8 InfernalCount;
|
||||
SummonList Summons;
|
||||
bool Overrun;
|
||||
bool Teleported;
|
||||
bool WaitForTeleport;
|
||||
uint32 TeleportTimer;
|
||||
uint32 OverrunCounter;
|
||||
uint32 OverrunCounter2;
|
||||
uint32 InfernalPoint;
|
||||
uint32 RespawnTimer;
|
||||
bool DoRespawn;
|
||||
bool DoHide;
|
||||
bool IsDummy;
|
||||
uint32 MassTeleportTimer;
|
||||
bool DoMassTeleport;
|
||||
uint64 DummyGuid;
|
||||
|
||||
struct Spell
|
||||
{
|
||||
uint32 SpellId;
|
||||
uint32 Cooldown;
|
||||
uint32 TargetType;
|
||||
} Spells[HYJAL_AI_MAX_SPELLS];
|
||||
|
||||
private:
|
||||
uint32 SpellTimer[3];
|
||||
//std::list<uint64> CreatureList;
|
||||
};
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,51 +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 SC_HYJAL_TRASH_AI_H
|
||||
#define SC_HYJAL_TRASH_AI_H
|
||||
|
||||
#include "hyjal.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
|
||||
#define MINRAIDDAMAGE 700000//minimal damage before trash can drop loot and reputation, resets if faction leader dies
|
||||
|
||||
struct hyjal_trashAI : public npc_escortAI
|
||||
{
|
||||
hyjal_trashAI(Creature* creature);
|
||||
|
||||
void UpdateAI(uint32 diff);
|
||||
|
||||
void JustDied(Unit* /*killer*/);
|
||||
|
||||
void DamageTaken(Unit* done_by, uint32 &damage, DamageEffectType, SpellSchoolMask);
|
||||
|
||||
public:
|
||||
InstanceScript* instance;
|
||||
bool IsEvent;
|
||||
uint32 Delay;
|
||||
uint32 LastOverronPos;
|
||||
bool IsOverrun;
|
||||
bool SetupOverrun;
|
||||
uint32 OverrunType;
|
||||
uint8 faction;
|
||||
bool useFlyPath;
|
||||
uint32 damageTaken;
|
||||
float DummyTarget[3];
|
||||
|
||||
//private:
|
||||
};
|
||||
#endif
|
||||
@@ -1,333 +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_Mount_Hyjal
|
||||
SD%Complete: 100
|
||||
SDComment: Instance Data Scripts and functions to acquire mobs and set encounter status for use in various Hyjal Scripts
|
||||
SDCategory: Caverns of Time, Mount Hyjal
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "hyjal_trash.h"
|
||||
#include "Player.h"
|
||||
#include "WorldPacket.h"
|
||||
#include "Opcodes.h"
|
||||
#include "Chat.h"
|
||||
|
||||
/* Battle of Mount Hyjal encounters:
|
||||
0 - Rage Winterchill event
|
||||
1 - Anetheron event
|
||||
2 - Kaz'rogal event
|
||||
3 - Azgalor event
|
||||
4 - Archimonde event
|
||||
*/
|
||||
|
||||
#define YELL_EFFORTS "All of your efforts have been in vain, for the draining of the World Tree has already begun. Soon the heart of your world will beat no more."
|
||||
#define YELL_EFFORTS_NAME "Archimonde"
|
||||
|
||||
class instance_hyjal : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_hyjal() : InstanceMapScript("instance_hyjal", 534) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_mount_hyjal_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_mount_hyjal_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_mount_hyjal_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
m_uiAncientGemGUID.clear();
|
||||
|
||||
RageWinterchill = 0;
|
||||
Anetheron = 0;
|
||||
Kazrogal = 0;
|
||||
Azgalor = 0;
|
||||
Archimonde = 0;
|
||||
JainaProudmoore = 0;
|
||||
Thrall = 0;
|
||||
TyrandeWhisperwind = 0;
|
||||
HordeGate = 0;
|
||||
ElfGate = 0;
|
||||
RaidDamage = 0;
|
||||
Trash = 0;
|
||||
hordeRetreat = 0;
|
||||
allianceRetreat = 0;
|
||||
|
||||
ArchiYell = false;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < EncounterCount; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_HORDE_ENCAMPMENT_PORTAL:
|
||||
HordeGate = go->GetGUID();
|
||||
if (allianceRetreat)
|
||||
HandleGameObject(0, true, go);
|
||||
else
|
||||
HandleGameObject(0, false, go);
|
||||
break;
|
||||
case GO_NIGHT_ELF_VILLAGE_PORTAL:
|
||||
ElfGate = go->GetGUID();
|
||||
if (hordeRetreat)
|
||||
HandleGameObject(0, true, go);
|
||||
else
|
||||
HandleGameObject(0, false, go);
|
||||
break;
|
||||
case GO_ANCIENT_GEM:
|
||||
m_uiAncientGemGUID.push_back(go->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case RAGE_WINTERCHILL: RageWinterchill = creature->GetGUID(); break;
|
||||
case ANETHERON: Anetheron = creature->GetGUID(); break;
|
||||
case KAZROGAL: Kazrogal = creature->GetGUID(); break;
|
||||
case AZGALOR: Azgalor = creature->GetGUID(); break;
|
||||
case ARCHIMONDE: Archimonde = creature->GetGUID(); break;
|
||||
case JAINA: JainaProudmoore = creature->GetGUID(); break;
|
||||
case THRALL: Thrall = creature->GetGUID(); break;
|
||||
case TYRANDE: TyrandeWhisperwind = creature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILL: return RageWinterchill;
|
||||
case DATA_ANETHERON: return Anetheron;
|
||||
case DATA_KAZROGAL: return Kazrogal;
|
||||
case DATA_AZGALOR: return Azgalor;
|
||||
case DATA_ARCHIMONDE: return Archimonde;
|
||||
case DATA_JAINAPROUDMOORE: return JainaProudmoore;
|
||||
case DATA_THRALL: return Thrall;
|
||||
case DATA_TYRANDEWHISPERWIND: return TyrandeWhisperwind;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILLEVENT:
|
||||
m_auiEncounter[0] = data;
|
||||
break;
|
||||
case DATA_ANETHERONEVENT:
|
||||
m_auiEncounter[1] = data;
|
||||
break;
|
||||
case DATA_KAZROGALEVENT:
|
||||
m_auiEncounter[2] = data;
|
||||
break;
|
||||
case DATA_AZGALOREVENT:
|
||||
{
|
||||
m_auiEncounter[3] = data;
|
||||
if (data == DONE)
|
||||
{
|
||||
if (ArchiYell)
|
||||
break;
|
||||
|
||||
ArchiYell = true;
|
||||
|
||||
Creature* creature = instance->GetCreature(Azgalor);
|
||||
if (creature)
|
||||
{
|
||||
Creature* unit = creature->SummonCreature(NPC_WORLD_TRIGGER_TINY, creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN, 10000);
|
||||
|
||||
Map* map = creature->GetMap();
|
||||
if (map->IsDungeon() && unit)
|
||||
{
|
||||
unit->SetVisible(false);
|
||||
Map::PlayerList const &PlayerList = map->GetPlayers();
|
||||
if (PlayerList.isEmpty())
|
||||
return;
|
||||
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
{
|
||||
if (i->GetSource())
|
||||
{
|
||||
WorldPacket packet;
|
||||
ChatHandler::BuildChatPacket(packet, CHAT_MSG_MONSTER_YELL, LANG_UNIVERSAL, unit, i->GetSource(), YELL_EFFORTS);
|
||||
i->GetSource()->GetSession()->SendPacket(&packet);
|
||||
|
||||
WorldPacket data2(SMSG_PLAY_SOUND, 4);
|
||||
data2 << 10986;
|
||||
i->GetSource()->GetSession()->SendPacket(&data2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA_ARCHIMONDEEVENT:
|
||||
m_auiEncounter[4] = data;
|
||||
break;
|
||||
case DATA_RESET_TRASH_COUNT:
|
||||
Trash = 0;
|
||||
break;
|
||||
case DATA_TRASH:
|
||||
if (data)
|
||||
Trash = data;
|
||||
else
|
||||
Trash--;
|
||||
DoUpdateWorldState(WORLD_STATE_ENEMYCOUNT, Trash);
|
||||
break;
|
||||
case TYPE_RETREAT:
|
||||
if (data == SPECIAL)
|
||||
{
|
||||
if (!m_uiAncientGemGUID.empty())
|
||||
{
|
||||
for (std::list<uint64>::const_iterator itr = m_uiAncientGemGUID.begin(); itr != m_uiAncientGemGUID.end(); ++itr)
|
||||
{
|
||||
//don't know how long it expected
|
||||
DoRespawnGameObject(*itr, DAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case DATA_ALLIANCE_RETREAT:
|
||||
allianceRetreat = data;
|
||||
HandleGameObject(HordeGate, true);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_HORDE_RETREAT:
|
||||
hordeRetreat = data;
|
||||
HandleGameObject(ElfGate, true);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_RAIDDAMAGE:
|
||||
RaidDamage += data;
|
||||
if (RaidDamage >= MINRAIDDAMAGE)
|
||||
RaidDamage = MINRAIDDAMAGE;
|
||||
break;
|
||||
case DATA_RESET_RAIDDAMAGE:
|
||||
RaidDamage = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
// TC_LOG_DEBUG("scripts", "Instance Hyjal: Instance data updated for event %u (Data=%u)", type, data);
|
||||
|
||||
if (data == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << m_auiEncounter[0] << ' ' << m_auiEncounter[1] << ' ' << m_auiEncounter[2] << ' '
|
||||
<< m_auiEncounter[3] << ' ' << m_auiEncounter[4]
|
||||
<< ' ' << allianceRetreat << ' ' << hordeRetreat
|
||||
<< ' ' << RaidDamage;
|
||||
|
||||
str_data = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_RAGEWINTERCHILLEVENT: return m_auiEncounter[0];
|
||||
case DATA_ANETHERONEVENT: return m_auiEncounter[1];
|
||||
case DATA_KAZROGALEVENT: return m_auiEncounter[2];
|
||||
case DATA_AZGALOREVENT: return m_auiEncounter[3];
|
||||
case DATA_ARCHIMONDEEVENT: return m_auiEncounter[4];
|
||||
case DATA_TRASH: return Trash;
|
||||
case DATA_ALLIANCE_RETREAT: return allianceRetreat;
|
||||
case DATA_HORDE_RETREAT: return hordeRetreat;
|
||||
case DATA_RAIDDAMAGE: return RaidDamage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] >> m_auiEncounter[4] >> allianceRetreat >> hordeRetreat >> RaidDamage;
|
||||
for (uint8 i = 0; i < EncounterCount; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS) // Do not load an encounter as IN_PROGRESS - reset it instead.
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32 m_auiEncounter[EncounterCount];
|
||||
std::string str_data;
|
||||
std::list<uint64> m_uiAncientGemGUID;
|
||||
uint64 RageWinterchill;
|
||||
uint64 Anetheron;
|
||||
uint64 Kazrogal;
|
||||
uint64 Azgalor;
|
||||
uint64 Archimonde;
|
||||
uint64 JainaProudmoore;
|
||||
uint64 Thrall;
|
||||
uint64 TyrandeWhisperwind;
|
||||
uint64 HordeGate;
|
||||
uint64 ElfGate;
|
||||
uint32 Trash;
|
||||
uint32 hordeRetreat;
|
||||
uint32 allianceRetreat;
|
||||
uint32 RaidDamage;
|
||||
bool ArchiYell;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_mount_hyjal()
|
||||
{
|
||||
new instance_hyjal();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "SpellInfo.h"
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CURSE_OF_EXERTION = 52772,
|
||||
SPELL_WOUNDING_STRIKE_N = 52771,
|
||||
SPELL_WOUNDING_STRIKE_H = 58830,
|
||||
SPELL_TIME_STOP = 58848,
|
||||
SPELL_TIME_WARP = 52766,
|
||||
SPELL_TIME_STEP_N = 52737,
|
||||
SPELL_TIME_STEP_H = 58829,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CURSE_OF_EXERTION = 1,
|
||||
EVENT_SPELL_WOUNDING_STRIKE = 2,
|
||||
EVENT_SPELL_TIME_STOP = 3,
|
||||
EVENT_SPELL_TIME_WARP = 4,
|
||||
EVENT_TIME_WARP = 5,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_TIME_WARP = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4
|
||||
};
|
||||
|
||||
class boss_epoch : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_epoch() : CreatureScript("boss_epoch") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_epochAI (creature);
|
||||
}
|
||||
|
||||
struct boss_epochAI : public ScriptedAI
|
||||
{
|
||||
boss_epochAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
uint8 warps;
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
warps = 0;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE_OF_EXERTION, 9000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WOUNDING_STRIKE, 3000);
|
||||
events.ScheduleEvent(EVENT_SPELL_TIME_WARP, 25000);
|
||||
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_TIME_STOP, 20000);
|
||||
}
|
||||
|
||||
void SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
|
||||
{
|
||||
if (spellInfo->Id == SPELL_TIME_STEP_H || spellInfo->Id == SPELL_TIME_STEP_N)
|
||||
{
|
||||
if (target == me)
|
||||
return;
|
||||
|
||||
if (warps >= 2)
|
||||
{
|
||||
warps = 0;
|
||||
return;
|
||||
}
|
||||
warps++;
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_TIME_STEP_N, SPELL_TIME_STEP_H), true);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_CURSE_OF_EXERTION:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, SPELL_CURSE_OF_EXERTION, false);
|
||||
events.RepeatEvent(9000);
|
||||
break;
|
||||
case EVENT_SPELL_WOUNDING_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_WOUNDING_STRIKE_N, SPELL_WOUNDING_STRIKE_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_TIME_STOP:
|
||||
me->CastSpell(me, SPELL_TIME_STOP, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_TIME_WARP:
|
||||
Talk(SAY_TIME_WARP);
|
||||
me->CastSpell(me, SPELL_TIME_WARP, false);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_TIME_STEP_N, SPELL_TIME_STEP_H), true);
|
||||
|
||||
events.RepeatEvent(25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_epoch()
|
||||
{
|
||||
new boss_epoch();
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CORRUPTING_BLIGHT = 60588,
|
||||
SPELL_VOID_STRIKE = 60590,
|
||||
SPELL_CORRUPTION_OF_TIME_AURA = 60451,
|
||||
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CORRUPTING_BLIGHT = 1,
|
||||
EVENT_SPELL_VOID_STRIKE = 2,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_DEATH = 1,
|
||||
SAY_FAIL = 2
|
||||
};
|
||||
|
||||
class boss_infinite_corruptor : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_infinite_corruptorAI(creature);
|
||||
}
|
||||
|
||||
struct boss_infinite_corruptorAI : public ScriptedAI
|
||||
{
|
||||
boss_infinite_corruptorAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
uint32 beamTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
if (pInstance->GetData(DATA_GUARDIANTIME_EVENT) == 0)
|
||||
me->DespawnOrUnsummon(500);
|
||||
|
||||
me->SummonCreature(NPC_TIME_RIFT, 2337.6f, 1270.0f, 132.95f, 2.79f);
|
||||
me->SummonCreature(NPC_GUARDIAN_OF_TIME, 2319.3f, 1267.7f, 132.8f, 1.0f);
|
||||
beamTimer = 1;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
events.ScheduleEvent(EVENT_SPELL_VOID_STRIKE, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CORRUPTING_BLIGHT, 12000);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
{
|
||||
if (cr->GetEntry() == NPC_TIME_RIFT)
|
||||
cr->DespawnOrUnsummon(1000);
|
||||
else
|
||||
{
|
||||
cr->DespawnOrUnsummon(5000);
|
||||
cr->RemoveAllAuras();
|
||||
cr->MonsterSay("You have my thanks for saving my existence in this timeline. Now i must report back to my superiors. They must know immediately of what i just experienced.", LANG_UNIVERSAL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
pInstance->SetData(DATA_SHOW_INFINITE_TIMER, 0);
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (!me->IsAlive())
|
||||
return;
|
||||
|
||||
if (param == ACTION_RUN_OUT_OF_TIME)
|
||||
{
|
||||
Talk(SAY_FAIL);
|
||||
summons.DespawnAll();
|
||||
me->DespawnOrUnsummon(500);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (beamTimer)
|
||||
{
|
||||
beamTimer += diff;
|
||||
if (beamTimer >= 2000)
|
||||
{
|
||||
me->CastSpell(me, SPELL_CORRUPTION_OF_TIME_CHANNEL, true);
|
||||
beamTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_VOID_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_VOID_STRIKE, false);
|
||||
events.RepeatEvent(8000);
|
||||
break;
|
||||
case EVENT_SPELL_CORRUPTING_BLIGHT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, SPELL_CORRUPTING_BLIGHT, false);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_infinite_corruptor()
|
||||
{
|
||||
new boss_infinite_corruptor();
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "Player.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CARRION_SWARM_N = 52720,
|
||||
SPELL_CARRION_SWARM_H = 58852,
|
||||
SPELL_MIND_BLAST_N = 52722,
|
||||
SPELL_MIND_BLAST_H = 58850,
|
||||
SPELL_SLEEP_N = 52721,
|
||||
SPELL_SLEEP_H = 58849,
|
||||
SPELL_VAMPIRIC_TOUCH = 52723,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CARRION_SWARM = 1,
|
||||
EVENT_SPELL_MIND_BLAST = 2,
|
||||
EVENT_SPELL_SLEEP = 3,
|
||||
EVENT_SPELL_VAMPIRIC_TOUCH = 4,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 2,
|
||||
SAY_KILL = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_SLEEP = 5,
|
||||
SAY_30HEALTH = 6,
|
||||
SAY_15HEALTH = 7,
|
||||
SAY_ESCAPE_SPEECH_1 = 8,
|
||||
SAY_ESCAPE_SPEECH_2 = 9,
|
||||
SAY_OUTRO = 10
|
||||
};
|
||||
|
||||
class boss_mal_ganis : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_mal_ganis() : CreatureScript("boss_mal_ganis") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_mal_ganisAI (creature);
|
||||
}
|
||||
|
||||
struct boss_mal_ganisAI : public ScriptedAI
|
||||
{
|
||||
boss_mal_ganisAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
finished = false;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
bool finished;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true);
|
||||
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true);
|
||||
events.Reset();
|
||||
if (finished)
|
||||
{
|
||||
Talk(SAY_OUTRO);
|
||||
me->DespawnOrUnsummon(20000);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_CARRION_SWARM, 6000);
|
||||
events.ScheduleEvent(EVENT_SPELL_MIND_BLAST, 11000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SLEEP, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_VAMPIRIC_TOUCH, 15000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* who, uint32 &damage, DamageEffectType, SpellSchoolMask)
|
||||
{
|
||||
if (!finished && damage >= me->GetHealth())
|
||||
{
|
||||
damage = 0;
|
||||
finished = true;
|
||||
me->SetRegeneratingHealth(false);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
if (InstanceScript* pInstance = me->GetInstanceScript())
|
||||
{
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, pInstance->GetData64(DATA_ARTHAS)))
|
||||
cr->AI()->DoAction(ACTION_KILLED_MALGANIS);
|
||||
|
||||
// give credit to players
|
||||
me->CastSpell(me, 58630, true);
|
||||
}
|
||||
|
||||
// quest completion
|
||||
if (who)
|
||||
if (Player* player = who->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
player->RewardPlayerAndGroupAtEvent(31006, player); // Royal Escort quest, Mal'ganis bunny
|
||||
|
||||
EnterEvadeMode();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_CARRION_SWARM:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_CARRION_SWARM_N, SPELL_CARRION_SWARM_H), false);
|
||||
events.RepeatEvent(7000);
|
||||
break;
|
||||
case EVENT_SPELL_MIND_BLAST:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_MIND_BLAST_N, SPELL_MIND_BLAST_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_SLEEP:
|
||||
Talk(SAY_SLEEP);
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50.0f, true))
|
||||
me->CastSpell(target, DUNGEON_MODE(SPELL_SLEEP_N, SPELL_SLEEP_H), false);
|
||||
events.RepeatEvent(17000);
|
||||
break;
|
||||
case EVENT_SPELL_VAMPIRIC_TOUCH:
|
||||
me->CastSpell(me, SPELL_VAMPIRIC_TOUCH, true);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_mal_ganis()
|
||||
{
|
||||
new boss_mal_ganis();
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_CONSTRICTING_CHAINS_N = 52696,
|
||||
SPELL_CONSTRICTING_CHAINS_H = 58823,
|
||||
SPELL_DISEASE_EXPULSION_N = 52666,
|
||||
SPELL_DISEASE_EXPULSION_H = 58824,
|
||||
SPELL_FRENZY = 58841,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_CONSTRICTING_CHAINS = 1,
|
||||
EVENT_SPELL_DISEASE_EXPULSION = 2,
|
||||
EVENT_SPELL_FRENZY = 3,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_SPAWN = 2,
|
||||
SAY_DEATH = 3
|
||||
};
|
||||
|
||||
class boss_meathook : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_meathook() : CreatureScript("boss_meathook") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_meathookAI (creature);
|
||||
}
|
||||
|
||||
struct boss_meathookAI : public ScriptedAI
|
||||
{
|
||||
boss_meathookAI(Creature* c) : ScriptedAI(c)
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
void Reset() { events.Reset(); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.RescheduleEvent(EVENT_SPELL_CONSTRICTING_CHAINS, 15000);
|
||||
events.RescheduleEvent(EVENT_SPELL_DISEASE_EXPULSION, 4000);
|
||||
events.RescheduleEvent(EVENT_SPELL_FRENZY, 20000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_DISEASE_EXPULSION:
|
||||
me->CastSpell(me, DUNGEON_MODE(SPELL_DISEASE_EXPULSION_N, SPELL_DISEASE_EXPULSION_H), false);
|
||||
events.RepeatEvent(6000);
|
||||
break;
|
||||
case EVENT_SPELL_FRENZY:
|
||||
me->CastSpell(me, SPELL_FRENZY, false);
|
||||
events.RepeatEvent(20000);
|
||||
break;
|
||||
case EVENT_SPELL_CONSTRICTING_CHAINS:
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_BOTTOMAGGRO, 0, 50.0f, true))
|
||||
me->CastSpell(pTarget, DUNGEON_MODE(SPELL_CONSTRICTING_CHAINS_N, SPELL_CONSTRICTING_CHAINS_H), false);
|
||||
events.RepeatEvent(14000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_meathook()
|
||||
{
|
||||
new boss_meathook();
|
||||
}
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SHADOW_BOLT_N = 57725,
|
||||
SPELL_SHADOW_BOLT_H = 58827,
|
||||
SPELL_STEAL_FLESH_CHANNEL = 52708,
|
||||
SPELL_STEAL_FLESH_TARGET = 52711,
|
||||
SPELL_STEAL_FLESH_CASTER = 52712,
|
||||
SPELL_SUMMON_GHOULS = 52451,
|
||||
SPELL_EXPLODE_GHOUL_N = 52480,
|
||||
SPELL_EXPLODE_GHOUL_H = 58825,
|
||||
SPELL_CURSE_OF_TWISTED_FAITH = 58845,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SPELL_SHADOW_BOLT = 1,
|
||||
EVENT_SPELL_STEAL_FLESH = 2,
|
||||
EVENT_SPELL_SUMMON_GHOULS = 3,
|
||||
EVENT_EXPLODE_GHOUL = 4,
|
||||
EVENT_SPELL_CURSE = 5,
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SPAWN = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_EXPLODE_GHOUL = 4,
|
||||
SAY_STEAL_FLESH = 5,
|
||||
SAY_SUMMON_GHOULS = 6
|
||||
};
|
||||
|
||||
class boss_salramm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_salramm() : CreatureScript("boss_salramm") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_salrammAI (creature);
|
||||
}
|
||||
|
||||
struct boss_salrammAI : public ScriptedAI
|
||||
{
|
||||
boss_salrammAI(Creature* c) : ScriptedAI(c), summons(me)
|
||||
{
|
||||
Talk(SAY_SPAWN);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
SummonList summons;
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) { summons.Summon(cr); }
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHADOW_BOLT, 7000);
|
||||
events.ScheduleEvent(EVENT_SPELL_STEAL_FLESH, 11000);
|
||||
events.ScheduleEvent(EVENT_SPELL_SUMMON_GHOULS, 16000);
|
||||
events.ScheduleEvent(EVENT_EXPLODE_GHOUL, 22000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_CURSE, 25000);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (!urand(0,1))
|
||||
return;
|
||||
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void ExplodeGhoul()
|
||||
{
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* cr = ObjectAccessor::GetCreature(*me, (*itr)))
|
||||
if (cr->IsAlive())
|
||||
{
|
||||
me->CastSpell(cr, DUNGEON_MODE(SPELL_EXPLODE_GHOUL_N, SPELL_EXPLODE_GHOUL_H), false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.GetEvent())
|
||||
{
|
||||
case EVENT_SPELL_SHADOW_BOLT:
|
||||
me->CastSpell(me->GetVictim(), DUNGEON_MODE(SPELL_SHADOW_BOLT_N, SPELL_SHADOW_BOLT_H), false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_SPELL_STEAL_FLESH:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_STEAL_FLESH);
|
||||
me->CastSpell(me->GetVictim(), SPELL_STEAL_FLESH_CHANNEL, false);
|
||||
events.RepeatEvent(12000);
|
||||
break;
|
||||
case EVENT_SPELL_SUMMON_GHOULS:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_SUMMON_GHOULS);
|
||||
me->CastSpell(me, SPELL_SUMMON_GHOULS, false);
|
||||
events.RepeatEvent(10000);
|
||||
break;
|
||||
case EVENT_EXPLODE_GHOUL:
|
||||
if (!urand(0,2))
|
||||
Talk(SAY_EXPLODE_GHOUL);
|
||||
ExplodeGhoul();
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SPELL_CURSE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CURSE_OF_TWISTED_FAITH, false);
|
||||
events.RepeatEvent(30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class spell_boss_salramm_steal_flesh : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_boss_salramm_steal_flesh() : SpellScriptLoader("spell_boss_salramm_steal_flesh") { }
|
||||
|
||||
class spell_boss_salramm_steal_flesh_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_boss_salramm_steal_flesh_AuraScript);
|
||||
|
||||
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
Unit* target = GetUnitOwner();
|
||||
if (caster)
|
||||
{
|
||||
caster->CastSpell(caster, SPELL_STEAL_FLESH_CASTER, true);
|
||||
caster->CastSpell(target, SPELL_STEAL_FLESH_TARGET, true);
|
||||
}
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_boss_salramm_steal_flesh_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_PERIODIC_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_boss_salramm_steal_flesh_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_salramm()
|
||||
{
|
||||
new boss_salramm();
|
||||
new spell_boss_salramm_steal_flesh();
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#ifndef DEF_CULLING_OF_STRATHOLME_H
|
||||
#define DEF_CULLING_OF_STRATHOLME_H
|
||||
|
||||
enum Data
|
||||
{
|
||||
DATA_ARTHAS_EVENT,
|
||||
DATA_GUARDIANTIME_EVENT,
|
||||
|
||||
// Communication
|
||||
DATA_SHOW_CRATES,
|
||||
DATA_CRATE_COUNT,
|
||||
DATA_START_WAVES,
|
||||
DATA_SHOW_INFINITE_TIMER,
|
||||
DATA_ARTHAS_REPOSITION,
|
||||
};
|
||||
|
||||
enum Data64
|
||||
{
|
||||
DATA_ARTHAS,
|
||||
DATA_INFINITE,
|
||||
DATA_SHKAF_GATE,
|
||||
DATA_EXIT_GATE,
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_MEATHOOK = 26529,
|
||||
NPC_SALRAMM = 26530,
|
||||
NPC_EPOCH = 26532,
|
||||
NPC_MAL_GANIS = 26533,
|
||||
NPC_INFINITE = 32273,
|
||||
NPC_ARTHAS = 26499,
|
||||
NPC_JAINA = 26497,
|
||||
NPC_UTHER = 26528,
|
||||
|
||||
NPC_GUARDIAN_OF_TIME = 32281,
|
||||
NPC_TIME_RIFT = 28409,
|
||||
|
||||
NPC_CHROMIE_MIDDLE = 27915,
|
||||
NPC_GRAIN_CREATE_TRIGGER = 30996,
|
||||
NPC_HOURGLASS = 28656,
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_SHKAF_GATE = 188686,
|
||||
GO_EXIT_GATE = 191788,
|
||||
GO_MALGANIS_CHEST_N = 190663,
|
||||
GO_MALGANIS_CHEST_H = 193597,
|
||||
GO_SUSPICIOUS_CRATE = 190094,
|
||||
GO_PLAGUED_CRATE = 190095,
|
||||
};
|
||||
|
||||
enum WorldStatesCoT
|
||||
{
|
||||
WORLDSTATE_SHOW_CRATES = 3479,
|
||||
WORLDSTATE_CRATES_REVEALED = 3480,
|
||||
WORLDSTATE_WAVE_COUNT = 3504,
|
||||
WORLDSTATE_TIME_GUARDIAN = 3931,
|
||||
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932,
|
||||
};
|
||||
|
||||
enum CrateSpells
|
||||
{
|
||||
SPELL_CRATES_CREDIT = 58109,
|
||||
SPELL_ARCANE_DISRUPTION = 49590,
|
||||
|
||||
SPELL_HUMAN_FEMALE = 35483,
|
||||
SPELL_HUMAN_MALE = 35482,
|
||||
};
|
||||
|
||||
enum EventPositions
|
||||
{
|
||||
EVENT_POS_CHROMIE = 0,
|
||||
EVENT_POS_HOURGLASS = 1,
|
||||
EVENT_SRC_UTHER,
|
||||
EVENT_SRC_JAINA,
|
||||
EVENT_SRC_HORSE1,
|
||||
EVENT_SRC_HORSE2,
|
||||
EVENT_SRC_HORSE3,
|
||||
EVENT_DST_UTHER,
|
||||
EVENT_DST_HORSE1,
|
||||
EVENT_DST_HORSE2,
|
||||
EVENT_DST_HORSE3,
|
||||
EVENT_POS_RETREAT,
|
||||
EVENT_SRC_TOWN_CITYMAN1,
|
||||
EVENT_SRC_TOWN_CITYMAN2,
|
||||
EVENT_DST_CITYMAN,
|
||||
EVENT_SRC_MALGANIS,
|
||||
EVENT_SRC_MEATHOOK,
|
||||
EVENT_SRC_SALRAMM,
|
||||
EVENT_SRC_HALL_CITYMAN1,
|
||||
EVENT_SRC_HALL_CITYMAN2,
|
||||
EVENT_SRC_HALL_CITYMAN3,
|
||||
EVENT_SRC_EPOCH,
|
||||
EVENT_DST_EPOCH,
|
||||
EVENT_SRC_CORRUPTOR,
|
||||
EVENT_SRC_MALGANIS_FINAL,
|
||||
};
|
||||
|
||||
enum ArthasPhase
|
||||
{
|
||||
COS_PROGRESS_NOT_STARTED = 0,
|
||||
COS_PROGRESS_CRATES_FOUND = 1,
|
||||
COS_PROGRESS_START_INTRO = 2,
|
||||
COS_PROGRESS_FINISHED_INTRO = 3,
|
||||
COS_PROGRESS_FINISHED_CITY_INTRO = 4,
|
||||
COS_PROGRESS_KILLED_MEATHOOK = 5,
|
||||
COS_PROGRESS_KILLED_SALRAMM = 6,
|
||||
COS_PROGRESS_REACHED_TOWN_HALL = 7,
|
||||
COS_PROGRESS_KILLED_EPOCH = 8,
|
||||
COS_PROGRESS_LAST_CITY = 9,
|
||||
COS_PROGRESS_BEFORE_MALGANIS = 10,
|
||||
COS_PROGRESS_FINISHED = 11,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_START_EVENT = 1,
|
||||
ACTION_START_CITY = 2,
|
||||
ACTION_KILLED_SALRAMM = 3,
|
||||
ACTION_START_TOWN_HALL = 4,
|
||||
ACTION_START_SECRET_PASSAGE = 5,
|
||||
ACTION_START_LAST_CITY = 6,
|
||||
ACTION_RUN_OUT_OF_TIME = 7,
|
||||
ACTION_START_MALGANIS = 8,
|
||||
ACTION_KILLED_MALGANIS = 9,
|
||||
};
|
||||
|
||||
const Position LeaderIntroPos1 = {1938.05f, 1289.79f, 145.38f, 3.18f};
|
||||
const Position LeaderIntroPos2 = {2050.66f, 1287.33f, 142.67f, M_PI};
|
||||
const Position LeaderIntroPos2special = {2092.15f, 1276.65f, 140.52f, 0.22f};
|
||||
const Position LeaderIntroPos3 = {2365.63f, 1194.84f, 131.97f, 0.0f};
|
||||
const Position LeaderIntroPos4 = {2423.12f, 1119.43f, 148.07f, 0.0f};
|
||||
const Position LeaderIntroPos5 = {2540.48f, 1129.06f, 130.86f, 0.0f};
|
||||
const Position LeaderIntroPos6 = {2327.39f, 1412.47f, 127.69f, 0.0f};
|
||||
|
||||
const Position EventPos[] =
|
||||
{
|
||||
{1813.298f, 1283.578f, 142.326f, 3.878161f}, // chromie
|
||||
{1809.46f, 1286.05f, 142.62f, 4.8f}, // hourglass
|
||||
{1795.76f, 1271.54f, 140.61f, 0.21f}, // source for uther
|
||||
{1895.48f, 1292.66f, 143.706f, 0.023475f}, // source for jaina
|
||||
{1788.38f, 1273.7f, 140.15f, 0.2f}, // source for horses
|
||||
{1788.76f, 1271.54f, 140.62f, 0.21f},
|
||||
{1788.74f, 1267.38f, 140.18f, 0.11f},
|
||||
{1897.6f, 1285.5f, 143.44f, 0.32f}, // dest for uther
|
||||
{1888.56f, 1289.95f, 143.8f, 0.01f}, // dest for horses
|
||||
{1888.94f, 1285.41f, 143.69f, 0.08f},
|
||||
{1889.55f, 1279.95f, 143.62f, 0.1f},
|
||||
{1751.9f, 1262.45f, 137.62f, 3.35f}, // retreat position after intro (uther + horses)
|
||||
{2091.977f, 1275.021f, 140.757f, 0.558f}, // source for town city man 1
|
||||
{2093.514f, 1275.842f, 140.408f, 3.801f}, // 2
|
||||
{2089.04f, 1277.98f, 140.85f, 2.35f}, // cityman dest pos
|
||||
{2117.349f, 1288.624f, 136.271f, 1.37f}, // malganis city intro
|
||||
{2351.45f, 1197.81f, 130.45f, 3.83f}, // meathook spawn position
|
||||
{2351.45f, 1197.81f, 130.45f, 3.83f}, // salramm spawn position
|
||||
{2398.14f, 1207.81f, 134.04f, 5.15f}, // source for hall city man 1
|
||||
{2403.22f, 1205.54f, 134.04f, 3.31f}, // 2
|
||||
{2400.82f, 1201.69f, 134.01f, 1.53f}, // 3
|
||||
{2463.131f, 1115.391f, 152.473f, 3.41f}, // epoch spawn position
|
||||
{2451.809f, 1112.901f, 149.220f, 3.36f}, // epoch move pos
|
||||
{2329.07f, 1276.98f, 132.68f, 4.0f}, // infinite corruptor pos
|
||||
{2298.25f, 1500.56f, 128.37f, 4.95f} // malganis final pos
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,422 +0,0 @@
|
||||
/*
|
||||
REWRITTEN FROM SCRATCH BY XINEF, IT OWNS NOW!
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "CreatureTextMgr.h"
|
||||
#include "culling_of_stratholme.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SpellInfo.h"
|
||||
|
||||
class instance_culling_of_stratholme : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* pMap) const
|
||||
{
|
||||
return new instance_culling_of_stratholme_InstanceMapScript(pMap);
|
||||
}
|
||||
|
||||
struct instance_culling_of_stratholme_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_culling_of_stratholme_InstanceMapScript(Map* pMap) : InstanceScript(pMap)
|
||||
{
|
||||
// NPCs
|
||||
_arthasGUID = 0;
|
||||
_infiniteGUID = 0;
|
||||
|
||||
// GOs
|
||||
_shkafGateGUID = 0;
|
||||
_exitGateGUID = 0;
|
||||
|
||||
// Instance
|
||||
_crateCount = 0;
|
||||
_showCrateTimer = 0;
|
||||
_guardianTimer = 0;
|
||||
_respawnAndReposition = false;
|
||||
_encounterState = COS_PROGRESS_NOT_STARTED;
|
||||
_loadTimer = 0;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void FillInitialWorldStates(WorldPacket& data)
|
||||
{
|
||||
data << uint32(WORLDSTATE_SHOW_CRATES) << uint32(0);
|
||||
data << uint32(WORLDSTATE_CRATES_REVEALED) << uint32(_crateCount);
|
||||
data << uint32(WORLDSTATE_WAVE_COUNT) << uint32(0);
|
||||
data << uint32(WORLDSTATE_TIME_GUARDIAN) << uint32(25);
|
||||
data << uint32(WORLDSTATE_TIME_GUARDIAN_SHOW) << uint32(0);
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* plr)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() == 1)
|
||||
SetData(DATA_ARTHAS_REPOSITION, 2);
|
||||
|
||||
EnsureGridLoaded();
|
||||
|
||||
if (plr->getRace() != RACE_HUMAN && plr->getRace() != RACE_DWARF && plr->getRace() != RACE_GNOME)
|
||||
plr->CastSpell(plr, ((plr->getGender() == GENDER_MALE) ? SPELL_HUMAN_MALE : SPELL_HUMAN_FEMALE), true);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_ARTHAS:
|
||||
_arthasGUID = creature->GetGUID();
|
||||
if (_encounterState == COS_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
else
|
||||
Reposition(creature);
|
||||
break;
|
||||
case NPC_INFINITE:
|
||||
_infiniteGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_SHKAF_GATE:
|
||||
_shkafGateGUID = go->GetGUID();
|
||||
if (_encounterState >= COS_PROGRESS_KILLED_EPOCH)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_EXIT_GATE:
|
||||
_exitGateGUID = go->GetGUID();
|
||||
if (_encounterState == COS_PROGRESS_FINISHED)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_SHOW_CRATES:
|
||||
DoUpdateWorldState(WORLDSTATE_SHOW_CRATES, data);
|
||||
return;
|
||||
case DATA_SHOW_INFINITE_TIMER:
|
||||
if (!instance->IsHeroic() || !_guardianTimer)
|
||||
return;
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, data);
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS)));
|
||||
if (data == 0)
|
||||
{
|
||||
_guardianTimer = 0;
|
||||
SaveToDB();
|
||||
}
|
||||
else if (!_infiniteGUID)
|
||||
instance->SummonCreature(NPC_INFINITE, EventPos[EVENT_SRC_CORRUPTOR]);
|
||||
return;
|
||||
case DATA_START_WAVES:
|
||||
DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, 1);
|
||||
if (instance->IsHeroic())
|
||||
{
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, true);
|
||||
_guardianTimer = 26*MINUTE*IN_MILLISECONDS;
|
||||
if (!_infiniteGUID)
|
||||
instance->SummonCreature(NPC_INFINITE, EventPos[EVENT_SRC_CORRUPTOR]);
|
||||
}
|
||||
return;
|
||||
case DATA_CRATE_COUNT:
|
||||
_crateCount++;
|
||||
if (_crateCount == 5)
|
||||
{
|
||||
Map::PlayerList const &PlayerList = instance->GetPlayers();
|
||||
if (!PlayerList.isEmpty())
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
i->GetSource()->KilledMonsterCredit(NPC_GRAIN_CREATE_TRIGGER, 0);
|
||||
|
||||
_showCrateTimer++;
|
||||
if (GetData(DATA_ARTHAS_EVENT) < COS_PROGRESS_CRATES_FOUND)
|
||||
SetData(DATA_ARTHAS_EVENT, COS_PROGRESS_CRATES_FOUND);
|
||||
}
|
||||
|
||||
DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount);
|
||||
return;
|
||||
case DATA_ARTHAS_EVENT:
|
||||
// Start Event
|
||||
_encounterState = data;
|
||||
if (data == COS_PROGRESS_START_INTRO)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
arthas->AI()->DoAction(ACTION_START_EVENT);
|
||||
}
|
||||
else if (data == COS_PROGRESS_KILLED_SALRAMM)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
arthas->AI()->DoAction(ACTION_KILLED_SALRAMM);
|
||||
}
|
||||
break;
|
||||
case DATA_ARTHAS_REPOSITION:
|
||||
if (data == 2)
|
||||
_respawnAndReposition = true;
|
||||
else if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
Reposition(arthas);
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (type == DATA_ARTHAS_EVENT)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_ARTHAS_EVENT:
|
||||
return _encounterState;
|
||||
case DATA_GUARDIANTIME_EVENT:
|
||||
return _guardianTimer;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier) const
|
||||
{
|
||||
switch (identifier)
|
||||
{
|
||||
case DATA_SHKAF_GATE:
|
||||
return _shkafGateGUID;
|
||||
case DATA_ARTHAS:
|
||||
return _arthasGUID;
|
||||
case DATA_EXIT_GATE:
|
||||
return _exitGateGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
if (_loadTimer)
|
||||
{
|
||||
_loadTimer += diff;
|
||||
if (_loadTimer > 3000)
|
||||
{
|
||||
UpdateEventState();
|
||||
_loadTimer = 0;
|
||||
}
|
||||
}
|
||||
// Used when arthas dies
|
||||
if (_respawnAndReposition)
|
||||
{
|
||||
if (Creature *arthas = instance->GetCreature(_arthasGUID))
|
||||
{
|
||||
if (!arthas->IsAlive())
|
||||
{
|
||||
EnsureGridLoaded();
|
||||
arthas->setDeathState(DEAD);
|
||||
arthas->Respawn();
|
||||
}
|
||||
else
|
||||
{
|
||||
arthas->AI()->Reset();
|
||||
_respawnAndReposition = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used after 5-th crates is revealed
|
||||
if (_showCrateTimer)
|
||||
{
|
||||
_showCrateTimer += diff;
|
||||
if (_showCrateTimer >= 20000)
|
||||
{
|
||||
UpdateEventState();
|
||||
_showCrateTimer = 0; // just to be sure
|
||||
}
|
||||
}
|
||||
|
||||
// Used to display how much time players have
|
||||
if (_guardianTimer)
|
||||
{
|
||||
uint32 div = uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS));
|
||||
_guardianTimer -= diff;
|
||||
uint32 divAfter = uint32(_guardianTimer / (MINUTE*IN_MILLISECONDS));
|
||||
|
||||
if (divAfter == 0)
|
||||
{
|
||||
_guardianTimer = 0;
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
|
||||
|
||||
// Inform infinite we run out of time
|
||||
if (instance->IsHeroic() && _infiniteGUID)
|
||||
if (Creature* cr = instance->GetCreature(_infiniteGUID))
|
||||
cr->AI()->DoAction(ACTION_RUN_OUT_OF_TIME);
|
||||
|
||||
}
|
||||
else if (div > divAfter)
|
||||
{
|
||||
if (divAfter == 5)
|
||||
ChromieWhisper(1);
|
||||
else if (divAfter == 1)
|
||||
ChromieWhisper(2);
|
||||
|
||||
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, divAfter);
|
||||
SaveToDB();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEventState()
|
||||
{
|
||||
if (_encounterState > COS_PROGRESS_NOT_STARTED)
|
||||
{
|
||||
// Summon Chromie and global whisper
|
||||
instance->SummonCreature(NPC_CHROMIE_MIDDLE, EventPos[EVENT_POS_CHROMIE]);
|
||||
instance->SummonCreature(NPC_HOURGLASS, EventPos[EVENT_POS_HOURGLASS]);
|
||||
|
||||
if (_encounterState == COS_PROGRESS_CRATES_FOUND ||
|
||||
_encounterState == COS_PROGRESS_START_INTRO)
|
||||
{
|
||||
ChromieWhisper(0);
|
||||
|
||||
// hide crates count
|
||||
DoUpdateWorldState(WORLDSTATE_SHOW_CRATES, 0);
|
||||
_showCrateTimer = 0;
|
||||
_encounterState = COS_PROGRESS_CRATES_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ChromieWhisper(uint8 textId)
|
||||
{
|
||||
if (!instance->GetPlayers().isEmpty())
|
||||
if (Player* player = instance->GetPlayers().getFirst()->GetSource())
|
||||
{
|
||||
Position pos;
|
||||
player->GetPosition(&pos);
|
||||
if (Creature* cr = instance->SummonCreature(NPC_CHROMIE_MIDDLE, pos))
|
||||
{
|
||||
cr->SetVisible(false);
|
||||
cr->DespawnOrUnsummon(1000);
|
||||
sCreatureTextMgr->SendChat(cr, textId, player, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reposition(Creature* arthas)
|
||||
{
|
||||
switch (GetData(DATA_ARTHAS_EVENT))
|
||||
{
|
||||
case COS_PROGRESS_FINISHED_INTRO:
|
||||
arthas->UpdatePosition(LeaderIntroPos2, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos2);
|
||||
arthas->SetFacingTo(LeaderIntroPos2.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_FINISHED_CITY_INTRO:
|
||||
case COS_PROGRESS_KILLED_MEATHOOK:
|
||||
case COS_PROGRESS_KILLED_SALRAMM:
|
||||
arthas->UpdatePosition(LeaderIntroPos2special, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos2special);
|
||||
arthas->SetFacingTo(LeaderIntroPos2special.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_REACHED_TOWN_HALL:
|
||||
arthas->UpdatePosition(LeaderIntroPos3, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos3);
|
||||
arthas->SetFacingTo(LeaderIntroPos3.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_KILLED_EPOCH:
|
||||
arthas->UpdatePosition(LeaderIntroPos4, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos4);
|
||||
arthas->SetFacingTo(LeaderIntroPos4.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_LAST_CITY:
|
||||
arthas->UpdatePosition(LeaderIntroPos5, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos5);
|
||||
arthas->SetFacingTo(LeaderIntroPos5.GetOrientation());
|
||||
break;
|
||||
case COS_PROGRESS_BEFORE_MALGANIS:
|
||||
arthas->UpdatePosition(LeaderIntroPos6, true);
|
||||
arthas->SetHomePosition(LeaderIntroPos6);
|
||||
arthas->SetFacingTo(LeaderIntroPos6.GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureGridLoaded()
|
||||
{
|
||||
instance->LoadGrid(LeaderIntroPos1.GetPositionX(), LeaderIntroPos1.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos2.GetPositionX(), LeaderIntroPos2.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos3.GetPositionX(), LeaderIntroPos3.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos4.GetPositionX(), LeaderIntroPos4.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos5.GetPositionX(), LeaderIntroPos5.GetPositionY());
|
||||
instance->LoadGrid(LeaderIntroPos6.GetPositionX(), LeaderIntroPos6.GetPositionY());
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "C S " << _encounterState << ' ' << _guardianTimer;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
|
||||
|
||||
if (dataHead1 == 'C' && dataHead2 == 'S')
|
||||
{
|
||||
_encounterState = data0;
|
||||
_guardianTimer = data1;
|
||||
|
||||
//UpdateEventState();
|
||||
_loadTimer++;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
private:
|
||||
// NPCs
|
||||
uint64 _arthasGUID;
|
||||
uint64 _infiniteGUID;
|
||||
|
||||
// GOs
|
||||
uint64 _shkafGateGUID;
|
||||
uint64 _exitGateGUID;
|
||||
uint32 _encounterState;
|
||||
uint32 _crateCount;
|
||||
uint32 _showCrateTimer;
|
||||
uint32 _guardianTimer;
|
||||
|
||||
bool _respawnAndReposition;
|
||||
uint32 _loadTimer;
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_culling_of_stratholme()
|
||||
{
|
||||
new instance_culling_of_stratholme();
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
|
||||
enum CaptainSkarloc
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_TAUNT = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_DEATH = 3,
|
||||
|
||||
SPELL_HOLY_LIGHT = 29427,
|
||||
SPELL_CLEANSE = 29380,
|
||||
SPELL_HAMMER_OF_JUSTICE = 13005,
|
||||
SPELL_HOLY_SHIELD = 31904,
|
||||
SPELL_DEVOTION_AURA = 8258,
|
||||
SPELL_CONSECRATION = 38385,
|
||||
|
||||
WAYPOINTS_COUNT = 4,
|
||||
|
||||
EVENT_INITIAL_TALK = 1,
|
||||
EVENT_START_FIGHT = 2,
|
||||
EVENT_SPELL_CLEANSE = 10,
|
||||
EVENT_SPELL_HAMMER = 11,
|
||||
EVENT_SPELL_HOLY_LIGHT = 12,
|
||||
EVENT_SPELL_HOLY_SHIELD = 13,
|
||||
EVENT_SPELL_CONSECRATION = 14
|
||||
};
|
||||
|
||||
const Position startPath[WAYPOINTS_COUNT] =
|
||||
{
|
||||
{2008.38f, 281.57f, 65.70f, 0.0f},
|
||||
{2035.71f, 271.38f, 63.495f, 0.0f},
|
||||
{2049.12f, 252.31f, 62.855f, 0.0f},
|
||||
{2058.77f, 236.04f, 63.92f, 0.0f}
|
||||
};
|
||||
|
||||
class boss_captain_skarloc : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_captain_skarloc() : CreatureScript("boss_captain_skarloc") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_captain_skarlocAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_captain_skarlocAI : public ScriptedAI
|
||||
{
|
||||
boss_captain_skarlocAI(Creature* creature) : ScriptedAI(creature), summons(me) { }
|
||||
|
||||
EventMap events;
|
||||
EventMap events2;
|
||||
SummonList summons;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
events2.Reset();
|
||||
summons.DespawnAll();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summons.Summon(summon);
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetData64(DATA_THRALL_GUID)))
|
||||
thrall->AI()->JustSummoned(summon);
|
||||
summon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
|
||||
if (summon->GetEntry() == NPC_SKARLOC_MOUNT)
|
||||
return;
|
||||
|
||||
if (summons.size() == 1)
|
||||
summon->GetMotionMaster()->MovePoint(0, 2060.788f, 237.301f, 63.999f);
|
||||
else
|
||||
summon->GetMotionMaster()->MovePoint(0, 2056.870f, 234.853f, 63.839f);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
|
||||
Movement::PointsArray path;
|
||||
path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
for (uint8 i = 0; i < WAYPOINTS_COUNT; ++i)
|
||||
path.push_back(G3D::Vector3(startPath[i].GetPositionX(), startPath[i].GetPositionY(), startPath[i].GetPositionZ()));
|
||||
|
||||
me->GetMotionMaster()->MoveSplinePath(&path);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if (type != ESCORT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
// Xinef: we can rely here on internal counting
|
||||
if (id == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2038.549f, 273.303f, 63.420f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2032.810f, 269.416f, 63.561f, 5.30f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
}
|
||||
else if (id == 2)
|
||||
{
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->Dismount();
|
||||
me->SetWalk(true);
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
summon->SetWalk(true);
|
||||
}
|
||||
|
||||
if (me->movespline->Finalized())
|
||||
{
|
||||
events2.ScheduleEvent(EVENT_INITIAL_TALK, 500);
|
||||
events2.ScheduleEvent(EVENT_START_FIGHT, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
me->CastSpell(me, SPELL_DEVOTION_AURA, true);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 6000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_SHIELD, 10000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 1000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_SKARLOC_KILLED);
|
||||
me->GetInstanceScript()->SetData(DATA_THRALL_ADD_FLAG, 0);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INITIAL_TALK:
|
||||
Talk(SAY_ENTER);
|
||||
break;
|
||||
case EVENT_START_FIGHT:
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetInCombatWithZone();
|
||||
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
|
||||
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
|
||||
if (summon->GetEntry() != NPC_SKARLOC_MOUNT)
|
||||
{
|
||||
summon->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
summon->SetInCombatWithZone();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_HOLY_LIGHT:
|
||||
me->CastSpell(me, SPELL_HOLY_LIGHT, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_LIGHT, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_CLEANSE:
|
||||
if (roll_chance_i(33))
|
||||
Talk(SAY_TAUNT);
|
||||
me->CastSpell(me, SPELL_CLEANSE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CLEANSE, 10000);
|
||||
break;
|
||||
case EVENT_SPELL_HAMMER:
|
||||
me->CastSpell(me->GetVictim(), SPELL_HAMMER_OF_JUSTICE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_HOLY_SHIELD:
|
||||
me->CastSpell(me, SPELL_CLEANSE, false);
|
||||
events.ScheduleEvent(SPELL_HOLY_SHIELD, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_CONSECRATION:
|
||||
me->CastSpell(me, SPELL_CONSECRATION, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_CONSECRATION, 20000);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_captain_skarloc()
|
||||
{
|
||||
new boss_captain_skarloc();
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
|
||||
|
||||
enum EpochHunter
|
||||
{
|
||||
SAY_AGGRO = 3,
|
||||
SAY_SLAY = 4,
|
||||
SAY_BREATH = 5,
|
||||
SAY_DEATH = 6,
|
||||
|
||||
SPELL_SAND_BREATH = 31914,
|
||||
SPELL_IMPENDING_DEATH = 31916,
|
||||
SPELL_MAGIC_DISRUPTION_AURA = 33834,
|
||||
SPELL_WING_BUFFET = 31475,
|
||||
|
||||
EVENT_SPELL_SAND_BREATH = 1,
|
||||
EVENT_SPELL_IMPENDING_DEATH = 2,
|
||||
EVENT_SPELL_DISRUPTION = 3,
|
||||
EVENT_SPELL_WING_BUFFET = 4
|
||||
};
|
||||
|
||||
class boss_epoch_hunter : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_epoch_hunter() : CreatureScript("boss_epoch_hunter") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<boss_epoch_hunterAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_epoch_hunterAI : public ScriptedAI
|
||||
{
|
||||
boss_epoch_hunterAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 8000);
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 2000);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 20000);
|
||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 14000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (killer == me)
|
||||
return;
|
||||
Talk(SAY_DEATH);
|
||||
me->GetInstanceScript()->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_EPOCH_KILLED);
|
||||
if (Creature* taretha = ObjectAccessor::GetCreature(*me, me->GetInstanceScript()->GetData64(DATA_TARETHA_GUID)))
|
||||
taretha->AI()->DoAction(me->GetEntry());
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_SAND_BREATH:
|
||||
if (roll_chance_i(50))
|
||||
Talk(SAY_BREATH);
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAND_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SAND_BREATH, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_IMPENDING_DEATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_IMPENDING_DEATH, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPENDING_DEATH, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_WING_BUFFET:
|
||||
me->CastSpell(me, SPELL_WING_BUFFET, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_WING_BUFFET, 30000);
|
||||
break;
|
||||
case EVENT_SPELL_DISRUPTION:
|
||||
me->CastSpell(me, SPELL_MAGIC_DISRUPTION_AURA, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_DISRUPTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_epoch_hunter()
|
||||
{
|
||||
new boss_epoch_hunter();
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "SmartScriptMgr.h"
|
||||
|
||||
enum LieutenantDrake
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_SLAY = 2,
|
||||
SAY_MORTAL = 3,
|
||||
SAY_SHOUT = 4,
|
||||
SAY_DEATH = 5,
|
||||
|
||||
SPELL_WHIRLWIND = 31909,
|
||||
SPELL_EXPLODING_SHOT = 33792,
|
||||
SPELL_HAMSTRING = 9080,
|
||||
SPELL_MORTAL_STRIKE = 31911,
|
||||
SPELL_FRIGHTENING_SHOUT = 33789,
|
||||
|
||||
EVENT_WHIRLWIND = 1,
|
||||
EVENT_FRIGHTENING_SHOUT = 2,
|
||||
EVENT_MORTAL_STRIKE = 3,
|
||||
EVENT_HAMSTRING = 4,
|
||||
EVENT_EXPLODING_SHOT = 5
|
||||
};
|
||||
|
||||
class boss_lieutenant_drake : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_lieutenant_drake() : CreatureScript("boss_lieutenant_drake") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_lieutenant_drakeAI(creature);
|
||||
}
|
||||
|
||||
struct boss_lieutenant_drakeAI : public ScriptedAI
|
||||
{
|
||||
boss_lieutenant_drakeAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
pathPoints.clear();
|
||||
WPPath* path = sSmartWaypointMgr->GetPath(me->GetEntry());
|
||||
if (!path || path->empty())
|
||||
return;
|
||||
|
||||
pathPoints.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
|
||||
|
||||
uint32 wpCounter = 1;
|
||||
WPPath::const_iterator itr;
|
||||
while ((itr = path->find(wpCounter++)) != path->end())
|
||||
{
|
||||
WayPoint* wp = itr->second;
|
||||
pathPoints.push_back(G3D::Vector3(wp->x, wp->y, wp->z));
|
||||
}
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
ScriptedAI::InitializeAI();
|
||||
//Talk(SAY_ENTER);
|
||||
JustReachedHome();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
me->SetWalk(true);
|
||||
Movement::MoveSplineInit init(me);
|
||||
init.MovebyPath(pathPoints);
|
||||
init.SetCyclic();
|
||||
init.Launch();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 4000);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 14000);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 9000);
|
||||
events.ScheduleEvent(EVENT_HAMSTRING, 18000);
|
||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 1000);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_DRAKE_KILLED);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_WHIRLWIND:
|
||||
me->CastSpell(me, SPELL_WHIRLWIND, false);
|
||||
events.ScheduleEvent(EVENT_WHIRLWIND, 25000);
|
||||
break;
|
||||
case EVENT_EXPLODING_SHOT:
|
||||
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 40.0f))
|
||||
me->CastSpell(target, SPELL_EXPLODING_SHOT, false);
|
||||
events.ScheduleEvent(EVENT_EXPLODING_SHOT, 25000);
|
||||
break;
|
||||
case EVENT_MORTAL_STRIKE:
|
||||
if (roll_chance_i(40))
|
||||
Talk(SAY_MORTAL);
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_STRIKE, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_STRIKE, 10000);
|
||||
break;
|
||||
case EVENT_FRIGHTENING_SHOUT:
|
||||
if (roll_chance_i(40))
|
||||
Talk(SAY_SHOUT);
|
||||
me->CastSpell(me, SPELL_FRIGHTENING_SHOUT, false);
|
||||
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, 25000);
|
||||
break;
|
||||
case EVENT_HAMSTRING:
|
||||
me->CastSpell(me->GetVictim(), SPELL_HAMSTRING, false);
|
||||
events.ScheduleEvent(EVENT_HAMSTRING, 25000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
Movement::PointsArray pathPoints;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_boss_lieutenant_drake()
|
||||
{
|
||||
new boss_lieutenant_drake();
|
||||
}
|
||||
@@ -1,345 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "Player.h"
|
||||
|
||||
const Position instancePositions[INSTANCE_POSITIONS_COUNT] =
|
||||
{
|
||||
{2188.18f, 228.90f, 53.025f, 1.77f}, // Orcs Gather Point 1
|
||||
{2103.23f, 93.55f, 53.096f, 3.78f}, // Orcs Gather Point 2
|
||||
{2128.43f, 71.01f, 64.42f, 1.74f} // Lieutenant Drake Summon Position
|
||||
};
|
||||
|
||||
const Position thrallPositions[THRALL_POSITIONS_COUNT] =
|
||||
{
|
||||
{2181.37f, 119.15f, 89.45f, 5.75f}, // After wearing armor
|
||||
{2096.09f, 195.91f, 65.22f, 2.45f}, // After Fourth Ambush
|
||||
{2062.9f, 229.93f, 64.454f, 2.45f}, // After Captain Skarloc death
|
||||
{2486.91f, 626.356f, 58.0761f, 0.0f}, // Arrived at Tarren Mill
|
||||
{2660.47f, 659.223f, 62.0f, 5.78f} // Taretha Met
|
||||
|
||||
};
|
||||
|
||||
class instance_old_hillsbrad : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_old_hillsbrad() : InstanceMapScript("instance_old_hillsbrad", 560) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_old_hillsbrad_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_old_hillsbrad_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_old_hillsbrad_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
_encounterProgress = 0;
|
||||
_barrelCount = 0;
|
||||
_attemptsCount = 0;
|
||||
|
||||
_thrallGUID = 0;
|
||||
_tarethaGUID = 0;
|
||||
|
||||
_initalFlamesSet.clear();
|
||||
_finalFlamesSet.clear();
|
||||
_prisonersSet.clear();
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() == 1)
|
||||
CleanupInstance();
|
||||
|
||||
EnsureGridLoaded();
|
||||
|
||||
if (_encounterProgress < ENCOUNTER_PROGRESS_BARRELS)
|
||||
player->SendUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, _barrelCount);
|
||||
}
|
||||
|
||||
void CleanupInstance()
|
||||
{
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_NONE)
|
||||
return;
|
||||
|
||||
_events.ScheduleEvent(EVENT_INITIAL_BARRELS_FLAME, 0);
|
||||
_events.ScheduleEvent(EVENT_FINAL_BARRELS_FLAME, 0);
|
||||
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_BARRELS)
|
||||
_events.ScheduleEvent(EVENT_SUMMON_LIEUTENANT, 0);
|
||||
else
|
||||
SetData(DATA_THRALL_REPOSITION, 2);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_THRALL:
|
||||
_thrallGUID = creature->GetGUID();
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
else
|
||||
Reposition(creature);
|
||||
break;
|
||||
case NPC_ORC_PRISONER:
|
||||
_prisonersSet.insert(creature->GetGUID());
|
||||
break;
|
||||
case NPC_TARETHA:
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_FINISHED)
|
||||
creature->SetVisible(false);
|
||||
_tarethaGUID = creature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject)
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_BARREL:
|
||||
if (_encounterProgress >= ENCOUNTER_PROGRESS_BARRELS)
|
||||
gameobject->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE);
|
||||
break;
|
||||
case GO_PRISON_DOOR:
|
||||
if (_encounterProgress >= ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ROARING_FLAME:
|
||||
// Xinef: hack in DB to distinguish final / initial flames
|
||||
if (gameobject->GetPhaseMask() & 0x2)
|
||||
_finalFlamesSet.insert(gameobject->GetGUID());
|
||||
else
|
||||
_initalFlamesSet.insert(gameobject->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case DATA_THRALL_REPOSITION:
|
||||
if (data > 1)
|
||||
_events.ScheduleEvent(EVENT_THRALL_REPOSITION, data == 2 ? 0 : 10000);
|
||||
else if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
Reposition(thrall);
|
||||
return;
|
||||
case DATA_ESCORT_PROGRESS:
|
||||
_encounterProgress = data;
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_BOMBS_PLACED:
|
||||
{
|
||||
if (_barrelCount >= 5 || _encounterProgress > ENCOUNTER_PROGRESS_NONE)
|
||||
return;
|
||||
|
||||
DoUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, ++_barrelCount);
|
||||
if (_barrelCount == 5)
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_INITIAL_BARRELS_FLAME, 4000);
|
||||
_events.ScheduleEvent(EVENT_FINAL_BARRELS_FLAME, 12000);
|
||||
_events.ScheduleEvent(EVENT_SUMMON_LIEUTENANT, 18000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DATA_THRALL_ADD_FLAG:
|
||||
if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
thrall->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 data) const
|
||||
{
|
||||
if (data == DATA_ESCORT_PROGRESS)
|
||||
return _encounterProgress;
|
||||
else if (data == DATA_ATTEMPTS_COUNT)
|
||||
return _attemptsCount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data) const
|
||||
{
|
||||
if (data == DATA_THRALL_GUID)
|
||||
return _thrallGUID;
|
||||
else if (data == DATA_TARETHA_GUID)
|
||||
return _tarethaGUID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
_events.Update(diff);
|
||||
switch (_events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_INITIAL_BARRELS_FLAME:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[0].GetPositionX(), instancePositions[0].GetPositionY());
|
||||
instance->LoadGrid(instancePositions[1].GetPositionX(), instancePositions[1].GetPositionY());
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _prisonersSet.begin(); itr != _prisonersSet.end(); ++itr)
|
||||
if (Creature* orc = instance->GetCreature(*itr))
|
||||
{
|
||||
uint8 index = orc->GetDistance(instancePositions[0]) < 80.0f ? 0 : 1;
|
||||
Position pos(instancePositions[index]);
|
||||
orc->MovePosition(pos, frand(1.0f, 3.0f) + 15.0f * (float)rand_norm(), (float)rand_norm() * static_cast<float>(2 * M_PI));
|
||||
orc->GetMotionMaster()->MovePoint(1, pos);
|
||||
orc->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _initalFlamesSet.begin(); itr != _initalFlamesSet.end(); ++itr)
|
||||
if (GameObject* gobject = instance->GetGameObject(*itr))
|
||||
{
|
||||
gobject->SetRespawnTime(0);
|
||||
gobject->UpdateObjectVisibility(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_FINAL_BARRELS_FLAME:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[0].GetPositionX(), instancePositions[0].GetPositionY());
|
||||
instance->LoadGrid(instancePositions[1].GetPositionX(), instancePositions[1].GetPositionY());
|
||||
|
||||
if (_encounterProgress == ENCOUNTER_PROGRESS_NONE)
|
||||
{
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(NPC_LODGE_QUEST_TRIGGER, 0);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _finalFlamesSet.begin(); itr != _finalFlamesSet.end(); ++itr)
|
||||
if (GameObject* gobject = instance->GetGameObject(*itr))
|
||||
{
|
||||
gobject->SetRespawnTime(0);
|
||||
gobject->UpdateObjectVisibility(true);
|
||||
}
|
||||
|
||||
for (std::set<uint64>::const_iterator itr = _prisonersSet.begin(); itr != _prisonersSet.end(); ++itr)
|
||||
if (Creature* orc = instance->GetCreature(*itr))
|
||||
if (roll_chance_i(25))
|
||||
orc->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
|
||||
SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_BARRELS);
|
||||
DoUpdateWorldState(WORLD_STATE_BARRELS_PLANTED, 0);
|
||||
break;
|
||||
}
|
||||
case EVENT_SUMMON_LIEUTENANT:
|
||||
{
|
||||
instance->LoadGrid(instancePositions[2].GetPositionX(), instancePositions[2].GetPositionY());
|
||||
if (Creature* drake = instance->SummonCreature(NPC_LIEUTENANT_DRAKE, instancePositions[2]))
|
||||
drake->AI()->Talk(0);
|
||||
}
|
||||
case EVENT_THRALL_REPOSITION:
|
||||
{
|
||||
if (Creature* thrall = instance->GetCreature(_thrallGUID))
|
||||
{
|
||||
if (!thrall->IsAlive())
|
||||
{
|
||||
++_attemptsCount;
|
||||
EnsureGridLoaded();
|
||||
thrall->SetVisible(false);
|
||||
Reposition(thrall);
|
||||
thrall->setDeathState(DEAD);
|
||||
thrall->Respawn();
|
||||
thrall->SetVisible(true);
|
||||
SaveToDB();
|
||||
}
|
||||
else
|
||||
thrall->AI()->Reset();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Reposition(Creature* thrall)
|
||||
{
|
||||
switch (uint32 data = GetData(DATA_ESCORT_PROGRESS))
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
thrall->UpdatePosition(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED], true);
|
||||
thrall->SetHomePosition(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED]);
|
||||
thrall->SetFacingTo(thrallPositions[data - ENCOUNTER_PROGRESS_THRALL_ARMORED].GetOrientation());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void EnsureGridLoaded()
|
||||
{
|
||||
for (uint8 i = 0; i < THRALL_POSITIONS_COUNT; ++i)
|
||||
instance->LoadGrid(thrallPositions[i].GetPositionX(), thrallPositions[i].GetPositionY());
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "O H " << _encounterProgress << ' ' << _attemptsCount;
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1;
|
||||
|
||||
if (dataHead1 == 'O' && dataHead2 == 'H')
|
||||
{
|
||||
_encounterProgress = data0;
|
||||
_attemptsCount = data1;
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounterProgress;
|
||||
uint32 _barrelCount;
|
||||
uint32 _attemptsCount;
|
||||
|
||||
uint64 _thrallGUID;
|
||||
uint64 _tarethaGUID;
|
||||
std::set<uint64> _initalFlamesSet;
|
||||
std::set<uint64> _finalFlamesSet;
|
||||
std::set<uint64> _prisonersSet;
|
||||
|
||||
EventMap _events;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_old_hillsbrad()
|
||||
{
|
||||
new instance_old_hillsbrad();
|
||||
}
|
||||
@@ -1,907 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "Player.h"
|
||||
|
||||
/*enum Erozion
|
||||
{
|
||||
QUEST_ENTRY_HILLSBRAD = 10282,
|
||||
QUEST_ENTRY_DIVERSION = 10283,
|
||||
QUEST_ENTRY_ESCAPE = 10284,
|
||||
QUEST_ENTRY_RETURN = 10285,
|
||||
ITEM_ENTRY_BOMBS = 25853
|
||||
};
|
||||
*/
|
||||
enum Says
|
||||
{
|
||||
SAY_START_EVENT_PART1 = 0,
|
||||
SAY_ARMORY = 1,
|
||||
SAY_SKARLOC_MEET = 2,
|
||||
SAY_SKARLOC_TAUNT = 3,
|
||||
SAY_START_EVENT_PART2 = 4,
|
||||
SAY_MOUNTS_UP = 5,
|
||||
SAY_CHURCH_END = 6,
|
||||
SAY_MEET_TARETHA = 7,
|
||||
SAY_EPOCH_WONDER = 8,
|
||||
SAY_EPOCH_KILL_TARETHA = 9,
|
||||
SAY_EVENT_COMPLETE = 10,
|
||||
SAY_RANDOM_LOW_HP = 11,
|
||||
SAY_RANDOM_DIE = 12,
|
||||
SAY_RANDOM_AGGRO = 13,
|
||||
SAY_RANDOM_KILL = 14,
|
||||
SAY_LEAVE_COMBAT = 15,
|
||||
SAY_KILL_ARMORER = 16,
|
||||
SAY_GO_ARMORED = 17,
|
||||
SAY_ENTER_CHURCH = 18,
|
||||
SAY_GREET_TARETHA = 19,
|
||||
SAY_CHAT_TARETHA1 = 20,
|
||||
|
||||
SAY_TARETHA_FREE = 0,
|
||||
SAY_TARETHA_ESCAPED = 1,
|
||||
SAY_TARETHA_TALK1 = 2,
|
||||
SAY_TARETHA_TALK2 = 3,
|
||||
|
||||
SAY_ARMORER_THRALL = 0,
|
||||
|
||||
SAY_LOOKOUT_SAW = 0,
|
||||
SAY_LOOKOUT_GO = 1,
|
||||
SAY_LOOKOUT_CHURCH = 2,
|
||||
SAY_LOOKOUT_INN = 3,
|
||||
|
||||
SAY_EPOCH_ENTER1 = 0,
|
||||
SAY_EPOCH_ENTER2 = 1,
|
||||
SAY_EPOCH_ENTER3 = 2,
|
||||
|
||||
SAY_EROZION_1 = 0,
|
||||
SAY_EROZION_2 = 1,
|
||||
SAY_EROZION_3 = 2,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_STRIKE = 14516,
|
||||
SPELL_SHIELD_BLOCK = 12169,
|
||||
SPELL_SUMMON_EROZION_IMAGE = 33954,
|
||||
|
||||
SPELL_SHADOW_PRISON = 33071,
|
||||
SPELL_SHADOW_SPIKE = 33125,
|
||||
|
||||
SPELL_TELEPORT = 34776,
|
||||
SPELL_MEMORY_WIPE = 33336,
|
||||
SPELL_MEMORY_WIPE_RESUME = 33337
|
||||
};
|
||||
|
||||
enum Npcs
|
||||
{
|
||||
NPC_TM_GUARDSMAN = 18092,
|
||||
NPC_TM_PROTECTOR = 18093,
|
||||
NPC_TM_LOOKOUT = 18094,
|
||||
|
||||
NPC_EPOCH_GUARDSMAN = 23175,
|
||||
NPC_EPOCH_PROTECTOR = 23179,
|
||||
NPC_EPOCH_LOOKOUT = 23177,
|
||||
|
||||
NPC_INFINITE_DEFILER = 18171,
|
||||
NPC_INFINITE_SABOTEUR = 18172,
|
||||
NPC_INFINITE_SLAYER = 18170
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
THRALL_WEAPON_ITEM = 927,
|
||||
THRALL_SHIELD_ITEM = 2129,
|
||||
THRALL_MODEL_UNEQUIPPED = 17292,
|
||||
THRALL_MODEL_EQUIPPED = 18165,
|
||||
|
||||
ACTION_SET_IMMUNE_FLAG = 1,
|
||||
ACTION_REMOVE_IMMUNE_FLAG = 2,
|
||||
ACTION_TRANSFORM = 3,
|
||||
ACTION_MOVE = 4,
|
||||
ACTION_START_COMBAT = 5
|
||||
};
|
||||
|
||||
#define SPEED_RUNNING 1.0f
|
||||
#define SPEED_MOUNTED 1.6f
|
||||
|
||||
enum Events
|
||||
{
|
||||
// Combat
|
||||
EVENT_CHECK_HEALTH = 1,
|
||||
EVENT_SPELL_STRIKE = 2,
|
||||
EVENT_SPELL_SHIELD_BLOCK = 3,
|
||||
|
||||
EVENT_OPEN_DOORS = 6,
|
||||
EVENT_START_WP = 7,
|
||||
|
||||
EVENT_SET_FACING = 9,
|
||||
EVENT_KILL_ARMORER = 10,
|
||||
EVENT_TALK_KILL_ARMORER = 11,
|
||||
|
||||
EVENT_DRESSING_KNEEL = 20,
|
||||
EVENT_DRESSING_ARMOR = 21,
|
||||
EVENT_DRESSING_STAND = 22,
|
||||
EVENT_DRESSING_AXE = 23,
|
||||
EVENT_DRESSING_SHIELD = 24,
|
||||
EVENT_DRESSING_TALK = 25,
|
||||
|
||||
EVENT_ENTER_MOUNT = 30,
|
||||
EVENT_TALK_START_RIDE = 31,
|
||||
|
||||
EVENT_LOOK_1 = 40,
|
||||
EVENT_MOVE_AROUND = 41,
|
||||
EVENT_LOOK_2 = 42,
|
||||
EVENT_LOOK_3 = 43,
|
||||
EVENT_SUMMON_GUARDS = 44,
|
||||
EVENT_SUMMON_TALK1 = 45,
|
||||
EVENT_SUMMON_TALK2 = 46,
|
||||
|
||||
EVENT_LOOK_4 = 50,
|
||||
EVENT_SUMMON_GUARDS_2 = 51,
|
||||
EVENT_SUMMON_TALK3 = 52,
|
||||
|
||||
EVENT_THRALL_TALK = 60,
|
||||
EVENT_SUMMON_CHRONO = 61,
|
||||
EVENT_THRALL_TALK_2 = 62,
|
||||
EVENT_TARETHA_FALL = 63,
|
||||
EVENT_THRALL_TALK_3 = 64,
|
||||
EVENT_THRALL_MOVE_DOWN = 65,
|
||||
|
||||
EVENT_EPOCH_INTRO = 70,
|
||||
EVENT_SUMMON_INFINITES = 71,
|
||||
EVENT_TRANSFORM = 72,
|
||||
EVENT_START_WAVE_1 = 73,
|
||||
EVENT_CHECK_WAVE_1 = 74,
|
||||
EVENT_CHECK_WAVE_2 = 75,
|
||||
EVENT_CHECK_WAVE_3 = 76,
|
||||
EVENT_CALL_EPOCH = 77,
|
||||
|
||||
EVENT_THRALL_FACE_TARETHA = 80,
|
||||
EVENT_THRALL_TALK_4 = 81,
|
||||
EVENT_TARETHA_TALK_1 = 82,
|
||||
EVENT_THRALL_TALK_5 = 83,
|
||||
EVENT_SUMMON_EROZION = 84,
|
||||
EVENT_EROZION_TALK_1 = 85,
|
||||
EVENT_EROZION_ACTION_1 = 86,
|
||||
EVENT_EROZION_TALK_2 = 87,
|
||||
EVENT_EROZION_ACTION_2 = 88,
|
||||
EVENT_EROZION_TALK_3 = 89,
|
||||
EVENT_THRALL_TALK_6 = 90,
|
||||
EVENT_THRALL_RUN_AWAY = 91,
|
||||
EVENT_TARETHA_TALK_2 = 92
|
||||
|
||||
};
|
||||
|
||||
class npc_thrall_old_hillsbrad : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_thrall_old_hillsbrad() : CreatureScript("npc_thrall_old_hillsbrad") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_thrall_old_hillsbradAI>(creature);
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
InstanceScript* instance = creature->GetInstanceScript();
|
||||
if (!instance)
|
||||
return true;
|
||||
|
||||
uint32 menuId = creature->GetCreatureTemplate()->GossipMenuId;
|
||||
if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_SKARLOC_KILLED)
|
||||
menuId = 7830;
|
||||
else if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_TARREN_MILL)
|
||||
menuId = 7840;
|
||||
else if (instance->GetData(DATA_ESCORT_PROGRESS) == ENCOUNTER_PROGRESS_TARETHA_MEET)
|
||||
menuId = 7853;
|
||||
|
||||
player->PrepareGossipMenu(creature, menuId, true);
|
||||
player->SendPreparedGossip(creature);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, Creature* creature, uint32 sender, uint32 action)
|
||||
{
|
||||
GossipMenuItemData const* gossipMenuItemData = player->PlayerTalkClass->GetGossipMenu().GetItemData(0);
|
||||
InstanceScript* instance = creature->GetInstanceScript();
|
||||
if (!instance || (gossipMenuItemData && gossipMenuItemData->GossipActionMenuId != 0))
|
||||
return false;
|
||||
|
||||
player->PlayerTalkClass->ClearMenus();
|
||||
player->CLOSE_GOSSIP_MENU();
|
||||
|
||||
creature->AI()->DoAction(instance->GetData(DATA_ESCORT_PROGRESS));
|
||||
creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct npc_thrall_old_hillsbradAI : public npc_escortAI
|
||||
{
|
||||
npc_thrall_old_hillsbradAI(Creature* creature) : npc_escortAI(creature), summons(me)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
switch (param)
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_DRAKE_KILLED:
|
||||
events.ScheduleEvent(EVENT_OPEN_DOORS, 0);
|
||||
events.ScheduleEvent(EVENT_START_WP, 3000);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
events.ScheduleEvent(EVENT_SUMMON_CHRONO, 0);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_2, 6000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_FALL, 11000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_3, 14000);
|
||||
events.ScheduleEvent(EVENT_THRALL_MOVE_DOWN, 17000);
|
||||
break;
|
||||
case NPC_TARETHA:
|
||||
events.ScheduleEvent(EVENT_THRALL_FACE_TARETHA, 0);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_4, 4000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_TALK_1, 13000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_5, 17000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_EROZION, 17500);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_1, 18000);
|
||||
events.ScheduleEvent(EVENT_EROZION_ACTION_1, 26000);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_2, 29000);
|
||||
events.ScheduleEvent(EVENT_EROZION_TALK_3, 42000);
|
||||
events.ScheduleEvent(EVENT_EROZION_ACTION_2, 47000);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK_6, 48000);
|
||||
events.ScheduleEvent(EVENT_THRALL_RUN_AWAY, 51000);
|
||||
events.ScheduleEvent(EVENT_TARETHA_TALK_2, 53000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointStart(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 30:
|
||||
Talk(SAY_START_EVENT_PART2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_START_EVENT_PART1);
|
||||
break;
|
||||
case 8:
|
||||
events.ScheduleEvent(EVENT_SET_FACING, 500);
|
||||
break;
|
||||
case 9:
|
||||
SetRun(false);
|
||||
events.ScheduleEvent(EVENT_KILL_ARMORER, 500);
|
||||
events.ScheduleEvent(EVENT_TALK_KILL_ARMORER, 4000);
|
||||
break;
|
||||
case 10:
|
||||
SetRun(true);
|
||||
events.ScheduleEvent(EVENT_DRESSING_KNEEL, 500);
|
||||
events.ScheduleEvent(EVENT_DRESSING_ARMOR, 3000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_STAND, 4000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_AXE, 7000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_SHIELD, 9000);
|
||||
events.ScheduleEvent(EVENT_DRESSING_TALK, 12000);
|
||||
break;
|
||||
case 13:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 16:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2147.43f, 122.194f, 76.422f, 0.67f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2146.27f, 126.13f, 76.241f, 0.60f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2142.62f, 120.38f, 75.862f, 0.48f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2141.74f, 123.95f, 75.732f, 0.24f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 18:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2138.37f, 167.98f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_WARDEN, 2142.76f, 173.62f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2140.96f, 168.64f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_VETERAN, 2142.53f, 171.03f, 66.23f, 2.59f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 22:
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2108.73f, 190.43f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2109.74f, 195.29f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_MAGE, 2107.74f, 192.59f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_DURNHOLDE_SENTRY, 2112.26f, 195.13f, 66.23f, 5.56f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 27:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_AMBUSHES_1);
|
||||
break;
|
||||
case 28:
|
||||
me->SummonCreature(NPC_CAPTAIN_SKARLOC, 1995.78f, 277.46f, 66.64f, 0.74f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case 29:
|
||||
SetEscortPaused(true);
|
||||
Talk(SAY_SKARLOC_MEET);
|
||||
break;
|
||||
case 30:
|
||||
events.ScheduleEvent(EVENT_ENTER_MOUNT, 3000);
|
||||
events.ScheduleEvent(EVENT_TALK_START_RIDE, 7000);
|
||||
break;
|
||||
case 59:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_TARREN_MILL);
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 7000);
|
||||
UnMountSelf();
|
||||
_mounted = false;
|
||||
SetRun(false);
|
||||
break;
|
||||
case 60:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
if (Creature* horse = me->FindNearestCreature(NPC_SKARLOC_MOUNT, 10.0f))
|
||||
horse->GetMotionMaster()->MovePoint(0, 2501.15f, 572.14f, 54.13f);
|
||||
|
||||
SetEscortPaused(true);
|
||||
SetRun(true);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case 64:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 67:
|
||||
events.ScheduleEvent(EVENT_LOOK_1, 500);
|
||||
events.ScheduleEvent(EVENT_MOVE_AROUND, 3500);
|
||||
events.ScheduleEvent(EVENT_LOOK_2, 5000);
|
||||
events.ScheduleEvent(EVENT_LOOK_3, 6700);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDS, 6000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK1, 6500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK2, 12000);
|
||||
break;
|
||||
case 82:
|
||||
events.ScheduleEvent(EVENT_LOOK_4, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_GUARDS_2, 1000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_TALK3, 1500);
|
||||
break;
|
||||
case 91:
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_INN);
|
||||
break;
|
||||
case 92:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 94:
|
||||
summons.DespawnAll();
|
||||
SetEscortPaused(true);
|
||||
SetRun(true);
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_TARETHA_MEET);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->AI()->Talk(SAY_TARETHA_ESCAPED);
|
||||
events.ScheduleEvent(EVENT_THRALL_TALK, 2000);
|
||||
break;
|
||||
case 101:
|
||||
SetEscortPaused(true);
|
||||
events.ScheduleEvent(EVENT_EPOCH_INTRO, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_INFINITES, 1500);
|
||||
events.ScheduleEvent(EVENT_TRANSFORM, 8000);
|
||||
events.ScheduleEvent(EVENT_START_WAVE_1, 25000);
|
||||
break;
|
||||
case 103:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_FINISHED);
|
||||
me->SetVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MountSelf()
|
||||
{
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
me->SetSpeed(MOVE_RUN, SPEED_MOUNTED);
|
||||
}
|
||||
|
||||
void UnMountSelf()
|
||||
{
|
||||
me->Dismount();
|
||||
me->SetSpeed(MOVE_RUN, SPEED_RUNNING);
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 point)
|
||||
{
|
||||
npc_escortAI::MovementInform(type, point);
|
||||
if (type == POINT_MOTION_TYPE && point == 0xFFFFFF /*POINT_LAST_POINT*/)
|
||||
{
|
||||
if (roll_chance_i(30))
|
||||
Talk(SAY_LEAVE_COMBAT);
|
||||
if (_mounted)
|
||||
MountSelf();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit*)
|
||||
{
|
||||
combatEvents.Reset();
|
||||
combatEvents.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
combatEvents.ScheduleEvent(EVENT_SPELL_SHIELD_BLOCK, 8000);
|
||||
combatEvents.ScheduleEvent(EVENT_SPELL_STRIKE, 2000);
|
||||
|
||||
if (roll_chance_i(50))
|
||||
Talk(SAY_RANDOM_AGGRO);
|
||||
|
||||
if (me->IsMounted())
|
||||
{
|
||||
_mounted = true;
|
||||
UnMountSelf();
|
||||
}
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_mounted = false;
|
||||
events.Reset();
|
||||
combatEvents.Reset();
|
||||
summons.DespawnAll();
|
||||
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
instance->SetData(DATA_THRALL_REPOSITION, 1);
|
||||
|
||||
uint32 data = instance->GetData(DATA_ESCORT_PROGRESS);
|
||||
if (data >= ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
ReorderInstance(data);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit*)
|
||||
{
|
||||
Talk(SAY_RANDOM_KILL);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
if (summon->GetEntry() == NPC_INFINITE_SLAYER || summon->GetEntry() == NPC_INFINITE_SABOTEUR || summon->GetEntry() == NPC_INFINITE_DEFILER)
|
||||
summon->GetMotionMaster()->MovePoint(10, 2634.25f, 672.01f, 54.445f);
|
||||
|
||||
summons.Summon(summon);
|
||||
}
|
||||
void SummonedCreatureDespawn(Creature* summon) { summons.Despawn(summon); }
|
||||
void SummonedCreatureDies(Creature* summon, Unit*) { summons.Despawn(summon); }
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
if (killer == me)
|
||||
return;
|
||||
|
||||
summons.DespawnAll();
|
||||
Talk(SAY_RANDOM_DIE);
|
||||
RemoveEscortState(STATE_ESCORT_ESCORTING);
|
||||
instance->SetData(DATA_THRALL_REPOSITION, 3);
|
||||
if (instance->GetData(DATA_ATTEMPTS_COUNT) < 20)
|
||||
me->CastSpell(me, SPELL_SUMMON_EROZION_IMAGE, true);
|
||||
else
|
||||
me->SetRespawnTime(DAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_OPEN_DOORS:
|
||||
if (GameObject* doors = me->FindNearestGameObject(GO_PRISON_DOOR, 10.0f))
|
||||
doors->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case EVENT_START_WP:
|
||||
Start(true, true);
|
||||
SetDespawnAtEnd(false);
|
||||
break;
|
||||
case EVENT_SET_FACING:
|
||||
if (Creature* armorer = me->FindNearestCreature(NPC_DURNHOLDE_ARMORER, 30.0f))
|
||||
{
|
||||
armorer->AI()->Talk(SAY_ARMORER_THRALL);
|
||||
armorer->SetFacingToObject(me);
|
||||
me->SetFacingToObject(armorer);
|
||||
}
|
||||
break;
|
||||
case EVENT_KILL_ARMORER:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK_UNARMED);
|
||||
if (Creature* armorer = me->FindNearestCreature(NPC_DURNHOLDE_ARMORER, 30.0f))
|
||||
armorer->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
break;
|
||||
case EVENT_TALK_KILL_ARMORER:
|
||||
Talk(SAY_KILL_ARMORER);
|
||||
break;
|
||||
case EVENT_DRESSING_KNEEL:
|
||||
me->SetFacingTo(2.61f);
|
||||
Talk(SAY_ARMORY);
|
||||
me->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
break;
|
||||
case EVENT_DRESSING_ARMOR:
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
break;
|
||||
case EVENT_DRESSING_STAND:
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
case EVENT_DRESSING_AXE:
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_ITEM);
|
||||
break;
|
||||
case EVENT_DRESSING_SHIELD:
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_ITEM);
|
||||
break;
|
||||
case EVENT_DRESSING_TALK:
|
||||
instance->SetData(DATA_ESCORT_PROGRESS, ENCOUNTER_PROGRESS_THRALL_ARMORED);
|
||||
Talk(SAY_GO_ARMORED);
|
||||
break;
|
||||
case EVENT_ENTER_MOUNT:
|
||||
MountSelf();
|
||||
if (Creature* mount = me->FindNearestCreature(NPC_SKARLOC_MOUNT, 10.0f))
|
||||
{
|
||||
me->SetFacingTo(mount->GetOrientation());
|
||||
mount->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
case EVENT_TALK_START_RIDE:
|
||||
Talk(SAY_MOUNTS_UP);
|
||||
break;
|
||||
case EVENT_LOOK_1:
|
||||
me->SetFacingTo(5.058f);
|
||||
break;
|
||||
case EVENT_MOVE_AROUND:
|
||||
me->GetMotionMaster()->MovePoint(0, 2477.146f, 695.041f, 55.801f);
|
||||
break;
|
||||
case EVENT_LOOK_2:
|
||||
me->SetFacingTo(2.297f);
|
||||
break;
|
||||
case EVENT_LOOK_3:
|
||||
me->SetFacingTo(0.64f);
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDS:
|
||||
SetRun(true);
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2501.34f, 700.80f, 55.573f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2503.02f, 699.11f, 55.57f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2503.04f, 702.495f, 50.63f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2504.72f, 700.806f, 55.62f, 3.92f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK1:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_SAW);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK2:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_GO);
|
||||
summons.DoAction(ACTION_REMOVE_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_LOOK_4:
|
||||
me->SetFacingTo(0.41f);
|
||||
Talk(SAY_ENTER_CHURCH);
|
||||
break;
|
||||
case EVENT_SUMMON_GUARDS_2:
|
||||
me->SummonCreature(NPC_TM_PROTECTOR, 2630.75f, 664.80f, 54.28f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_LOOKOUT, 2632.20f, 661.98f, 54.30f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2630.02f, 662.75f, 54.28f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_TM_GUARDSMAN, 2632.86f, 664.05f, 54.31f, 4.37f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
break;
|
||||
case EVENT_SUMMON_TALK3:
|
||||
if (Creature* summon = summons.GetCreatureWithEntry(NPC_TM_LOOKOUT))
|
||||
summon->AI()->Talk(SAY_LOOKOUT_CHURCH);
|
||||
break;
|
||||
case EVENT_THRALL_TALK:
|
||||
Talk(SAY_MEET_TARETHA);
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
break;
|
||||
case EVENT_SUMMON_CHRONO:
|
||||
if (Creature* epoch = me->SummonCreature(NPC_EPOCH_HUNTER, 2640.49f, 696.15f, 64.31f, 4.51f, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
{
|
||||
epoch->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER1);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_TALK_2:
|
||||
me->SetFacingTo(2.67f);
|
||||
Talk(SAY_EPOCH_WONDER);
|
||||
break;
|
||||
case EVENT_TARETHA_FALL:
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER2);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
{
|
||||
Taretha->CastSpell(Taretha, SPELL_SHADOW_SPIKE);
|
||||
Taretha->SetStandState(UNIT_STAND_STATE_DEAD);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_TALK_3:
|
||||
me->SetFacingTo(5.78f);
|
||||
Talk(SAY_EPOCH_KILL_TARETHA);
|
||||
break;
|
||||
case EVENT_THRALL_MOVE_DOWN:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case EVENT_EPOCH_INTRO:
|
||||
me->SetFacingTo(1.33f);
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
epoch->AI()->Talk(SAY_EPOCH_ENTER3);
|
||||
break;
|
||||
case EVENT_SUMMON_INFINITES:
|
||||
me->SummonCreature(NPC_EPOCH_LOOKOUT, 2647.57f, 701.17f, 56.215f, 4.3f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_EPOCH_GUARDSMAN, 2629.46f, 704.76f, 56.286f, 4.98f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_EPOCH_PROTECTOR, 2640.14f, 709.44f, 56.135f, 4.70f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
summons.DoAction(ACTION_MOVE);
|
||||
break;
|
||||
case EVENT_TRANSFORM:
|
||||
summons.DoAction(ACTION_TRANSFORM);
|
||||
summons.DoAction(ACTION_SET_IMMUNE_FLAG);
|
||||
break;
|
||||
case EVENT_START_WAVE_1:
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_1, 500);
|
||||
summons.DoAction(ACTION_REMOVE_IMMUNE_FLAG);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_1:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_INFINITE_SABOTEUR, 2599.57f, 683.72f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2599.57f, 677.0f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_DEFILER, 2592.57f, 680.0f, 55.975f, 0.05f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_2, 500);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_1, 500);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_2:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2642.62f, 701.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SLAYER, 2638.62f, 701.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_SABOTEUR, 2638.62f, 705.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
me->SummonCreature(NPC_INFINITE_DEFILER, 2642.62f, 705.43f, 55.965f, 4.46f, TEMPSUMMON_MANUAL_DESPAWN);
|
||||
summons.DoAction(ACTION_START_COMBAT);
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_3, 500);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_2, 500);
|
||||
break;
|
||||
case EVENT_CHECK_WAVE_3:
|
||||
if (summons.size() == 1)
|
||||
{
|
||||
me->SetHomePosition(2634.79f, 672.964f, 54.8577f, 1.33f);
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
events.ScheduleEvent(EVENT_CALL_EPOCH, 8000);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_WAVE_3, 500);
|
||||
break;
|
||||
case EVENT_CALL_EPOCH:
|
||||
if (Creature* epoch = summons.GetCreatureWithEntry(NPC_EPOCH_HUNTER))
|
||||
{
|
||||
epoch->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
epoch->GetMotionMaster()->MovePoint(0, *me, false, true);
|
||||
}
|
||||
break;
|
||||
case EVENT_THRALL_FACE_TARETHA:
|
||||
{
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(20156, 0);
|
||||
|
||||
me->SetFacingTo(5.76f);
|
||||
break;
|
||||
}
|
||||
case EVENT_THRALL_TALK_4:
|
||||
Talk(SAY_GREET_TARETHA);
|
||||
break;
|
||||
case EVENT_TARETHA_TALK_1:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->AI()->Talk(SAY_TARETHA_TALK1);
|
||||
break;
|
||||
case EVENT_THRALL_TALK_5:
|
||||
Talk(SAY_CHAT_TARETHA1);
|
||||
break;
|
||||
case EVENT_SUMMON_EROZION:
|
||||
if (Creature* erozion = me->SummonCreature(NPC_EROZION, 2646.31f, 680.01f, 55.36f, 3.76f, TEMPSUMMON_MANUAL_DESPAWN))
|
||||
erozion->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_1:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
{
|
||||
erozion->CastSpell(erozion, SPELL_TELEPORT, true);
|
||||
erozion->AI()->Talk(SAY_EROZION_1);
|
||||
}
|
||||
break;
|
||||
case EVENT_EROZION_ACTION_1:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->CastSpell(erozion, SPELL_MEMORY_WIPE, false);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_2:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->AI()->Talk(SAY_EROZION_2);
|
||||
break;
|
||||
case EVENT_EROZION_TALK_3:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->AI()->Talk(SAY_EROZION_3);
|
||||
break;
|
||||
case EVENT_EROZION_ACTION_2:
|
||||
if (Creature* erozion = summons.GetCreatureWithEntry(NPC_EROZION))
|
||||
erozion->CastSpell(erozion, SPELL_MEMORY_WIPE_RESUME, false);
|
||||
break;
|
||||
case EVENT_THRALL_TALK_6:
|
||||
Talk(SAY_EVENT_COMPLETE);
|
||||
break;
|
||||
case EVENT_THRALL_RUN_AWAY:
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
case EVENT_TARETHA_TALK_2:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
{
|
||||
Taretha->SetFacingTo(4.233f);
|
||||
Taretha->AI()->Talk(SAY_TARETHA_TALK2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateEscortAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
combatEvents.Update(diff);
|
||||
switch (combatEvents.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH:
|
||||
if (me->HealthBelowPct(20))
|
||||
{
|
||||
Talk(SAY_RANDOM_LOW_HP);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH, 500);
|
||||
break;
|
||||
case EVENT_SPELL_STRIKE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_STRIKE, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_STRIKE, 6000);
|
||||
break;
|
||||
case EVENT_SPELL_SHIELD_BLOCK:
|
||||
me->CastSpell(me, SPELL_SHIELD_BLOCK, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_SHIELD_BLOCK, 6000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void ReorderInstance(uint32 data)
|
||||
{
|
||||
Start(true, true);
|
||||
SetEscortPaused(true);
|
||||
SetDespawnAtEnd(false);
|
||||
|
||||
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP|UNIT_NPC_FLAG_QUESTGIVER);
|
||||
|
||||
if (data < ENCOUNTER_PROGRESS_THRALL_ARMORED)
|
||||
{
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);
|
||||
me->SetDisplayId(THRALL_MODEL_UNEQUIPPED);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_ITEM);
|
||||
me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_ITEM);
|
||||
}
|
||||
|
||||
switch (data)
|
||||
{
|
||||
case ENCOUNTER_PROGRESS_THRALL_ARMORED:
|
||||
SetNextWaypoint(11, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_AMBUSHES_1:
|
||||
SetNextWaypoint(27, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_SKARLOC_KILLED:
|
||||
me->SummonCreature(NPC_SKARLOC_MOUNT, 2049.12f, 252.31f, 62.855f, me->GetOrientation(), TEMPSUMMON_MANUAL_DESPAWN);
|
||||
SetNextWaypoint(30, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARREN_MILL:
|
||||
SetNextWaypoint(61, false);
|
||||
break;
|
||||
case ENCOUNTER_PROGRESS_TARETHA_MEET:
|
||||
SetNextWaypoint(95, false);
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_TARETHA_GUID)))
|
||||
Taretha->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
EventMap combatEvents;
|
||||
SummonList summons;
|
||||
|
||||
bool _mounted;
|
||||
};
|
||||
};
|
||||
|
||||
class npc_taretha : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_taretha() : CreatureScript("npc_taretha") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return GetInstanceAI<npc_tarethaAI>(creature);
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player, Creature* creature)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
struct npc_tarethaAI : public npc_escortAI
|
||||
{
|
||||
npc_tarethaAI(Creature* creature) : npc_escortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
me->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
me->RemoveAllAuras();
|
||||
Start(false, true);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 waypointId)
|
||||
{
|
||||
if (waypointId == 7)
|
||||
{
|
||||
SetRun(false);
|
||||
Talk(SAY_TARETHA_FREE);
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_THRALL_GUID)))
|
||||
thrall->AI()->DoAction(me->GetEntry());
|
||||
}
|
||||
else if (waypointId == 9)
|
||||
me->SetVisible(false);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE);
|
||||
me->CastSpell(me, SPELL_SHADOW_PRISON, true);
|
||||
}
|
||||
|
||||
void AttackStart(Unit*) { }
|
||||
void MoveInLineOfSight(Unit*) { }
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_old_hillsbrad()
|
||||
{
|
||||
new npc_thrall_old_hillsbrad();
|
||||
new npc_taretha();
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_OLD_HILLSBRAD_H
|
||||
#define DEF_OLD_HILLSBRAD_H
|
||||
|
||||
enum DataIds
|
||||
{
|
||||
DATA_ESCORT_PROGRESS = 0,
|
||||
|
||||
DATA_BOMBS_PLACED = 10,
|
||||
DATA_THRALL_REPOSITION = 11,
|
||||
DATA_THRALL_ADD_FLAG = 12,
|
||||
DATA_THRALL_GUID = 13,
|
||||
DATA_TARETHA_GUID = 14,
|
||||
DATA_ATTEMPTS_COUNT = 15
|
||||
};
|
||||
|
||||
enum NpcIds
|
||||
{
|
||||
NPC_EROZION = 18723,
|
||||
NPC_THRALL = 17876,
|
||||
NPC_TARETHA = 18887,
|
||||
NPC_EPOCH_HUNTER = 18096,
|
||||
NPC_LIEUTENANT_DRAKE = 17848,
|
||||
|
||||
NPC_LODGE_QUEST_TRIGGER = 20155,
|
||||
NPC_ORC_PRISONER = 18598,
|
||||
|
||||
NPC_DURNHOLDE_ARMORER = 18764,
|
||||
NPC_DURNHOLDE_WARDEN = 17833,
|
||||
NPC_DURNHOLDE_VETERAN = 17860,
|
||||
NPC_DURNHOLDE_MAGE = 17860,
|
||||
NPC_DURNHOLDE_SENTRY = 17860,
|
||||
|
||||
NPC_CAPTAIN_SKARLOC = 17862,
|
||||
NPC_SKARLOC_MOUNT = 18798,
|
||||
|
||||
NPC_LORDAERON_SENTRY = 17815,
|
||||
NPC_LORDAERON_WATCHMAN = 17814,
|
||||
};
|
||||
|
||||
enum GobjectIds
|
||||
{
|
||||
GO_BARREL = 182589,
|
||||
GO_ROARING_FLAME = 182592,
|
||||
GO_PRISON_DOOR = 184393
|
||||
};
|
||||
|
||||
enum MiscIds
|
||||
{
|
||||
QUEST_DIVERSION = 10283,
|
||||
WORLD_STATE_BARRELS_PLANTED = 2436,
|
||||
SKARLOC_MOUNT_MODEL = 18223,
|
||||
|
||||
ENCOUNTER_PROGRESS_NONE = 0,
|
||||
ENCOUNTER_PROGRESS_BARRELS = 1,
|
||||
ENCOUNTER_PROGRESS_DRAKE_KILLED = 2,
|
||||
ENCOUNTER_PROGRESS_THRALL_ARMORED = 3,
|
||||
ENCOUNTER_PROGRESS_AMBUSHES_1 = 4,
|
||||
ENCOUNTER_PROGRESS_SKARLOC_KILLED = 5,
|
||||
ENCOUNTER_PROGRESS_TARREN_MILL = 6,
|
||||
ENCOUNTER_PROGRESS_TARETHA_MEET = 7,
|
||||
ENCOUNTER_PROGRESS_EPOCH_KILLED = 8,
|
||||
ENCOUNTER_PROGRESS_FINISHED = 9,
|
||||
|
||||
EVENT_INITIAL_BARRELS_FLAME = 1,
|
||||
EVENT_FINAL_BARRELS_FLAME = 2,
|
||||
EVENT_SUMMON_LIEUTENANT = 3,
|
||||
EVENT_THRALL_REPOSITION = 4,
|
||||
|
||||
INSTANCE_POSITIONS_COUNT = 3,
|
||||
THRALL_POSITIONS_COUNT = 5
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_FRENZY = 5,
|
||||
|
||||
SPELL_CLEAVE = 40504,
|
||||
SPELL_TIME_STOP = 31422,
|
||||
SPELL_ENRAGE = 37605,
|
||||
SPELL_SAND_BREATH = 31473,
|
||||
SPELL_CORRUPT_MEDIVH = 37853,
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_SANDBREATH = 1,
|
||||
EVENT_TIMESTOP = 2,
|
||||
EVENT_FRENZY = 3,
|
||||
EVENT_CLEAVE = 4
|
||||
};
|
||||
|
||||
class boss_aeonus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_aeonus() : CreatureScript("boss_aeonus") { }
|
||||
|
||||
struct boss_aeonusAI : public ScriptedAI
|
||||
{
|
||||
boss_aeonusAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
if (me->GetDistance2d(medivh) < 20.0f)
|
||||
me->CastSpell(me, SPELL_CORRUPT_MEDIVH, false);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
Talk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
{
|
||||
me->SetHomePosition(medivh->GetPositionX() + 14.0f*cos(medivh->GetAngle(me)), medivh->GetPositionY() + 14.0f*sin(medivh->GetAngle(me)), medivh->GetPositionZ(), me->GetAngle(medivh));
|
||||
me->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 5000);
|
||||
events.ScheduleEvent(EVENT_SANDBREATH, 20000);
|
||||
events.ScheduleEvent(EVENT_TIMESTOP, 15000);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000);
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
Talk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
instance->SetData(TYPE_AEONUS, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CLEAVE:
|
||||
me->CastSpell(me->GetVictim(), SPELL_CLEAVE, false);
|
||||
events.ScheduleEvent(EVENT_CLEAVE, 10000);
|
||||
break;
|
||||
case EVENT_SANDBREATH:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAND_BREATH, false);
|
||||
events.ScheduleEvent(EVENT_SANDBREATH, 20000);
|
||||
break;
|
||||
case EVENT_TIMESTOP:
|
||||
me->CastSpell(me, SPELL_TIME_STOP, false);
|
||||
events.ScheduleEvent(EVENT_TIMESTOP, 25000);
|
||||
break;
|
||||
case EVENT_FRENZY:
|
||||
Talk(EMOTE_FRENZY);
|
||||
me->CastSpell(me, SPELL_ENRAGE, false);
|
||||
events.ScheduleEvent(EVENT_FRENZY, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_aeonusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_aeonus()
|
||||
{
|
||||
new boss_aeonus();
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SPELL_ARCANE_BLAST = 31457,
|
||||
SPELL_ARCANE_DISCHARGE = 31472,
|
||||
SPELL_TIME_LAPSE = 31467,
|
||||
SPELL_ATTRACTION = 38540,
|
||||
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_ARCANE_BLAST = 1,
|
||||
EVENT_TIME_LAPSE = 2,
|
||||
EVENT_ARCANE_DISCHARGE = 3,
|
||||
EVENT_ATTRACTION = 4
|
||||
};
|
||||
|
||||
class boss_chrono_lord_deja : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_chrono_lord_deja() : CreatureScript("boss_chrono_lord_deja") { }
|
||||
|
||||
struct boss_chrono_lord_dejaAI : public ScriptedAI
|
||||
{
|
||||
boss_chrono_lord_dejaAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void OwnTalk(uint32 id)
|
||||
{
|
||||
if (me->GetEntry() == NPC_CHRONO_LORD_DEJA)
|
||||
Talk(id);
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
OwnTalk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_ARCANE_BLAST, 10000);
|
||||
events.ScheduleEvent(EVENT_TIME_LAPSE, 15000);
|
||||
events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, 25000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_ATTRACTION, 20000);
|
||||
|
||||
OwnTalk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
OwnTalk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
OwnTalk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
OwnTalk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(TYPE_CHRONO_LORD_DEJA, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_ARCANE_BLAST:
|
||||
me->CastSpell(me->GetVictim(), SPELL_ARCANE_BLAST, false);
|
||||
events.ScheduleEvent(EVENT_ARCANE_BLAST, 20000);
|
||||
break;
|
||||
case EVENT_TIME_LAPSE:
|
||||
me->CastSpell(me, SPELL_TIME_LAPSE, false);
|
||||
events.ScheduleEvent(EVENT_TIME_LAPSE, 20000);
|
||||
break;
|
||||
case EVENT_ARCANE_DISCHARGE:
|
||||
me->CastSpell(me, SPELL_ARCANE_DISCHARGE, false);
|
||||
events.ScheduleEvent(EVENT_ARCANE_DISCHARGE, 25000);
|
||||
break;
|
||||
case EVENT_ATTRACTION:
|
||||
me->CastSpell(me, SPELL_ATTRACTION, false);
|
||||
events.ScheduleEvent(EVENT_ATTRACTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_chrono_lord_dejaAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_chrono_lord_deja()
|
||||
{
|
||||
new boss_chrono_lord_deja();
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "the_black_morass.h"
|
||||
|
||||
enum Enums
|
||||
{
|
||||
SAY_ENTER = 0,
|
||||
SAY_AGGRO = 1,
|
||||
SAY_BANISH = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
|
||||
SPELL_HASTEN = 31458,
|
||||
SPELL_MORTAL_WOUND = 31464,
|
||||
SPELL_WING_BUFFET = 31475,
|
||||
SPELL_REFLECT = 38592,
|
||||
SPELL_BANISH_DRAGON_HELPER = 31550
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_HASTEN = 1,
|
||||
EVENT_MORTAL_WOUND = 2,
|
||||
EVENT_WING_BUFFET = 3,
|
||||
EVENT_SPELL_REFLECTION = 4
|
||||
};
|
||||
|
||||
class boss_temporus : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_temporus() : CreatureScript("boss_temporus") { }
|
||||
|
||||
struct boss_temporusAI : public ScriptedAI
|
||||
{
|
||||
boss_temporusAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
EventMap events;
|
||||
|
||||
void OwnTalk(uint32 id)
|
||||
{
|
||||
if (me->GetEntry() == NPC_TEMPORUS)
|
||||
Talk(id);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
}
|
||||
|
||||
void InitializeAI()
|
||||
{
|
||||
OwnTalk(SAY_ENTER);
|
||||
ScriptedAI::InitializeAI();
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* /*who*/)
|
||||
{
|
||||
events.ScheduleEvent(EVENT_HASTEN, 12000);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 5000);
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, 20000);
|
||||
if (IsHeroic())
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 28000);
|
||||
|
||||
OwnTalk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
if (victim->GetTypeId() == TYPEID_PLAYER)
|
||||
OwnTalk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/)
|
||||
{
|
||||
OwnTalk(SAY_DEATH);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
instance->SetData(TYPE_TEMPORUS, DONE);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (who->GetTypeId() == TYPEID_UNIT && who->GetEntry() == NPC_TIME_KEEPER)
|
||||
{
|
||||
if (me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
OwnTalk(SAY_BANISH);
|
||||
me->CastSpell(me, SPELL_BANISH_DRAGON_HELPER, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_HASTEN:
|
||||
me->CastSpell(me, SPELL_HASTEN, false);
|
||||
events.ScheduleEvent(EVENT_HASTEN, 20000);
|
||||
break;
|
||||
case EVENT_MORTAL_WOUND:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MORTAL_WOUND, false);
|
||||
events.ScheduleEvent(EVENT_MORTAL_WOUND, 10000);
|
||||
break;
|
||||
case EVENT_WING_BUFFET:
|
||||
me->CastSpell(me, SPELL_WING_BUFFET, false);
|
||||
events.ScheduleEvent(EVENT_WING_BUFFET, 20000);
|
||||
break;
|
||||
case EVENT_SPELL_REFLECTION:
|
||||
me->CastSpell(me, SPELL_REFLECT, false);
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 30000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new boss_temporusAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_temporus()
|
||||
{
|
||||
new boss_temporus();
|
||||
}
|
||||
@@ -1,341 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "the_black_morass.h"
|
||||
#include "Player.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "ScriptedCreature.h"
|
||||
|
||||
|
||||
const Position PortalLocation[4]=
|
||||
{
|
||||
{-2041.06f, 7042.08f, 29.99f, 1.30f},
|
||||
{-1968.18f, 7042.11f, 21.93f, 2.12f},
|
||||
{-1885.82f, 7107.36f, 22.32f, 3.07f},
|
||||
{-1928.11f, 7175.95f, 22.11f, 3.44f}
|
||||
};
|
||||
|
||||
class instance_the_black_morass : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
instance_the_black_morass() : InstanceMapScript("instance_the_black_morass", 269) { }
|
||||
|
||||
InstanceScript* GetInstanceScript(InstanceMap* map) const
|
||||
{
|
||||
return new instance_the_black_morass_InstanceMapScript(map);
|
||||
}
|
||||
|
||||
struct instance_the_black_morass_InstanceMapScript : public InstanceScript
|
||||
{
|
||||
instance_the_black_morass_InstanceMapScript(Map* map) : InstanceScript(map) { }
|
||||
|
||||
std::set<uint64> encounterNPCs;
|
||||
uint32 encounters[MAX_ENCOUNTER];
|
||||
uint64 _medivhGUID;
|
||||
uint8 _currentRift;
|
||||
uint8 _shieldPercent;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&encounters, 0, sizeof(encounters));
|
||||
_medivhGUID = 0;
|
||||
_currentRift = 0;
|
||||
_shieldPercent = 100;
|
||||
encounterNPCs.clear();
|
||||
}
|
||||
|
||||
void CleanupInstance()
|
||||
{
|
||||
Events.Reset();
|
||||
_currentRift = 0;
|
||||
_shieldPercent = 100;
|
||||
|
||||
instance->LoadGrid(-2023.0f, 7121.0f);
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
{
|
||||
medivh->DespawnOrUnsummon();
|
||||
medivh->SetRespawnTime(3);
|
||||
}
|
||||
|
||||
std::set<uint64> eCopy = encounterNPCs;
|
||||
for (std::set<uint64>::const_iterator itr = eCopy.begin(); itr != eCopy.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnPlayerEnter(Player* player)
|
||||
{
|
||||
if (instance->GetPlayersCountExceptGMs() <= 1 && GetData(TYPE_AEONUS) != DONE)
|
||||
CleanupInstance();
|
||||
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM, _currentRift > 0 ? 1 : 0);
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
player->SendUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_MEDIVH:
|
||||
_medivhGUID = creature->GetGUID();
|
||||
break;
|
||||
case NPC_TIME_RIFT:
|
||||
case NPC_CHRONO_LORD_DEJA:
|
||||
case NPC_INFINITE_CHRONO_LORD:
|
||||
case NPC_TEMPORUS:
|
||||
case NPC_INFINITE_TIMEREAVER:
|
||||
case NPC_AEONUS:
|
||||
case NPC_RIFT_KEEPER_WARLOCK:
|
||||
case NPC_RIFT_KEEPER_MAGE:
|
||||
case NPC_RIFT_LORD:
|
||||
case NPC_RIFT_LORD_2:
|
||||
case NPC_INFINITE_ASSASIN:
|
||||
case NPC_INFINITE_WHELP:
|
||||
case NPC_INFINITE_CRONOMANCER:
|
||||
case NPC_INFINITE_EXECUTIONER:
|
||||
case NPC_INFINITE_VANQUISHER:
|
||||
encounterNPCs.insert(creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnCreatureRemove(Creature* creature)
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_TIME_RIFT:
|
||||
case NPC_CHRONO_LORD_DEJA:
|
||||
case NPC_INFINITE_CHRONO_LORD:
|
||||
case NPC_TEMPORUS:
|
||||
case NPC_INFINITE_TIMEREAVER:
|
||||
case NPC_AEONUS:
|
||||
case NPC_RIFT_KEEPER_WARLOCK:
|
||||
case NPC_RIFT_KEEPER_MAGE:
|
||||
case NPC_RIFT_LORD:
|
||||
case NPC_RIFT_LORD_2:
|
||||
case NPC_INFINITE_ASSASIN:
|
||||
case NPC_INFINITE_WHELP:
|
||||
case NPC_INFINITE_CRONOMANCER:
|
||||
case NPC_INFINITE_EXECUTIONER:
|
||||
case NPC_INFINITE_VANQUISHER:
|
||||
encounterNPCs.erase(creature->GetGUID());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_AEONUS:
|
||||
{
|
||||
encounters[type] = DONE;
|
||||
SaveToDB();
|
||||
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
medivh->AI()->DoAction(ACTION_OUTRO);
|
||||
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
if (!players.isEmpty())
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource())
|
||||
{
|
||||
if (player->GetQuestStatus(QUEST_OPENING_PORTAL) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(QUEST_OPENING_PORTAL);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_MASTER_TOUCH) == QUEST_STATUS_INCOMPLETE)
|
||||
player->AreaExploredOrEventHappens(QUEST_MASTER_TOUCH);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_CHRONO_LORD_DEJA:
|
||||
case TYPE_TEMPORUS:
|
||||
encounters[type] = DONE;
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 60000);
|
||||
Events.SetPhase(1);
|
||||
SaveToDB();
|
||||
break;
|
||||
case DATA_RIFT_KILLED:
|
||||
if (!Events.IsInPhase(1))
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 4000);
|
||||
break;
|
||||
case DATA_MEDIVH:
|
||||
DoUpdateWorldState(WORLD_STATE_BM, 1);
|
||||
DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
Events.RescheduleEvent(EVENT_NEXT_PORTAL, 3000);
|
||||
break;
|
||||
case DATA_DAMAGE_SHIELD:
|
||||
--_shieldPercent;
|
||||
DoUpdateWorldState(WORLD_STATE_BM_SHIELD, _shieldPercent);
|
||||
if (!_shieldPercent)
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
if (medivh->IsAlive())
|
||||
{
|
||||
Unit::Kill(medivh, medivh);
|
||||
|
||||
// Xinef: delete all spawns
|
||||
std::set<uint64> eCopy = encounterNPCs;
|
||||
for (std::set<uint64>::iterator itr = eCopy.begin(); itr != eCopy.end(); ++itr)
|
||||
if (Creature* creature = instance->GetCreature(*itr))
|
||||
creature->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type) const
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_CHRONO_LORD_DEJA:
|
||||
case TYPE_TEMPORUS:
|
||||
case TYPE_AEONUS:
|
||||
return encounters[type];
|
||||
case DATA_SHIELD_PERCENT:
|
||||
return _shieldPercent;
|
||||
case DATA_RIFT_NUMBER:
|
||||
return _currentRift;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SetData64(uint32 type, uint64 data)
|
||||
{
|
||||
if (type == DATA_SUMMONED_NPC)
|
||||
encounterNPCs.insert(data);
|
||||
else if (type == DATA_DELETED_NPC)
|
||||
encounterNPCs.erase(data);
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data) const
|
||||
{
|
||||
if (data == DATA_MEDIVH)
|
||||
return _medivhGUID;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SummonPortalKeeper()
|
||||
{
|
||||
Creature* rift = NULL;
|
||||
for (std::set<uint64>::const_iterator itr = encounterNPCs.begin(); itr != encounterNPCs.end(); ++itr)
|
||||
if (Creature* summon = instance->GetCreature(*itr))
|
||||
if (summon->GetEntry() == NPC_TIME_RIFT)
|
||||
{
|
||||
rift = summon;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!rift)
|
||||
return;
|
||||
|
||||
int32 entry = 0;
|
||||
switch (_currentRift)
|
||||
{
|
||||
case 6: entry = GetData(TYPE_CHRONO_LORD_DEJA) == DONE ? (instance->IsHeroic() ? NPC_INFINITE_CHRONO_LORD : -NPC_CHRONO_LORD_DEJA) : NPC_CHRONO_LORD_DEJA; break;
|
||||
case 12: entry = GetData(TYPE_TEMPORUS) == DONE ? (instance->IsHeroic() ? NPC_INFINITE_TIMEREAVER : -NPC_TEMPORUS) : NPC_TEMPORUS; break;
|
||||
case 18: entry = NPC_AEONUS; break;
|
||||
default: entry = RAND(NPC_RIFT_KEEPER_WARLOCK, NPC_RIFT_KEEPER_MAGE, NPC_RIFT_LORD, NPC_RIFT_LORD_2); break;
|
||||
}
|
||||
|
||||
Position pos;
|
||||
rift->GetNearPosition(pos, 10.0f, 2*M_PI*rand_norm());
|
||||
|
||||
if (TempSummon* summon = instance->SummonCreature(abs(entry), pos))
|
||||
{
|
||||
summon->SetTempSummonType(TEMPSUMMON_CORPSE_TIMED_DESPAWN);
|
||||
summon->SetTimer(3*MINUTE*IN_MILLISECONDS);
|
||||
|
||||
if (entry < 0)
|
||||
summon->SetLootMode(0);
|
||||
|
||||
if (summon->GetEntry() != NPC_AEONUS)
|
||||
{
|
||||
rift->AI()->SetGUID(summon->GetGUID());
|
||||
rift->CastSpell(summon, SPELL_RIFT_CHANNEL, false);
|
||||
}
|
||||
else
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void Update(uint32 diff)
|
||||
{
|
||||
Events.Update(diff);
|
||||
switch (Events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_NEXT_PORTAL:
|
||||
++_currentRift;
|
||||
DoUpdateWorldState(WORLD_STATE_BM_RIFT, _currentRift);
|
||||
Events.ScheduleEvent(EVENT_SUMMON_KEEPER, 6000);
|
||||
Events.SetPhase(0);
|
||||
|
||||
if (Creature* medivh = instance->GetCreature(_medivhGUID))
|
||||
{
|
||||
uint8 position = (_currentRift-1)%4;
|
||||
instance->SummonCreature(NPC_TIME_RIFT, PortalLocation[position]);
|
||||
}
|
||||
break;
|
||||
case EVENT_SUMMON_KEEPER:
|
||||
SummonPortalKeeper();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "B M " << encounters[0] << ' ' << encounters[1] << ' ' << encounters[2];
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'B' && dataHead2 == 'M')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
loadStream >> encounters[i];
|
||||
}
|
||||
else
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
|
||||
protected:
|
||||
EventMap Events;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
void AddSC_instance_the_black_morass()
|
||||
{
|
||||
new instance_the_black_morass();
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "the_black_morass.h"
|
||||
#include "MoveSplineInit.h"
|
||||
|
||||
enum medivhSays
|
||||
{
|
||||
SAY_WEAK75 = 0,
|
||||
SAY_WEAK50 = 1,
|
||||
SAY_WEAK25 = 2,
|
||||
SAY_ENTER = 3,
|
||||
SAY_INTRO = 4,
|
||||
SAY_DEATH = 5,
|
||||
SAY_WIN = 6,
|
||||
SAY_ORCS_ENTER = 7,
|
||||
|
||||
SAY_ORCS_ANSWER = 0
|
||||
};
|
||||
|
||||
enum medivhSpells
|
||||
{
|
||||
SPELL_MANA_SHIELD = 31635,
|
||||
SPELL_MEDIVH_CHANNEL = 31556,
|
||||
SPELL_BLACK_CRYSTAL = 32563,
|
||||
SPELL_PORTAL_CRYSTALS = 32564,
|
||||
SPELL_BANISH_PURPLE = 32566,
|
||||
SPELL_BANISH_GREEN = 32567,
|
||||
|
||||
SPELL_CORRUPT = 31326,
|
||||
SPELL_CORRUPT_AEONUS = 37853,
|
||||
};
|
||||
|
||||
enum medivhMisc
|
||||
{
|
||||
NPC_DP_EMITTER_STALKER = 18582,
|
||||
NPC_DP_CRYSTAL_STALKER = 18553,
|
||||
NPC_SHADOW_COUNCIL_ENFORCER = 17023,
|
||||
GO_DARK_PORTAL = 185103,
|
||||
|
||||
EVENT_CHECK_HEALTH_25 = 1,
|
||||
EVENT_CHECK_HEALTH_50 = 2,
|
||||
EVENT_CHECK_HEALTH_75 = 3,
|
||||
EVENT_SUMMON_CRYSTAL = 4,
|
||||
EVENT_SUMMON_FLYING_CRYSTAL = 5,
|
||||
|
||||
EVENT_OUTRO_1 = 10,
|
||||
EVENT_OUTRO_2 = 11,
|
||||
EVENT_OUTRO_3 = 12,
|
||||
EVENT_OUTRO_4 = 13,
|
||||
EVENT_OUTRO_5 = 14,
|
||||
EVENT_OUTRO_6 = 15,
|
||||
EVENT_OUTRO_7 = 16,
|
||||
EVENT_OUTRO_8 = 17
|
||||
};
|
||||
|
||||
class NpcRunToHome : public BasicEvent
|
||||
{
|
||||
public:
|
||||
NpcRunToHome(Creature& owner) : _owner(owner) { }
|
||||
|
||||
bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
|
||||
{
|
||||
_owner.GetMotionMaster()->MoveTargetedHome();
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
Creature& _owner;
|
||||
};
|
||||
|
||||
class npc_medivh_bm : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_medivh_bm() : CreatureScript("npc_medivh_bm") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_medivh_bmAI(creature);
|
||||
}
|
||||
|
||||
struct npc_medivh_bmAI : public ScriptedAI
|
||||
{
|
||||
npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
|
||||
groundArray.clear();
|
||||
airArray.clear();
|
||||
|
||||
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ()));
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ()));
|
||||
for (uint8 i = 0; i < 10; ++i)
|
||||
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + 8.0f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ()));
|
||||
|
||||
for (uint8 i = 0; i < 40; ++i)
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX() + i*0.25f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + i*0.25f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ() + i/4.0f));
|
||||
for (uint8 i = 40; i < 80; ++i)
|
||||
airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f*cos(2.0f*M_PI*i/10.0f), creature->GetPositionY() + 10.0f*sin(2.0f*M_PI*i/10.0f), creature->GetPositionZ() + i/4.0f));
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
EventMap events;
|
||||
Movement::PointsArray groundArray;
|
||||
Movement::PointsArray airArray;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
me->CastSpell(me, SPELL_MANA_SHIELD, true);
|
||||
|
||||
if (instance->GetData(TYPE_AEONUS) != DONE)
|
||||
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
instance->SetData64(DATA_SUMMONED_NPC, summon->GetGUID());
|
||||
if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER)
|
||||
{
|
||||
summon->DespawnOrUnsummon(25000);
|
||||
summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true);
|
||||
summon->GetMotionMaster()->MoveSplinePath(&airArray);
|
||||
}
|
||||
else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER)
|
||||
{
|
||||
summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true);
|
||||
Movement::MoveSplineInit init(summon);
|
||||
init.MovebyPath(groundArray);
|
||||
init.SetCyclic();
|
||||
init.Launch();
|
||||
}
|
||||
}
|
||||
|
||||
void SummonedCreatureDespawn(Creature* summon)
|
||||
{
|
||||
instance->SetData64(DATA_DELETED_NPC, summon->GetGUID());
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who)
|
||||
{
|
||||
if (!events.Empty() || instance->GetData(TYPE_AEONUS) == DONE)
|
||||
return;
|
||||
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f))
|
||||
{
|
||||
Talk(SAY_ENTER);
|
||||
instance->SetData(DATA_MEDIVH, 1);
|
||||
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
|
||||
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_75, 500);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_50, 500);
|
||||
events.ScheduleEvent(EVENT_CHECK_HEALTH_25, 500);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 2000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 4000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_CRYSTAL, 6000);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 8000);
|
||||
}
|
||||
}
|
||||
|
||||
void AttackStart(Unit* ) { }
|
||||
|
||||
void DoAction(int32 param)
|
||||
{
|
||||
if (param == ACTION_OUTRO)
|
||||
{
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_OUTRO_1, 4000);
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
|
||||
me->SummonGameObject(GO_DARK_PORTAL, -2086.0f, 7125.6215f, 30.5f, 6.148f, 0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* )
|
||||
{
|
||||
me->SetRespawnTime(DAY);
|
||||
events.Reset();
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_CHECK_HEALTH_25:
|
||||
case EVENT_CHECK_HEALTH_50:
|
||||
case EVENT_CHECK_HEALTH_75:
|
||||
if (instance->GetData(DATA_SHIELD_PERCENT) <= eventId*25)
|
||||
{
|
||||
Talk(eventId-1);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(eventId, 500);
|
||||
break;
|
||||
case EVENT_SUMMON_CRYSTAL:
|
||||
me->SummonCreature(NPC_DP_EMITTER_STALKER, me->GetPositionX() + 8.0f, me->GetPositionY(), me->GetPositionZ());
|
||||
break;
|
||||
case EVENT_SUMMON_FLYING_CRYSTAL:
|
||||
me->CastSpell(me, SPELL_PORTAL_CRYSTALS, true);
|
||||
events.ScheduleEvent(EVENT_SUMMON_FLYING_CRYSTAL, 1000);
|
||||
break;
|
||||
case EVENT_OUTRO_1:
|
||||
me->SetFacingTo(6.21f);
|
||||
Talk(SAY_WIN);
|
||||
events.ScheduleEvent(EVENT_OUTRO_2, 17000);
|
||||
break;
|
||||
case EVENT_OUTRO_2:
|
||||
me->SetFacingTo(3.07f);
|
||||
events.ScheduleEvent(EVENT_OUTRO_3, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_3:
|
||||
SummonOrcs(-2046.158f, -3.0f, 37000, 30000, true);
|
||||
events.ScheduleEvent(EVENT_OUTRO_4, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_4:
|
||||
SummonOrcs(-2055.97f, -2.0f, 33000, 28000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_5, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_5:
|
||||
SummonOrcs(-2064.0f, -1.5f, 29000, 26000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_6, 2000);
|
||||
break;
|
||||
case EVENT_OUTRO_6:
|
||||
SummonOrcs(-2074.35f, -0.1f, 26000, 24000, false);
|
||||
events.ScheduleEvent(EVENT_OUTRO_7, 7000);
|
||||
break;
|
||||
case EVENT_OUTRO_7:
|
||||
Talk(SAY_ORCS_ENTER);
|
||||
events.ScheduleEvent(EVENT_OUTRO_8, 7000);
|
||||
break;
|
||||
case EVENT_OUTRO_8:
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_SHADOW_COUNCIL_ENFORCER, 20.0f))
|
||||
{
|
||||
cr->SetFacingTo(3.07f);
|
||||
cr->AI()->Talk(SAY_ORCS_ANSWER);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SummonOrcs(float x, float y, uint32 duration, uint32 homeTime, bool first)
|
||||
{
|
||||
for (uint8 i = 0; i < 6; ++i)
|
||||
{
|
||||
if (Creature* cr = me->SummonCreature(NPC_SHADOW_COUNCIL_ENFORCER, -2091.731f, 7133.083f - 3.0f*i, 34.589f, 0.0f))
|
||||
{
|
||||
cr->GetMotionMaster()->MovePoint(0, (first && i == 3) ? x+2.0f : x, cr->GetPositionY()+y, cr->GetMap()->GetHeight(x, cr->GetPositionY()+y, MAX_HEIGHT, true));
|
||||
cr->m_Events.AddEvent(new NpcRunToHome(*cr), cr->m_Events.CalculateTime(homeTime+urand(0, 2000)));
|
||||
cr->DespawnOrUnsummon(duration+urand(0, 2000));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
enum timeRift
|
||||
{
|
||||
EVENT_SUMMON_AT_RIFT = 1,
|
||||
EVENT_CHECK_DEATH = 2
|
||||
};
|
||||
|
||||
class npc_time_rift : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_time_rift() : CreatureScript("npc_time_rift") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const
|
||||
{
|
||||
return new npc_time_riftAI(creature);
|
||||
}
|
||||
|
||||
struct npc_time_riftAI : public NullCreatureAI
|
||||
{
|
||||
npc_time_riftAI(Creature* creature) : NullCreatureAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
riftKeeperGUID = 0;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
InstanceScript* instance;
|
||||
uint64 riftKeeperGUID;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (instance->GetData(DATA_RIFT_NUMBER) >= 18)
|
||||
{
|
||||
me->DespawnOrUnsummon(30000);
|
||||
return;
|
||||
}
|
||||
|
||||
events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 16000);
|
||||
events.ScheduleEvent(EVENT_CHECK_DEATH, 8000);
|
||||
}
|
||||
|
||||
void SetGUID(uint64 guid, int32)
|
||||
{
|
||||
riftKeeperGUID = guid;
|
||||
}
|
||||
|
||||
void DoSummonAtRift(uint32 entry)
|
||||
{
|
||||
Position pos;
|
||||
me->GetNearPosition(pos, 10.0f, 2*M_PI*rand_norm());
|
||||
|
||||
if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 15000))
|
||||
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetData64(DATA_MEDIVH)))
|
||||
{
|
||||
float o = medivh->GetAngle(summon)+frand(-1.0f, 1.0f);
|
||||
summon->SetHomePosition(medivh->GetPositionX() + 14.0f*cos(o), medivh->GetPositionY() + 14.0f*sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh));
|
||||
summon->GetMotionMaster()->MoveTargetedHome();
|
||||
summon->SetReactState(REACT_DEFENSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void DoSelectSummon()
|
||||
{
|
||||
uint32 entry = RAND(NPC_INFINITE_ASSASIN, NPC_INFINITE_WHELP, NPC_INFINITE_CRONOMANCER, NPC_INFINITE_EXECUTIONER, NPC_INFINITE_VANQUISHER);
|
||||
if (entry == NPC_INFINITE_WHELP)
|
||||
{
|
||||
DoSummonAtRift(entry);
|
||||
DoSummonAtRift(entry);
|
||||
DoSummonAtRift(entry);
|
||||
}
|
||||
else
|
||||
DoSummonAtRift(entry);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SUMMON_AT_RIFT:
|
||||
DoSelectSummon();
|
||||
events.ScheduleEvent(EVENT_SUMMON_AT_RIFT, 15000);
|
||||
break;
|
||||
case EVENT_CHECK_DEATH:
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
Creature* riftKeeper = ObjectAccessor::GetCreature(*me, riftKeeperGUID);
|
||||
if (!riftKeeper || !riftKeeper->IsAlive())
|
||||
{
|
||||
instance->SetData(DATA_RIFT_KILLED, 1);
|
||||
me->DespawnOrUnsummon(0);
|
||||
break;
|
||||
}
|
||||
else
|
||||
me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_CHECK_DEATH, 500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class spell_black_morass_corrupt_medivh : public SpellScriptLoader
|
||||
{
|
||||
public:
|
||||
spell_black_morass_corrupt_medivh() : SpellScriptLoader("spell_black_morass_corrupt_medivh") { }
|
||||
|
||||
class spell_black_morass_corrupt_medivh_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_black_morass_corrupt_medivh_AuraScript);
|
||||
|
||||
void PeriodicTick(AuraEffect const* /*aurEff*/)
|
||||
{
|
||||
if (InstanceScript* instance = GetUnitOwner()->GetInstanceScript())
|
||||
instance->SetData(DATA_DAMAGE_SHIELD, 1);
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
|
||||
}
|
||||
|
||||
InstanceScript* _instance;
|
||||
};
|
||||
|
||||
AuraScript* GetAuraScript() const
|
||||
{
|
||||
return new spell_black_morass_corrupt_medivh_AuraScript();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_the_black_morass()
|
||||
{
|
||||
new npc_medivh_bm();
|
||||
new npc_time_rift();
|
||||
new spell_black_morass_corrupt_medivh();
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
REWRITTEN BY XINEF
|
||||
*/
|
||||
|
||||
#ifndef DEF_THEBLACKMORASS_H
|
||||
#define DEF_THEBLACKMORASS_H
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_CHRONO_LORD_DEJA = 0,
|
||||
TYPE_TEMPORUS = 1,
|
||||
TYPE_AEONUS = 2,
|
||||
MAX_ENCOUNTER = 3,
|
||||
|
||||
DATA_MEDIVH = 10,
|
||||
DATA_RIFT_KILLED = 11,
|
||||
DATA_DAMAGE_SHIELD = 12,
|
||||
DATA_SHIELD_PERCENT = 13,
|
||||
DATA_RIFT_NUMBER = 14,
|
||||
|
||||
DATA_SUMMONED_NPC = 20,
|
||||
DATA_DELETED_NPC = 21,
|
||||
};
|
||||
|
||||
enum WorldStateIds
|
||||
{
|
||||
WORLD_STATE_BM = 2541,
|
||||
WORLD_STATE_BM_SHIELD = 2540,
|
||||
WORLD_STATE_BM_RIFT = 2784
|
||||
};
|
||||
|
||||
enum QuestIds
|
||||
{
|
||||
QUEST_OPENING_PORTAL = 10297,
|
||||
QUEST_MASTER_TOUCH = 9836
|
||||
};
|
||||
|
||||
enum CreatureIds
|
||||
{
|
||||
NPC_MEDIVH = 15608,
|
||||
NPC_TIME_RIFT = 17838,
|
||||
NPC_TIME_KEEPER = 17918,
|
||||
|
||||
NPC_RIFT_KEEPER_WARLOCK = 21104,
|
||||
NPC_RIFT_KEEPER_MAGE = 21148,
|
||||
NPC_RIFT_LORD = 17839,
|
||||
NPC_RIFT_LORD_2 = 21140,
|
||||
|
||||
NPC_CHRONO_LORD_DEJA = 17879,
|
||||
NPC_INFINITE_CHRONO_LORD = 21697,
|
||||
NPC_TEMPORUS = 17880,
|
||||
NPC_INFINITE_TIMEREAVER = 21698,
|
||||
NPC_AEONUS = 17881,
|
||||
|
||||
NPC_INFINITE_ASSASIN = 17835,
|
||||
NPC_INFINITE_WHELP = 21818,
|
||||
NPC_INFINITE_CRONOMANCER = 17892,
|
||||
NPC_INFINITE_EXECUTIONER = 18994,
|
||||
NPC_INFINITE_VANQUISHER = 18995
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
SPELL_RIFT_CHANNEL = 31387,
|
||||
|
||||
EVENT_NEXT_PORTAL = 1,
|
||||
EVENT_SUMMON_KEEPER = 2,
|
||||
|
||||
ACTION_OUTRO = 1
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user