Conflicts:
	src/server/authserver/Main.cpp
	src/server/authserver/Server/AuthSession.cpp
	src/server/authserver/Server/AuthSession.h
	src/server/game/Server/WorldSocket.cpp
	src/server/game/Server/WorldSocket.h
	src/server/scripts/World/npcs_special.cpp
This commit is contained in:
Shauren
2014-09-12 20:26:46 +02:00
63 changed files with 2059 additions and 1305 deletions

View File

@@ -72,7 +72,7 @@ public:
void Reset() override
{
Initialize();
events.Reset();
summons.DespawnAll();
}

View File

@@ -30,12 +30,21 @@ enum Spells
SPELL_STORMPIKE = 51876 // not sure
};
enum Yells
enum Texts
{
YELL_AGGRO = 0,
YELL_EVADE = 1,
YELL_RESPAWN = 2,
YELL_RANDOM = 3
SAY_AGGRO = 0,
SAY_EVADE = 1,
SAY_RESPAWN = 2,
SAY_RANDOM = 3
};
enum Events
{
EVENT_WHIRLWIND = 1,
EVENT_WHIRLWIND2,
EVENT_KNOCKDOWN,
EVENT_FRENZY,
EVENT_RANDOM_YELL
};
class boss_drekthar : public CreatureScript
@@ -45,92 +54,85 @@ public:
struct boss_drektharAI : public ScriptedAI
{
boss_drektharAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
WhirlwindTimer = urand(1 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
Whirlwind2Timer = urand(1 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
KnockdownTimer = 12 * IN_MILLISECONDS;
FrenzyTimer = 6 * IN_MILLISECONDS;
ResetTimer = 5 * IN_MILLISECONDS;
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); //20 to 30 seconds
}
uint32 WhirlwindTimer;
uint32 Whirlwind2Timer;
uint32 KnockdownTimer;
uint32 FrenzyTimer;
uint32 YellTimer;
uint32 ResetTimer;
boss_drektharAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
Initialize();
events.Reset();
}
void EnterCombat(Unit* /*who*/) override
{
Talk(YELL_AGGRO);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_WHIRLWIND, urand(1 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_WHIRLWIND2, urand(1 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_KNOCKDOWN, 12 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_FRENZY, 6 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_RANDOM_YELL, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS)); //20 to 30 seconds
}
void JustRespawned() override
{
Reset();
Talk(YELL_RESPAWN);
Talk(SAY_RESPAWN);
}
bool CheckInRoom()
{
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(SAY_EVADE);
return false;
}
return true;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
if (!UpdateVictim() || !CheckInRoom())
return;
if (WhirlwindTimer <= diff)
{
DoCastVictim(SPELL_WHIRLWIND);
WhirlwindTimer = urand(8 * IN_MILLISECONDS, 18 * IN_MILLISECONDS);
} else WhirlwindTimer -= diff;
events.Update(diff);
if (Whirlwind2Timer <= diff)
{
DoCastVictim(SPELL_WHIRLWIND2);
Whirlwind2Timer = urand(7 * IN_MILLISECONDS, 25 * IN_MILLISECONDS);
} else Whirlwind2Timer -= diff;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (KnockdownTimer <= diff)
while (uint32 eventId = events.ExecuteEvent())
{
DoCastVictim(SPELL_KNOCKDOWN);
KnockdownTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
} else KnockdownTimer -= diff;
if (FrenzyTimer <= diff)
{
DoCastVictim(SPELL_FRENZY);
FrenzyTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS);
} else FrenzyTimer -= diff;
if (YellTimer <= diff)
{
Talk(YELL_RANDOM);
YellTimer = urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS); //20 to 30 seconds
} else YellTimer -= diff;
// check if creature is not outside of building
if (ResetTimer <= diff)
{
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
switch (eventId)
{
EnterEvadeMode();
Talk(YELL_EVADE);
case EVENT_WHIRLWIND:
DoCastVictim(SPELL_WHIRLWIND);
events.ScheduleEvent(EVENT_WHIRLWIND, urand(8 * IN_MILLISECONDS, 18 * IN_MILLISECONDS));
break;
case EVENT_WHIRLWIND2:
DoCastVictim(SPELL_WHIRLWIND2);
events.ScheduleEvent(EVENT_WHIRLWIND2, urand(7 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
break;
case EVENT_KNOCKDOWN:
DoCastVictim(SPELL_KNOCKDOWN);
events.ScheduleEvent(EVENT_KNOCKDOWN, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
break;
case EVENT_FRENZY:
DoCastVictim(SPELL_FRENZY);
events.ScheduleEvent(EVENT_FRENZY, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS));
break;
case EVENT_RANDOM_YELL:
Talk(SAY_RANDOM);
events.ScheduleEvent(EVENT_RANDOM_YELL, urand(20 * IN_MILLISECONDS, 30 * IN_MILLISECONDS));
break;
default:
break;
}
ResetTimer = 5 * IN_MILLISECONDS;
} else ResetTimer -= diff;
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override

View File

@@ -27,11 +27,20 @@ enum Spells
SPELL_MORTAL_STRIKE = 16856
};
enum Yells
enum Texts
{
YELL_AGGRO = 0,
YELL_EVADE = 1,
YELL_BUFF = 2
SAY_AGGRO = 0,
SAY_EVADE = 1,
SAY_BUFF = 2
};
enum Events
{
EVENT_CLEAVE = 1,
EVENT_FRIGHTENING_SHOUT,
EVENT_WHIRLWIND1,
EVENT_WHIRLWIND2,
EVENT_MORTAL_STRIKE
};
enum Action
@@ -46,97 +55,85 @@ public:
struct boss_galvangarAI : public ScriptedAI
{
boss_galvangarAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
CleaveTimer = urand(1 * IN_MILLISECONDS, 9 * IN_MILLISECONDS);
FrighteningShoutTimer = urand(2 * IN_MILLISECONDS, 19 * IN_MILLISECONDS);
Whirlwind1Timer = urand(1 * IN_MILLISECONDS, 13 * IN_MILLISECONDS);
Whirlwind2Timer = urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
MortalStrikeTimer = urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS);
ResetTimer = 5 * IN_MILLISECONDS;
}
uint32 CleaveTimer;
uint32 FrighteningShoutTimer;
uint32 Whirlwind1Timer;
uint32 Whirlwind2Timer;
uint32 MortalStrikeTimer;
uint32 ResetTimer;
boss_galvangarAI(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
Initialize();
events.Reset();
}
void EnterCombat(Unit* /*who*/) override
{
Talk(YELL_AGGRO);
}
void JustRespawned() override
{
Reset();
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_CLEAVE, urand(1 * IN_MILLISECONDS, 9 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, urand(2 * IN_MILLISECONDS, 19 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_WHIRLWIND1, urand(1 * IN_MILLISECONDS, 13 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_WHIRLWIND2, urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(5 * IN_MILLISECONDS, 20 * IN_MILLISECONDS));
}
void DoAction(int32 actionId) override
{
if (actionId == ACTION_BUFF_YELL)
Talk(YELL_BUFF);
Talk(SAY_BUFF);
}
bool CheckInRoom()
{
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
{
EnterEvadeMode();
Talk(SAY_EVADE);
return false;
}
return true;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
if (!UpdateVictim() || !CheckInRoom())
return;
if (CleaveTimer <= diff)
{
DoCastVictim(SPELL_CLEAVE);
CleaveTimer = urand(10 * IN_MILLISECONDS, 16 * IN_MILLISECONDS);
} else CleaveTimer -= diff;
events.Update(diff);
if (FrighteningShoutTimer <= diff)
{
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
FrighteningShoutTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
} else FrighteningShoutTimer -= diff;
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (Whirlwind1Timer <= diff)
while (uint32 eventId = events.ExecuteEvent())
{
DoCastVictim(SPELL_WHIRLWIND1);
Whirlwind1Timer = urand(6 * IN_MILLISECONDS, 10 * IN_MILLISECONDS);
} else Whirlwind1Timer -= diff;
if (Whirlwind2Timer <= diff)
{
DoCastVictim(SPELL_WHIRLWIND2);
Whirlwind2Timer = urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS);
} else Whirlwind2Timer -= diff;
if (MortalStrikeTimer <= diff)
{
DoCastVictim(SPELL_MORTAL_STRIKE);
MortalStrikeTimer = urand(10 * IN_MILLISECONDS, 30 * IN_MILLISECONDS);
} else MortalStrikeTimer -= diff;
// check if creature is not outside of building
if (ResetTimer <= diff)
{
if (me->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 50)
switch (eventId)
{
EnterEvadeMode();
Talk(YELL_EVADE);
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, urand(10 * IN_MILLISECONDS, 16 * IN_MILLISECONDS));
break;
case EVENT_FRIGHTENING_SHOUT:
DoCastVictim(SPELL_FRIGHTENING_SHOUT);
events.ScheduleEvent(EVENT_FRIGHTENING_SHOUT, urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS));
break;
case EVENT_WHIRLWIND1:
DoCastVictim(SPELL_WHIRLWIND1);
events.ScheduleEvent(EVENT_WHIRLWIND1, urand(6 * IN_MILLISECONDS, 10 * IN_MILLISECONDS));
break;
case EVENT_WHIRLWIND2:
DoCastVictim(SPELL_WHIRLWIND2);
events.ScheduleEvent(EVENT_WHIRLWIND2, urand(10 * IN_MILLISECONDS, 25 * IN_MILLISECONDS));
break;
case EVENT_MORTAL_STRIKE:
DoCastVictim(SPELL_MORTAL_STRIKE);
events.ScheduleEvent(EVENT_MORTAL_STRIKE, urand(10 * IN_MILLISECONDS, 30 * IN_MILLISECONDS));
break;
default:
break;
}
ResetTimer = 5 * IN_MILLISECONDS;
} else ResetTimer -= diff;
}
DoMeleeAttackIfReady();
}
private:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override

