Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2023-03-21 08:46:26 -06:00
committed by GitHub
55 changed files with 3356 additions and 948 deletions

View File

@@ -155,6 +155,9 @@ public:
if (data == SPECIAL)
encounter = SPECIAL;
break;
case DATA_HORSEMAN_EVENT:
encounter = data;
break;
}
}
@@ -177,6 +180,8 @@ public:
{
if (type == TYPE_MOGRAINE_AND_WHITE_EVENT)
return encounter;
else if (type == DATA_HORSEMAN_EVENT)
return encounter;
return 0;
}
private:

View File

@@ -24,6 +24,7 @@
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "SpellAuraEffects.h"
#include "SpellScript.h"
#include "TaskScheduler.h"
@@ -981,14 +982,29 @@ enum headlessHorseman
EVENT_HORSEMAN_CONFLAGRATION = 5,
EVENT_SUMMON_PUMPKIN = 6,
EVENT_HORSEMAN_FOLLOW = 7,
// Headless Horseman
TALK_ENTRANCE = 0,
TALK_REJOINED = 1,
TALK_CONFLAGRATION = 2,
TALK_SPROUTING_PUMPKINS = 3,
TALK_DEATH = 4,
TALK_PLAYER_DEATH = 5,
// Head of the Horseman
TALK_LAUGH = 0,
TALK_LOST_HEAD = 1,
// Player
TALK_PLAYER_RISE = 22695,
TALK_PLAYER_TIME_IS_NIGH = 22696,
TALK_PLAYER_FELT_DEATH = 22720,
TALK_PLAYER_KNOW_DEMISE = 22721,
};
enum hhSounds
enum hhMisc
{
SOUND_AGGRO = 11961,
SOUND_SLAY = 11962,
SOUND_SPROUT = 11963,
SOUND_DEATH = 11964,
DATA_HORSEMAN_EVENT = 5,
};
struct boss_headless_horseman : public ScriptedAI
@@ -1006,8 +1022,7 @@ struct boss_headless_horseman : public ScriptedAI
void JustDied(Unit* /*killer*/) override
{
summons.DespawnAll();
me->Say("This end have I reached before. What new adventure lies in store?", LANG_UNIVERSAL);
me->PlayDirectSound(SOUND_DEATH);
Talk(TALK_DEATH);
std::list<Creature*> unitList;
me->GetCreaturesWithEntryInRange(unitList, 100.0f, NPC_PUMPKIN_FIEND);
for (std::list<Creature*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
@@ -1016,12 +1031,14 @@ struct boss_headless_horseman : public ScriptedAI
Map::PlayerList const& players = me->GetMap()->GetPlayers();
if (!players.IsEmpty() && players.begin()->GetSource() && players.begin()->GetSource()->GetGroup())
sLFGMgr->FinishDungeon(players.begin()->GetSource()->GetGroup()->GetGUID(), lfg::LFG_DUNGEON_HEADLESS_HORSEMAN, me->FindMap());
if (InstanceScript* instance = me->GetInstanceScript())
instance->SetData(DATA_HORSEMAN_EVENT, DONE);
}
void KilledUnit(Unit* /*who*/) override
{
me->Yell("Your body lies beaten, battered and broken. Let my curse be your own, fate has spoken.", LANG_UNIVERSAL);
me->PlayDirectSound(SOUND_SLAY);
Talk(TALK_PLAYER_DEATH);
}
void DoAction(int32 param) override
@@ -1052,7 +1069,7 @@ struct boss_headless_horseman : public ScriptedAI
events.CancelEvent(EVENT_HORSEMAN_WHIRLWIND);
events.CancelEvent(EVENT_HORSEMAN_CONFLAGRATION);
events.CancelEvent(EVENT_SUMMON_PUMPKIN);
me->Yell("Here's my body, fit and pure! Now, your blackened souls I'll cure!", LANG_UNIVERSAL);
Talk(TALK_REJOINED);
if (phase == 1)
events.ScheduleEvent(EVENT_HORSEMAN_CONFLAGRATION, 6s);
@@ -1131,6 +1148,14 @@ struct boss_headless_horseman : public ScriptedAI
me->SetSpeed(MOVE_WALK, 5.0f, true);
}
void JustReachedHome() override
{
if (InstanceScript* instance = me->GetInstanceScript())
instance->SetData(DATA_HORSEMAN_EVENT, FAIL);
me->DespawnOrUnsummon();
}
void UpdateAI(uint32 diff) override
{
events.Update(diff);
@@ -1152,23 +1177,22 @@ struct boss_headless_horseman : public ScriptedAI
switch (talkCount)
{
case 1:
player->Say("Horseman rise...", LANG_UNIVERSAL);
player->Say(TALK_PLAYER_RISE);
break;
case 2:
player->Say("Your time is nigh...", LANG_UNIVERSAL);
player->Say(TALK_PLAYER_TIME_IS_NIGH);
if (Creature* trigger = me->SummonTrigger(1765.28f, 1347.46f, 17.5514f, 0.0f, 15 * IN_MILLISECONDS))
trigger->CastSpell(trigger, SPELL_EARTH_EXPLOSION, true);
break;
case 3:
me->GetMotionMaster()->MovePath(236820, false);
me->CastSpell(me, SPELL_SHAKE_CAMERA_SMALL, true);
player->Say("You felt death once...", LANG_UNIVERSAL);
me->Say("It is over, your search is done. Let fate choose now, the righteous one.", LANG_UNIVERSAL);
me->PlayDirectSound(SOUND_AGGRO);
player->Say(TALK_PLAYER_FELT_DEATH);
Talk(TALK_ENTRANCE);
break;
case 4:
me->CastSpell(me, SPELL_SHAKE_CAMERA_MEDIUM, true);
player->Say("Now, know demise!", LANG_UNIVERSAL);
player->Say(TALK_PLAYER_KNOW_DEMISE);
talkCount = 0;
return; // pop and return, skip repeat
}
@@ -1220,7 +1244,7 @@ struct boss_headless_horseman : public ScriptedAI
{
me->CastSpell(target, SPELL_HORSEMAN_CONFLAGRATION, false);
target->CastSpell(target, SPELL_HORSEMAN_CONFLAGRATION_SOUND, true);
me->Say("Harken, cur! Tis you I spurn! Now feel... the burn!", LANG_UNIVERSAL, target);
Talk(TALK_CONFLAGRATION);
}
events.RepeatEvent(12500);
@@ -1236,8 +1260,7 @@ struct boss_headless_horseman : public ScriptedAI
}
else
{
me->Say("Soldiers arise, stand and fight! Bring victory at last to this fallen knight!", LANG_UNIVERSAL);
me->PlayDirectSound(SOUND_SPROUT);
Talk(TALK_SPROUTING_PUMPKINS);
events.RepeatEvent(15000);
talkCount = 0;
}
@@ -1334,6 +1357,8 @@ struct boss_headless_horseman_head : public ScriptedAI
me->CastSpell(me, SPELL_THROW_HEAD_BACK, true);
if (Unit* owner = GetOwner())
owner->RemoveAura(SPELL_HORSEMAN_IMMUNITY);
Talk(TALK_LOST_HEAD);
}
}
@@ -1351,20 +1376,8 @@ struct boss_headless_horseman_head : public ScriptedAI
if (timer >= 30000)
{
timer = urand(0, 15000);
uint32 sound = 11965;
switch (urand(0, 2))
{
case 1:
sound = 11975;
break;
case 2:
sound = 11976;
break;
}
me->CastSpell(me, SPELL_HORSEMAN_SPEAKS, true);
me->TextEmote("Headless Horseman laughs");
me->PlayDirectSound(sound);
Talk(TALK_LAUGH);
}
}
};
@@ -1450,6 +1463,33 @@ public:
}
};
class go_pumpkin_shrine : public GameObjectScript
{
public:
go_pumpkin_shrine() : GameObjectScript("go_pumpkin_shrine") {}
bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) override
{
CloseGossipMenuFor(player);
if (InstanceScript* instance = go->GetInstanceScript())
{
if (instance->GetData(DATA_HORSEMAN_EVENT) == IN_PROGRESS || instance->GetData(DATA_HORSEMAN_EVENT) == DONE)
return true;
if (player->FindNearestCreature(NPC_HEADLESS_HORSEMAN_MOUNTED, 100.0f))
return true;
if (Creature* horseman = go->SummonCreature(NPC_HEADLESS_HORSEMAN_MOUNTED, 1754.00f, 1346.00f, 17.50f, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 0))
horseman->CastSpell(player, SPELL_SUMMONING_RHYME_TARGET, true);
instance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS);
}
return true;
}
};
void AddSC_event_hallows_end_scripts()
{
// Spells
@@ -1475,6 +1515,7 @@ void AddSC_event_hallows_end_scripts()
// Headless Horseman
new go_loosely_turned_soil();
new go_pumpkin_shrine();
RegisterCreatureAI(boss_headless_horseman);
RegisterCreatureAI(boss_headless_horseman_head);
RegisterCreatureAI(boss_headless_horseman_pumpkin);

View File

@@ -203,7 +203,7 @@ public:
events.ScheduleEvent(EVENT_SPELL_HAMMER, 30000);
break;
case EVENT_SPELL_HOLY_SHIELD:
me->CastSpell(me, SPELL_CLEANSE, false);
me->CastSpell(me, SPELL_HOLY_SHIELD, false);
events.ScheduleEvent(SPELL_HOLY_SHIELD, 30000);
break;
case EVENT_SPELL_CONSECRATION:

View File

@@ -130,7 +130,7 @@ public:
case NPC_INFINITE_EXECUTIONER_2:
case NPC_INFINITE_VANQUISHER:
case NPC_INFINITE_VANQUISHER_2:
creature->DespawnOrUnsummon();
creature->DespawnOrUnsummon(1);
break;
default:
break;

View File

@@ -3051,95 +3051,110 @@ public:
}
};
class npc_icc_spire_frostwyrm : public CreatureScript
enum SpireFrostwyrm
{
public:
npc_icc_spire_frostwyrm() : CreatureScript("npc_icc_spire_frostwyrm") { }
SPELL_BLIZZARD = 70362,
SPELL_CLEAVE = 70361,
SPELL_FROSTBREATH = 70116,
struct npc_icc_spire_frostwyrmAI : public ScriptedAI
HORDE_AREATRIGGER = 5630
};
struct npc_icc_spire_frostwyrm : public ScriptedAI
{
npc_icc_spire_frostwyrm(Creature* creature) : ScriptedAI(creature)
{
npc_icc_spire_frostwyrmAI(Creature* creature) : ScriptedAI(creature)
_scheduler.SetValidator([this]
{
me->SetCanFly(true);
me->SetDisableGravity(true);
}
return !me->HasUnitState(UNIT_STATE_CASTING);
});
EventMap events;
void Reset() override
{
events.Reset();
events.ScheduleEvent(1, 15s, 25s); // blizzard
events.ScheduleEvent(2, 5s); // cleave
events.ScheduleEvent(3, 10s, 15s); // frost breath
}
void DoAction(int32 a) override
{
if (a != -1)
return;
if (me->GetHomePosition().GetPositionZ() < 225.0f)
return;
me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), 191.26f, me->GetOrientation());
me->GetMotionMaster()->MoveLand(1, me->GetPositionX(), me->GetPositionY(), 191.26f, 2.5f * 7.0f);
Talk(0);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == EFFECT_MOTION_TYPE && id == 1)
{
me->SetCanFly(false);
me->SetDisableGravity(false);
if (Player* p = SelectTargetFromPlayerList(100.0f))
{
Talk(p->GetTeamId() == TEAM_HORDE ? 1 : 2);
AttackStart(p);
}
}
}
bool CanAIAttack(Unit const* target) const override
{
return me->GetPositionZ() < 225.0f && me->GetHomePosition().GetExactDist(target) < 200.0f;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case 1:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 40.0f, true))
me->CastSpell(target, 70362, false);
events.Repeat(25s, 35s);
break;
case 2:
me->CastSpell(me->GetVictim(), 70361, false);
events.Repeat(5s);
break;
case 3:
me->CastSpell(me->GetVictim(), 70116, false);
events.Repeat(10s, 15s);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetIcecrownCitadelAI<npc_icc_spire_frostwyrmAI>(creature);
_canResetFlyingEffects = true;
}
void Reset() override
{
if (!_canResetFlyingEffects)
{
me->SetCanFly(false);
me->SetDisableGravity(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
}
}
void JustEngagedWith(Unit* /*victim*/) override
{
_scheduler.Schedule(15s, 25s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_BLIZZARD);
context.Repeat(25s, 35s);
}).Schedule(5s, [this](TaskContext context)
{
DoCastVictim(SPELL_CLEAVE);
context.Repeat();
}).Schedule(10s, 15s, [this](TaskContext context)
{
DoCastVictim(SPELL_FROSTBREATH);
context.Repeat();
});
_canResetFlyingEffects = false;
}
void DoAction(int32 action) override
{
const Position posHordeMove = { -433.667084f, 2080.347412f, 191.253860f, 3.825093f };
const Position posAllianceMove = { -433.589508f, 2344.564697f, 191.253616f, 2.543328f };
bool hordeSide = action == HORDE_AREATRIGGER || action == HORDE_AREATRIGGER + 1;
Position landingPosition = hordeSide ? posHordeMove : posAllianceMove;
me->GetMotionMaster()->MovePoint(1, landingPosition);
me->SetHomePosition(landingPosition);
Talk(0);
}
void MovementInform(uint32 type, uint32 id) override
{
if (type == EFFECT_MOTION_TYPE && id == 1)
{
me->SetCanFly(false);
me->SetDisableGravity(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
_canResetFlyingEffects = false;
}
}
void JustReachedHome() override
{
ScriptedAI::JustReachedHome();
if (!_canResetFlyingEffects)
{
me->SetCanFly(false);
me->SetDisableGravity(false);
me->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_ALWAYS_STAND | UNIT_BYTE1_FLAG_HOVER);
}
}
bool CanAIAttack(Unit const* target) const override
{
return me->GetPositionZ() < 225.0f && me->GetHomePosition().GetExactDist(target) < 200.0f;
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_scheduler.Update(diff,
std::bind(&ScriptedAI::DoMeleeAttackIfReady, this));
}
private:
TaskScheduler _scheduler;
bool _canResetFlyingEffects;
};
#define VENGEFUL_WP_COUNT 6
@@ -3746,16 +3761,27 @@ public:
}
};
class at_icc_spire_frostwyrm : public AreaTriggerScript
class at_icc_spire_frostwyrm : public OnlyOnceAreaTriggerScript
{
public:
at_icc_spire_frostwyrm() : AreaTriggerScript("at_icc_spire_frostwyrm") { }
at_icc_spire_frostwyrm() : OnlyOnceAreaTriggerScript("at_icc_spire_frostwyrm") { }
bool OnTrigger(Player* player, AreaTrigger const* /*areaTrigger*/) override
bool _OnTrigger(Player* player, AreaTrigger const* areaTrigger) override
{
if (Creature* frostwyrm = player->FindNearestCreature(NPC_SPIRE_FROSTWYRM, 150.0f, true))
if (frostwyrm->GetPositionZ() > 250.0f && frostwyrm->AI())
frostwyrm->AI()->DoAction(-1);
if (player->GetInstanceScript()->GetPersistentData(DATA_SPIRE_FROSTWYRM) != DONE)
{
player->GetInstanceScript()->StorePersistentData(DATA_SPIRE_FROSTWYRM, DONE);
const Position posHordeWyrm = { -375.538879f, 2120.774658f, 242.256775f, 3.714352f };
const Position posAllianceWyrm = { -361.154358f, 2305.821289f, 244.771713f, 2.704335f };
bool hordeSide = areaTrigger->entry == HORDE_AREATRIGGER || areaTrigger->entry == HORDE_AREATRIGGER + 1;
if (Creature* frostwyrm = player->SummonCreature(NPC_SPIRE_FROSTWYRM, hordeSide ? posHordeWyrm : posAllianceWyrm))
{
frostwyrm->AI()->DoAction(areaTrigger->entry);
}
}
return true;
}
};
@@ -3803,7 +3829,7 @@ void AddSC_icecrown_citadel()
new npc_icc_skybreaker_luminary();
new npc_icc_valkyr_herald();
new npc_icc_severed_essence();
new npc_icc_spire_frostwyrm();
RegisterIcecrownCitadelCreatureAI(npc_icc_spire_frostwyrm);
new npc_icc_vengeful_fleshreaper();
new npc_icc_buff_switcher();
new npc_icc_nerubar_broodkeeper();

