mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-23 18:36:31 +01:00
Scripts/The Escape From Durnholde: Minor improvements
* Converted to BossAI * Prevent repeating boss kills on Thrall event wipe
This commit is contained in:
@@ -47,123 +47,110 @@ enum CaptainSkarloc
|
||||
SPELL_CONSECRATION = 38385
|
||||
};
|
||||
|
||||
class boss_captain_skarloc : public CreatureScript
|
||||
struct boss_captain_skarloc : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_captain_skarloc() : CreatureScript("boss_captain_skarloc") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_captain_skarloc(Creature* creature) : BossAI(creature, DATA_CAPTAIN_SKARLOC)
|
||||
{
|
||||
return GetOldHillsbradAI<boss_captain_skarlocAI>(creature);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
struct boss_captain_skarlocAI : public ScriptedAI
|
||||
void Initialize()
|
||||
{
|
||||
boss_captain_skarlocAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
Holy_Light_Timer = urand(20000, 30000);
|
||||
Cleanse_Timer = 10000;
|
||||
HammerOfJustice_Timer = urand(20000, 35000);
|
||||
HolyShield_Timer = 240000;
|
||||
DevotionAura_Timer = 3000;
|
||||
Consecration_Timer = 8000;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
uint32 Holy_Light_Timer;
|
||||
uint32 Cleanse_Timer;
|
||||
uint32 HammerOfJustice_Timer;
|
||||
uint32 HolyShield_Timer;
|
||||
uint32 DevotionAura_Timer;
|
||||
uint32 Consecration_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
//This is not correct. Should taunt Thrall before engage in combat
|
||||
Talk(SAY_TAUNT1);
|
||||
Talk(SAY_TAUNT2);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_HORSE_RIDE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Holy_Light
|
||||
if (Holy_Light_Timer <= diff)
|
||||
{
|
||||
Holy_Light_Timer = urand(20000, 30000);
|
||||
DoCast(me, SPELL_HOLY_LIGHT);
|
||||
Holy_Light_Timer = 30000;
|
||||
} else Holy_Light_Timer -= diff;
|
||||
|
||||
//Cleanse
|
||||
if (Cleanse_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CLEANSE);
|
||||
Cleanse_Timer = 10000;
|
||||
HammerOfJustice_Timer = urand(20000, 35000);
|
||||
} else Cleanse_Timer -= diff;
|
||||
|
||||
//Hammer of Justice
|
||||
if (HammerOfJustice_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_HAMMER_OF_JUSTICE);
|
||||
HammerOfJustice_Timer = 60000;
|
||||
} else HammerOfJustice_Timer -= diff;
|
||||
|
||||
//Holy Shield
|
||||
if (HolyShield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOLY_SHIELD);
|
||||
HolyShield_Timer = 240000;
|
||||
DevotionAura_Timer = 3000;
|
||||
Consecration_Timer = 8000;
|
||||
}
|
||||
} else HolyShield_Timer -= diff;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 Holy_Light_Timer;
|
||||
uint32 Cleanse_Timer;
|
||||
uint32 HammerOfJustice_Timer;
|
||||
uint32 HolyShield_Timer;
|
||||
uint32 DevotionAura_Timer;
|
||||
uint32 Consecration_Timer;
|
||||
|
||||
void Reset() override
|
||||
//Devotion_Aura
|
||||
if (DevotionAura_Timer <= diff)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
DoCast(me, SPELL_DEVOTION_AURA);
|
||||
DevotionAura_Timer = urand(45000, 55000);
|
||||
} else DevotionAura_Timer -= diff;
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
//Consecration
|
||||
if (Consecration_Timer <= diff)
|
||||
{
|
||||
//This is not correct. Should taunt Thrall before engage in combat
|
||||
Talk(SAY_TAUNT1);
|
||||
Talk(SAY_TAUNT2);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
|
||||
instance->SetData(TYPE_THRALL_PART1, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Holy_Light
|
||||
if (Holy_Light_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOLY_LIGHT);
|
||||
Holy_Light_Timer = 30000;
|
||||
} else Holy_Light_Timer -= diff;
|
||||
|
||||
//Cleanse
|
||||
if (Cleanse_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_CLEANSE);
|
||||
Cleanse_Timer = 10000;
|
||||
} else Cleanse_Timer -= diff;
|
||||
|
||||
//Hammer of Justice
|
||||
if (HammerOfJustice_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_HAMMER_OF_JUSTICE);
|
||||
HammerOfJustice_Timer = 60000;
|
||||
} else HammerOfJustice_Timer -= diff;
|
||||
|
||||
//Holy Shield
|
||||
if (HolyShield_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_HOLY_SHIELD);
|
||||
HolyShield_Timer = 240000;
|
||||
} else HolyShield_Timer -= diff;
|
||||
|
||||
//Devotion_Aura
|
||||
if (DevotionAura_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_DEVOTION_AURA);
|
||||
DevotionAura_Timer = urand(45000, 55000);
|
||||
} else DevotionAura_Timer -= diff;
|
||||
|
||||
//Consecration
|
||||
if (Consecration_Timer <= diff)
|
||||
{
|
||||
//DoCastVictim(SPELL_CONSECRATION);
|
||||
Consecration_Timer = urand(5000, 10000);
|
||||
} else Consecration_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
//DoCastVictim(SPELL_CONSECRATION);
|
||||
Consecration_Timer = urand(5000, 10000);
|
||||
} else Consecration_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_captain_skarloc()
|
||||
{
|
||||
new boss_captain_skarloc();
|
||||
RegisterOldHillsbradCreatureAI(boss_captain_skarloc);
|
||||
}
|
||||
|
||||
@@ -45,107 +45,94 @@ enum EpochHunter
|
||||
SPELL_WING_BUFFET = 31475
|
||||
};
|
||||
|
||||
class boss_epoch_hunter : public CreatureScript
|
||||
struct boss_epoch_hunter : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_epoch_hunter() : CreatureScript("boss_epoch_hunter") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_epoch_hunter(Creature* creature) : BossAI(creature, DATA_EPOCH_HUNTER)
|
||||
{
|
||||
return GetOldHillsbradAI<boss_epoch_hunterAI>(creature);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
struct boss_epoch_hunterAI : public ScriptedAI
|
||||
void Initialize()
|
||||
{
|
||||
boss_epoch_hunterAI(Creature* creature) : ScriptedAI(creature)
|
||||
SandBreath_Timer = urand(8000, 16000);
|
||||
ImpendingDeath_Timer = urand(25000, 30000);
|
||||
WingBuffet_Timer = 35000;
|
||||
Mda_Timer = 40000;
|
||||
}
|
||||
|
||||
uint32 SandBreath_Timer;
|
||||
uint32 ImpendingDeath_Timer;
|
||||
uint32 WingBuffet_Timer;
|
||||
uint32 Mda_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_FINISHED);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Sand Breath
|
||||
if (SandBreath_Timer <= diff)
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
if (me->IsNonMeleeSpellCast(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
void Initialize()
|
||||
DoCastVictim(SPELL_SAND_BREATH);
|
||||
|
||||
Talk(SAY_BREATH);
|
||||
|
||||
SandBreath_Timer = urand(10000, 20000);
|
||||
} else SandBreath_Timer -= diff;
|
||||
|
||||
if (ImpendingDeath_Timer <= diff)
|
||||
{
|
||||
SandBreath_Timer = urand(8000, 16000);
|
||||
ImpendingDeath_Timer = urand(25000, 30000);
|
||||
WingBuffet_Timer = 35000;
|
||||
Mda_Timer = 40000;
|
||||
}
|
||||
DoCastVictim(SPELL_IMPENDING_DEATH);
|
||||
ImpendingDeath_Timer = 25000 + rand32() % 5000;
|
||||
} else ImpendingDeath_Timer -= diff;
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
uint32 SandBreath_Timer;
|
||||
uint32 ImpendingDeath_Timer;
|
||||
uint32 WingBuffet_Timer;
|
||||
uint32 Mda_Timer;
|
||||
|
||||
void Reset() override
|
||||
if (WingBuffet_Timer <= diff)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_WING_BUFFET);
|
||||
WingBuffet_Timer = 25000 + rand32() % 10000;
|
||||
} else WingBuffet_Timer -= diff;
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
if (Mda_Timer <= diff)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
|
||||
instance->SetData(TYPE_THRALL_PART4, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Sand Breath
|
||||
if (SandBreath_Timer <= diff)
|
||||
{
|
||||
if (me->IsNonMeleeSpellCast(false))
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
|
||||
DoCastVictim(SPELL_SAND_BREATH);
|
||||
|
||||
Talk(SAY_BREATH);
|
||||
|
||||
SandBreath_Timer = urand(10000, 20000);
|
||||
} else SandBreath_Timer -= diff;
|
||||
|
||||
if (ImpendingDeath_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_IMPENDING_DEATH);
|
||||
ImpendingDeath_Timer = 25000 + rand32() % 5000;
|
||||
} else ImpendingDeath_Timer -= diff;
|
||||
|
||||
if (WingBuffet_Timer <= diff)
|
||||
{
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
DoCast(target, SPELL_WING_BUFFET);
|
||||
WingBuffet_Timer = 25000 + rand32() % 10000;
|
||||
} else WingBuffet_Timer -= diff;
|
||||
|
||||
if (Mda_Timer <= diff)
|
||||
{
|
||||
DoCast(me, SPELL_MAGIC_DISRUPTION_AURA);
|
||||
Mda_Timer = 15000;
|
||||
} else Mda_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
DoCast(me, SPELL_MAGIC_DISRUPTION_AURA);
|
||||
Mda_Timer = 15000;
|
||||
} else Mda_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_epoch_hunter()
|
||||
{
|
||||
new boss_epoch_hunter();
|
||||
RegisterOldHillsbradCreatureAI(boss_epoch_hunter);
|
||||
}
|
||||
|
||||
@@ -30,37 +30,6 @@ EndScriptData */
|
||||
#include "old_hillsbrad.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
|
||||
/*######
|
||||
## go_barrel_old_hillsbrad
|
||||
######*/
|
||||
|
||||
class go_barrel_old_hillsbrad : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
go_barrel_old_hillsbrad() : GameObjectScript("go_barrel_old_hillsbrad") { }
|
||||
|
||||
struct go_barrel_old_hillsbradAI : public GameObjectAI
|
||||
{
|
||||
go_barrel_old_hillsbradAI(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
bool OnGossipHello(Player* /*player*/) override
|
||||
{
|
||||
if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE)
|
||||
return false;
|
||||
|
||||
instance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
GameObjectAI* GetAI(GameObject* go) const override
|
||||
{
|
||||
return GetOldHillsbradAI<go_barrel_old_hillsbradAI>(go);
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## boss_lieutenant_drake
|
||||
######*/
|
||||
@@ -103,106 +72,117 @@ Position const DrakeWP[]=
|
||||
{ 2128.20f, 70.9763f, 64.4221f }
|
||||
};
|
||||
|
||||
class boss_lieutenant_drake : public CreatureScript
|
||||
struct boss_lieutenant_drake : public BossAI
|
||||
{
|
||||
public:
|
||||
boss_lieutenant_drake() : CreatureScript("boss_lieutenant_drake") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
boss_lieutenant_drake(Creature* creature) : BossAI(creature, DATA_LIEUTENANT_DRAKE)
|
||||
{
|
||||
return GetOldHillsbradAI<boss_lieutenant_drakeAI>(creature);
|
||||
Initialize();
|
||||
}
|
||||
|
||||
struct boss_lieutenant_drakeAI : public ScriptedAI
|
||||
void Initialize()
|
||||
{
|
||||
boss_lieutenant_drakeAI(Creature* creature) : ScriptedAI(creature)
|
||||
CanPatrol = true;
|
||||
wpId = 0;
|
||||
|
||||
Whirlwind_Timer = 20000;
|
||||
Fear_Timer = 30000;
|
||||
MortalStrike_Timer = 45000;
|
||||
ExplodingShout_Timer = 25000;
|
||||
}
|
||||
|
||||
bool CanPatrol;
|
||||
uint32 wpId;
|
||||
|
||||
uint32 Whirlwind_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 MortalStrike_Timer;
|
||||
uint32 ExplodingShout_Timer;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
Initialize();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
/// @todo make this work
|
||||
if (CanPatrol && wpId == 0)
|
||||
{
|
||||
Initialize();
|
||||
me->GetMotionMaster()->MovePoint(wpId, DrakeWP[wpId]);
|
||||
++wpId;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Whirlwind
|
||||
if (Whirlwind_Timer <= diff)
|
||||
{
|
||||
CanPatrol = true;
|
||||
wpId = 0;
|
||||
DoCastVictim(SPELL_WHIRLWIND);
|
||||
Whirlwind_Timer = 20000 + rand32() % 5000;
|
||||
} else Whirlwind_Timer -= diff;
|
||||
|
||||
Whirlwind_Timer = 20000;
|
||||
Fear_Timer = 30000;
|
||||
MortalStrike_Timer = 45000;
|
||||
ExplodingShout_Timer = 25000;
|
||||
}
|
||||
|
||||
bool CanPatrol;
|
||||
uint32 wpId;
|
||||
|
||||
uint32 Whirlwind_Timer;
|
||||
uint32 Fear_Timer;
|
||||
uint32 MortalStrike_Timer;
|
||||
uint32 ExplodingShout_Timer;
|
||||
|
||||
void Reset() override
|
||||
//Fear
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
Talk(SAY_SHOUT);
|
||||
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
|
||||
Fear_Timer = 25000 + rand32() % 10000;
|
||||
} else Fear_Timer -= diff;
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
//Mortal Strike
|
||||
if (MortalStrike_Timer <= diff)
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
}
|
||||
Talk(SAY_MORTAL);
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
MortalStrike_Timer = 20000 + rand32() % 10000;
|
||||
} else MortalStrike_Timer -= diff;
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
/*######
|
||||
## go_barrel_old_hillsbrad
|
||||
######*/
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
/// @todo make this work
|
||||
if (CanPatrol && wpId == 0)
|
||||
{
|
||||
me->GetMotionMaster()->MovePoint(wpId, DrakeWP[wpId]);
|
||||
++wpId;
|
||||
}
|
||||
struct go_barrel_old_hillsbrad : public GameObjectAI
|
||||
{
|
||||
go_barrel_old_hillsbrad(GameObject* go) : GameObjectAI(go), instance(go->GetInstanceScript()) { }
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
InstanceScript* instance;
|
||||
|
||||
//Whirlwind
|
||||
if (Whirlwind_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_WHIRLWIND);
|
||||
Whirlwind_Timer = 20000 + rand32() % 5000;
|
||||
} else Whirlwind_Timer -= diff;
|
||||
|
||||
//Fear
|
||||
if (Fear_Timer <= diff)
|
||||
{
|
||||
Talk(SAY_SHOUT);
|
||||
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
|
||||
Fear_Timer = 25000 + rand32() % 10000;
|
||||
} else Fear_Timer -= diff;
|
||||
|
||||
//Mortal Strike
|
||||
if (MortalStrike_Timer <= diff)
|
||||
{
|
||||
Talk(SAY_MORTAL);
|
||||
DoCastVictim(SPELL_MORTAL_STRIKE);
|
||||
MortalStrike_Timer = 20000 + rand32() % 10000;
|
||||
} else MortalStrike_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
bool OnGossipHello(Player* /*player*/) override
|
||||
{
|
||||
if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE)
|
||||
return false;
|
||||
|
||||
instance->SetData(TYPE_BARREL_DIVERSION, IN_PROGRESS);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_lieutenant_drake()
|
||||
{
|
||||
new go_barrel_old_hillsbrad();
|
||||
new boss_lieutenant_drake();
|
||||
RegisterOldHillsbradCreatureAI(boss_lieutenant_drake);
|
||||
RegisterOldHillsbradGameObjectAI(go_barrel_old_hillsbrad);
|
||||
}
|
||||
|
||||
@@ -23,14 +23,12 @@ SDCategory: Caverns of Time, Old Hillsbrad Foothills
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "Creature.h"
|
||||
#include "InstanceScript.h"
|
||||
#include "Log.h"
|
||||
#include "Map.h"
|
||||
#include "old_hillsbrad.h"
|
||||
#include "Player.h"
|
||||
|
||||
#define MAX_ENCOUNTER 6
|
||||
#include "TemporarySummon.h"
|
||||
|
||||
#define THRALL_ENTRY 17876
|
||||
#define TARETHA_ENTRY 18887
|
||||
@@ -56,13 +54,14 @@ public:
|
||||
instance_old_hillsbrad_InstanceMapScript(InstanceMap* map) : InstanceScript(map)
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
SetBossNumber(OldHillsbradFoothillsBossCount);
|
||||
|
||||
ThrallEscortState = OH_ESCORT_PRISON_TO_SKARLOC;
|
||||
mBarrelCount = 0;
|
||||
mThrallEventCount = 0;
|
||||
}
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
OHThrallEscortStates ThrallEscortState;
|
||||
uint32 mBarrelCount;
|
||||
uint32 mThrallEventCount;
|
||||
|
||||
@@ -70,23 +69,6 @@ public:
|
||||
ObjectGuid TarethaGUID;
|
||||
ObjectGuid EpochGUID;
|
||||
|
||||
Player* GetPlayerInMap()
|
||||
{
|
||||
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())
|
||||
return player;
|
||||
}
|
||||
}
|
||||
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: GetPlayerInMap, but PlayerList is empty!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UpdateQuestCredit()
|
||||
{
|
||||
Map::PlayerList const& players = instance->GetPlayers();
|
||||
@@ -119,14 +101,6 @@ public:
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
Player* player = GetPlayerInMap();
|
||||
|
||||
if (!player)
|
||||
{
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: SetData (Type: %u Data %u) cannot find any player.", type, data);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_BARREL_DIVERSION:
|
||||
@@ -141,62 +115,34 @@ public:
|
||||
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: go_barrel_old_hillsbrad count %u", mBarrelCount);
|
||||
|
||||
m_auiEncounter[0] = IN_PROGRESS;
|
||||
|
||||
if (mBarrelCount == 5)
|
||||
{
|
||||
UpdateQuestCredit();
|
||||
player->SummonCreature(DRAKE_ENTRY, 2128.43f, 71.01f, 64.42f, 1.74f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30min);
|
||||
m_auiEncounter[0] = DONE;
|
||||
if (TempSummon* drake = instance->SummonCreature(DRAKE_ENTRY, { 2128.43f, 71.01f, 64.42f, 1.74f }, nullptr, Milliseconds(30min).count()))
|
||||
drake->SetTempSummonType(TEMPSUMMON_DEAD_DESPAWN);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TYPE_THRALL_EVENT:
|
||||
{
|
||||
if (data == FAIL)
|
||||
if (data != OH_ESCORT_DEATH_EVENT)
|
||||
{
|
||||
if (mThrallEventCount <= 20)
|
||||
{
|
||||
++mThrallEventCount;
|
||||
m_auiEncounter[1] = NOT_STARTED;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.", mThrallEventCount);
|
||||
m_auiEncounter[2] = NOT_STARTED;
|
||||
m_auiEncounter[3] = NOT_STARTED;
|
||||
m_auiEncounter[4] = NOT_STARTED;
|
||||
m_auiEncounter[5] = NOT_STARTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_auiEncounter[1] = data;
|
||||
m_auiEncounter[2] = data;
|
||||
m_auiEncounter[3] = data;
|
||||
m_auiEncounter[4] = data;
|
||||
m_auiEncounter[5] = data;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event failed %u times. Resetting all sub-events.", mThrallEventCount);
|
||||
}
|
||||
ThrallEscortState = OHThrallEscortStates(data);
|
||||
if (Creature* thrall = instance->GetCreature(ThrallGUID))
|
||||
thrall->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
else
|
||||
m_auiEncounter[1] = data;
|
||||
{
|
||||
++mThrallEventCount;
|
||||
if (mThrallEventCount >= 20)
|
||||
ThrallEscortState = OH_ESCORT_FINISHED; // wipe limit reached
|
||||
else
|
||||
ThrallEscortState = OH_ESCORT_PRISON_TO_SKARLOC; // not correct, see npc_thrall_old_hillsbrad::InitializeAI for details
|
||||
}
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall escort event adjusted to data %u.", data);
|
||||
break;
|
||||
}
|
||||
case TYPE_THRALL_PART1:
|
||||
m_auiEncounter[2] = data;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part I adjusted to data %u.", data);
|
||||
break;
|
||||
case TYPE_THRALL_PART2:
|
||||
m_auiEncounter[3] = data;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part II adjusted to data %u.", data);
|
||||
break;
|
||||
case TYPE_THRALL_PART3:
|
||||
m_auiEncounter[4] = data;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part III adjusted to data %u.", data);
|
||||
break;
|
||||
case TYPE_THRALL_PART4:
|
||||
m_auiEncounter[5] = data;
|
||||
TC_LOG_DEBUG("scripts", "Instance Old Hillsbrad: Thrall event part IV adjusted to data %u.", data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,17 +151,9 @@ public:
|
||||
switch (data)
|
||||
{
|
||||
case TYPE_BARREL_DIVERSION:
|
||||
return m_auiEncounter[0];
|
||||
return mBarrelCount >= 5 ? DONE : IN_PROGRESS;
|
||||
case TYPE_THRALL_EVENT:
|
||||
return m_auiEncounter[1];
|
||||
case TYPE_THRALL_PART1:
|
||||
return m_auiEncounter[2];
|
||||
case TYPE_THRALL_PART2:
|
||||
return m_auiEncounter[3];
|
||||
case TYPE_THRALL_PART3:
|
||||
return m_auiEncounter[4];
|
||||
case TYPE_THRALL_PART4:
|
||||
return m_auiEncounter[5];
|
||||
return ThrallEscortState;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -228,13 +166,24 @@ public:
|
||||
return ThrallGUID;
|
||||
case DATA_TARETHA:
|
||||
return TarethaGUID;
|
||||
case DATA_EPOCH:
|
||||
case DATA_EPOCH_HUNTER:
|
||||
return EpochGUID;
|
||||
}
|
||||
return ObjectGuid::Empty;
|
||||
}
|
||||
};
|
||||
|
||||
void ReadSaveDataMore(std::istringstream&) override
|
||||
{
|
||||
if (GetBossState(DATA_LIEUTENANT_DRAKE) == DONE)
|
||||
mBarrelCount = 5;
|
||||
/* TODO not correct, see npc_thrall_old_hillsbrad::InitializeAI for details
|
||||
if (GetBossState(DATA_CAPTAIN_SKARLOC) == DONE)
|
||||
ThrallEscortState = OH_ESCORT_HORSE_RIDE;
|
||||
if (GetBossState(DATA_EPOCH_HUNTER) == DONE)
|
||||
ThrallEscortState = OH_ESCORT_FINISHED;
|
||||
*/
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void AddSC_instance_old_hillsbrad()
|
||||
|
||||
@@ -49,60 +49,53 @@ enum Erozion
|
||||
};
|
||||
#define GOSSIP_HELLO_EROZION2 "[PH] Teleport please, i'm tired." //not in DB,maybe incorrect?
|
||||
|
||||
Position const ThrallRespawnPositionAfterSkarloc(2062.934f, 229.14508f, 64.57113f, 2.338741064071655273);
|
||||
Position const ThrallRespawnPositionAfterHorseRide(2486.5637f, 624.09796f, 57.95088f, 4.136430263519287109);
|
||||
Position const ThrallRespawnPositionAfterMeetingTaretha(2660.0847f, 659.54816f, 62.020317f, 5.864306449890136718);
|
||||
|
||||
/*######
|
||||
## npc_erozion
|
||||
######*/
|
||||
|
||||
class npc_erozion : public CreatureScript
|
||||
struct npc_erozion : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_erozion() : CreatureScript("npc_erozion") { }
|
||||
npc_erozion(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
|
||||
|
||||
struct npc_erozionAI : public ScriptedAI
|
||||
InstanceScript* instance;
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
npc_erozionAI(Creature* creature) : ScriptedAI(creature), instance(creature->GetInstanceScript()) { }
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
ItemPosCountVec dest;
|
||||
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
{
|
||||
ItemPosCountVec dest;
|
||||
uint8 msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, ITEM_ENTRY_BOMBS, 1);
|
||||
if (msg == EQUIP_ERR_OK)
|
||||
{
|
||||
player->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true);
|
||||
}
|
||||
SendGossipMenuFor(player, 9515, me->GetGUID());
|
||||
player->StoreNewItem(dest, ITEM_ENTRY_BOMBS, true);
|
||||
}
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 2)
|
||||
CloseGossipMenuFor(player);
|
||||
return true;
|
||||
SendGossipMenuFor(player, 9515, me->GetGUID());
|
||||
}
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 2)
|
||||
CloseGossipMenuFor(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
if (me->IsQuestGiver())
|
||||
player->PrepareQuestMenu(me->GetGUID());
|
||||
|
||||
if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS))
|
||||
AddGossipItemFor(player, GOSSIP_MENU_EROZION, GOSSIP_OPTION_BOMB, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE)
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
|
||||
SendGossipMenuFor(player, 9778, me->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
return GetOldHillsbradAI<npc_erozionAI>(creature);
|
||||
if (me->IsQuestGiver())
|
||||
player->PrepareQuestMenu(me->GetGUID());
|
||||
|
||||
if (instance->GetData(TYPE_BARREL_DIVERSION) != DONE && !player->HasItemCount(ITEM_ENTRY_BOMBS))
|
||||
AddGossipItemFor(player, GOSSIP_MENU_EROZION, GOSSIP_OPTION_BOMB, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
if (player->GetQuestStatus(QUEST_ENTRY_RETURN) == QUEST_STATUS_COMPLETE)
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_HELLO_EROZION2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
|
||||
SendGossipMenuFor(player, 9778, me->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -191,355 +184,381 @@ enum ThrallOldHillsbrad
|
||||
#define SPEED_RUN (1.0f)
|
||||
#define SPEED_MOUNT (1.6f)
|
||||
|
||||
class npc_thrall_old_hillsbrad : public CreatureScript
|
||||
struct npc_thrall_old_hillsbrad : public EscortAI
|
||||
{
|
||||
public:
|
||||
npc_thrall_old_hillsbrad() : CreatureScript("npc_thrall_old_hillsbrad") { }
|
||||
|
||||
struct npc_thrall_old_hillsbradAI : public EscortAI
|
||||
npc_thrall_old_hillsbrad(Creature* creature) : EscortAI(creature)
|
||||
{
|
||||
npc_thrall_old_hillsbradAI(Creature* creature) : EscortAI(creature)
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
HadMount = false;
|
||||
me->setActive(true);
|
||||
me->SetFarVisible(true);
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
LowHp = false;
|
||||
}
|
||||
|
||||
void InitializeAI() override
|
||||
{
|
||||
/* correct respawn positions after wipe cannot be used because of how waypoints are set up for this creature
|
||||
* it would require splitting the path into 4 segments, moving it out of script_waypoint table and changing
|
||||
* all waypoint ids in WaypointReached function
|
||||
switch (instance->GetData(TYPE_THRALL_EVENT))
|
||||
{
|
||||
Initialize();
|
||||
instance = creature->GetInstanceScript();
|
||||
HadMount = false;
|
||||
me->setActive(true);
|
||||
me->SetFarVisible(true);
|
||||
case OH_ESCORT_HORSE_RIDE:
|
||||
me->Relocate(ThrallRespawnPositionAfterSkarloc);
|
||||
break;
|
||||
case OH_ESCORT_BARN_TO_TARETHA:
|
||||
me->Relocate(ThrallRespawnPositionAfterHorseRide);
|
||||
break;
|
||||
case OH_ESCORT_EPOCH_HUNTER:
|
||||
me->Relocate(ThrallRespawnPositionAfterMeetingTaretha);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) != OH_ESCORT_PRISON_TO_SKARLOC)
|
||||
{
|
||||
LowHp = false;
|
||||
me->SetVirtualItem(0, THRALL_WEAPON_ITEM);
|
||||
me->SetVirtualItem(1, THRALL_SHIELD_ITEM);
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
}
|
||||
*/
|
||||
|
||||
InstanceScript* instance;
|
||||
EscortAI::InitializeAI();
|
||||
me->SetRespawnCompatibilityMode(true);
|
||||
}
|
||||
|
||||
bool LowHp;
|
||||
bool HadMount;
|
||||
InstanceScript* instance;
|
||||
|
||||
void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
|
||||
bool LowHp;
|
||||
bool HadMount;
|
||||
|
||||
void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 8:
|
||||
SetRun(false);
|
||||
me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 9:
|
||||
Talk(SAY_TH_ARMORY);
|
||||
me->SetVirtualItem(0, THRALL_WEAPON_ITEM);
|
||||
me->SetVirtualItem(1, THRALL_SHIELD_ITEM);
|
||||
break;
|
||||
case 10:
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
break;
|
||||
case 11:
|
||||
SetRun();
|
||||
break;
|
||||
case 15:
|
||||
me->SummonCreature(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 21:
|
||||
me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 25:
|
||||
me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 29:
|
||||
Talk(SAY_TH_SKARLOC_MEET);
|
||||
case 8:
|
||||
SetRun(false);
|
||||
me->SummonCreature(18764, 2181.87f, 112.46f, 89.45f, 0.26f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 9:
|
||||
Talk(SAY_TH_ARMORY);
|
||||
me->SetVirtualItem(0, THRALL_WEAPON_ITEM);
|
||||
me->SetVirtualItem(1, THRALL_SHIELD_ITEM);
|
||||
break;
|
||||
case 10:
|
||||
me->SetDisplayId(THRALL_MODEL_EQUIPPED);
|
||||
break;
|
||||
case 11:
|
||||
SetRun();
|
||||
break;
|
||||
case 15:
|
||||
me->SummonCreature(NPC_RIFLE, 2200.28f, 137.37f, 87.93f, 5.07f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2197.44f, 131.83f, 87.93f, 0.78f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2203.62f, 135.40f, 87.93f, 3.70f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2200.75f, 130.13f, 87.93f, 1.48f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 21:
|
||||
me->SummonCreature(NPC_RIFLE, 2135.80f, 154.01f, 67.45f, 4.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2144.36f, 151.87f, 67.74f, 4.46f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2142.12f, 154.41f, 67.12f, 4.56f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2138.08f, 155.38f, 67.24f, 4.60f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 25:
|
||||
me->SummonCreature(NPC_RIFLE, 2102.98f, 192.17f, 65.24f, 6.02f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WARDEN, 2108.48f, 198.75f, 65.18f, 5.15f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2106.11f, 197.29f, 65.18f, 5.63f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_VETERAN, 2104.18f, 194.82f, 65.18f, 5.75f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 29:
|
||||
Talk(SAY_TH_SKARLOC_MEET);
|
||||
if (instance->GetBossState(DATA_CAPTAIN_SKARLOC) != DONE)
|
||||
me->SummonCreature(ENTRY_SCARLOC, 2036.48f, 271.22f, 63.43f, 5.27f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s);
|
||||
//temporary, skarloc should rather be triggered to walk up to thrall
|
||||
break;
|
||||
case 30:
|
||||
SetEscortPaused(true);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
SetRun(false);
|
||||
break;
|
||||
case 31:
|
||||
Talk(SAY_TH_MOUNTS_UP);
|
||||
DoMount();
|
||||
SetRun();
|
||||
break;
|
||||
case 37:
|
||||
//possibly regular patrollers? If so, remove this and let database handle them
|
||||
me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 59:
|
||||
me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10s);
|
||||
DoUnmount();
|
||||
HadMount = false;
|
||||
SetRun(false);
|
||||
break;
|
||||
case 60:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
//make horsie run off
|
||||
SetEscortPaused(true);
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
instance->SetData(TYPE_THRALL_PART2, DONE);
|
||||
SetRun();
|
||||
break;
|
||||
case 64:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 68:
|
||||
me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 71:
|
||||
SetRun();
|
||||
break;
|
||||
case 81:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 83:
|
||||
me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
break;
|
||||
case 84:
|
||||
Talk(SAY_TH_CHURCH_END);
|
||||
SetRun();
|
||||
break;
|
||||
case 91:
|
||||
me->SetWalk(true);
|
||||
SetRun(false);
|
||||
break;
|
||||
case 93:
|
||||
me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 94:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA)))
|
||||
Taretha->AI()->Talk(SAY_TA_ESCAPED, me);
|
||||
break;
|
||||
case 95:
|
||||
Talk(SAY_TH_MEET_TARETHA);
|
||||
instance->SetData(TYPE_THRALL_PART3, DONE);
|
||||
SetEscortPaused(true);
|
||||
break;
|
||||
case 96:
|
||||
Talk(SAY_TH_EPOCH_WONDER);
|
||||
break;
|
||||
case 97:
|
||||
Talk(SAY_TH_EPOCH_KILL_TARETHA);
|
||||
SetRun();
|
||||
break;
|
||||
case 98:
|
||||
//trigger epoch Yell("Thrall! Come outside and face your fate! ....")
|
||||
//from here, thrall should not never be allowed to move to point 106 which he currently does.
|
||||
break;
|
||||
case 106:
|
||||
{
|
||||
//trigger taretha to run down outside
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA)))
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
ENSURE_AI(EscortAI, (Taretha->AI()))->Start(false, true, player->GetGUID());
|
||||
}
|
||||
|
||||
//kill credit Creature for quest
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
{
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(20156);
|
||||
}
|
||||
|
||||
//alot will happen here, thrall and taretha talk, erozion appear at spot to explain
|
||||
me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 2min);
|
||||
}
|
||||
break;
|
||||
case 108:
|
||||
//last waypoint, just set Thrall invisible, respawn is turned off
|
||||
me->SetVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
Initialize();
|
||||
|
||||
if (HadMount)
|
||||
else
|
||||
{
|
||||
me->SetNpcFlag(UNIT_NPC_FLAG_GOSSIP); // wipe recovery, prevent repeatedly farming the boss
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_HORSE_RIDE);
|
||||
}
|
||||
SetEscortPaused(true);
|
||||
//temporary, skarloc should rather be triggered to walk up to thrall
|
||||
break;
|
||||
case 30:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 31:
|
||||
Talk(SAY_TH_MOUNTS_UP);
|
||||
HadMount = true;
|
||||
DoMount();
|
||||
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
SetRun();
|
||||
break;
|
||||
case 37:
|
||||
//possibly regular patrollers? If so, remove this and let database handle them
|
||||
me->SummonCreature(NPC_WATCHMAN, 2124.26f, 522.16f, 56.87f, 3.99f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_WATCHMAN, 2121.69f, 525.37f, 57.11f, 4.01f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_SENTRY, 2124.65f, 524.55f, 56.63f, 3.98f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 59:
|
||||
me->SummonCreature(SKARLOC_MOUNT, 2488.64f, 625.77f, 58.26f, 4.71f, TEMPSUMMON_TIMED_DESPAWN, 10s);
|
||||
DoUnmount();
|
||||
HadMount = false;
|
||||
me->SetVirtualItem(0, 0);
|
||||
me->SetVirtualItem(1, 0);
|
||||
me->SetDisplayId(THRALL_MODEL_UNEQUIPPED);
|
||||
}
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
Talk(SAY_TH_LEAVE_COMBAT);
|
||||
}
|
||||
}
|
||||
void StartWP()
|
||||
{
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
SetEscortPaused(false);
|
||||
}
|
||||
void DoMount()
|
||||
{
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT);
|
||||
}
|
||||
void DoUnmount()
|
||||
{
|
||||
me->Dismount();
|
||||
me->SetSpeedRate(MOVE_RUN, SPEED_RUN);
|
||||
}
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_AGGRO);
|
||||
if (me->IsMounted())
|
||||
{
|
||||
DoUnmount();
|
||||
HadMount = true;
|
||||
}
|
||||
SetRun(false);
|
||||
break;
|
||||
case 60:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
//make horsie run off
|
||||
SetEscortPaused(true);
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_BARN_TO_TARETHA);
|
||||
SetRun();
|
||||
break;
|
||||
case 64:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 68:
|
||||
me->SummonCreature(NPC_BARN_PROTECTOR, 2500.22f, 692.60f, 55.50f, 2.84f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_LOOKOUT, 2500.13f, 696.55f, 55.51f, 3.38f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.55f, 693.64f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_BARN_GUARDSMAN, 2500.94f, 695.81f, 55.50f, 3.14f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 71:
|
||||
SetRun();
|
||||
break;
|
||||
case 81:
|
||||
SetRun(false);
|
||||
break;
|
||||
case 83:
|
||||
me->SummonCreature(NPC_CHURCH_PROTECTOR, 2627.33f, 646.82f, 56.03f, 4.28f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_LOOKOUT, 2624.14f, 648.03f, 56.03f, 4.50f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2625.32f, 649.60f, 56.03f, 4.38f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
me->SummonCreature(NPC_CHURCH_GUARDSMAN, 2627.22f, 649.00f, 56.03f, 4.34f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 5s);
|
||||
break;
|
||||
case 84:
|
||||
Talk(SAY_TH_CHURCH_END);
|
||||
SetRun();
|
||||
break;
|
||||
case 91:
|
||||
me->SetWalk(true);
|
||||
SetRun(false);
|
||||
break;
|
||||
case 93:
|
||||
me->SummonCreature(NPC_INN_PROTECTOR, 2652.71f, 660.31f, 61.93f, 1.67f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_LOOKOUT, 2648.96f, 662.59f, 61.93f, 0.79f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_GUARDSMAN, 2657.36f, 662.34f, 61.93f, 2.68f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
me->SummonCreature(NPC_INN_GUARDSMAN, 2656.39f, 659.77f, 61.93f, 2.61f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5s);
|
||||
break;
|
||||
case 94:
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA)))
|
||||
Taretha->AI()->Talk(SAY_TA_ESCAPED, me);
|
||||
break;
|
||||
case 95:
|
||||
Talk(SAY_TH_MEET_TARETHA);
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_EPOCH_HUNTER);
|
||||
SetEscortPaused(true);
|
||||
break;
|
||||
case 96:
|
||||
Talk(SAY_TH_EPOCH_WONDER);
|
||||
break;
|
||||
case 97:
|
||||
Talk(SAY_TH_EPOCH_KILL_TARETHA);
|
||||
SetRun();
|
||||
break;
|
||||
case 98:
|
||||
//trigger epoch Yell("Thrall! Come outside and face your fate! ....")
|
||||
//from here, thrall should not never be allowed to move to point 106 which he currently does.
|
||||
break;
|
||||
case 106:
|
||||
{
|
||||
//trigger taretha to run down outside
|
||||
if (Creature* Taretha = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TARETHA)))
|
||||
{
|
||||
if (Player* player = GetPlayerForEscort())
|
||||
ENSURE_AI(EscortAI, (Taretha->AI()))->Start(false, true, player->GetGUID());
|
||||
}
|
||||
|
||||
//kill credit Creature for quest
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
{
|
||||
if (Player* player = itr->GetSource())
|
||||
player->KilledMonsterCredit(20156);
|
||||
}
|
||||
|
||||
//alot will happen here, thrall and taretha talk, erozion appear at spot to explain
|
||||
me->SummonCreature(EROZION_ENTRY, 2646.47f, 680.416f, 55.38f, 4.16f, TEMPSUMMON_TIMED_DESPAWN, 2min);
|
||||
}
|
||||
break;
|
||||
case 108:
|
||||
//last waypoint, just set Thrall invisible, respawn is turned off
|
||||
me->SetVisible(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
switch (summoned->GetEntry())
|
||||
{
|
||||
/// @todo make Scarloc start into event instead, and not start attack directly
|
||||
case NPC_BARN_GUARDSMAN:
|
||||
case NPC_BARN_PROTECTOR:
|
||||
case NPC_BARN_LOOKOUT:
|
||||
case SKARLOC_MOUNT:
|
||||
case EROZION_ENTRY:
|
||||
break;
|
||||
default:
|
||||
summoned->AI()->AttackStart(me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_KILL);
|
||||
}
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
instance->SetData(TYPE_THRALL_EVENT, FAIL);
|
||||
|
||||
// Don't do a yell if he kills self (if player goes too far or at the end).
|
||||
if (killer == me)
|
||||
return;
|
||||
|
||||
Talk(SAY_TH_RANDOM_DIE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
EscortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
/// @todo add his abilities'n-crap here
|
||||
if (!LowHp && HealthBelowPct(20))
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_LOW_HP);
|
||||
LowHp = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
CloseGossipMenuFor(player);
|
||||
instance->SetData(TYPE_THRALL_EVENT, IN_PROGRESS);
|
||||
instance->SetData(TYPE_THRALL_PART1, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_TH_START_EVENT_PART1);
|
||||
|
||||
Start(true, true, player->GetGUID());
|
||||
|
||||
SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far
|
||||
SetDespawnAtEnd(false);
|
||||
SetDespawnAtFar(false);
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC2_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC2, me->GetGUID());
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 20:
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC3, me->GetGUID());
|
||||
me->SummonCreature(SKARLOC_MOUNT, 2038.81f, 270.26f, 63.20f, 5.41f, TEMPSUMMON_TIMED_DESPAWN, 12s);
|
||||
instance->SetData(TYPE_THRALL_PART2, IN_PROGRESS);
|
||||
|
||||
Talk(SAY_TH_START_EVENT_PART2);
|
||||
|
||||
StartWP();
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
CloseGossipMenuFor(player);
|
||||
instance->SetData(TYPE_THRALL_PART3, IN_PROGRESS);
|
||||
StartWP();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
if (me->IsQuestGiver())
|
||||
{
|
||||
player->PrepareQuestMenu(me->GetGUID());
|
||||
player->SendPreparedQuest(me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetData(TYPE_BARREL_DIVERSION) == DONE && !instance->GetData(TYPE_THRALL_EVENT))
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_WALKING_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_START, me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_PART1) == DONE && !instance->GetData(TYPE_THRALL_PART2))
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC1_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC1, me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_PART2) == DONE && !instance->GetData(TYPE_THRALL_PART3))
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_TARREN_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_TARREN, me->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void Reset() override
|
||||
{
|
||||
return GetOldHillsbradAI<npc_thrall_old_hillsbradAI>(creature);
|
||||
Initialize();
|
||||
|
||||
if (HadMount)
|
||||
DoMount();
|
||||
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
DoUnmount();
|
||||
HadMount = false;
|
||||
me->SetVirtualItem(0, 0);
|
||||
me->SetVirtualItem(1, 0);
|
||||
me->SetDisplayId(THRALL_MODEL_UNEQUIPPED);
|
||||
}
|
||||
if (HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
Talk(SAY_TH_LEAVE_COMBAT);
|
||||
}
|
||||
}
|
||||
void StartWP()
|
||||
{
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
SetEscortPaused(false);
|
||||
}
|
||||
void DoMount()
|
||||
{
|
||||
me->Mount(SKARLOC_MOUNT_MODEL);
|
||||
me->SetSpeedRate(MOVE_RUN, SPEED_MOUNT);
|
||||
}
|
||||
void DoUnmount()
|
||||
{
|
||||
me->Dismount();
|
||||
me->SetSpeedRate(MOVE_RUN, SPEED_RUN);
|
||||
}
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_AGGRO);
|
||||
if (me->IsMounted())
|
||||
DoUnmount();
|
||||
}
|
||||
|
||||
void JustReachedHome() override
|
||||
{
|
||||
EscortAI::JustReachedHome();
|
||||
if (HadMount)
|
||||
DoMount();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summoned) override
|
||||
{
|
||||
switch (summoned->GetEntry())
|
||||
{
|
||||
/// @todo make Scarloc start into event instead, and not start attack directly
|
||||
case NPC_BARN_GUARDSMAN:
|
||||
case NPC_BARN_PROTECTOR:
|
||||
case NPC_BARN_LOOKOUT:
|
||||
case SKARLOC_MOUNT:
|
||||
case EROZION_ENTRY:
|
||||
break;
|
||||
default:
|
||||
summoned->AI()->AttackStart(me);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_KILL);
|
||||
}
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
instance->SetData(TYPE_THRALL_EVENT, OH_ESCORT_DEATH_EVENT);
|
||||
|
||||
// Don't do a yell if he kills self (if player goes too far or at the end).
|
||||
if (killer == me)
|
||||
return;
|
||||
|
||||
Talk(SAY_TH_RANDOM_DIE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
EscortAI::UpdateAI(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
/// @todo add his abilities'n-crap here
|
||||
if (!LowHp && HealthBelowPct(20))
|
||||
{
|
||||
Talk(SAY_TH_RANDOM_LOW_HP);
|
||||
LowHp = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
switch (action)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF + 1:
|
||||
CloseGossipMenuFor(player);
|
||||
|
||||
Talk(SAY_TH_START_EVENT_PART1);
|
||||
|
||||
Start(true, true, player->GetGUID());
|
||||
|
||||
SetMaxPlayerDistance(100.0f);//not really needed, because it will not despawn if player is too far
|
||||
SetDespawnAtEnd(false);
|
||||
SetDespawnAtFar(false);
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 2:
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC2_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC2, me->GetGUID());
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 20:
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC3, me->GetGUID());
|
||||
me->SummonCreature(SKARLOC_MOUNT, 2038.81f, 270.26f, 63.20f, 5.41f, TEMPSUMMON_TIMED_DESPAWN, 12s);
|
||||
|
||||
Talk(SAY_TH_START_EVENT_PART2);
|
||||
|
||||
StartWP();
|
||||
break;
|
||||
|
||||
case GOSSIP_ACTION_INFO_DEF + 3:
|
||||
CloseGossipMenuFor(player);
|
||||
StartWP();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
if (me->IsQuestGiver())
|
||||
{
|
||||
player->PrepareQuestMenu(me->GetGUID());
|
||||
player->SendPreparedQuest(me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetBossState(DATA_LIEUTENANT_DRAKE) == DONE && instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_PRISON_TO_SKARLOC)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_WALKING_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_START, me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_HORSE_RIDE)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_SKARLOC1_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_SKARLOC1, me->GetGUID());
|
||||
}
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_BARN_TO_TARETHA)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_TARREN_MID, GOSSIP_ITEM_DEFAULT_OP, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_TARREN, me->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -556,82 +575,64 @@ enum Taretha
|
||||
GOSSIP_ITEM_EPOCH2_OID = 0 //We'll get you out, Taretha. Don't worry. I doubt the wizard would wander too far away.
|
||||
};
|
||||
|
||||
class npc_taretha : public CreatureScript
|
||||
struct npc_taretha : public EscortAI
|
||||
{
|
||||
public:
|
||||
npc_taretha() : CreatureScript("npc_taretha") { }
|
||||
|
||||
struct npc_tarethaAI : public EscortAI
|
||||
npc_taretha(Creature* creature) : EscortAI(creature)
|
||||
{
|
||||
npc_tarethaAI(Creature* creature) : EscortAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
|
||||
InstanceScript* instance;
|
||||
InstanceScript* instance;
|
||||
|
||||
void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
|
||||
{
|
||||
switch (waypointId)
|
||||
{
|
||||
case 6:
|
||||
Talk(SAY_TA_FREE);
|
||||
break;
|
||||
case 7:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override { }
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
EscortAI::UpdateAI(diff);
|
||||
}
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_EPOCH2_MID, GOSSIP_ITEM_EPOCH2_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_EPOCH2, me->GetGUID());
|
||||
}
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 2)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == IN_PROGRESS)
|
||||
{
|
||||
instance->SetData(TYPE_THRALL_PART4, IN_PROGRESS);
|
||||
if (instance->GetGuidData(DATA_EPOCH).IsEmpty())
|
||||
me->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 2min);
|
||||
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THRALL)))
|
||||
ENSURE_AI(npc_thrall_old_hillsbrad::npc_thrall_old_hillsbradAI, thrall->AI())->StartWP();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
if (instance->GetData(TYPE_THRALL_PART3) == DONE && instance->GetData(TYPE_THRALL_PART4) == NOT_STARTED)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_EPOCH1_MID, GOSSIP_ITEM_EPOCH1_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_EPOCH1, me->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void WaypointReached(uint32 waypointId, uint32 /*pathId*/) override
|
||||
{
|
||||
return GetOldHillsbradAI<npc_tarethaAI>(creature);
|
||||
switch (waypointId)
|
||||
{
|
||||
case 6:
|
||||
Talk(SAY_TA_FREE);
|
||||
break;
|
||||
case 7:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_CHEER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override { }
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override
|
||||
{
|
||||
uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId);
|
||||
ClearGossipMenuFor(player);
|
||||
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 1)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_EPOCH2_MID, GOSSIP_ITEM_EPOCH2_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_EPOCH2, me->GetGUID());
|
||||
}
|
||||
if (action == GOSSIP_ACTION_INFO_DEF + 2)
|
||||
{
|
||||
CloseGossipMenuFor(player);
|
||||
|
||||
if (instance->GetGuidData(DATA_EPOCH_HUNTER).IsEmpty())
|
||||
me->SummonCreature(ENTRY_EPOCH, 2639.13f, 698.55f, 65.43f, 4.59f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 2min);
|
||||
|
||||
if (Creature* thrall = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_THRALL)))
|
||||
ENSURE_AI(npc_thrall_old_hillsbrad, thrall->AI())->StartWP();
|
||||
|
||||
me->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OnGossipHello(Player* player) override
|
||||
{
|
||||
if (instance->GetData(TYPE_THRALL_EVENT) == OH_ESCORT_EPOCH_HUNTER && instance->GetBossState(DATA_EPOCH_HUNTER) != DONE)
|
||||
{
|
||||
AddGossipItemFor(player, GOSSIP_ITEM_EPOCH1_MID, GOSSIP_ITEM_EPOCH1_OID, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
SendGossipMenuFor(player, GOSSIP_ID_EPOCH1, me->GetGUID());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -641,7 +642,7 @@ public:
|
||||
|
||||
void AddSC_old_hillsbrad()
|
||||
{
|
||||
new npc_erozion();
|
||||
new npc_thrall_old_hillsbrad();
|
||||
new npc_taretha();
|
||||
RegisterOldHillsbradCreatureAI(npc_erozion);
|
||||
RegisterOldHillsbradCreatureAI(npc_thrall_old_hillsbrad);
|
||||
RegisterOldHillsbradCreatureAI(npc_taretha);
|
||||
}
|
||||
|
||||
@@ -23,19 +23,19 @@
|
||||
#define OHScriptName "instance_old_hillsbrad"
|
||||
#define DataHeader "OH"
|
||||
|
||||
constexpr uint32 OldHillsbradFoothillsBossCount = 3;
|
||||
|
||||
enum OHDataTypes
|
||||
{
|
||||
TYPE_BARREL_DIVERSION = 1,
|
||||
TYPE_THRALL_EVENT = 2,
|
||||
TYPE_THRALL_PART1 = 3,
|
||||
TYPE_THRALL_PART2 = 4,
|
||||
TYPE_THRALL_PART3 = 5,
|
||||
TYPE_THRALL_PART4 = 6,
|
||||
DATA_LIEUTENANT_DRAKE = 0,
|
||||
DATA_CAPTAIN_SKARLOC = 1,
|
||||
DATA_EPOCH_HUNTER = 2,
|
||||
|
||||
DATA_THRALL = 7,
|
||||
DATA_TARETHA = 8,
|
||||
DATA_EPOCH = 9
|
||||
TYPE_BARREL_DIVERSION = 3,
|
||||
TYPE_THRALL_EVENT = 4,
|
||||
|
||||
DATA_THRALL = 5,
|
||||
DATA_TARETHA = 6
|
||||
};
|
||||
|
||||
enum OHWorldStateIds
|
||||
@@ -43,10 +43,24 @@ enum OHWorldStateIds
|
||||
WORLD_STATE_OH = 2436
|
||||
};
|
||||
|
||||
enum OHThrallEscortStates
|
||||
{
|
||||
OH_ESCORT_PRISON_TO_SKARLOC,
|
||||
OH_ESCORT_HORSE_RIDE,
|
||||
OH_ESCORT_BARN_TO_TARETHA,
|
||||
OH_ESCORT_EPOCH_HUNTER,
|
||||
OH_ESCORT_FINISHED,
|
||||
|
||||
OH_ESCORT_DEATH_EVENT // increment wipe counter
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetOldHillsbradAI(T* obj)
|
||||
{
|
||||
return GetInstanceAI<AI>(obj, OHScriptName);
|
||||
}
|
||||
|
||||
#define RegisterOldHillsbradCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetOldHillsbradAI)
|
||||
#define RegisterOldHillsbradGameObjectAI(ai_name) RegisterGameObjectAIWithFactory(ai_name, GetOldHillsbradAI)
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user