View File

@@ -21,7 +21,7 @@
enum Spells
{
SPELL_CURSE_OF_BLOOD = 24673,
SPELL_ILLUSION = 17773,
SPELL_ILLUSION = 17773
};
enum Events
@@ -113,7 +113,7 @@ public:
CreatureAI* GetAI(Creature* creature) const override
{
return new boss_jandicebarovAI(creature);
return GetInstanceAI<boss_jandicebarovAI>(creature);
}
};

View File

@@ -81,7 +81,7 @@ public:
events.ScheduleEvent(EVENT_ICE_ARMOR, 180000);
break;
case EVENT_FROSTBOLT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.0f, true))
DoCast(target, SPELL_FROSTBOLT);
events.ScheduleEvent(EVENT_FROSTBOLT, 8000);
break;

View File

@@ -106,7 +106,6 @@ public:
EventMap events;
};
CreatureAI* GetAI(Creature* creature) const override
{
return new boss_vectusAI(creature);

View File

@@ -87,14 +87,14 @@ public:
{
Initialize();
instance->SetData(DATA_EPOCH_EVENT, NOT_STARTED);
instance->SetBossState(DATA_EPOCH, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_EPOCH_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_EPOCH, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
@@ -136,7 +136,7 @@ public:
{
Talk(SAY_DEATH);
instance->SetData(DATA_EPOCH_EVENT, DONE);
instance->SetBossState(DATA_EPOCH, DONE);
}
void KilledUnit(Unit* victim) override

View File

@@ -22,7 +22,9 @@
enum Spells
{
SPELL_CORRUPTING_BLIGHT = 60588,
SPELL_VOID_STRIKE = 60590
SPELL_VOID_STRIKE = 60590,
SPELL_CORRUPTION_OF_TIME_CHANNEL = 60422,
SPELL_CORRUPTION_OF_TIME_TARGET = 60451
};
enum Yells
@@ -32,52 +34,78 @@ enum Yells
SAY_FAIL = 2
};
enum Events
{
EVENT_CORRUPTING_BLIGHT = 1,
EVENT_VOID_STRIKE
};
class boss_infinite_corruptor : public CreatureScript
{
public:
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
public:
boss_infinite_corruptor() : CreatureScript("boss_infinite_corruptor") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_infinite_corruptorAI>(creature);
}
struct boss_infinite_corruptorAI : public ScriptedAI
{
boss_infinite_corruptorAI(Creature* creature) : ScriptedAI(creature)
struct boss_infinite_corruptorAI : public BossAI
{
instance = creature->GetInstanceScript();
}
boss_infinite_corruptorAI(Creature* creature) : BossAI(creature, DATA_INFINITE) { }
InstanceScript* instance;
void Reset() override
{
_Reset();
void Reset() override
if (Creature* guardian = me->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
{
DoCast((Unit*)NULL, SPELL_CORRUPTION_OF_TIME_CHANNEL, false);
guardian->CastSpell(guardian, SPELL_CORRUPTION_OF_TIME_TARGET, false);
}
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
_EnterCombat();
events.ScheduleEvent(EVENT_CORRUPTING_BLIGHT, 7000);
events.ScheduleEvent(EVENT_VOID_STRIKE, 5000);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
if (Creature* guardian = me->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
{
guardian->RemoveAurasDueToSpell(SPELL_CORRUPTION_OF_TIME_TARGET);
guardian->DespawnOrUnsummon(5000);
}
if (Creature* rift = me->FindNearestCreature(NPC_TIME_RIFT, 100.0f))
rift->DespawnOrUnsummon();
}
void ExecuteEvent(uint32 eventId) override
{
switch (eventId)
{
case EVENT_CORRUPTING_BLIGHT:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 60.0f, true))
DoCast(target, SPELL_CORRUPTING_BLIGHT);
events.ScheduleEvent(EVENT_CORRUPTING_BLIGHT, 17000);
break;
case EVENT_VOID_STRIKE:
DoCastVictim(SPELL_VOID_STRIKE);
events.ScheduleEvent(EVENT_VOID_STRIKE, 5000);
break;
default:
break;
}
}
};
CreatureAI* GetAI(Creature* creature) const override
{
instance->SetData(DATA_INFINITE_EVENT, NOT_STARTED);
return GetInstanceAI<boss_infinite_corruptorAI>(creature);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_INFINITE_EVENT, IN_PROGRESS);
}
void UpdateAI(uint32 /*diff*/) override
{
//Return since we have no target
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
instance->SetData(DATA_INFINITE_EVENT, DONE);
}
};
};
void AddSC_boss_infinite_corruptor()

View File