View File

@@ -148,6 +148,12 @@ enum DataTypes
DATA_BPC_TRASH_DIED = 300,
};
enum PersistentData
{
DATA_SPIRE_FROSTWYRM = 0,
MAX_DATA_INDEXES
};
enum CreaturesIds
{
// At Light's Hammer

View File

@@ -199,6 +199,7 @@ public:
SetHeaders(DataHeader);
SetBossNumber(MAX_ENCOUNTERS);
SetPersistentDataCount(MAX_DATA_INDEXES);
LoadBossBoundaries(boundaries);
LoadDoorData(doorData);
TeamIdInInstance = TEAM_NEUTRAL;

View File

@@ -34,81 +34,54 @@ enum Spells
SPELL_SHADOW_POWER = 35322
};
enum Events
struct boss_gatewatcher_gyrokill : public BossAI
{
EVENT_STREAM_OF_MACHINE_FLUID = 1,
EVENT_SAW_BLADE = 2,
EVENT_SHADOW_POWER = 3
};
class boss_gatewatcher_gyrokill : public CreatureScript
{
public:
boss_gatewatcher_gyrokill() : CreatureScript("boss_gatewatcher_gyrokill") { }
struct boss_gatewatcher_gyrokillAI : public BossAI
boss_gatewatcher_gyrokill(Creature* creature) : BossAI(creature, DATA_GATEWATCHER_GYROKILL)
{
boss_gatewatcher_gyrokillAI(Creature* creature) : BossAI(creature, DATA_GATEWATCHER_GYROKILL) { }
void JustDied(Unit* /*killer*/) override
scheduler.SetValidator([this]
{
_JustDied();
Talk(SAY_DEATH);
}
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
events.ScheduleEvent(EVENT_STREAM_OF_MACHINE_FLUID, 10000);
events.ScheduleEvent(EVENT_SAW_BLADE, 20000);
events.ScheduleEvent(EVENT_SHADOW_POWER, 30000);
Talk(SAY_AGGRO);
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_STREAM_OF_MACHINE_FLUID:
me->CastSpell(me->GetVictim(), SPELL_STREAM_OF_MACHINE_FLUID, false);
events.ScheduleEvent(EVENT_STREAM_OF_MACHINE_FLUID, urand(12000, 14000));
break;
case EVENT_SAW_BLADE:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 50.0f))
me->CastSpell(target, SPELL_SAW_BLADE, false);
Talk(SAY_SAW_BLADE);
events.ScheduleEvent(EVENT_SAW_BLADE, 25000);
break;
case EVENT_SHADOW_POWER:
me->CastSpell(me, SPELL_SHADOW_POWER, false);
events.ScheduleEvent(EVENT_SAW_BLADE, 25000);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
void JustDied(Unit* /*killer*/) override
{
return GetMechanarAI<boss_gatewatcher_gyrokillAI>(creature);
_JustDied();
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
scheduler.Schedule(10s, [this](TaskContext context)
{
DoCastVictim(SPELL_STREAM_OF_MACHINE_FLUID);
context.Repeat(12s, 14s);
}).Schedule(20s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_SAW_BLADE, 0, 50.0f);
Talk(SAY_SAW_BLADE);
context.Repeat(25s);
}).Schedule(30s, [this](TaskContext context)
{
me->CastSpell(me, SPELL_SHADOW_POWER, false);
context.Repeat(25s);
});
Talk(SAY_AGGRO);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
{
Talk(SAY_SLAY);
}
}
};
void AddSC_boss_gatewatcher_gyrokill()
{
new boss_gatewatcher_gyrokill();
RegisterMechanarCreatureAI(boss_gatewatcher_gyrokill);
}