@@ -26,15 +26,13 @@ Script Data End */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "culling_of_stratholme.h"
#include "Player.h"
enum Spells
{
SPELL_CARRION_SWARM = 52720, //A cresting wave of chaotic magic splashes over enemies in front of the caster, dealing 3230 to 3570 Shadow damage and 380 to 420 Shadow damage every 3 sec. for 15 sec.
H_SPELL_CARRION_SWARM = 58852,
SPELL_MIND_BLAST = 52722, //Inflicts 4163 to 4837 Shadow damage to an enemy.
H_SPELL_MIND_BLAST = 58850,
SPELL_SLEEP = 52721, //Puts an enemy to sleep for up to 10 sec. Any damage caused will awaken the target.
H_SPELL_SLEEP = 58849,
SPELL_VAMPIRIC_TOUCH = 52723, //Heals the caster for half the damage dealt by a melee attack.
SPELL_MAL_GANIS_KILL_CREDIT = 58124, // Quest credit
SPELL_KILL_CREDIT = 58630 // Non-existing spell as encounter credit, created in spell_dbc
@@ -75,7 +73,6 @@ public:
{
Initialize();
instance = creature->GetInstanceScript();
uiOutroStep = 0;
}
void Initialize()
@@ -108,14 +105,13 @@ public:
void Reset() override
{
Initialize();
instance->SetData(DATA_MAL_GANIS_EVENT, NOT_STARTED);
instance->SetBossState(DATA_MAL_GANIS, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_MAL_GANIS_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_MAL_GANIS, IN_PROGRESS);
}
void DamageTaken(Unit* done_by, uint32 &damage) override
@@ -159,7 +155,7 @@ public:
{
EnterEvadeMode();
me->DisappearAndDie();
instance->SetData(DATA_MAL_GANIS_EVENT, FAIL);
instance->SetBossState(DATA_MAL_GANIS, FAIL);
}
if (uiCarrionSwarmTimer < diff)
@@ -197,7 +193,7 @@ public:
switch (uiOutroStep)
{
case 1:
Talk(SAY_ESCAPE_SPEECH_1);
Talk(SAY_OUTRO);
me->GetMotionMaster()->MoveTargetedHome();
++uiOutroStep;
uiOutroTimer = 8000;
@@ -212,7 +208,7 @@ public:
case 3:
Talk(SAY_OUTRO);
++uiOutroStep;
uiOutroTimer = 16000;
//uiOutroTimer = 16000;
break;
case 4:
me->HandleEmoteCommand(33);
@@ -232,7 +228,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
instance->SetData(DATA_MAL_GANIS_EVENT, DONE);
instance->SetBossState(DATA_MAL_GANIS, DONE);
DoCastAOE(SPELL_MAL_GANIS_KILL_CREDIT);
// give achievement credit and LFG rewards to players. criteria use spell 58630 which doesn't exist, but it was created in spell_dbc
DoCastAOE(SPELL_KILL_CREDIT);

View File

@@ -15,14 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Script Data Start
SDName: Boss meathook
SDAuthor: Tartalo
SD%Complete: 100
SDComment: It may need timer adjustment
SDCategory:
Script Data End */
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "culling_of_stratholme.h"
@@ -30,9 +22,7 @@ Script Data End */
enum Spells
{
SPELL_CONSTRICTING_CHAINS = 52696, //Encases the targets in chains, dealing 1800 Physical damage every 1 sec. and stunning the target for 5 sec.
H_SPELL_CONSTRICTING_CHAINS = 58823,
SPELL_DISEASE_EXPULSION = 52666, //Meathook belches out a cloud of disease, dealing 1710 to 1890 Nature damage and interrupting the spell casting of nearby enemy targets for 4 sec.
H_SPELL_DISEASE_EXPULSION = 58824,
SPELL_FRENZY = 58841 //Increases the caster's Physical damage by 10% for 30 sec.
};
@@ -44,96 +34,72 @@ enum Yells
SAY_DEATH = 3
};
enum Events
{
EVENT_CHAIN = 1,
EVENT_DISEASE,
EVENT_FRENZY
};
class boss_meathook : public CreatureScript
{
public:
boss_meathook() : CreatureScript("boss_meathook") { }
public:
boss_meathook() : CreatureScript("boss_meathook") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<boss_meathookAI>(creature);
}
struct boss_meathookAI : public ScriptedAI
{
boss_meathookAI(Creature* creature) : ScriptedAI(creature)
struct boss_meathookAI : public BossAI
{
Initialize();
instance = creature->GetInstanceScript();
Talk(SAY_SPAWN);
}
void Initialize()
{
uiChainTimer = urand(12000, 17000); //seen on video 13, 17, 15, 12, 16
uiDiseaseTimer = urand(2000, 4000); //approx 3s
uiFrenzyTimer = urand(21000, 26000); //made it up
}
uint32 uiChainTimer;
uint32 uiDiseaseTimer;
uint32 uiFrenzyTimer;
InstanceScript* instance;
void Reset() override
{
Initialize();
instance->SetData(DATA_MEATHOOK_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_MEATHOOK_EVENT, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiDiseaseTimer <= diff)
boss_meathookAI(Creature* creature) : BossAI(creature, DATA_MEATHOOK)
{
DoCastAOE(SPELL_DISEASE_EXPULSION);
uiDiseaseTimer = urand(1500, 4000);
} else uiDiseaseTimer -= diff;
Talk(SAY_SPAWN);
}
if (uiFrenzyTimer <= diff)
void EnterCombat(Unit* /*who*/) override
{
DoCast(me, SPELL_FRENZY);
uiFrenzyTimer = urand(21000, 26000);
} else uiFrenzyTimer -= diff;
Talk(SAY_AGGRO);
_EnterCombat();
events.ScheduleEvent(EVENT_CHAIN, urand(12000, 17000));
events.ScheduleEvent(EVENT_DISEASE, urand(2000, 4000));
events.ScheduleEvent(EVENT_FRENZY, urand(21000, 26000));
}
if (uiChainTimer <= diff)
void ExecuteEvent(uint32 eventId) override
{
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
DoCast(target, SPELL_CONSTRICTING_CHAINS); //anyone but the tank
uiChainTimer = urand(2000, 4000);
} else uiChainTimer -= diff;
switch (eventId)
{
case EVENT_CHAIN:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
DoCast(target, SPELL_CONSTRICTING_CHAINS);
events.ScheduleEvent(EVENT_CHAIN, urand(2000, 4000));
case EVENT_DISEASE:
DoCastAOE(SPELL_DISEASE_EXPULSION);
events.ScheduleEvent(EVENT_DISEASE, urand(1500, 4000));
break;
case EVENT_FRENZY:
DoCast(me, SPELL_FRENZY);
events.ScheduleEvent(EVENT_FRENZY, urand(21000, 26000));
break;
default:
break;
}
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
_JustDied();
}
void JustDied(Unit* /*killer*/) override
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
};
CreatureAI* GetAI(Creature* creature) const override
{
Talk(SAY_DEATH);
instance->SetData(DATA_MEATHOOK_EVENT, DONE);
return GetInstanceAI<boss_meathookAI>(creature);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() != TYPEID_PLAYER)
return;
Talk(SAY_SLAY);
}
};
};
void AddSC_boss_meathook()

View File

@@ -89,14 +89,14 @@ public:
{
Initialize();
instance->SetData(DATA_SALRAMM_EVENT, NOT_STARTED);
instance->SetBossState(DATA_SALRAMM, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
instance->SetData(DATA_SALRAMM_EVENT, IN_PROGRESS);
instance->SetBossState(DATA_SALRAMM, IN_PROGRESS);
}
void UpdateAI(uint32 diff) override
@@ -145,7 +145,7 @@ public:
{
Talk(SAY_DEATH);
instance->SetData(DATA_SALRAMM_EVENT, DONE);
instance->SetBossState(DATA_SALRAMM, DONE);
}
void KilledUnit(Unit* victim) override

View File

@@ -103,7 +103,7 @@ enum Says
//Drakonian
SAY_PHASE302 = 0,
SAY_PHASE305 = 1,
SAY_PHASE305 = 1
};
enum NPCs
@@ -111,7 +111,6 @@ enum NPCs
NPC_INFINITE_ADVERSARY = 27742,
NPC_INFINITE_HUNTER = 27743,
NPC_INFINITE_AGENT = 27744,
NPC_TIME_RIFT = 28409,
NPC_ZOMBIE = 27737,
NPC_GHOUL = 28249,
NPC_NECROMANCER = 28200,
@@ -128,7 +127,7 @@ enum NPCs
NPC_CITY_MAN = 28167,
NPC_CITY_MAN2 = 28169,
NPC_CITY_MAN3 = 31126,
NPC_CITY_MAN4 = 31127,
NPC_CITY_MAN4 = 31127
};
enum Spells
@@ -138,7 +137,7 @@ enum Spells
SPELL_EXORCISM_N = 52445,
SPELL_EXORCISM_H = 58822,
SPELL_HOLY_LIGHT = 52444,
SPELL_ARCANE_DISRUPTION = 49590,
SPELL_ARCANE_DISRUPTION = 49590
};
enum GossipMenuArthas
@@ -392,6 +391,7 @@ public:
uint32 gossipStep;
uint32 bossEvent;
uint32 wave;
uint32 WavesCounter;
uint64 utherGUID;
uint64 jainaGUID;
@@ -411,17 +411,19 @@ public:
{
Initialize();
instance->SetData(DATA_ARTHAS_EVENT, NOT_STARTED);
switch (instance->GetData(DATA_ARTHAS_EVENT))
{
case NOT_STARTED:
bStepping = true;
step = 0;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bossEvent = DATA_MEATHOOK_EVENT;
gossipStep = 0;
break;
}
instance->SetBossState(DATA_ARTHAS, NOT_STARTED);
bStepping = true;
step = 0;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bossEvent = DATA_MEATHOOK;
gossipStep = 0;
}
void AttackStart(Unit* who)
{
if (who && !who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC))
npc_escortAI::AttackStart(who);
}
void EnterCombat(Unit* /*who*/) override
@@ -431,7 +433,7 @@ public:
void JustDied(Unit* /*killer*/) override
{
instance->SetData(DATA_ARTHAS_EVENT, FAIL);
instance->SetBossState(DATA_ARTHAS, FAIL);
}
void SpawnTimeRift(uint32 timeRiftID, uint64* guidVector)
@@ -488,16 +490,15 @@ public:
case 11:
case 22:
case 23:
case 26:
case 55:
case 56:
SetHoldState(true);
bStepping = true;
break;
case 7:
if (Unit* cityman0 = me->SummonCreature(NPC_CITY_MAN, 2091.977f, 1275.021f, 140.757f, 0.558f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
if (Unit* cityman0 = me->FindNearestCreature(NPC_CITY_MAN, 160.0f))
citymenGUID[0] = cityman0->GetGUID();
if (Unit* cityman1 = me->SummonCreature(NPC_CITY_MAN2, 2093.514f, 1275.842f, 140.408f, 3.801f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000))
if (Unit* cityman1 = me->FindNearestCreature(NPC_CITY_MAN2, 160.0f))
citymenGUID[1] = cityman1->GetGUID();
break;
case 8:
@@ -534,10 +535,12 @@ public:
case 21:
Talk(SAY_PHASE301);
break;
case 25:
case 26:
SetRun(false);
SpawnTimeRift(0, &infiniteDraconianGUID[0]);
Talk(SAY_PHASE307);
SetHoldState(true);
bStepping = true;
break;
case 29:
SetRun(false);
@@ -565,8 +568,8 @@ public:
Talk(SAY_PHASE403);
break;
case 36:
if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_SHKAF_GATE)))
pGate->SetGoState(GO_STATE_ACTIVE);
if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_SHKAF_GATE)))
gate->SetGoState(GO_STATE_ACTIVE);
break;
case 45:
SetRun(true);
@@ -575,18 +578,18 @@ public:
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SetHoldState(true);
break;
case 47:
case 48:
SetRun(false);
Talk(SAY_PHASE405);
break;
case 48:
case 49:
SetRun(true);
Talk(SAY_PHASE406);
break;
case 53:
case 50:
Talk(SAY_PHASE407);
break;
case 54:
case 51:
gossipStep = 5;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
SetHoldState(true);
@@ -598,8 +601,6 @@ public:
{
npc_escortAI::UpdateAI(diff);
DoMeleeAttackIfReady();
if (bStepping)
{
if (phaseTimer <= diff)
@@ -765,6 +766,9 @@ public:
stalkerGUID = pStalker->GetGUID();
me->SetTarget(stalkerGUID);
}
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, 0);
JumpToNextStep(1000);
break;
case 25:
@@ -892,14 +896,15 @@ public:
}
Talk(SAY_PHASE209);
bossEvent = DATA_MEATHOOK_EVENT;
instance->SetData(DATA_ARTHAS_EVENT, IN_PROGRESS);
bossEvent = DATA_MEATHOOK;
instance->SetBossState(DATA_ARTHAS, IN_PROGRESS);
me->SetReactState(REACT_DEFENSIVE);
SetDespawnAtFar(false);
JumpToNextStep(5000);
break;
case 41: //Summon wave group
// Summon wave groups - start the Infinite Corruptor timer
case 41:
case 43:
case 45:
case 47:
@@ -907,10 +912,15 @@ public:
case 53:
case 55:
case 57:
if (instance->GetData(bossEvent) != DONE)
if (!wave && IsHeroic() && instance->GetData(DATA_INFINITE_COUNTER) == NOT_STARTED)
instance->SetData(DATA_INFINITE_COUNTER, IN_PROGRESS);
if (instance->GetBossState(bossEvent) != DONE)
{
SpawnWaveGroup(wave, waveGUID);
wave++;
WavesCounter++;
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, WavesCounter);
}
JumpToNextStep(500);
break;
@@ -922,7 +932,7 @@ public:
case 54:
case 56:
case 58:
if (instance->GetData(bossEvent) != DONE)
if (instance->GetBossState(bossEvent) != DONE)
{
uint32 mobCounter = 0;
uint32 deadCounter = 0;
@@ -946,12 +956,14 @@ public:
break;
case 49: //Summon Boss
case 59:
if (instance->GetData(bossEvent) != DONE)
if (instance->GetBossState(bossEvent) != DONE)
{
WavesCounter++;
instance->DoUpdateWorldState(WORLDSTATE_WAVE_COUNT, WavesCounter);
uint32 uiBossID = 0;
if (bossEvent == DATA_MEATHOOK_EVENT)
if (bossEvent == DATA_MEATHOOK)
uiBossID = NPC_MEATHOOK;
else if (bossEvent == DATA_SALRAMM_EVENT)
else if (bossEvent == DATA_SALRAMM)
uiBossID = NPC_SALRAMM;
if (Unit* pBoss = me->SummonCreature(uiBossID, 2232.19f, 1331.933f, 126.662f, 3.15f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 900000))
@@ -965,19 +977,19 @@ public:
break;
case 50: //Wait Boss death
case 60:
if (instance->GetData(bossEvent) == DONE)
if (instance->GetBossState(bossEvent) == DONE)
{
JumpToNextStep(1000);
if (bossEvent == DATA_MEATHOOK_EVENT)
bossEvent = DATA_SALRAMM_EVENT;
else if (bossEvent == DATA_SALRAMM_EVENT)
if (bossEvent == DATA_MEATHOOK)
bossEvent = DATA_SALRAMM;
else if (bossEvent == DATA_SALRAMM)
{
SetHoldState(false);
bStepping = false;
bossEvent = DATA_EPOCH_EVENT;
bossEvent = DATA_EPOCH;
}
}
else if (instance->GetData(bossEvent) == FAIL)
else if (instance->GetBossState(bossEvent) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1074,9 +1086,12 @@ public:
phaseTimer = 1000;
else
{
if (step == 72) Talk(SAY_PHASE308);
if (step == 74) Talk(SAY_PHASE308);
if (step == 76) Talk(SAY_PHASE310);
if (step == 72)
Talk(SAY_PHASE308);
if (step == 74)
Talk(SAY_PHASE308);
if (step == 76)
Talk(SAY_PHASE310);
SetHoldState(false);
bStepping = false;
SetRun(true);
@@ -1097,7 +1112,7 @@ public:
JumpToNextStep(1000);
break;
case 80:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
{
SpawnTimeRift(17, &epochGUID);
if (Creature* epoch = ObjectAccessor::GetCreature(*me, epochGUID))
@@ -1107,12 +1122,12 @@ public:
JumpToNextStep(18000);
break;
case 81:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
Talk(SAY_PHASE315);
JumpToNextStep(6000);
break;
case 82:
if (instance->GetData(DATA_EPOCH_EVENT) != DONE)
if (instance->GetBossState(DATA_EPOCH) != DONE)
{
if (Creature* epoch = ObjectAccessor::GetCreature(*me, epochGUID))
{
@@ -1126,15 +1141,15 @@ public:
JumpToNextStep(1000);
break;
case 83:
if (instance->GetData(DATA_EPOCH_EVENT) == DONE)
if (instance->GetBossState(DATA_EPOCH) == DONE)
{
gossipStep = 3;
me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
bStepping = false;
bossEvent = DATA_MAL_GANIS_EVENT;
bossEvent = DATA_MAL_GANIS;
JumpToNextStep(15000);
}
else if (instance->GetData(DATA_EPOCH_EVENT) == FAIL)
else if (instance->GetBossState(DATA_EPOCH) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1153,8 +1168,8 @@ public:
malganisGUID = malganis->GetGUID();
malganis->SetReactState(REACT_PASSIVE);
}
if (GameObject* pGate = instance->instance->GetGameObject(instance->GetData64(DATA_MAL_GANIS_GATE_1)))
pGate->SetGoState(GO_STATE_ACTIVE);
if (GameObject* gate = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_MAL_GANIS_GATE_1)))
gate->SetGoState(GO_STATE_ACTIVE);
SetHoldState(false);
bStepping = false;
JumpToNextStep(0);
@@ -1174,12 +1189,12 @@ public:
JumpToNextStep(1000);
break;
case 88:
if (instance->GetData(DATA_MAL_GANIS_EVENT) == DONE)
if (instance->GetBossState(DATA_MAL_GANIS) == DONE)
{
SetHoldState(false);
JumpToNextStep(1000);
}
else if (instance->GetData(DATA_MAL_GANIS_EVENT) == FAIL)
else if (instance->GetBossState(DATA_MAL_GANIS) == FAIL)
npc_escortAI::EnterEvadeMode();
else
phaseTimer = 10000;
@@ -1192,7 +1207,7 @@ public:
JumpToNextStep(7000);
break;
case 90:
instance->SetData(DATA_ARTHAS_EVENT, DONE); //Rewards: Achiev & Chest ;D
instance->SetBossState(DATA_ARTHAS, DONE); //Rewards: Achiev & Chest ;D
me->SetTarget(instance->GetData64(DATA_MAL_GANIS_GATE_2)); //Look behind
Talk(SAY_PHASE504);
bStepping = false;
@@ -1214,6 +1229,8 @@ public:
if (HealthBelowPct(40))
DoCast(me, SPELL_HOLY_LIGHT);
DoMeleeAttackIfReady();
}
};

View File

@@ -19,19 +19,10 @@
#define DEF_CULLING_OF_STRATHOLME_H
#define DataHeader "CS"
#define CoSScriptName "instance_culling_of_stratholme"
uint32 const EncounterCount = 5;
enum Data
{
DATA_MEATHOOK_EVENT,
DATA_SALRAMM_EVENT,
DATA_EPOCH_EVENT,
DATA_MAL_GANIS_EVENT,
DATA_INFINITE_EVENT,
DATA_ARTHAS_EVENT,
DATA_CRATE_COUNT,
};
enum Data64
enum DataTypes
{
DATA_ARTHAS,
DATA_MEATHOOK,
@@ -39,28 +30,35 @@ enum Data64
DATA_EPOCH,
DATA_MAL_GANIS,
DATA_INFINITE,
DATA_CRATE_COUNT,
DATA_SHKAF_GATE,
DATA_MAL_GANIS_GATE_1,
DATA_MAL_GANIS_GATE_2,
DATA_EXIT_GATE,
DATA_MAL_GANIS_CHEST
DATA_MAL_GANIS_CHEST,
DATA_INFINITE_COUNTER
};
enum Creatures
enum CreatureIds
{
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_CHROMIE_2 = 27915,
NPC_GENERIC_BUNNY = 28960,
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_CHROMIE = 26527,
NPC_CHROMIE_2 = 27915,
NPC_CHROMIE_3 = 30997,
NPC_GENERIC_BUNNY = 28960,
NPC_TIME_RIFT = 28409,
NPC_GUARDIAN_OF_TIME = 32281
};
enum GameObjects
enum GameObjectIds
{
GO_SHKAF_GATE = 188686,
GO_MALGANIS_GATE_1 = 187711,
@@ -69,7 +67,7 @@ enum GameObjects
GO_MALGANIS_CHEST_N = 190663,
GO_MALGANIS_CHEST_H = 193597,
GO_SUSPICIOUS_CRATE = 190094,
GO_PLAGUED_CRATE = 190095,
GO_PLAGUED_CRATE = 190095
};
enum WorldStatesCoT
@@ -78,12 +76,28 @@ enum WorldStatesCoT
WORLDSTATE_CRATES_REVEALED = 3480,
WORLDSTATE_WAVE_COUNT = 3504,
WORLDSTATE_TIME_GUARDIAN = 3931,
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932,
WORLDSTATE_TIME_GUARDIAN_SHOW = 3932
};
enum CrateSpells
{
SPELL_CRATES_CREDIT = 58109,
SPELL_CRATES_CREDIT = 58109
};
enum Texts
{
SAY_CRATES_COMPLETED = 0,
// Chromie
SAY_INFINITE_START = 0, // On Infinite Corruptor event start
SAY_INFINITE = 1, // On Infinite Corruptor event at 5 minutes
SAY_INFINITE_FAIL = 2, // On Infinite Corruptor event fail
// Infinite Corruptor
SAY_FAIL_EVENT = 2 // On Infinite Corruptor event fail
};
enum InstanceEvents
{
EVENT_INFINITE_TIMER = 1
};
#endif

View File

@@ -23,8 +23,6 @@
#include "TemporarySummon.h"
#include "SpellInfo.h"
#define MAX_ENCOUNTER 5
/* Culling of Stratholme encounters:
0 - Meathook
1 - Salramm the Fleshcrafter
@@ -33,51 +31,51 @@
4 - Infinite Corruptor (Heroic only)
*/
enum Texts
Position const ChromieSummonPos[] =
{
SAY_CRATES_COMPLETED = 0,
{ 1813.298f, 1283.578f, 142.3258f, 3.878161f },
{ 2273.725f, 1483.684f, 128.7205f, 6.057528f }
};
Position const ChromieSummonPos = {1813.298f, 1283.578f, 142.3258f, 3.878161f};
Position const InfiniteCorruptorPos = { 2335.47f, 1262.04f, 132.921f, 1.42079f };
Position const TimeRiftPos = { 2334.626f, 1280.45f, 133.0066f, 1.727876f };
Position const GuardianOfTimePos = { 2321.489f, 1268.383f, 132.8507f, 0.418879f };
DoorData const doorData[] =
{
{ GO_MALGANIS_GATE_2, DATA_MAL_GANIS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
{ GO_EXIT_GATE, DATA_MAL_GANIS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
{ 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
class instance_culling_of_stratholme : public InstanceMapScript
{
public:
instance_culling_of_stratholme() : InstanceMapScript("instance_culling_of_stratholme", 595) { }
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_culling_of_stratholme_InstanceMapScript(map);
}
instance_culling_of_stratholme() : InstanceMapScript(CoSScriptName, 595) { }
struct instance_culling_of_stratholme_InstanceMapScript : public InstanceScript
{
instance_culling_of_stratholme_InstanceMapScript(Map* map) : InstanceScript(map)
{
SetHeaders(DataHeader);
_arthasGUID = 0;
_meathookGUID = 0;
_salrammGUID = 0;
_epochGUID = 0;
_malGanisGUID = 0;
_infiniteGUID = 0;
_shkafGateGUID = 0;
SetBossNumber(EncounterCount);
LoadDoorData(doorData);
_chromieGUID = 0;
_arthasGUID = 0;
_meathookGUID = 0;
_salrammGUID = 0;
_epochGUID = 0;
_malGanisGUID = 0;
_infiniteGUID = 0;
_shkafGateGUID = 0;
_malGanisGate1GUID = 0;
_malGanisGate2GUID = 0;
_exitGateGUID = 0;
_exitGateGUID = 0;
_malGanisChestGUID = 0;
_genericBunnyGUID = 0;
memset(&_encounterState[0], 0, sizeof(uint32) * MAX_ENCOUNTER);
_crateCount = 0;
}
bool IsEncounterInProgress() const override
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (_encounterState[i] == IN_PROGRESS)
return true;
return false;
_genericBunnyGUID = 0;
_crateCount = 0;
_eventTimer = 0;
}
void FillInitialWorldStates(WorldPacket& data) override
@@ -93,6 +91,9 @@ class instance_culling_of_stratholme : public InstanceMapScript
{
switch (creature->GetEntry())
{
case NPC_CHROMIE:
_chromieGUID = creature->GetGUID();
break;
case NPC_ARTHAS:
_arthasGUID = creature->GetGUID();
break;
@@ -110,10 +111,13 @@ class instance_culling_of_stratholme : public InstanceMapScript
break;
case NPC_INFINITE:
_infiniteGUID = creature->GetGUID();
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 1);
break;
case NPC_GENERIC_BUNNY:
_genericBunnyGUID = creature->GetGUID();
break;
default:
break;
}
}
@@ -129,17 +133,30 @@ class instance_culling_of_stratholme : public InstanceMapScript
break;
case GO_MALGANIS_GATE_2:
_malGanisGate2GUID = go->GetGUID();
AddDoor(go, true);
break;
case GO_EXIT_GATE:
_exitGateGUID = go->GetGUID();
if (_encounterState[3] == DONE)
HandleGameObject(_exitGateGUID, true);
AddDoor(go, true);
break;
case GO_MALGANIS_CHEST_N:
case GO_MALGANIS_CHEST_H:
_malGanisChestGUID = go->GetGUID();
if (_encounterState[3] == DONE)
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
break;
default:
break;
}
}
void OnGameObjectRemove(GameObject* go) override
{
switch (go->GetEntry())
{
case GO_MALGANIS_GATE_2:
case GO_EXIT_GATE:
AddDoor(go, false);
break;
default:
break;
}
}
@@ -148,36 +165,6 @@ class instance_culling_of_stratholme : public InstanceMapScript
{
switch (type)
{
case DATA_MEATHOOK_EVENT:
_encounterState[0] = data;
break;
case DATA_SALRAMM_EVENT:
_encounterState[1] = data;
break;
case DATA_EPOCH_EVENT:
_encounterState[2] = data;
break;
case DATA_MAL_GANIS_EVENT:
_encounterState[3] = data;
switch (_encounterState[3])
{
case NOT_STARTED:
HandleGameObject(_malGanisGate2GUID, true);
break;
case IN_PROGRESS:
HandleGameObject(_malGanisGate2GUID, false);
break;
case DONE:
HandleGameObject(_exitGateGUID, true);
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
break;
}
break;
case DATA_INFINITE_EVENT:
_encounterState[4] = data;
break;
case DATA_CRATE_COUNT:
_crateCount = data;
if (_crateCount == 5)
@@ -186,34 +173,70 @@ class instance_culling_of_stratholme : public InstanceMapScript
bunny->CastSpell(bunny, SPELL_CRATES_CREDIT, true);
// Summon Chromie and global whisper
if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos))
if (Creature* chromie = instance->SummonCreature(NPC_CHROMIE_2, ChromieSummonPos[0]))
if (!instance->GetPlayers().isEmpty())
chromie->AI()->TalkToMap(SAY_CRATES_COMPLETED);
}
DoUpdateWorldState(WORLDSTATE_CRATES_REVEALED, _crateCount);
break;
case DATA_INFINITE_COUNTER:
_infiniteCouterState = data;
if (data == IN_PROGRESS)
{
if (!_infiniteGUID)
{
_eventTimer = 25;
instance->SummonCreature(NPC_INFINITE, InfiniteCorruptorPos);
instance->SummonCreature(NPC_TIME_RIFT, TimeRiftPos);
instance->SummonCreature(NPC_GUARDIAN_OF_TIME, GuardianOfTimePos);
events.ScheduleEvent(EVENT_INFINITE_TIMER, 1);
}
}
break;
default:
break;
}
}
bool SetBossState(uint32 type, EncounterState state) override
{
if (!InstanceScript::SetBossState(type, state))
return false;
switch (type)
{
case DATA_INFINITE:
if (state == DONE)
{
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, 0);
}
break;
case DATA_MAL_GANIS:
if (state == DONE)
{
if (GameObject* go = instance->GetGameObject(_malGanisChestGUID))
go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND);
instance->SummonCreature(NPC_CHROMIE_3, ChromieSummonPos[1]);
}
break;
default:
break;
}
if (data == DONE)
SaveToDB();
return true;
}
uint32 GetData(uint32 type) const override
{
switch (type)
{
case DATA_MEATHOOK_EVENT:
return _encounterState[0];
case DATA_SALRAMM_EVENT:
return _encounterState[1];
case DATA_EPOCH_EVENT:
return _encounterState[2];
case DATA_MAL_GANIS_EVENT:
return _encounterState[3];
case DATA_INFINITE_EVENT:
return _encounterState[4];
case DATA_CRATE_COUNT:
return _crateCount;
case DATA_INFINITE_COUNTER:
return _infiniteCouterState;
default:
break;
}
return 0;
}
@@ -244,58 +267,70 @@ class instance_culling_of_stratholme : public InstanceMapScript
return _exitGateGUID;
case DATA_MAL_GANIS_CHEST:
return _malGanisChestGUID;
default:
break;
}
return 0;
}
std::string GetSaveData() override
void Update(uint32 diff) override
{
OUT_SAVE_INST_DATA;
events.Update(diff);
std::ostringstream saveStream;
saveStream << "C S " << _encounterState[0] << ' ' << _encounterState[1] << ' '
<< _encounterState[2] << ' ' << _encounterState[3] << ' ' << _encounterState[4];
OUT_SAVE_INST_DATA_COMPLETE;
return saveStream.str();
}
void Load(const char* in) override
{
if (!in)
while (uint32 eventId = events.ExecuteEvent())
{
OUT_LOAD_INST_DATA_FAIL;
return;
switch (eventId)
{
case EVENT_INFINITE_TIMER:
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN, _eventTimer);
switch (_eventTimer)
{
case 25:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE_START);
break;
case 5:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE);
break;
case 0:
if (instance->HavePlayers())
if (Creature* chromie = instance->GetCreature(_chromieGUID))
chromie->AI()->TalkToMap(SAY_INFINITE_FAIL);
if (Creature* infinite = instance->GetCreature(_infiniteGUID))
{
if (Creature* guardian = infinite->FindNearestCreature(NPC_GUARDIAN_OF_TIME, 100.0f))
infinite->Kill(guardian);
if (Creature* rift = infinite->FindNearestCreature(NPC_TIME_RIFT, 100.0f))
{
infinite->GetMotionMaster()->MovePoint(0, rift->GetPositionX(), rift->GetPositionY(), rift->GetPositionZ());
rift->DespawnOrUnsummon(3000);
}
infinite->DespawnOrUnsummon(3000);
infinite->AI()->Talk(SAY_FAIL_EVENT);
}
DoUpdateWorldState(WORLDSTATE_TIME_GUARDIAN_SHOW, 0);
return;
default:
break;
}
events.ScheduleEvent(EVENT_INFINITE_TIMER, 60000);
--_eventTimer;
break;
default:
break;
}
}
OUT_LOAD_INST_DATA(in);
char dataHead1, dataHead2;
uint16 data0, data1, data2, data3, data4;
std::istringstream loadStream(in);
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4;
if (dataHead1 == 'C' && dataHead2 == 'S')
{
_encounterState[0] = data0;
_encounterState[1] = data1;
_encounterState[2] = data2;
_encounterState[3] = data3;
_encounterState[4] = data4;
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (_encounterState[i] == IN_PROGRESS)
_encounterState[i] = NOT_STARTED;
}
else
OUT_LOAD_INST_DATA_FAIL;
OUT_LOAD_INST_DATA_COMPLETE;
}
private:
uint64 _chromieGUID;
uint64 _arthasGUID;
uint64 _meathookGUID;
uint64 _salrammGUID;
@@ -308,9 +343,18 @@ class instance_culling_of_stratholme : public InstanceMapScript
uint64 _exitGateGUID;
uint64 _malGanisChestGUID;
uint64 _genericBunnyGUID;
uint32 _encounterState[MAX_ENCOUNTER];
uint32 _crateCount;
uint32 _eventTimer;
uint32 _infiniteCouterState;
EventMap events;
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_culling_of_stratholme_InstanceMapScript(map);
}
};
void AddSC_instance_culling_of_stratholme()