View File

@@ -35,83 +35,55 @@ enum Spells
SPELL_STREAM_OF_MACHINE_FLUID = 35311
};
enum Events
struct boss_gatewatcher_iron_hand : public BossAI
{
EVENT_STREAM_OF_MACHINE_FLUID = 1,
EVENT_JACKHAMMER = 2,
EVENT_SHADOW_POWER = 3
};
class boss_gatewatcher_iron_hand : public CreatureScript
{
public:
boss_gatewatcher_iron_hand(): CreatureScript("boss_gatewatcher_iron_hand") { }
struct boss_gatewatcher_iron_handAI : public BossAI
boss_gatewatcher_iron_hand(Creature* creature) : BossAI(creature, DATA_GATEWATCHER_IRON_HAND)
{
boss_gatewatcher_iron_handAI(Creature* creature) : BossAI(creature, DATA_GATEWATCHER_IRON_HAND) { }
void JustEngagedWith(Unit* /*who*/) override
scheduler.SetValidator([this]
{
_JustEngagedWith();
events.ScheduleEvent(EVENT_STREAM_OF_MACHINE_FLUID, 15000);
events.ScheduleEvent(EVENT_JACKHAMMER, 35000);
events.ScheduleEvent(EVENT_SHADOW_POWER, 25000);
Talk(SAY_AGGRO);
}
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_STREAM_OF_MACHINE_FLUID:
me->CastSpell(me->GetVictim(), SPELL_STREAM_OF_MACHINE_FLUID, false);
events.ScheduleEvent(EVENT_STREAM_OF_MACHINE_FLUID, 20000);
break;
case EVENT_JACKHAMMER:
Talk(EMOTE_HAMMER);
Talk(SAY_HAMMER);
me->CastSpell(me, SPELL_JACKHAMMER, false);
events.ScheduleEvent(EVENT_JACKHAMMER, 40000);
break;
case EVENT_SHADOW_POWER:
me->CastSpell(me, SPELL_SHADOW_POWER, false);
events.ScheduleEvent(EVENT_SHADOW_POWER, 25000);
break;
default:
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
void JustEngagedWith(Unit* /*who*/) override
{
return GetMechanarAI<boss_gatewatcher_iron_handAI>(creature);
_JustEngagedWith();
scheduler.Schedule(15s, [this](TaskContext context)
{
DoCastVictim(SPELL_STREAM_OF_MACHINE_FLUID);
context.Repeat(20s);
}).Schedule(35s, [this](TaskContext context)
{
Talk(EMOTE_HAMMER);
Talk(SAY_HAMMER);
DoCastSelf(SPELL_JACKHAMMER);
context.Repeat(40s);
}).Schedule(25s, [this](TaskContext context)
{
DoCastSelf(SPELL_SHADOW_POWER);
context.Repeat(25s);
});
Talk(SAY_AGGRO);
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
{
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
};
void AddSC_boss_gatewatcher_iron_hand()
{
new boss_gatewatcher_iron_hand();
RegisterMechanarCreatureAI(boss_gatewatcher_iron_hand);
}

View File

@@ -27,16 +27,23 @@ enum Spells
SPELL_REFLECTIVE_MAGIC_SHIELD = 35158,
SPELL_REFLECTIVE_DAMAGE_SHIELD = 35159,
SPELL_POLARITY_SHIFT = 39096,
SPELL_BERSERK = 26662
SPELL_BERSERK = 26662,
SPELL_NETHER_CHARGE_PASSIVE = 35150,
SPELL_SUMMON_NETHER_CHARGE_NE = 35153,
SPELL_SUMMON_NETHER_CHARGE_NW = 35904,
SPELL_SUMMON_NETHER_CHARGE_SE = 35905,
SPELL_SUMMON_NETHER_CHARGE_SW = 35906,
};
enum Yells
{
YELL_AGGRO = 0,
YELL_REFLECTIVE_MAGIC_SHIELD = 1,
YELL_REFLECTIVE_DAMAGE_SHIELD = 2,
YELL_KILL = 3,
YELL_DEATH = 4
SAY_AGGRO = 0,
SAY_REFLECTIVE_MAGIC_SHIELD = 1,
SAY_REFLECTIVE_DAMAGE_SHIELD = 2,
SAY_KILL = 3,
SAY_DEATH = 4
};
enum Creatures
@@ -44,101 +51,84 @@ enum Creatures
NPC_NETHER_CHARGE = 20405
};
enum Events
struct boss_mechano_lord_capacitus : public BossAI
{
EVENT_HEADCRACK = 1,
EVENT_REFLECTIVE_DAMAGE_SHIELD = 2,
EVENT_REFLECTIVE_MAGIE_SHIELD = 3,
EVENT_POSITIVE_SHIFT = 4,
EVENT_SUMMON_NETHER_CHARGE = 5,
EVENT_BERSERK = 6
};
class boss_mechano_lord_capacitus : public CreatureScript
{
public:
boss_mechano_lord_capacitus() : CreatureScript("boss_mechano_lord_capacitus") { }
struct boss_mechano_lord_capacitusAI : public BossAI
boss_mechano_lord_capacitus(Creature* creature) : BossAI(creature, DATA_MECHANOLORD_CAPACITUS)
{
boss_mechano_lord_capacitusAI(Creature* creature) : BossAI(creature, DATA_MECHANOLORD_CAPACITUS) { }
void JustEngagedWith(Unit* /*who*/) override
scheduler.SetValidator([this]
{
_JustEngagedWith();
Talk(YELL_AGGRO);
events.ScheduleEvent(EVENT_HEADCRACK, 6000);
events.ScheduleEvent(EVENT_SUMMON_NETHER_CHARGE, 10000);
events.ScheduleEvent(EVENT_BERSERK, 180000);
events.ScheduleEvent(IsHeroic() ? EVENT_POSITIVE_SHIFT : EVENT_REFLECTIVE_DAMAGE_SHIELD, 15000);
}
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void KilledUnit(Unit* victim) override
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
Talk(SAY_AGGRO);
scheduler.Schedule(6s, [this](TaskContext context)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(YELL_KILL);
}
void JustDied(Unit* /*killer*/) override
DoCastVictim(SPELL_HEADCRACK);
context.Repeat(20s);
}).Schedule(10s, [this](TaskContext context)
{
_JustDied();
Talk(YELL_DEATH);
}
void JustSummoned(Creature* summon) override
uint32 spellId = RAND(SPELL_SUMMON_NETHER_CHARGE_NE,
SPELL_SUMMON_NETHER_CHARGE_NW,
SPELL_SUMMON_NETHER_CHARGE_SE,
SPELL_SUMMON_NETHER_CHARGE_SW);
DoCastAOE(spellId);
IsHeroic() ? context.Repeat(2s, 5s) : context.Repeat(9s, 11s);
}).Schedule(3min, [this](TaskContext /*context*/)
{
summons.Summon(summon);
summon->GetMotionMaster()->MoveRandom(30.0f);
}
DoCastSelf(SPELL_BERSERK, true);
});
void UpdateAI(uint32 diff) override
if (IsHeroic())
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
scheduler.Schedule(15s, [this](TaskContext context)
{
case EVENT_HEADCRACK:
me->CastSpell(me->GetVictim(), SPELL_HEADCRACK, false);
events.ScheduleEvent(EVENT_HEADCRACK, 20000);
break;
case EVENT_REFLECTIVE_DAMAGE_SHIELD:
Talk(YELL_REFLECTIVE_DAMAGE_SHIELD);
me->CastSpell(me, SPELL_REFLECTIVE_DAMAGE_SHIELD, false);
events.ScheduleEvent(EVENT_REFLECTIVE_MAGIE_SHIELD, 20000);
break;
case EVENT_REFLECTIVE_MAGIE_SHIELD:
Talk(YELL_REFLECTIVE_MAGIC_SHIELD);
me->CastSpell(me, SPELL_REFLECTIVE_MAGIC_SHIELD, false);
events.ScheduleEvent(EVENT_REFLECTIVE_DAMAGE_SHIELD, 20000);
break;
case EVENT_SUMMON_NETHER_CHARGE:
{
Position pos = me->GetRandomNearPosition(8.0f);
me->SummonCreature(NPC_NETHER_CHARGE, pos, TEMPSUMMON_TIMED_DESPAWN, 18000);
events.ScheduleEvent(EVENT_SUMMON_NETHER_CHARGE, 5000);
break;
}
case EVENT_POSITIVE_SHIFT:
me->CastSpell(me, SPELL_POLARITY_SHIFT, true);
events.ScheduleEvent(EVENT_POSITIVE_SHIFT, 30000);
break;
case EVENT_BERSERK:
me->CastSpell(me, SPELL_BERSERK, true);
break;
}
DoMeleeAttackIfReady();
DoCastSelf(SPELL_POLARITY_SHIFT, true);
context.Repeat(30s);
});
}
};
else
{
scheduler.Schedule(15s, [this](TaskContext context)
{
if (IsEvenNumber(context.GetRepeatCounter()))
{
Talk(SAY_REFLECTIVE_DAMAGE_SHIELD);
DoCastSelf(SPELL_REFLECTIVE_DAMAGE_SHIELD);
}
else
{
Talk(SAY_REFLECTIVE_MAGIC_SHIELD);
DoCastSelf(SPELL_REFLECTIVE_MAGIC_SHIELD);
}
CreatureAI* GetAI(Creature* creature) const override
context.Repeat(20s);
});
}
}
void KilledUnit(Unit* victim) override
{
return GetMechanarAI<boss_mechano_lord_capacitusAI>(creature);
if (victim->IsPlayer())
{
Talk(SAY_KILL);
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
summon->GetMotionMaster()->MoveRandom(30.0f);
}
};
@@ -153,84 +143,62 @@ enum polarityShift
SPELL_NEGATIVE_CHARGE = 39093
};
class spell_capacitus_polarity_charge : public SpellScriptLoader
class spell_capacitus_polarity_charge : public SpellScript
{
public:
spell_capacitus_polarity_charge() : SpellScriptLoader("spell_capacitus_polarity_charge") { }
PrepareSpellScript(spell_capacitus_polarity_charge);
class spell_capacitus_polarity_charge_SpellScript : public SpellScript
void HandleTargets(std::list<WorldObject*>& targetList)
{
PrepareSpellScript(spell_capacitus_polarity_charge_SpellScript);
uint8 count = 0;
for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
++count;
void HandleTargets(std::list<WorldObject*>& targetList)
if (count)
{
uint8 count = 0;
for (std::list<WorldObject*>::iterator ihit = targetList.begin(); ihit != targetList.end(); ++ihit)
if ((*ihit)->GetGUID() != GetCaster()->GetGUID())
if (Player* target = (*ihit)->ToPlayer())
if (target->HasAura(GetTriggeringSpell()->Id))
++count;
if (count)
{
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
}
uint32 spellId = GetSpellInfo()->Id == SPELL_POSITIVE_CHARGE ? SPELL_POSITIVE_CHARGE_STACK : SPELL_NEGATIVE_CHARGE_STACK;
GetCaster()->SetAuraStack(spellId, GetCaster(), count);
}
}
void HandleDamage(SpellEffIndex /*effIndex*/)
{
if (!GetTriggeringSpell())
return;
Unit* target = GetHitUnit();
if (target->HasAura(GetTriggeringSpell()->Id))
SetHitDamage(0);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_charge_SpellScript::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_capacitus_polarity_charge_SpellScript::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
SpellScript* GetSpellScript() const override
void HandleDamage(SpellEffIndex /*effIndex*/)
{
return new spell_capacitus_polarity_charge_SpellScript();
if (!GetTriggeringSpell())
return;
Unit* target = GetHitUnit();
if (target->HasAura(GetTriggeringSpell()->Id))
SetHitDamage(0);
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_charge::HandleDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_capacitus_polarity_charge::HandleTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY);
}
};
class spell_capacitus_polarity_shift : public SpellScriptLoader
class spell_capacitus_polarity_shift : public SpellScript
{
public:
spell_capacitus_polarity_shift() : SpellScriptLoader("spell_capacitus_polarity_shift") { }
PrepareSpellScript(spell_capacitus_polarity_shift);
class spell_capacitus_polarity_shift_SpellScript : public SpellScript
void HandleDummy(SpellEffIndex /*effIndex*/)
{
PrepareSpellScript(spell_capacitus_polarity_shift_SpellScript);
if (Unit* target = GetHitUnit())
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, GetCaster()->GetGUID());
}
void HandleDummy(SpellEffIndex /*effIndex*/)
{
if (Unit* target = GetHitUnit())
target->CastSpell(target, roll_chance_i(50) ? SPELL_POSITIVE_POLARITY : SPELL_NEGATIVE_POLARITY, true, nullptr, nullptr, GetCaster()->GetGUID());
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_shift_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_capacitus_polarity_shift_SpellScript();
OnEffectHitTarget += SpellEffectFn(spell_capacitus_polarity_shift::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
void AddSC_boss_mechano_lord_capacitus()
{
new boss_mechano_lord_capacitus();
new spell_capacitus_polarity_charge();
new spell_capacitus_polarity_shift();
RegisterMechanarCreatureAI(boss_mechano_lord_capacitus);
RegisterSpellScript(spell_capacitus_polarity_charge);
RegisterSpellScript(spell_capacitus_polarity_shift);
}

View File

@@ -30,201 +30,174 @@ enum Says
enum Spells
{
SPELL_SUMMON_RAGIN_FLAMES = 35275,
SPELL_FROST_ATTACK = 35263,
SPELL_FROST_ATTACK = 45196, // This is definitely spell added in TBC but did it replaced both 35264 and 39086 or only normal version?
SPELL_SUMMON_RAGING_FLAMES = 35275,
SPELL_QUELL_RAGING_FLAMES = 35277,
SPELL_ARCANE_BLAST = 35314,
SPELL_DRAGONS_BREATH = 35250,
// Raging Flames
SPELL_RAGING_FLAMES_DUMMY = 35274, // NYI, no clue what it can do
SPELL_RAGING_FLAMES_AREA_AURA = 35281,
SPELL_INVIS_STEALTH_DETECTION = 18950,
SPELL_INFERNO = 35268,
SPELL_INFERNO_DAMAGE = 35283
};
enum Events
struct boss_nethermancer_sepethrea : public BossAI
{
EVENT_FROST_ATTACK = 1,
EVENT_ARCANE_BLAST = 2,
EVENT_DRAGONS_BREATH = 3,
};
class boss_nethermancer_sepethrea : public CreatureScript
{
public:
boss_nethermancer_sepethrea(): CreatureScript("boss_nethermancer_sepethrea") { }
struct boss_nethermancer_sepethreaAI : public BossAI
boss_nethermancer_sepethrea(Creature* creature) : BossAI(creature, DATA_NETHERMANCER_SEPRETHREA)
{
boss_nethermancer_sepethreaAI(Creature* creature) : BossAI(creature, DATA_NETHERMANCER_SEPRETHREA) { }
void JustEngagedWith(Unit* /*who*/) override
scheduler.SetValidator([this]
{
_JustEngagedWith();
events.ScheduleEvent(EVENT_FROST_ATTACK, 6000);
events.ScheduleEvent(EVENT_ARCANE_BLAST, 14000);
events.ScheduleEvent(EVENT_DRAGONS_BREATH, 18000);
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
Talk(SAY_AGGRO);
me->CastSpell(me, SPELL_SUMMON_RAGIN_FLAMES, true);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (Unit* victim = me->GetVictim())
{
summon->AI()->AttackStart(victim);
summon->AddThreat(victim, 1000.0f);
summon->SetInCombatWithZone();
}
}
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
void JustDied(Unit* /*killer*/) override
{
events.Reset();
if (instance)
{
instance->SetBossState(DATA_NETHERMANCER_SEPRETHREA, DONE);
instance->SaveToDB();
}
Talk(SAY_DEATH);
for (SummonList::const_iterator itr = summons.begin(); itr != summons.end(); ++itr)
if (Creature* summon = ObjectAccessor::GetCreature(*me, *itr))
Unit::Kill(summon, summon);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_FROST_ATTACK:
me->CastSpell(me->GetVictim(), SPELL_FROST_ATTACK, false);
events.ScheduleEvent(EVENT_FROST_ATTACK, 8000);
break;
case EVENT_ARCANE_BLAST:
me->CastSpell(me->GetVictim(), SPELL_ARCANE_BLAST, false);
events.ScheduleEvent(EVENT_ARCANE_BLAST, 12000);
break;
case EVENT_DRAGONS_BREATH:
me->CastSpell(me->GetVictim(), SPELL_DRAGONS_BREATH, true);
events.ScheduleEvent(EVENT_DRAGONS_BREATH, 16000);
if (roll_chance_i(50))
Talk(SAY_DRAGONS_BREATH);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
void JustEngagedWith(Unit* /*who*/) override
{
return GetMechanarAI<boss_nethermancer_sepethreaAI>(creature);
_JustEngagedWith();
scheduler.Schedule(6s, [this](TaskContext context)
{
DoCastVictim(SPELL_FROST_ATTACK);
context.Repeat(8s);
}).Schedule(15s, 25s, [this](TaskContext context)
{
DoCastVictim(SPELL_ARCANE_BLAST);
if (me->GetVictim())
{
DoModifyThreatByPercent(me->GetVictim(), -50);
}
context.Repeat();
}).Schedule(20s, 30s, [this](TaskContext context)
{
DoCastVictim(SPELL_DRAGONS_BREATH);
context.Repeat(25s, 35s);
if (roll_chance_i(50))
{
Talk(SAY_DRAGONS_BREATH);
}
});
Talk(SAY_AGGRO);
DoCastSelf(SPELL_SUMMON_RAGING_FLAMES, true);
}
void EnterEvadeMode(EvadeReason why) override
{
// Fails probably because target is in evade mode (yes, she kills them on evade too). We'll kill them directly in their script for now
DoCastSelf(SPELL_QUELL_RAGING_FLAMES, true);
ScriptedAI::EnterEvadeMode(why);
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (Unit* victim = me->GetVictim())
{
summon->AI()->AttackStart(victim);
summon->AddThreat(victim, 1000.0f);
summon->SetInCombatWithZone();
}
}
void KilledUnit(Unit* victim) override
{
if (victim->IsPlayer())
{
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
DoCastSelf(SPELL_QUELL_RAGING_FLAMES, true);
}
};
enum raginFlames
struct npc_raging_flames : public ScriptedAI
{
SPELL_INFERNO = 35268,
SPELL_FIRE_TAIL = 35278,
SPELL_INFERNO_DAMAGE = 35283,
npc_raging_flames(Creature* creature) : ScriptedAI(creature) { }
EVENT_SPELL_FIRE_TAIL = 1,
EVENT_SPELL_INFERNO = 2
};
class npc_ragin_flames : public CreatureScript
{
public:
npc_ragin_flames() : CreatureScript("npc_ragin_flames") { }
struct npc_ragin_flamesAI : public ScriptedAI
void InitializeAI() override
{
npc_ragin_flamesAI(Creature* creature) : ScriptedAI(creature) { }
EventMap events;
void Reset() override
{
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ALL, true);
}
void JustEngagedWith(Unit*) override
{
events.ScheduleEvent(EVENT_SPELL_FIRE_TAIL, 500);
events.ScheduleEvent(EVENT_SPELL_INFERNO, urand(10000, 20000));
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
switch (events.ExecuteEvent())
{
case EVENT_SPELL_INFERNO:
if (me->IsWithinCombatRange(me->GetVictim(), 5.0f))
{
me->CastSpell(me, SPELL_INFERNO, true);
events.ScheduleEvent(EVENT_SPELL_INFERNO, 20000);
}
else
events.ScheduleEvent(EVENT_SPELL_INFERNO, 1000);
break;
case EVENT_SPELL_FIRE_TAIL:
me->CastSpell(me, SPELL_FIRE_TAIL, true);
events.ScheduleEvent(EVENT_SPELL_FIRE_TAIL, 500);
break;
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetMechanarAI<npc_ragin_flamesAI>(creature);
me->SetCorpseDelay(20);
}
// It's more tricky actually
void FixateRandomTarget()
{
me->GetThreatMgr().ClearAllThreat();
if (TempSummon* summon = me->ToTempSummon())
if (Creature* summoner = summon->GetSummonerCreatureBase())
if (summoner->IsAIEnabled)
if (Unit* target = summoner->AI()->SelectTarget(SelectTargetMethod::Random, 1, 100.0f, true, false))
me->AddThreat(target, 1000000.0f);
}
void IsSummonedBy(WorldObject* /*summoner*/) override
{
DoZoneInCombat();
DoCastSelf(SPELL_RAGING_FLAMES_AREA_AURA);
DoCastSelf(SPELL_INVIS_STEALTH_DETECTION);
FixateRandomTarget();
_scheduler.Schedule(15s, 25s, [this](TaskContext task)
{
DoCastSelf(SPELL_INFERNO);
FixateRandomTarget();
task.Repeat(20s, 30s);
});
}
void Reset() override
{
_scheduler.CancelAll();
}
void EnterEvadeMode(EvadeReason /*why*/) override
{
me->KillSelf();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
_scheduler.Update(diff);
DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
};
class spell_ragin_flames_inferno : public SpellScriptLoader
class spell_ragin_flames_inferno : public AuraScript
{
public:
spell_ragin_flames_inferno() : SpellScriptLoader("spell_ragin_flames_inferno") { }
PrepareAuraScript(spell_ragin_flames_inferno);
class spell_ragin_flames_inferno_AuraScript : public AuraScript
void HandlePeriodic(AuraEffect const* aurEff)
{
PrepareAuraScript(spell_ragin_flames_inferno_AuraScript);
GetUnitOwner()->CastCustomSpell(SPELL_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetUnitOwner(), TRIGGERED_FULL_MASK);
}
void HandlePeriodic(AuraEffect const* aurEff)
{
GetUnitOwner()->CastCustomSpell(SPELL_INFERNO_DAMAGE, SPELLVALUE_BASE_POINT0, aurEff->GetAmount(), GetUnitOwner(), TRIGGERED_FULL_MASK);
}
void Register() override
{
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ragin_flames_inferno_AuraScript::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
AuraScript* GetAuraScript() const override
void Register() override
{
return new spell_ragin_flames_inferno_AuraScript();
OnEffectPeriodic += AuraEffectPeriodicFn(spell_ragin_flames_inferno::HandlePeriodic, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
}
};
void AddSC_boss_nethermancer_sepethrea()
{
new boss_nethermancer_sepethrea();
new npc_ragin_flames();
new spell_ragin_flames_inferno();
RegisterMechanarCreatureAI(boss_nethermancer_sepethrea);
RegisterMechanarCreatureAI(npc_raging_flames);
RegisterSpellScript(spell_ragin_flames_inferno);
}

View File

@@ -43,116 +43,77 @@ enum Spells
SPELL_SUMMON_NETHER_WRAITH_4 = 35288,
};
enum Events
struct boss_pathaleon_the_calculator : public BossAI
{
EVENT_SUMMON = 1,
EVENT_MANA_TAP = 2,
EVENT_ARCANE_TORRENT = 3,
EVENT_DOMINATION = 4,
EVENT_ARCANE_EXPLOSION = 5,
EVENT_FRENZY = 6,
};
class boss_pathaleon_the_calculator : public CreatureScript
{
public:
boss_pathaleon_the_calculator(): CreatureScript("boss_pathaleon_the_calculator") { }
struct boss_pathaleon_the_calculatorAI : public BossAI
boss_pathaleon_the_calculator(Creature* creature) : BossAI(creature, DATA_PATHALEON_THE_CALCULATOR)
{
boss_pathaleon_the_calculatorAI(Creature* creature) : BossAI(creature, DATA_PATHALEON_THE_CALCULATOR) { }
void InitializeAI() override
scheduler.SetValidator([this]
{
BossAI::InitializeAI();
}
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
void JustEngagedWith(Unit* /*who*/) override
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
ScheduleHealthCheckEvent(20, [&]()
{
_JustEngagedWith();
events.ScheduleEvent(EVENT_SUMMON, 30000);
events.ScheduleEvent(EVENT_MANA_TAP, 12000);
events.ScheduleEvent(EVENT_ARCANE_TORRENT, 16000);
events.ScheduleEvent(EVENT_DOMINATION, 25000);
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 8000);
events.ScheduleEvent(EVENT_FRENZY, 1000);
Talk(SAY_AGGRO);
}
summons.DespawnAll();
DoCastSelf(SPELL_DISGRUNTLED_ANGER, true);
Talk(SAY_ENRAGE);
});
void KilledUnit(Unit* victim) override
scheduler.Schedule(30s, [this](TaskContext context)
{
if (victim->GetTypeId() == TYPEID_PLAYER)
Talk(SAY_SLAY);
}
for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i)
me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true);
void JustDied(Unit* /*killer*/) override
Talk(SAY_SUMMON);
context.Repeat(30s, 40s);
}).Schedule(12s, [this](TaskContext context)
{
_JustDied();
Talk(SAY_DEATH);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false)))
{
case EVENT_ARCANE_EXPLOSION:
me->CastSpell(me, SPELL_ARCANE_EXPLOSION, false);
events.ScheduleEvent(EVENT_ARCANE_EXPLOSION, 12000);
break;
case EVENT_ARCANE_TORRENT:
me->RemoveAurasDueToSpell(SPELL_MANA_TAP);
me->ModifyPower(POWER_MANA, 5000);
me->CastSpell(me, SPELL_ARCANE_TORRENT, false);
events.ScheduleEvent(EVENT_ARCANE_TORRENT, 15000);
break;
case EVENT_MANA_TAP:
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, PowerUsersSelector(me, POWER_MANA, 40.0f, false)))
me->CastSpell(target, SPELL_MANA_TAP, false);
events.ScheduleEvent(EVENT_MANA_TAP, 18000);
break;
case EVENT_DOMINATION:
Talk(SAY_DOMINATION);
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 50.0f))
me->CastSpell(target, SPELL_DOMINATION, false);
events.ScheduleEvent(EVENT_DOMINATION, 30000);
break;
case EVENT_FRENZY:
if (me->HealthBelowPct(20))
{
summons.DespawnAll();
me->CastSpell(me, SPELL_DISGRUNTLED_ANGER, true);
Talk(SAY_ENRAGE);
break;
}
events.ScheduleEvent(EVENT_FRENZY, 1000);
break;
case EVENT_SUMMON:
for (uint8 i = 0; i < DUNGEON_MODE(3, 4); ++i)
me->CastSpell(me, SPELL_SUMMON_NETHER_WRAITH_1 + i, true);
Talk(SAY_SUMMON);
events.ScheduleEvent(EVENT_SUMMON, urand(30000, 45000));
break;
DoCast(target, SPELL_MANA_TAP);
}
context.Repeat(18s);
}).Schedule(16s, [this](TaskContext context)
{
me->RemoveAurasDueToSpell(SPELL_MANA_TAP);
me->ModifyPower(POWER_MANA, 5000);
DoCastSelf(SPELL_ARCANE_TORRENT);
context.Repeat(15s);
}).Schedule(25s, [this](TaskContext context)
{
Talk(SAY_DOMINATION);
DoCastRandomTarget(SPELL_DOMINATION, 1, 50.0f);
context.Repeat(30s);
}).Schedule(8s, [this](TaskContext context)
{
DoCastAOE(SPELL_ARCANE_EXPLOSION);
context.Repeat(12s);
});
DoMeleeAttackIfReady();
}
};
Talk(SAY_AGGRO);
}
CreatureAI* GetAI(Creature* creature) const override
void KilledUnit(Unit* victim) override
{
return GetMechanarAI<boss_pathaleon_the_calculatorAI>(creature);
if (victim->IsPlayer())
{
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
{
_JustDied();
Talk(SAY_DEATH);
}
};
void AddSC_boss_pathaleon_the_calculator()
{
new boss_pathaleon_the_calculator();
RegisterMechanarCreatureAI(boss_pathaleon_the_calculator);
}

View File

@@ -72,4 +72,6 @@ inline AI* GetMechanarAI(T* obj)
return GetInstanceAI<AI>(obj, MechanarScriptName);
}
#define RegisterMechanarCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetMechanarAI)
#endif