View File

@@ -487,6 +487,14 @@ public:
Talk(SAY_TWIGGY_FLATHEAD_OVER);
Reset();
}
else if (creature) // Makes BIG WILL attackable.
{
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
creature->setFaction(14);
creature->AI()->AttackStart(warrior);
}
}
} else WaveTimer -= diff;
}

View File

@@ -28,146 +28,92 @@ enum Spells
SPELL_ECK_SPRING_2 = 55837 //Eck leaps at a distant target.
};
static Position EckSpawnPoint = { 1643.877930f, 936.278015f, 107.204948f, 0.668432f };
enum Events
{
EVENT_BITE = 1,
EVENT_SPIT,
EVENT_SPRING,
EVENT_BERSERK
};
class boss_eck : public CreatureScript
{
public:
boss_eck() : CreatureScript("boss_eck") { }
CreatureAI* GetAI(Creature* creature) const override
struct boss_eckAI : public BossAI
{
return GetInstanceAI<boss_eckAI>(creature);
}
struct boss_eckAI : public ScriptedAI
{
boss_eckAI(Creature* creature) : ScriptedAI(creature)
boss_eckAI(Creature* creature) : BossAI(creature, DATA_ECK_THE_FEROCIOUS_EVENT)
{
Initialize();
instance = creature->GetInstanceScript();
}
void Initialize()
{
uiBerserkTimer = urand(60 * IN_MILLISECONDS, 90 * IN_MILLISECONDS); //60-90 secs according to wowwiki
uiBiteTimer = 5 * IN_MILLISECONDS;
uiSpitTimer = 10 * IN_MILLISECONDS;
uiSpringTimer = 8 * IN_MILLISECONDS;
bBerserk = false;
Berserk = false;
}
uint32 uiBerserkTimer;
uint32 uiBiteTimer;
uint32 uiSpitTimer;
uint32 uiSpringTimer;
bool bBerserk;
InstanceScript* instance;
void Reset() override
{
_Reset();
Initialize();
instance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, NOT_STARTED);
}
void EnterCombat(Unit* /*who*/) override
{
instance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, IN_PROGRESS);
_EnterCombat();
events.ScheduleEvent(EVENT_BITE, 5 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SPIT, 10 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_SPRING, 8 * IN_MILLISECONDS);
events.ScheduleEvent(EVENT_BERSERK, urand(60 * IN_MILLISECONDS, 90 * IN_MILLISECONDS)); //60-90 secs according to wowwiki
}
void UpdateAI(uint32 diff) override
void DamageTaken(Unit* /*attacker*/, uint32& damage) override
{
//Return since we have no target
if (!UpdateVictim())
return;
if (uiBiteTimer <= diff)
if (me->HealthBelowPctDamaged(20, damage) && !Berserk)
{
DoCastVictim(SPELL_ECK_BITE);
uiBiteTimer = urand(8*IN_MILLISECONDS, 12*IN_MILLISECONDS);
} else uiBiteTimer -= diff;
if (uiSpitTimer <= diff)
{
DoCastVictim(SPELL_ECK_SPIT);
uiSpitTimer = urand(6*IN_MILLISECONDS, 14*IN_MILLISECONDS);
} else uiSpitTimer -= diff;
if (uiSpringTimer <= diff)
{
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
if (target && target->GetTypeId() == TYPEID_PLAYER)
{
DoCast(target, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2));
uiSpringTimer = urand(5*IN_MILLISECONDS, 10*IN_MILLISECONDS);
}
} else uiSpringTimer -= diff;
//Berserk on timer or 20% of health
if (!bBerserk)
{
if (uiBerserkTimer <= diff)
{
DoCast(me, SPELL_ECK_BERSERK);
bBerserk = true;
}
else
{
uiBerserkTimer -= diff;
if (HealthBelowPct(20))
{
DoCast(me, SPELL_ECK_BERSERK);
bBerserk = true;
}
}
events.RescheduleEvent(EVENT_BERSERK, 1000);
Berserk = true;
}
DoMeleeAttackIfReady();
}
void JustDied(Unit* /*killer*/) override
void ExecuteEvent(uint32 eventId) override
{
instance->SetData(DATA_ECK_THE_FEROCIOUS_EVENT, DONE);
switch (eventId)
{
case EVENT_BITE:
DoCastVictim(SPELL_ECK_BITE);
events.ScheduleEvent(EVENT_BITE, urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS));
break;
case EVENT_SPIT:
DoCastVictim(SPELL_ECK_SPIT);
events.ScheduleEvent(EVENT_SPIT, urand(6 * IN_MILLISECONDS, 14 * IN_MILLISECONDS));
break;
case EVENT_SPRING:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 35.0f, true))
DoCast(target, RAND(SPELL_ECK_SPRING_1, SPELL_ECK_SPRING_2));
events.ScheduleEvent(EVENT_SPRING, urand(5 * IN_MILLISECONDS, 10 * IN_MILLISECONDS));
break;
case EVENT_BERSERK:
DoCast(me, SPELL_ECK_BERSERK);
Berserk = true;
break;
default:
break;
}
}
private:
bool Berserk;
};
};
class npc_ruins_dweller : public CreatureScript
{
public:
npc_ruins_dweller() : CreatureScript("npc_ruins_dweller") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetInstanceAI<npc_ruins_dwellerAI>(creature);
return GetInstanceAI<boss_eckAI>(creature);
}
struct npc_ruins_dwellerAI : public ScriptedAI
{
npc_ruins_dwellerAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
void JustDied(Unit* /*killer*/) override
{
instance->SetData64(DATA_RUIN_DWELLER_DIED, me->GetGUID());
if (instance->GetData(DATA_ALIVE_RUIN_DWELLERS) == 0)
me->SummonCreature(CREATURE_ECK, EckSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300*IN_MILLISECONDS);
}
};
};
void AddSC_boss_eck()
{
new boss_eck();
new npc_ruins_dweller();
}

View File

@@ -26,8 +26,7 @@ enum Data
DATA_MOORABI_EVENT,
DATA_DRAKKARI_COLOSSUS_EVENT,
DATA_GAL_DARAH_EVENT,
DATA_ECK_THE_FEROCIOUS_EVENT,
DATA_ALIVE_RUIN_DWELLERS
DATA_ECK_THE_FEROCIOUS_EVENT
};
enum Data64
@@ -39,8 +38,7 @@ enum Data64
DATA_MOORABI_STATUE,
DATA_DRAKKARI_COLOSSUS_STATUE,
DATA_DRAKKARI_COLOSSUS,
DATA_RUIN_DWELLER_DIED,
DATA_STATUE_ACTIVATE,
DATA_STATUE_ACTIVATE
};
enum mainCreatures

View File

@@ -31,6 +31,8 @@
4 - Eck the Ferocious
*/
Position const EckSpawnPoint = { 1643.877930f, 936.278015f, 107.204948f, 0.668432f };
class instance_gundrak : public InstanceMapScript
{
public:
@@ -134,7 +136,7 @@ public:
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
}
bool IsEncounterInProgress() const override
bool IsEncounterInProgress() const override
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
@@ -274,6 +276,17 @@ public:
}
}
void OnUnitDeath(Unit* unit) override
{
if (unit->GetEntry() == CREATURE_RUIN_DWELLER)
{
DwellerGUIDs.erase(unit->GetGUID());
if (DwellerGUIDs.empty())
unit->SummonCreature(CREATURE_ECK, EckSpawnPoint, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 300 * IN_MILLISECONDS);
}
}
void SetData(uint32 type, uint32 data) override
{
switch (type)
@@ -329,9 +342,7 @@ public:
void SetData64(uint32 type, uint64 data) override
{
if (type == DATA_RUIN_DWELLER_DIED)
DwellerGUIDs.erase(data);
else if (type == DATA_STATUE_ACTIVATE)
if (type == DATA_STATUE_ACTIVATE)
{
toActivate = data;
timer = 3500;
@@ -353,8 +364,6 @@ public:
return m_auiEncounter[3];
case DATA_ECK_THE_FEROCIOUS_EVENT:
return m_auiEncounter[4];
case DATA_ALIVE_RUIN_DWELLERS:
return DwellerGUIDs.size();
}
return 0;

View File

@@ -26,7 +26,6 @@ EndScriptData */
/* ContentData
npc_iruk
npc_corastrasza
npc_jenny
npc_sinkhole_kill_credit
npc_khunok_the_behemoth
npc_nerubar_victim
@@ -406,125 +405,6 @@ public:
}
};
/*######
## npc_jenny
######*/
enum Jenny
{
QUEST_LOADER_UP = 11881,
NPC_FEZZIX_GEARTWIST = 25849,
NPC_JENNY = 25969,
SPELL_GIVE_JENNY_CREDIT = 46358,
SPELL_CRATES_CARRIED = 46340,
SPELL_DROP_CRATE = 46342
};
class npc_jenny : public CreatureScript
{
public:
npc_jenny() : CreatureScript("npc_jenny") { }
struct npc_jennyAI : public ScriptedAI
{
npc_jennyAI(Creature* creature) : ScriptedAI(creature)
{
setCrateNumber = false;
}
bool setCrateNumber;
void Reset() override
{
if (!setCrateNumber)
setCrateNumber = true;
me->SetReactState(REACT_PASSIVE);
if (!me->GetOwner())
return;
switch (me->GetOwner()->ToPlayer()->GetTeamId())
{
case TEAM_ALLIANCE:
me->setFaction(FACTION_ESCORT_A_NEUTRAL_ACTIVE);
break;
default:
case TEAM_HORDE:
me->setFaction(FACTION_ESCORT_H_NEUTRAL_ACTIVE);
break;
}
}
void DamageTaken(Unit* /*pDone_by*/, uint32& /*uiDamage*/) override
{
DoCast(me, SPELL_DROP_CRATE, true);
}
void UpdateAI(uint32 /*diff*/) override
{
if (setCrateNumber)
{
me->AddAura(SPELL_CRATES_CARRIED, me);
setCrateNumber = false;
}
if (!setCrateNumber && !me->HasAura(SPELL_CRATES_CARRIED))
me->DisappearAndDie();
if (!UpdateVictim())
return;
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_jennyAI(creature);
}
};
/*######
## npc_fezzix_geartwist
######*/
class npc_fezzix_geartwist : public CreatureScript
{
public:
npc_fezzix_geartwist() : CreatureScript("npc_fezzix_geartwist") { }
struct npc_fezzix_geartwistAI : public ScriptedAI
{
npc_fezzix_geartwistAI(Creature* creature) : ScriptedAI(creature) { }
void MoveInLineOfSight(Unit* who) override
{
ScriptedAI::MoveInLineOfSight(who);
if (who->GetEntry() != NPC_JENNY || !who->HasAura(SPELL_CRATES_CARRIED))
return;
Unit* owner = who->GetOwner();
if (!owner || !me->IsWithinDistInMap(who, 10.0f))
return;
if (Player* player = owner->ToPlayer())
{
owner->CastSpell(owner, SPELL_GIVE_JENNY_CREDIT, true); // Maybe is not working.
player->CompleteQuest(QUEST_LOADER_UP);
who->ToCreature()->DisappearAndDie();
}
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_fezzix_geartwistAI(creature);
}
};
/*######
## npc_nesingwary_trapper
######*/
@@ -2111,65 +1991,6 @@ public:
}
};
/*######
## Quest 11608: Bury Those Cockroaches!
######*/
enum BuryThoseCockroaches
{
// Quest
QUEST_BURY_THOSE_COCKROACHES = 11608,
// Spells
SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION = 45502
};
class npc_seaforium_depth_charge : public CreatureScript
{
public:
npc_seaforium_depth_charge() : CreatureScript("npc_seaforium_depth_charge") { }
struct npc_seaforium_depth_chargeAI : public ScriptedAI
{
npc_seaforium_depth_chargeAI(Creature* creature) : ScriptedAI(creature) { }
uint32 uiExplosionTimer;
void Reset() override
{
uiExplosionTimer = urand(5000, 10000);
}
void UpdateAI(uint32 diff) override
{
if (uiExplosionTimer < diff)
{
DoCast(SPELL_SEAFORIUM_DEPTH_CHARGE_EXPLOSION);
for (uint8 i = 0; i < 4; ++i)
{
if (Creature* cCredit = me->FindNearestCreature(25402 + i, 10.0f))//25402-25405 credit markers
{
if (Unit* uOwner = me->GetOwner())
{
Player* owner = uOwner->ToPlayer();
if (owner && owner->GetQuestStatus(QUEST_BURY_THOSE_COCKROACHES) == QUEST_STATUS_INCOMPLETE)
owner->KilledMonsterCredit(cCredit->GetEntry(), cCredit->GetGUID());
}
}
}
me->Kill(me);
return;
} else uiExplosionTimer -= diff;
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return new npc_seaforium_depth_chargeAI(creature);
}
};
/*######
## Help Those That Cannot Help Themselves, Quest 11876
######*/
@@ -2577,8 +2398,6 @@ void AddSC_borean_tundra()
new npc_corastrasza();
new npc_iruk();
new npc_nerubar_victim();
new npc_jenny();
new npc_fezzix_geartwist();
new npc_nesingwary_trapper();
new npc_lurgglbr();
new npc_nexus_drake_hatchling();
@@ -2593,7 +2412,6 @@ void AddSC_borean_tundra()
new npc_bonker_togglevolt();
new npc_trapped_mammoth_calf();
new npc_magmoth_crusher();
new npc_seaforium_depth_charge();
new npc_valiance_keep_cannoneer();
new npc_warmage_coldarra();
new npc_hidden_cultist();

View File

@@ -80,7 +80,7 @@ public:
switch (eventId)
{
case EVENT_VOID_BLAST:
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true))
{
DoCast(target, SPELL_VOID_BLAST);
++VoidBlastCounter;

View File

@@ -114,7 +114,6 @@ class boss_broggok : public CreatureScript
break;
}
}
};
CreatureAI* GetAI(Creature* creature) const override