View File

@@ -15,146 +15,12 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Zangarmarsh
SD%Complete: 100
SDComment: Quest support: 9752, 9785, 9803, 10009. Mark Of ... buffs.
SDCategory: Zangarmarsh
EndScriptData */
/* ContentData
npcs_ashyen_and_keleth
npc_cooshcoosh
npc_elder_kuruti
npc_mortog_steamhead
npc_kayra_longmane
npc_timothy_daniels
EndContentData */
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedEscortAI.h"
#include "ScriptedGossip.h"
// Theirs
/*######
## npcs_ashyen_and_keleth
######*/
#define GOSSIP_ITEM_BLESS_ASH "Grant me your mark, wise ancient."
#define GOSSIP_ITEM_BLESS_KEL "Grant me your mark, mighty ancient."
enum AshyenAndKeleth
{
GOSSIP_REWARD_BLESS = 0,
NPC_ASHYEN = 17900,
NPC_KELETH = 17901,
SPELL_BLESS_ASH_EXA = 31815,
SPELL_BLESS_ASH_REV = 31811,
SPELL_BLESS_ASH_HON = 31810,
SPELL_BLESS_ASH_FRI = 31808,
SPELL_BLESS_KEL_EXA = 31814,
SPELL_BLESS_KEL_REV = 31813,
SPELL_BLESS_KEL_HON = 31812,
SPELL_BLESS_KEL_FRI = 31807
};
class npcs_ashyen_and_keleth : public CreatureScript
{
public:
npcs_ashyen_and_keleth() : CreatureScript("npcs_ashyen_and_keleth") { }
bool OnGossipHello(Player* player, Creature* creature) override
{
if (player->GetReputationRank(942) > REP_NEUTRAL)
{
if (creature->GetEntry() == NPC_ASHYEN)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_ASH, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
if (creature->GetEntry() == NPC_KELETH)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_ITEM_BLESS_KEL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
}
SendGossipMenuFor(player, player->GetGossipTextId(creature), creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) override
{
ClearGossipMenuFor(player);
if (action == GOSSIP_ACTION_INFO_DEF + 1)
{
creature->setPowerType(POWER_MANA);
creature->SetMaxPower(POWER_MANA, 200); //set a "fake" mana value, we can't depend on database doing it in this case
creature->SetPower(POWER_MANA, 200);
if (creature->GetEntry() == NPC_ASHYEN) //check which Creature we are dealing with
{
uint32 spell = 0;
switch (player->GetReputationRank(942))
{
//mark of lore
case REP_FRIENDLY:
spell = SPELL_BLESS_ASH_FRI;
break;
case REP_HONORED:
spell = SPELL_BLESS_ASH_HON;
break;
case REP_REVERED:
spell = SPELL_BLESS_ASH_REV;
break;
case REP_EXALTED:
spell = SPELL_BLESS_ASH_EXA;
break;
default:
break;
}
if (spell)
{
creature->CastSpell(player, spell, true);
creature->AI()->Talk(GOSSIP_REWARD_BLESS);
}
}
if (creature->GetEntry() == NPC_KELETH)
{
uint32 spell = 0;
switch (player->GetReputationRank(942)) //mark of war
{
case REP_FRIENDLY:
spell = SPELL_BLESS_KEL_FRI;
break;
case REP_HONORED:
spell = SPELL_BLESS_KEL_HON;
break;
case REP_REVERED:
spell = SPELL_BLESS_KEL_REV;
break;
case REP_EXALTED:
spell = SPELL_BLESS_KEL_EXA;
break;
default:
break;
}
if (spell)
{
creature->CastSpell(player, spell, true);
creature->AI()->Talk(GOSSIP_REWARD_BLESS);
}
}
CloseGossipMenuFor(player);
player->TalkedToCreature(creature->GetEntry(), creature->GetGUID());
}
return true;
}
};
/*######
## npc_cooshcoosh
######*/
@@ -451,7 +317,6 @@ public:
void AddSC_zangarmarsh()
{
// Theirs
new npcs_ashyen_and_keleth();
new npc_cooshcoosh();
new npc_elder_kuruti();
new npc_mortog_steamhead();

View File

@@ -1785,19 +1785,29 @@ class spell_gen_elune_candle : public SpellScript
}
};
/* 29266, 57685, 58951, 70592, 70628, 74490 - Permanent Feign Death
31261 - Permanent Feign Death (Root)
35356, 35357 - Spawn Feign Death */
class spell_gen_creature_permanent_feign_death : public AuraScript
/*
There are only 3 possible flags Feign Death auras can apply: UNIT_DYNFLAG_DEAD, UNIT_FLAG2_FEIGN_DEATH
and UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT. Some auras can apply only 2 flags
spell_gen_feign_death_all_flags applies all 3 flags
spell_gen_feign_death_no_dyn_flag applies no UNIT_DYNFLAG_DEAD (does not make the creature appear dead)
spell_gen_feign_death_no_prevent_emotes applies no UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT
REACT_PASSIVE should be handled directly in scripts since not all creatures should be passive. Otherwise
creature will be not able to aggro or execute MoveInLineOfSight events. Removing may cause more issues
than already exists
*/
class spell_gen_feign_death_all_flags : public AuraScript
{
PrepareAuraScript(spell_gen_creature_permanent_feign_death);
PrepareAuraScript(spell_gen_feign_death_all_flags);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->SetDynamicFlag(UNIT_DYNFLAG_DEAD);
target->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->SetImmuneToAll(true);
target->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->SetReactState(REACT_PASSIVE);
@@ -1808,16 +1818,83 @@ class spell_gen_creature_permanent_feign_death : public AuraScript
Unit* target = GetTarget();
target->RemoveDynamicFlag(UNIT_DYNFLAG_DEAD);
target->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->SetImmuneToAll(false);
target->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->SetReactState(REACT_AGGRESSIVE);
target->ToCreature()->InitializeReactState();
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectApplyFn(spell_gen_creature_permanent_feign_death::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectApply += AuraEffectApplyFn(spell_gen_feign_death_all_flags::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectApplyFn(spell_gen_feign_death_all_flags::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 35357 - Spawn Feign Death
// 51329 - Feign Death
class spell_gen_feign_death_no_dyn_flag : public AuraScript
{
PrepareAuraScript(spell_gen_feign_death_no_dyn_flag);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->SetReactState(REACT_PASSIVE);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->InitializeReactState();
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_feign_death_no_dyn_flag::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectApplyFn(spell_gen_feign_death_no_dyn_flag::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
// 58951 - Permanent Feign Death
class spell_gen_feign_death_no_prevent_emotes : public AuraScript
{
PrepareAuraScript(spell_gen_feign_death_no_prevent_emotes);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->SetUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->SetUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->SetReactState(REACT_PASSIVE);
}
void HandleEffectRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->RemoveUnitFlag2(UNIT_FLAG2_FEIGN_DEATH);
target->RemoveUnitFlag(UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
if (target->GetTypeId() == TYPEID_UNIT)
target->ToCreature()->InitializeReactState();
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_feign_death_no_prevent_emotes::HandleEffectApply, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectApplyFn(spell_gen_feign_death_no_prevent_emotes::HandleEffectRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
}
};
@@ -3689,6 +3766,29 @@ class spell_gen_paralytic_poison : public AuraScript
}
};
class spell_gen_prevent_emotes : public AuraScript
{
PrepareAuraScript(spell_gen_prevent_emotes);
void HandleEffectApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
}
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
Unit* target = GetTarget();
target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREVENT_EMOTES_FROM_CHAT_TEXT);
}
void Register() override
{
OnEffectApply += AuraEffectApplyFn(spell_gen_prevent_emotes::HandleEffectApply, EFFECT_FIRST_FOUND, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL);
OnEffectRemove += AuraEffectRemoveFn(spell_gen_prevent_emotes::OnRemove, EFFECT_FIRST_FOUND, SPELL_AURA_ANY, AURA_EFFECT_HANDLE_REAL);
}
};
enum BladeWarding
{
SPELL_GEN_BLADE_WARDING_TRIGGERED = 64442
@@ -4753,7 +4853,9 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_parachute);
RegisterSpellScript(spell_gen_pet_summoned);
RegisterSpellScript(spell_gen_remove_flight_auras);
RegisterSpellScript(spell_gen_creature_permanent_feign_death);
RegisterSpellScript(spell_gen_feign_death_all_flags);
RegisterSpellScript(spell_gen_feign_death_no_dyn_flag);
RegisterSpellScript(spell_gen_feign_death_no_prevent_emotes);
RegisterSpellScript(spell_pvp_trinket_wotf_shared_cd);
RegisterSpellScript(spell_gen_animal_blood);
RegisterSpellScript(spell_gen_divine_storm_cd_reset);
@@ -4795,6 +4897,7 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_despawn_self);
RegisterSpellScript(spell_gen_bandage);
RegisterSpellScript(spell_gen_paralytic_poison);
RegisterSpellScript(spell_gen_prevent_emotes);
RegisterSpellScript(spell_gen_blade_warding);
RegisterSpellScriptWithArgs(spell_gen_lifebloom, "spell_hexlord_lifebloom", SPELL_HEXLORD_MALACRASS_LIFEBLOOM_FINAL_HEAL);
RegisterSpellScriptWithArgs(spell_gen_lifebloom, "spell_tur_ragepaw_lifebloom", SPELL_TUR_RAGEPAW_LIFEBLOOM_FINAL_HEAL);