View File

@@ -30,7 +30,6 @@ npc_shattrathflaskvendors
npc_zephyr
npc_kservant
npc_ishanah
npc_khadgar
EndContentData */
#include "ScriptMgr.h"
@@ -469,73 +468,6 @@ public:
}
};
/*######
# npc_khadgar
######*/
#define KHADGAR_GOSSIP_1 "I've heard your name spoken only in whispers, mage. Who are you?"
#define KHADGAR_GOSSIP_2 "Go on, please."
#define KHADGAR_GOSSIP_3 "I see." //6th too this
#define KHADGAR_GOSSIP_4 "What did you do then?"
#define KHADGAR_GOSSIP_5 "What happened next?"
#define KHADGAR_GOSSIP_7 "There was something else I wanted to ask you."
class npc_khadgar : public CreatureScript
{
public:
npc_khadgar() : CreatureScript("npc_khadgar") { }
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
player->PlayerTalkClass->ClearMenus();
switch (action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(9876, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
player->SEND_GOSSIP_MENU(9877, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+3:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
player->SEND_GOSSIP_MENU(9878, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+4:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5);
player->SEND_GOSSIP_MENU(9879, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+5:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6);
player->SEND_GOSSIP_MENU(9880, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+6:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_7, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7);
player->SEND_GOSSIP_MENU(9881, creature->GetGUID());
break;
case GOSSIP_ACTION_INFO_DEF+7:
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(9243, creature->GetGUID());
break;
}
return true;
}
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
if (player->GetQuestStatus(10211) != QUEST_STATUS_INCOMPLETE)
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, KHADGAR_GOSSIP_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->SEND_GOSSIP_MENU(9243, creature->GetGUID());
return true;
}
};
void AddSC_shattrath_city()
{
new npc_raliq_the_drunk();
@@ -544,5 +476,4 @@ void AddSC_shattrath_city()
new npc_zephyr();
new npc_kservant();
new npc_ishanah();
new npc_khadgar();
}

View File

@@ -33,7 +33,6 @@ npc_guardian 100% guardianAI used to prevent players from accessin
npc_garments_of_quests 80% NPC's related to all Garments of-quests 5621, 5624, 5625, 5648, 565
npc_injured_patient 100% patients for triage-quests (6622 and 6624)
npc_doctor 100% Gustaf Vanhowzen and Gregory Victor, quest 6622 and 6624 (Triage)
npc_mount_vendor 100% Regular mount vendors all over the world. Display gossip if player doesn't meet the requirements to buy
npc_sayge 100% Darkmoon event fortune teller, buff player based on answers given
npc_snake_trap_serpents 80% AI for snakes that summoned by Snake Trap
npc_shadowfiend 100% restore 5% of owner's mana when shadowfiend die from damage
@@ -1169,105 +1168,6 @@ public:
}
};
/*######
## npc_mount_vendor
######*/
class npc_mount_vendor : public CreatureScript
{
public:
npc_mount_vendor() : CreatureScript("npc_mount_vendor") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
bool canBuy = false;
uint32 vendor = creature->GetEntry();
uint8 race = player->getRace();
switch (vendor)
{
case 384: //Katie Hunter
case 1460: //Unger Statforth
case 2357: //Merideth Carlson
case 4885: //Gregor MacVince
if (player->GetReputationRank(72) != REP_EXALTED && race != RACE_HUMAN)
player->SEND_GOSSIP_MENU(5855, creature->GetGUID());
else canBuy = true;
break;
case 1261: //Veron Amberstill
if (player->GetReputationRank(47) != REP_EXALTED && race != RACE_DWARF)
player->SEND_GOSSIP_MENU(5856, creature->GetGUID());
else canBuy = true;
break;
case 3362: //Ogunaro Wolfrunner
if (player->GetReputationRank(76) != REP_EXALTED && race != RACE_ORC)
player->SEND_GOSSIP_MENU(5841, creature->GetGUID());
else canBuy = true;
break;
case 3685: //Harb Clawhoof
if (player->GetReputationRank(81) != REP_EXALTED && race != RACE_TAUREN)
player->SEND_GOSSIP_MENU(5843, creature->GetGUID());
else canBuy = true;
break;
case 4730: //Lelanai
if (player->GetReputationRank(69) != REP_EXALTED && race != RACE_NIGHTELF)
player->SEND_GOSSIP_MENU(5844, creature->GetGUID());
else canBuy = true;
break;
case 4731: //Zachariah Post
if (player->GetReputationRank(68) != REP_EXALTED && race != RACE_UNDEAD_PLAYER)
player->SEND_GOSSIP_MENU(5840, creature->GetGUID());
else canBuy = true;
break;
case 7952: //Zjolnir
if (player->GetReputationRank(530) != REP_EXALTED && race != RACE_TROLL)
player->SEND_GOSSIP_MENU(5842, creature->GetGUID());
else canBuy = true;
break;
case 7955: //Milli Featherwhistle
if (player->GetReputationRank(54) != REP_EXALTED && race != RACE_GNOME)
player->SEND_GOSSIP_MENU(5857, creature->GetGUID());
else canBuy = true;
break;
case 16264: //Winaestra
if (player->GetReputationRank(911) != REP_EXALTED && race != RACE_BLOODELF)
player->SEND_GOSSIP_MENU(10305, creature->GetGUID());
else canBuy = true;
break;
case 17584: //Torallius the Pack Handler
if (player->GetReputationRank(930) != REP_EXALTED && race != RACE_DRAENEI)
player->SEND_GOSSIP_MENU(10239, creature->GetGUID());
else canBuy = true;
break;
case 48510: //Kall Worthaton
if (player->GetReputationRank(1133) != REP_EXALTED && race != RACE_GOBLIN)
player->SEND_GOSSIP_MENU(17494, creature->GetGUID());
else canBuy = true;
break;
}
if (canBuy)
{
if (creature->IsVendor())
player->ADD_GOSSIP_ITEM(GOSSIP_ICON_VENDOR, GOSSIP_TEXT_BROWSE_GOODS, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_TRADE);
player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
}
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
player->PlayerTalkClass->ClearMenus();
if (action == GOSSIP_ACTION_TRADE)
player->GetSession()->SendListInventory(creature->GetGUID());
return true;
}
};
/*######
## npc_sayge
######*/
@@ -2488,7 +2388,6 @@ void AddSC_npcs_special()
new npc_injured_patient();
new npc_garments_of_quests();
new npc_guardian();
new npc_mount_vendor();
new npc_sayge();
new npc_steam_tonk();
new npc_tonk_mine();