View File

@@ -59,6 +59,7 @@ enum WarriorSpells
SPELL_WARRIOR_UNRELENTING_ASSAULT_TRIGGER_2 = 64850,
SPELL_WARRIOR_VIGILANCE_PROC = 50725,
SPELL_WARRIOR_VIGILANCE_REDIRECT_THREAT = 59665,
SPELL_WARRIOR_WHIRLWIND_MAIN = 50622,
SPELL_WARRIOR_WHIRLWIND_OFF = 44949
};
@@ -646,12 +647,18 @@ class spell_warr_sweeping_strikes : public AuraScript
case SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_2:
case SPELL_WARRIOR_WHIRLWIND_OFF:
return false;
case SPELL_WARRIOR_WHIRLWIND_MAIN:
if (actor->HasSpellCooldown(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1))
{
return false;
}
break;
default:
break;
}
}
_procTarget = eventInfo.GetActor()->SelectNearbyNoTotemTarget(eventInfo.GetProcTarget());
_procTarget = actor->SelectNearbyNoTotemTarget(eventInfo.GetProcTarget());
return _procTarget != nullptr;
}
@@ -668,6 +675,11 @@ class spell_warr_sweeping_strikes : public AuraScript
}
else
{
if (spellInfo && spellInfo->Id == SPELL_WARRIOR_WHIRLWIND_MAIN)
{
eventInfo.GetActor()->AddSpellCooldown(SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, 0, 500);
}
int32 damage = damageInfo->GetUnmitigatedDamage();
GetTarget()->CastCustomSpell(_procTarget, SPELL_WARRIOR_SWEEPING_STRIKES_EXTRA_ATTACK_1, &damage, 0, 0, true, nullptr, aurEff);
}

View File

@@ -15,42 +15,57 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Npc_Taxi
SD%Complete: 0%
SDComment: To be used for taxi NPCs that are located globally.
SDCategory: NPCs
EndScriptData
*/
#include "Player.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#define GOSSIP_NETHER_DRAKE "I'm ready to fly! Take me up, dragon!"
#define GOSSIP_IRONWING "I'd like to take a flight around Stormwind Harbor."
#define GOSSIP_DABIREE1 "Fly me to Murketh and Shaadraz Gateways"
#define GOSSIP_DABIREE2 "Fly me to Shatter Point"
#define GOSSIP_BRACK1 "Fly me to Murketh and Shaadraz Gateways"
#define GOSSIP_BRACK2 "Fly me to The Abyssal Shelf"
#define GOSSIP_BRACK3 "Fly me to Spinebreaker Post"
#define GOSSIP_IRENA "Fly me to Skettis please"
#define GOSSIP_CLOUDBREAKER1 "Speaking of action, I've been ordered to undertake an air strike."
#define GOSSIP_CLOUDBREAKER2 "I need to intercept the Dawnblade reinforcements."
#define GOSSIP_DRAGONHAWK "<Ride the dragonhawk to Sun's Reach>"
#define GOSSIP_VERONIA "Fly me to Manaforge Coruu please"
#define GOSSIP_DEESAK "Fly me to Ogri'la please"
#define GOSSIP_AFRASASTRASZ1 "I would like to take a flight to the ground, Lord Of Afrasastrasz."
#define GOSSIP_AFRASASTRASZ2 "My Lord, I must go to the upper floor of the temple."
#define GOSSIP_TARIOLSTRASZ1 "My Lord, I must go to the upper floor of the temple."
#define GOSSIP_TARIOLSTRASZ2 "Can you spare a drake to travel to Lord Of Afrasastrasz, in the middle of the temple?"
#define GOSSIP_TORASTRASZA1 "I would like to see Lord Of Afrasastrasz, in the middle of the temple."
#define GOSSIP_TORASTRASZA2 "Yes, Please. I would like to return to the ground floor of the temple."
#define GOSSIP_CRIMSONWING "<Ride the gryphons to Survey Alcaz Island>"
#define GOSSIP_WILLIAMKEILAR1 "Take me to Northpass Tower."
#define GOSSIP_WILLIAMKEILAR2 "Take me to Eastwall Tower."
#define GOSSIP_WILLIAMKEILAR3 "Take me to Crown Guard Tower."
enum Npcs
{
NPC_NETHER_DRAKE = 20903, // Netherstorm - Protectorate Nether Drake
NPC_IRONWING = 29154, // Stormwind City - Thargold Ironwing
NPC_DABIR = 19409, // Hellfire Peninsula - Wing Commander Dabir'ee
NPC_BRACK = 19401, // Hellfire Peninsula - Wing Commander Brack
NPC_IRENA = 23413, // Blade's Edge Mountains - Skyguard Handler Irena
NPC_AYREN = 25059, // Isle of Quel'Danas - Ayren Cloudbreaker
NPC_DRAGONHAWK = 25236, // Isle of Quel'Danas - Unrestrained Dragonhawk
NPC_VERONIA = 20162, // Netherstorm - Veronia
NPC_DEESAK = 23415, // Terokkar Forest - Skyguard Handler Deesak
NPC_AFRASASTRASZ = 27575, // Dragonblight - Lord Afrasastrasz
NPC_TARIOLSTRASZ = 26443, // Dragonblight - Tariolstrasz
NPC_TORASTRASZA = 26949, // Dragonblight - Torastrasza
NPC_CESSA = 23704, // Dustwallow Marsh - Cassa Crimsonwing
NPC_KIELAR = 17209, // William Kielar <Spectral Gryphon Master> - Eastern Plaguelands Towers
};
enum Misc
{
REP_SKYGUARD = 1031, // Sha'tari Skyguard Reputation
// Netherstorm
QUEST_NETHERY_WINGS = 10438, // On Nethery Wings
ITEM_DISRUPTOR = 29778, // Phase Disruptor (Needed for On Nethery Wings)
QUEST_BEHIND_ENEMY = 10652, // Behind Enemy Lines
// Hellfire Peninsula - Alliance
QUEST_GATEWAYS_A = 10146, // Mission: The Murketh and Shaadraz Gateways
QUEST_SHATTER_POINT = 10340, // Shatter Point
// Hellfire Peninsula - Horde
QUEST_GATEWAYS_H = 10129, // Mission: The Murketh and Shaadraz Gateways
QUEST_ABBYSAL = 10162, // Mission: The Abyssal Shelf
QUEST_ABBYSAL_DAILY = 10347, // Return to the Abyssal Shelf (Daily)
QUEST_SPINEBREAKER = 10242, // Spinebreaker Post
// Isle of Quel'Danas (Daily)
QUEST_DEAD_SCAR = 11532, // Mission: Distraction at the Dead Scar
QUEST_AIR_STRIKE = 11533, // The Air Strikes Must Continue
QUEST_INTERCEPT = 11542, // Mission: Intercept the Reinforcements
QUEST_KEEP_AT_BEY = 11543, // Keeping the Enemy at Bay
// Dustwallow Marsh
QUEST_SURVEY_ALCAZ = 11142, // Survey Alcaz Island
};
class npc_taxi : public CreatureScript
{
@@ -62,87 +77,84 @@ public:
if (creature->IsQuestGiver())
player->PrepareQuestMenu(creature->GetGUID());
uint32 gossipmenuid = 0;
gossipmenuid = creature->GetCreatureTemplate()->GossipMenuId;
switch (creature->GetEntry())
{
case 20903: // Netherstorm - Protectorate Nether Drake
if (player->GetQuestStatus(10438) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(29778))
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_NETHER_DRAKE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
case NPC_NETHER_DRAKE:
if (player->GetQuestStatus(QUEST_NETHERY_WINGS) == QUEST_STATUS_INCOMPLETE && player->HasItemCount(ITEM_DISRUPTOR))
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
break;
case 29154: // Stormwind City - Thargold Ironwing
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_IRONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
case NPC_IRONWING:
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
break;
case 19409: // Hellfire Peninsula - Wing Commander Dabir'ee
//Mission: The Murketh and Shaadraz Gateways
if (player->GetQuestStatus(10146) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_DABIREE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
case NPC_DABIR:
if (player->GetQuestStatus(QUEST_GATEWAYS_A) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
//Shatter Point
if (!player->GetQuestRewardStatus(10340))
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_DABIREE2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
if (!player->GetQuestRewardStatus(QUEST_SHATTER_POINT))
AddGossipItemFor(player, gossipmenuid, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 5);
break;
case 19401: // Hellfire Peninsula - Wing Commander Brack
//Mission: The Murketh and Shaadraz Gateways
if (player->GetQuestStatus(10129) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BRACK1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
case NPC_BRACK:
if (player->GetQuestStatus(QUEST_GATEWAYS_H) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 8);
//Mission: The Abyssal Shelf || Return to the Abyssal Shelf
if (player->GetQuestStatus(10162) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(10347) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BRACK2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
if (player->GetQuestStatus(QUEST_ABBYSAL) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_ABBYSAL_DAILY) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 9);
//Spinebreaker Post
if (player->GetQuestStatus(10242) == QUEST_STATUS_COMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BRACK3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
if (player->GetQuestStatus(QUEST_SPINEBREAKER) == QUEST_STATUS_COMPLETE)
AddGossipItemFor(player, gossipmenuid, 4, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 10);
break;
case 23413: // Blade's Edge Mountains - Skyguard Handler Irena
if (player->GetReputationRank(1031) >= REP_HONORED)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_IRENA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
case NPC_IRENA:
if (player->GetReputationRank(REP_SKYGUARD) >= REP_HONORED)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 11);
break;
case 25059: // Isle of Quel'Danas - Ayren Cloudbreaker
if (player->GetQuestStatus(11532) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(11533) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_CLOUDBREAKER1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12);
case NPC_AYREN:
if (player->GetQuestStatus(QUEST_DEAD_SCAR) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_AIR_STRIKE) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 12);
if (player->GetQuestStatus(11542) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(11543) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_CLOUDBREAKER2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13);
if (player->GetQuestStatus(QUEST_INTERCEPT) == QUEST_STATUS_INCOMPLETE || player->GetQuestStatus(QUEST_KEEP_AT_BEY) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 13);
break;
case 25236: // Isle of Quel'Danas - Unrestrained Dragonhawk
if (player->GetQuestStatus(11542) == QUEST_STATUS_COMPLETE || player->GetQuestStatus(11543) == QUEST_STATUS_COMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_DRAGONHAWK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14);
case NPC_DRAGONHAWK:
if (player->GetQuestStatus(QUEST_INTERCEPT) == QUEST_STATUS_COMPLETE || player->GetQuestStatus(QUEST_KEEP_AT_BEY) == QUEST_STATUS_COMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 14);
break;
case 20162: // Netherstorm - Veronia
//Behind Enemy Lines
if (player->GetQuestStatus(10652) != QUEST_STATUS_REWARDED)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_VERONIA, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15);
case NPC_VERONIA:
if (player->GetQuestStatus(QUEST_BEHIND_ENEMY) != QUEST_STATUS_REWARDED)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 15);
break;
case 23415: // Terokkar Forest - Skyguard Handler Deesak
if (player->GetReputationRank(1031) >= REP_HONORED)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_DEESAK, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 16);
case NPC_DEESAK:
if (player->GetReputationRank(REP_SKYGUARD) >= REP_HONORED)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 16);
break;
case 27575: // Dragonblight - Lord Afrasastrasz
case NPC_AFRASASTRASZ:
// middle -> ground
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_AFRASASTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 17);
AddGossipItemFor(player, gossipmenuid, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 17);
// middle -> top
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_AFRASASTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 18);
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 18);
break;
case 26443: // Dragonblight - Tariolstrasz //need to check if quests are required before gossip available (12123, 12124)
case NPC_TARIOLSTRASZ:
// ground -> top
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_TARIOLSTRASZ1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 19);
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 19);
// ground -> middle
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_TARIOLSTRASZ2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
AddGossipItemFor(player, gossipmenuid, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 20);
break;
case 26949: // Dragonblight - Torastrasza
case NPC_TORASTRASZA:
// top -> middle
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_TORASTRASZA1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
AddGossipItemFor(player, gossipmenuid, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 21);
// top -> ground
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_TORASTRASZA2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 22);
break;
case 23704: // Dustwallow Marsh - Cassa Crimsonwing
if (player->GetQuestStatus(11142) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_CRIMSONWING, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
case NPC_CESSA:
if (player->GetQuestStatus(QUEST_SURVEY_ALCAZ) == QUEST_STATUS_INCOMPLETE)
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 25);
break;
case 17209:
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 26);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 27);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_WILLIAMKEILAR3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 28);
case NPC_KIELAR:
AddGossipItemFor(player, gossipmenuid, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 26); // Northpass Tower.
AddGossipItemFor(player, gossipmenuid, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 27); // Eastwall Tower.
AddGossipItemFor(player, gossipmenuid, 2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 28); // Crown Guard Tower.
break;
}
@@ -231,15 +243,6 @@ public:
CloseGossipMenuFor(player);
player->ActivateTaxiPathTo(879);
break;
case GOSSIP_ACTION_INFO_DEF + 23:
CloseGossipMenuFor(player);
player->CastSpell(player, 43074, true); //TaxiPath 736
break;
case GOSSIP_ACTION_INFO_DEF + 24:
CloseGossipMenuFor(player);
//player->ActivateTaxiPathTo(738);
player->CastSpell(player, 43136, false);
break;
case GOSSIP_ACTION_INFO_DEF + 25:
CloseGossipMenuFor(player);
player->CastSpell(player, 42295, true);