mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-24 14:16:31 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -117,6 +117,7 @@ void EventProcessor::CancelEventGroup(uint8 group)
|
||||
{
|
||||
if (itr->second->m_eventGroup != group)
|
||||
{
|
||||
++itr;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -691,6 +691,14 @@ void BossAI::ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> ex
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(healthPct, exec));
|
||||
};
|
||||
|
||||
void BossAI::ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec)
|
||||
{
|
||||
for (auto const& checks : healthPct)
|
||||
{
|
||||
_healthCheckEvents.push_back(HealthCheckEventData(checks, exec));
|
||||
}
|
||||
}
|
||||
|
||||
bool BossAI::_ProccessHealthCheckEvent(uint8 healthPct, uint32 damage, std::function<void()> exec) const
|
||||
{
|
||||
if (me->HealthBelowPctDamaged(healthPct, damage))
|
||||
|
||||
@@ -470,6 +470,7 @@ public:
|
||||
void UpdateAI(uint32 diff) override;
|
||||
|
||||
void ScheduleHealthCheckEvent(uint32 healthPct, std::function<void()> exec);
|
||||
void ScheduleHealthCheckEvent(std::initializer_list<uint8> healthPct, std::function<void()> exec);
|
||||
|
||||
// Hook used to execute events scheduled into EventMap without the need
|
||||
// to override UpdateAI
|
||||
|
||||
@@ -1635,7 +1635,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
|
||||
float x, y, z;
|
||||
target->GetPosition(x, y, z);
|
||||
if (e.action.moveToPos.ContactDistance > 0)
|
||||
target->GetContactPoint(me, x, y, z, e.action.moveToPos.ContactDistance);
|
||||
{
|
||||
target->GetNearPoint(me, x, y, z, e.action.moveToPos.ContactDistance, 0, target->GetAngle(me));
|
||||
}
|
||||
me->GetMotionMaster()->MovePoint(e.action.moveToPos.pointId, x + e.target.x, y + e.target.y, z + e.target.z, true, true, isControlled ? MOTION_SLOT_CONTROLLED : MOTION_SLOT_ACTIVE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1428,7 +1428,7 @@ enum SMARTAI_TARGETS
|
||||
SMART_TARGET_SUMMONED_CREATURES = 204, // Entry
|
||||
SMART_TARGET_INSTANCE_STORAGE = 205, // Instance data index, Type (creature (1), gameobject (2))
|
||||
|
||||
SMART_TARGET_AC_END = 205 // placeholder
|
||||
SMART_TARGET_AC_END = 206 // placeholder
|
||||
};
|
||||
|
||||
struct SmartTarget
|
||||
|
||||
@@ -208,7 +208,10 @@ void InstanceScript::UpdateMinionState(Creature* minion, EncounterState state)
|
||||
minion->Respawn();
|
||||
else
|
||||
{
|
||||
minion->AI()->DoZoneInCombat(nullptr, 100.0f);
|
||||
if (minion->GetReactState() == REACT_AGGRESSIVE)
|
||||
{
|
||||
minion->AI()->DoZoneInCombat(nullptr, 100.0f);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -362,6 +365,20 @@ void InstanceScript::StorePersistentData(uint32 index, uint32 data)
|
||||
persistentData[index] = data;
|
||||
}
|
||||
|
||||
void InstanceScript::DoForAllMinions(uint32 id, std::function<void(Creature*)> exec)
|
||||
{
|
||||
BossInfo* bossInfo = &bosses[id];
|
||||
MinionSet listCopy = bossInfo->minion;
|
||||
|
||||
for (auto const& minion : listCopy)
|
||||
{
|
||||
if (minion)
|
||||
{
|
||||
exec(minion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceScript::Load(const char* data)
|
||||
{
|
||||
if (!data)
|
||||
|
||||
@@ -260,6 +260,9 @@ public:
|
||||
|
||||
// Allows to perform particular actions
|
||||
virtual void DoAction(int32 /*action*/) {}
|
||||
|
||||
// Allows executing code using all creatures registered in the instance script as minions
|
||||
void DoForAllMinions(uint32 id, std::function<void(Creature*)> exec);
|
||||
protected:
|
||||
void SetHeaders(std::string const& dataHeaders);
|
||||
void SetBossNumber(uint32 number) { bosses.resize(number); }
|
||||
|
||||
@@ -69,6 +69,7 @@ enum Events
|
||||
EVENT_JEDOGA_PREPARE_RITUAL,
|
||||
EVENT_JEDOGA_MOVE_UP,
|
||||
EVENT_JEDOGA_MOVE_DOWN,
|
||||
EVENT_JEDGA_START_RITUAL,
|
||||
|
||||
// Initiate
|
||||
EVENT_RITUAL_BEGIN_MOVE,
|
||||
@@ -384,11 +385,9 @@ struct boss_jedoga_shadowseeker : public BossAI
|
||||
if (!summons.empty())
|
||||
{
|
||||
sacraficeTarget_GUID = Acore::Containers::SelectRandomContainerElement(summons);
|
||||
if (Creature* volunteer = ObjectAccessor::GetCreature(*me, sacraficeTarget_GUID))
|
||||
if (ObjectAccessor::GetCreature(*me, sacraficeTarget_GUID))
|
||||
{
|
||||
Talk(SAY_SACRIFICE_1);
|
||||
sacraficeTarget_GUID = volunteer->GetGUID();
|
||||
volunteer->AI()->DoAction(ACTION_RITUAL_BEGIN);
|
||||
events.ScheduleEvent(EVENT_JEDGA_START_RITUAL, 3s, 0, PHASE_RITUAL);
|
||||
}
|
||||
// Something failed, let players continue but do not grant achievement
|
||||
else
|
||||
@@ -506,6 +505,17 @@ struct boss_jedoga_shadowseeker : public BossAI
|
||||
me->GetMotionMaster()->MovePoint(POINT_DOWN, JedogaPosition[1], false);
|
||||
break;
|
||||
}
|
||||
case EVENT_JEDGA_START_RITUAL:
|
||||
{
|
||||
sacraficeTarget_GUID = Acore::Containers::SelectRandomContainerElement(summons);
|
||||
if (Creature* volunteer = ObjectAccessor::GetCreature(*me, sacraficeTarget_GUID))
|
||||
{
|
||||
Talk(SAY_SACRIFICE_1);
|
||||
sacraficeTarget_GUID = volunteer->GetGUID();
|
||||
volunteer->AI()->DoAction(ACTION_RITUAL_BEGIN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,12 +642,8 @@ struct npc_twilight_volunteer : public ScriptedAI
|
||||
if (Creature* jedoga = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_JEDOGA_SHADOWSEEKER)))
|
||||
{
|
||||
jedoga->AI()->Talk(SAY_SACRIFICE_2);
|
||||
jedoga->CastSpell(nullptr, SPELL_SACRIFICE_BEAM);
|
||||
|
||||
if (Creature* ritualTrigger = jedoga->SummonCreature(NPC_JEDOGA_CONTROLLER, JedogaPosition[2], TEMPSUMMON_TIMED_DESPAWN, 5000))
|
||||
{
|
||||
ritualTrigger->CastSpell(ritualTrigger, SPELL_SACRIFICE_VISUAL);
|
||||
}
|
||||
jedoga->CastSpell(nullptr, SPELL_SACRIFICE_BEAM); /// @todo: Visual is not working. (cosmetic)
|
||||
jedoga->AI()->DoAction(ACTION_SACRAFICE);
|
||||
}
|
||||
|
||||
Talk(SAY_SACRIFICED);
|
||||
@@ -656,6 +662,14 @@ struct npc_twilight_volunteer : public ScriptedAI
|
||||
me->SetHomePosition(JedogaPosition[2]);
|
||||
me->SetWalk(true);
|
||||
me->GetMotionMaster()->MovePoint(POINT_RITUAL, JedogaPosition[2], false);
|
||||
|
||||
if (Creature* jedoga = ObjectAccessor::GetCreature(*me, pInstance->GetGuidData(DATA_JEDOGA_SHADOWSEEKER)))
|
||||
{
|
||||
if (Creature* ritualTrigger = jedoga->SummonCreature(NPC_JEDOGA_CONTROLLER, JedogaPosition[2], TEMPSUMMON_TIMED_DESPAWN, 15000))
|
||||
{
|
||||
ritualTrigger->CastSpell(ritualTrigger, SPELL_SACRIFICE_VISUAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -688,31 +702,6 @@ class spell_random_lightning_visual_effect : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 56150 - Sacrifice Beam
|
||||
class spell_jedoga_sacrafice_beam : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_jedoga_sacrafice_beam);
|
||||
|
||||
bool Load() override
|
||||
{
|
||||
return GetCaster()->GetTypeId() == TYPEID_UNIT;
|
||||
}
|
||||
|
||||
void HandleRemoval(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
AuraRemoveMode const removeMode = GetTargetApplication()->GetRemoveMode();
|
||||
if (removeMode == AURA_REMOVE_BY_DEFAULT || removeMode == AURA_REMOVE_BY_EXPIRE)
|
||||
{
|
||||
GetCaster()->ToCreature()->AI()->DoAction(ACTION_SACRAFICE);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_jedoga_sacrafice_beam::HandleRemoval, EFFECT_1, SPELL_AURA_PERIODIC_TRIGGER_SPELL, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
// CriteriaID 7359, Volunteer Work (2056)
|
||||
class achievement_volunteer_work : public AchievementCriteriaScript
|
||||
{
|
||||
@@ -740,7 +729,6 @@ void AddSC_boss_jedoga_shadowseeker()
|
||||
|
||||
// Spells
|
||||
RegisterSpellScript(spell_random_lightning_visual_effect);
|
||||
RegisterSpellScript(spell_jedoga_sacrafice_beam);
|
||||
|
||||
// Achievements
|
||||
new achievement_volunteer_work();
|
||||
|
||||
@@ -85,8 +85,6 @@ enum PaletressEvents
|
||||
EVENT_SPELL_WAKING_NIGHTMARE,
|
||||
};
|
||||
|
||||
#define TEXT_RADIATE "Eadric the Pure begins to radiate light. Shield your eyes!"
|
||||
|
||||
class boss_eadric : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -119,10 +117,7 @@ public:
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0, 1) )
|
||||
Talk(TEXT_EADRIC_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_EADRIC_SLAIN_2);
|
||||
Talk(SAY_EADRIC_KILL_PLAYER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +126,7 @@ public:
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_RADIANCE, 16000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HAMMER_RIGHTEOUS, 25000);
|
||||
Talk(TEXT_EADRIC_AGGRO);
|
||||
Talk(SAY_EADRIC_AGGRO);
|
||||
me->CastSpell(me, SPELL_VENGEANCE, false);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, IN_PROGRESS);
|
||||
@@ -154,7 +149,7 @@ public:
|
||||
me->GetMap()->UpdateEncounterState(ENCOUNTER_CREDIT_CAST_SPELL, 68574, me); // paletress' spell credits encounter, but shouldn't credit achievements
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
events.Reset();
|
||||
Talk(TEXT_EADRIC_DEATH);
|
||||
Talk(SAY_EADRIC_DEFEATED);
|
||||
me->GetThreatMgr().clearReferences();
|
||||
me->SetRegeneratingHealth(false);
|
||||
_EnterEvadeMode();
|
||||
@@ -182,16 +177,14 @@ public:
|
||||
break;
|
||||
case EVENT_SPELL_RADIANCE:
|
||||
me->CastSpell((Unit*)nullptr, SPELL_RADIANCE, false);
|
||||
me->TextEmote(TEXT_RADIATE, nullptr, true);
|
||||
Talk(SAY_EADRIC_EMOTE_RADIANCE);
|
||||
events.Repeat(16s);
|
||||
break;
|
||||
case EVENT_SPELL_HAMMER_RIGHTEOUS:
|
||||
if( Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 55.0f, true) )
|
||||
{
|
||||
char buffer[100];
|
||||
snprintf(buffer, sizeof(buffer), "Eadric the Pure targets %s with the Hammer of the Righteous!", target->GetName().c_str());
|
||||
me->TextEmote(buffer, nullptr, true);
|
||||
Talk(TEXT_EADRIC_HAMMER);
|
||||
Talk(SAY_EADRIC_EMOTE_HAMMER_RIGHTEOUS, target);
|
||||
Talk(SAY_EADRIC_HAMMER_RIGHTEOUS);
|
||||
me->CastSpell(target, SPELL_HAMMER_JUSTICE, true);
|
||||
me->CastSpell(target, SPELL_HAMMER_RIGHTEOUS, false);
|
||||
}
|
||||
@@ -251,10 +244,7 @@ public:
|
||||
{
|
||||
if( who->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0, 1) )
|
||||
Talk(TEXT_PALETRESS_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_PALETRESS_SLAIN_2);
|
||||
Talk(SAY_PALETRESS_KILL_PLAYER);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,7 +254,7 @@ public:
|
||||
events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, 9s, 12s);
|
||||
events.ScheduleEvent(EVENT_SPELL_SMITE, 2s, 3s);
|
||||
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
Talk(TEXT_PALETRESS_AGGRO);
|
||||
Talk(SAY_PALETRESS_AGGRO);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_ARGENT_CHALLENGE, IN_PROGRESS);
|
||||
}
|
||||
@@ -275,7 +265,7 @@ public:
|
||||
{
|
||||
MemoryGUID.Clear();
|
||||
me->RemoveAura(SPELL_SHIELD);
|
||||
Talk(TEXT_PALETRESS_MEMORY_DEFEATED);
|
||||
Talk(SAY_PALETRESS_MEMORY_DEATH);
|
||||
}
|
||||
else if( param == (-1) )
|
||||
{
|
||||
@@ -302,7 +292,7 @@ public:
|
||||
me->CastSpell((Unit*)nullptr, 68574, true); // achievements
|
||||
me->SetFaction(FACTION_FRIENDLY);
|
||||
events.Reset();
|
||||
Talk(TEXT_PALETRESS_DEATH);
|
||||
Talk(SAY_PALETRESS_DEFEATED);
|
||||
me->GetThreatMgr().clearReferences();
|
||||
me->SetRegeneratingHealth(false);
|
||||
_EnterEvadeMode();
|
||||
@@ -341,7 +331,7 @@ public:
|
||||
if( !summoned && HealthBelowPct(25) )
|
||||
{
|
||||
me->InterruptNonMeleeSpells(true);
|
||||
Talk(TEXT_PALETRESS_MEMORY_SUMMON);
|
||||
Talk(SAY_PALETRESS_MEMORY_SUMMON);
|
||||
me->CastSpell((Unit*)nullptr, SPELL_HOLY_NOVA, false);
|
||||
me->CastSpell(me, SPELL_SHIELD, false);
|
||||
me->CastSpell((Unit*)nullptr, SPELL_SUMMON_MEMORY, false);
|
||||
|
||||
@@ -174,7 +174,7 @@ public:
|
||||
return;
|
||||
|
||||
pInstance->SetData(BOSS_BLACK_KNIGHT, IN_PROGRESS);
|
||||
Talk(TEXT_BK_AGGRO);
|
||||
Talk(SAY_BK_AGGRO);
|
||||
me->CastSpell((Unit*)nullptr, (pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_HORDE ? SPELL_RAISE_DEAD_JAEREN : SPELL_RAISE_DEAD_ARELAS), false);
|
||||
if( Creature* announcer = pInstance->instance->GetCreature(pInstance->GetGuidData(DATA_ANNOUNCER)) )
|
||||
announcer->DespawnOrUnsummon();
|
||||
@@ -209,7 +209,7 @@ public:
|
||||
{
|
||||
case 2:
|
||||
me->SetDisplayId(MODEL_SKELETON);
|
||||
Talk(TEXT_BK_SKELETON_RES);
|
||||
Talk(SAY_BK_PHASE_2);
|
||||
me->CastSpell(me, SPELL_ARMY_DEAD, false);
|
||||
|
||||
events.Reset();
|
||||
@@ -220,7 +220,7 @@ public:
|
||||
break;
|
||||
case 3:
|
||||
me->SetDisplayId(MODEL_GHOST);
|
||||
Talk(TEXT_BK_GHOST_RES);
|
||||
Talk(SAY_BK_PHASE_3);
|
||||
|
||||
events.Reset();
|
||||
events.ScheduleEvent(EVENT_SPELL_DEATH_BITE, 2s);
|
||||
@@ -251,8 +251,8 @@ public:
|
||||
case EVENT_ANNOUNCER_SAY_ZOMBIE:
|
||||
if( pInstance && !summons.empty() )
|
||||
if( Creature* ghoul = pInstance->instance->GetCreature(*summons.begin()) )
|
||||
ghoul->Yell("[Zombie] .... . Brains ....", LANG_UNIVERSAL);
|
||||
|
||||
if (urand(0, 1))
|
||||
ghoul->Yell("[Zombie] .... . Brains ....", LANG_UNIVERSAL); /// @todo: Multiple variations + not always happening, from video sources, needs sniff to transition from DB.
|
||||
break;
|
||||
case EVENT_SPELL_PLAGUE_STRIKE:
|
||||
if( me->GetVictim() )
|
||||
@@ -307,17 +307,14 @@ public:
|
||||
{
|
||||
if( victim->GetTypeId() == TYPEID_PLAYER )
|
||||
{
|
||||
if( urand(0, 1) )
|
||||
Talk(TEXT_BK_SLAIN_1);
|
||||
else
|
||||
Talk(TEXT_BK_SLAIN_2);
|
||||
Talk(SAY_BK_KILL_PLAYER);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
me->CastSpell((Unit*)nullptr, SPELL_BK_KILL_CREDIT, true);
|
||||
Talk(TEXT_BK_DEATH);
|
||||
Talk(SAY_BK_DEATH);
|
||||
if( pInstance )
|
||||
pInstance->SetData(BOSS_BLACK_KNIGHT, DONE);
|
||||
if( me->ToTempSummon() )
|
||||
|
||||
@@ -90,6 +90,11 @@ enum ChampionSpells
|
||||
SPELL_ROLLING_THROW = 67546, // not implemented yet!
|
||||
};
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_TRAMPLED = 0,
|
||||
};
|
||||
|
||||
#define SPELL_FIREBALL DUNGEON_MODE(SPELL_FIREBALL_N, SPELL_FIREBALL_H)
|
||||
#define SPELL_BLAST_WAVE DUNGEON_MODE(SPELL_BLAST_WAVE_N, SPELL_BLAST_WAVE_H)
|
||||
#define SPELL_POLYMORPH DUNGEON_MODE(SPELL_POLYMORPH_N, SPELL_POLYMORPH_H)
|
||||
@@ -647,16 +652,8 @@ public:
|
||||
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
switch( spell->Id )
|
||||
{
|
||||
case SPELL_TRAMPLE_STUN:
|
||||
{
|
||||
char buffer[50];
|
||||
snprintf(buffer, sizeof(buffer), "%s is trampled!", me->GetName().c_str());
|
||||
me->TextEmote(buffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (spell->Id == SPELL_TRAMPLE_STUN)
|
||||
Talk(SAY_TRAMPLED, me);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
|
||||
@@ -25,6 +25,17 @@
|
||||
const Position SpawnPosition = {746.67f, 684.08f, 412.5f, 4.65f};
|
||||
#define CLEANUP_CHECK_INTERVAL 5000
|
||||
|
||||
/**
|
||||
* @todo: Missing dialog/RP (already populated in DB) && spawns (can use ToC25 locations?) for:
|
||||
*
|
||||
* Garrosh Hellscream 34995
|
||||
* King Varian Wrynn 34990
|
||||
* Lady Jaina Proudmoore 34992 (missing in DB)
|
||||
* Thrall 34994
|
||||
*
|
||||
* And possibly NPC_TIRION 33628 is wrong (should be 34996, from ToC25, needs a sniff to confirm, check .h)
|
||||
*/
|
||||
|
||||
class Group;
|
||||
|
||||
class instance_trial_of_the_champion : public InstanceMapScript
|
||||
@@ -523,9 +534,9 @@ public:
|
||||
{
|
||||
Counter = urand(0, 1);
|
||||
if( Counter )
|
||||
announcer->AI()->Talk(TEXT_INTRODUCE_EADRIC);
|
||||
announcer->AI()->Talk(SAY_EADRIC_INTRO_ANNOUNCER);
|
||||
else
|
||||
announcer->AI()->Talk(TEXT_INTRODUCE_PALETRESS);
|
||||
announcer->AI()->Talk(SAY_JAEREN_PALETRESS_INTRO);
|
||||
}
|
||||
HandleGameObject(GO_EnterGateGUID, false);
|
||||
events.RescheduleEvent(EVENT_START_ARGENT_CHALLENGE_INTRO, 0ms);
|
||||
@@ -702,27 +713,27 @@ public:
|
||||
case 0:
|
||||
CHAMPION_TO_SUMMON = NPC_MOKRA;
|
||||
MINION_TO_SUMMON = NPC_ORGRIMMAR_MINION;
|
||||
TEXT_ID = TEXT_MOKRA_SKILLCRUSHER;
|
||||
TEXT_ID = SAY_GRAND_CHAMPIONS_INTRO_SKULLCRUSHER;
|
||||
break;
|
||||
case 1:
|
||||
CHAMPION_TO_SUMMON = NPC_ERESSEA;
|
||||
MINION_TO_SUMMON = NPC_SILVERMOON_MINION;
|
||||
TEXT_ID = TEXT_ERESSEA_DAWNSINGER;
|
||||
TEXT_ID = SAY_GRAND_CHAMPIONS_INTRO_DAWNSINGER;
|
||||
break;
|
||||
case 2:
|
||||
CHAMPION_TO_SUMMON = NPC_RUNOK;
|
||||
MINION_TO_SUMMON = NPC_THUNDER_BLUFF_MINION;
|
||||
TEXT_ID = TEXT_RUNOK_WILDMANE;
|
||||
TEXT_ID = SAY_GRAND_CHAMPIONS_INTRO_WILDMANE;
|
||||
break;
|
||||
case 3:
|
||||
CHAMPION_TO_SUMMON = NPC_ZULTORE;
|
||||
MINION_TO_SUMMON = NPC_SENJIN_MINION;
|
||||
TEXT_ID = TEXT_ZUL_TORE;
|
||||
TEXT_ID = SAY_GRAND_CHAMPIONS_INTRO_ZULTORE;
|
||||
break;
|
||||
case 4:
|
||||
CHAMPION_TO_SUMMON = NPC_VISCERI;
|
||||
MINION_TO_SUMMON = NPC_UNDERCITY_MINION;
|
||||
TEXT_ID = TEXT_DEATHSTALKER_VESCERI;
|
||||
TEXT_ID = SAY_GRAND_CHAMPIONS_INTRO_DEATHSTALKER;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
@@ -767,10 +778,7 @@ public:
|
||||
if (!shortver)
|
||||
if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
|
||||
{
|
||||
if( TeamIdInInstance == TEAM_HORDE )
|
||||
TEXT_ID -= 10;
|
||||
announcer->AI()->Talk(TEXT_ID);
|
||||
announcer->AI()->Talk(TEXT_ID + 1);
|
||||
announcer->AI()->Talk(TEXT_ID); /// @todo: Missing Argent Raid Spectator cheers.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1007,16 +1015,6 @@ public:
|
||||
HandleGameObject(GO_MainGateGUID, true, gate);
|
||||
HandleGameObject(GO_EnterGateGUID, false, gate);
|
||||
}
|
||||
if( Counter )
|
||||
{
|
||||
announcer->AI()->Talk(TEXT_CHEER_EADRIC_1);
|
||||
announcer->AI()->Talk(TEXT_CHEER_EADRIC_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
announcer->AI()->Talk(TEXT_CHEER_PALETRESS_1);
|
||||
announcer->AI()->Talk(TEXT_CHEER_PALETRESS_2);
|
||||
}
|
||||
}
|
||||
|
||||
for( int8 i = 0; i < 3; ++i )
|
||||
@@ -1060,7 +1058,7 @@ public:
|
||||
case EVENT_ARGENT_CHALLENGE_SAY_1:
|
||||
{
|
||||
if( Creature* ac = instance->GetCreature(NPC_ArgentChampionGUID) )
|
||||
ac->AI()->Talk(Counter ? TEXT_EADRIC_SAY_1 : TEXT_PALETRESS_SAY_1);
|
||||
ac->AI()->Talk(Counter ? SAY_EADRIC_INTRO : SAY_PALETRESS_INTRO_1);
|
||||
if( !Counter )
|
||||
events.ScheduleEvent(EVENT_ARGENT_CHALLENGE_SAY_2, 6s);
|
||||
}
|
||||
@@ -1068,7 +1066,7 @@ public:
|
||||
case EVENT_ARGENT_CHALLENGE_SAY_2:
|
||||
{
|
||||
if( Creature* ac = instance->GetCreature(NPC_ArgentChampionGUID) )
|
||||
ac->AI()->Talk(TEXT_PALETRESS_SAY_2);
|
||||
ac->AI()->Talk(SAY_PALETRESS_INTRO_2);
|
||||
}
|
||||
break;
|
||||
case EVENT_ARGENT_SOLDIER_GROUP_ATTACK:
|
||||
@@ -1163,7 +1161,7 @@ public:
|
||||
}
|
||||
|
||||
announcer->SetFacingToObject(bk_vehicle);
|
||||
announcer->AI()->Talk(TEXT_BK_RAFTERS);
|
||||
announcer->AI()->Talk(SAY_KNIGHT_INTRO);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1174,7 +1172,7 @@ public:
|
||||
Position exitPos = { 751.003357f, 638.145508f, 411.570129f, M_PI };
|
||||
bk->ExitVehicle(/*&exitPos*/);
|
||||
bk->GetMotionMaster()->MoveJump(exitPos, 2.0f, 2.0f);
|
||||
bk->AI()->Talk(TEXT_BK_SPOILED);
|
||||
bk->AI()->Talk(SAY_BK_INTRO_1);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_BLACK_KNIGHT_CAST_ANNOUNCER, 2s);
|
||||
}
|
||||
@@ -1212,7 +1210,7 @@ public:
|
||||
{
|
||||
bk->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
|
||||
bk->GetMotionMaster()->MovePoint(0, 746.81f, 623.15f, 411.42f);
|
||||
bk->AI()->Talk(TEXT_BK_LICH);
|
||||
bk->AI()->Talk(SAY_BK_INTRO_2);
|
||||
}
|
||||
if( Creature* announcer = instance->GetCreature(NPC_AnnouncerGUID) )
|
||||
if (announcer->IsAlive())
|
||||
@@ -1225,7 +1223,7 @@ public:
|
||||
if( Creature* bk = instance->GetCreature(NPC_BlackKnightGUID) )
|
||||
{
|
||||
bk->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
|
||||
bk->AI()->Talk(TEXT_BK_TASK);
|
||||
bk->AI()->Talk(SAY_BK_INTRO_3);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_BLACK_KNIGHT_ATTACK, 5s);
|
||||
}
|
||||
|
||||
@@ -21,10 +21,23 @@
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
|
||||
#define GOSSIP_START_EVENT1a "I am ready."
|
||||
#define GOSSIP_START_EVENT1b "I am ready. However I'd like to skip the pageantry."
|
||||
#define GOSSIP_START_EVENT2 "I'm ready for the next challenge."
|
||||
#define GOSSIP_START_EVENT3 "I'm ready."
|
||||
enum Texts
|
||||
{
|
||||
NPC_TEXT_NOT_MOUNTED_H = 15043, // Horde text
|
||||
NPC_TEXT_NOT_MOUNTED_A = 14757, // Alliance text
|
||||
|
||||
NPC_TEXT_CHALLENGE_1 = 14688,
|
||||
NPC_TEXT_CHALLENGE_2 = 14737,
|
||||
NPC_TEXT_CHALLENGE_3 = 14738,
|
||||
|
||||
GOSSIP_MENU_STAGE = 10614,
|
||||
|
||||
GOSSIP_START_EVENT_1A = 0,
|
||||
GOSSIP_START_EVENT_1B = 3, // Skip roleplay
|
||||
GOSSIP_START_EVENT_2 = 1,
|
||||
GOSSIP_START_EVENT_3 = 2,
|
||||
|
||||
};
|
||||
|
||||
class npc_announcer_toc5 : public CreatureScript
|
||||
{
|
||||
@@ -47,29 +60,28 @@ public:
|
||||
if (!player->GetVehicle())
|
||||
{
|
||||
if (pInstance->GetData(DATA_TEAMID_IN_INSTANCE) == TEAM_HORDE)
|
||||
gossipTextId = 15043; //Horde text
|
||||
gossipTextId = NPC_TEXT_NOT_MOUNTED_H;
|
||||
else
|
||||
gossipTextId = 14757; //Alliance text
|
||||
gossipTextId = NPC_TEXT_NOT_MOUNTED_A;
|
||||
}
|
||||
else
|
||||
{
|
||||
gossipTextId = 14688;
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1a, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1338);
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT1b, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1341);
|
||||
gossipTextId = NPC_TEXT_CHALLENGE_1;
|
||||
AddGossipItemFor(player, GOSSIP_MENU_STAGE, GOSSIP_START_EVENT_1A, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
AddGossipItemFor(player, GOSSIP_MENU_STAGE, GOSSIP_START_EVENT_1B, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
|
||||
}
|
||||
break;
|
||||
case INSTANCE_PROGRESS_CHAMPIONS_DEAD:
|
||||
gossipTextId = 14737;
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1339);
|
||||
gossipTextId = NPC_TEXT_CHALLENGE_2;
|
||||
AddGossipItemFor(player, GOSSIP_MENU_STAGE, GOSSIP_START_EVENT_2, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3);
|
||||
break;
|
||||
case INSTANCE_PROGRESS_ARGENT_CHALLENGE_DIED:
|
||||
gossipTextId = 14738;
|
||||
AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_START_EVENT3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1340);
|
||||
gossipTextId = NPC_TEXT_CHALLENGE_3;
|
||||
AddGossipItemFor(player, GOSSIP_MENU_STAGE, GOSSIP_START_EVENT_3, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
||||
SendGossipMenuFor(player, gossipTextId, creature->GetGUID());
|
||||
return true;
|
||||
}
|
||||
@@ -83,9 +95,9 @@ public:
|
||||
if(!pInstance)
|
||||
return true;
|
||||
|
||||
if(uiAction == GOSSIP_ACTION_INFO_DEF + 1338 || uiAction == GOSSIP_ACTION_INFO_DEF + 1341 || uiAction == GOSSIP_ACTION_INFO_DEF + 1339 || uiAction == GOSSIP_ACTION_INFO_DEF + 1340)
|
||||
if(uiAction == GOSSIP_ACTION_INFO_DEF + 1 || uiAction == GOSSIP_ACTION_INFO_DEF + 2 || uiAction == GOSSIP_ACTION_INFO_DEF + 3 || uiAction == GOSSIP_ACTION_INFO_DEF + 4)
|
||||
{
|
||||
pInstance->SetData(DATA_ANNOUNCER_GOSSIP_SELECT, (uiAction == GOSSIP_ACTION_INFO_DEF + 1341 ? 1 : 0));
|
||||
pInstance->SetData(DATA_ANNOUNCER_GOSSIP_SELECT, (uiAction == GOSSIP_ACTION_INFO_DEF + 2 ? 1 : 0));
|
||||
creature->RemoveNpcFlag(UNIT_NPC_FLAG_GOSSIP);
|
||||
}
|
||||
|
||||
|
||||
@@ -141,11 +141,28 @@ enum eNpcs
|
||||
|
||||
NPC_BLACK_KNIGHT = 35451,
|
||||
|
||||
NPC_JAEREN = 35004,
|
||||
NPC_ARELAS = 35005,
|
||||
NPC_JAEREN = 35004, // Horde
|
||||
NPC_ARELAS = 35005, // Alliance
|
||||
NPC_RISEN_JAEREN = 35545,
|
||||
NPC_RISEN_ARELAS = 35564,
|
||||
NPC_TIRION = 33628,
|
||||
NPC_TIRION = 33628, // Possibly wrong npc here, 34996 had already populated creature_text (from ToC25) that matches. Needs a sniff to confirm.
|
||||
|
||||
/// @todo: Argent Raid Spectator - FX - Missing spawns for Toc5 (map 650), ToC25 probably matches positions, needs a sniff to confirm.
|
||||
// Horde
|
||||
NPC_SPECTATOR_HORDE = 34883,
|
||||
NPC_SPECTATOR_BELF = 34904,
|
||||
NPC_SPECTATOR_TAUREN = 34903,
|
||||
NPC_SPECTATOR_TROLL = 34902,
|
||||
NPC_SPECTATOR_ORC = 34901,
|
||||
NPC_SPECTATOR_UNDEAD = 34905,
|
||||
|
||||
// Alliance
|
||||
NPC_SPECTATOR_ALLIANCE = 34887,
|
||||
NPC_SPECTATOR_DWARF = 34906,
|
||||
NPC_SPECTATOR_GNOME = 34910,
|
||||
NPC_SPECTATOR_HUMAN = 34900,
|
||||
NPC_SPECTATOR_NELF = 34909,
|
||||
NPC_SPECTATOR_DRAENEI = 34908,
|
||||
};
|
||||
|
||||
enum eGameObjects
|
||||
@@ -175,69 +192,57 @@ enum eVehicles
|
||||
|
||||
enum eTexts
|
||||
{
|
||||
TEXT_LANA_STOUTHAMMER = 1,
|
||||
TEXT_CHEER_LANA_STOUTHAMMER = 2,
|
||||
TEXT_COLOSOS = 3,
|
||||
TEXT_CHEER_COLOSOS = 4,
|
||||
TEXT_EVENSONG = 5,
|
||||
TEXT_CHEER_EVENSONG = 6,
|
||||
TEXT_MARSHAL_JACOB_ALERIUS = 7,
|
||||
TEXT_CHEER_MARSHAL_JACOB_ALERIUS = 8,
|
||||
TEXT_AMBROSE_BOLTSPARK = 9,
|
||||
TEXT_CHEER_AMBROSE_BOLTSPARK = 10,
|
||||
// Spectators
|
||||
SAY_SPECTATOR_CHEER = 0,
|
||||
|
||||
TEXT_DEATHSTALKER_VESCERI = 11,
|
||||
TEXT_CHEER_DEATHSTALKER_VESCERI = 12,
|
||||
TEXT_RUNOK_WILDMANE = 13,
|
||||
TEXT_CHEER_RUNOK_WILDMANE = 14,
|
||||
TEXT_ZUL_TORE = 15,
|
||||
TEXT_CHEER_ZUL_TORE = 16,
|
||||
TEXT_MOKRA_SKILLCRUSHER = 17,
|
||||
TEXT_CHEER_MOKRA_SKILLCRUSHER = 18,
|
||||
TEXT_ERESSEA_DAWNSINGER = 19,
|
||||
TEXT_CHEER_ERESSEA_DAWNSINGER = 20,
|
||||
// Announcers: Alliance Announcer - Arelas Brightstar && Horde Announcer - Jaeren Sunsworn
|
||||
SAY_EADRIC_INTRO_ANNOUNCER = 0,
|
||||
SAY_JAEREN_PALETRESS_INTRO = 1,
|
||||
SAY_GRAND_CHAMPIONS_INTRO_1 = 2,
|
||||
SAY_GRAND_CHAMPIONS_INTRO_DAWNSINGER = 3, // Boltspark
|
||||
SAY_GRAND_CHAMPIONS_INTRO_ZULTORE = 4, // Jaelyne
|
||||
SAY_GRAND_CHAMPIONS_INTRO_SKULLCRUSHER = 5, // Jacob
|
||||
SAY_GRAND_CHAMPIONS_INTRO_DEATHSTALKER = 6, // Lana
|
||||
SAY_GRAND_CHAMPIONS_INTRO_WILDMANE = 7, // Colosos
|
||||
SAY_KNIGHT_INTRO = 8,
|
||||
|
||||
// Eadric
|
||||
SAY_EADRIC_INTRO = 0,
|
||||
SAY_EADRIC_AGGRO = 1,
|
||||
SAY_EADRIC_EMOTE_RADIANCE = 2,
|
||||
SAY_EADRIC_EMOTE_HAMMER_RIGHTEOUS = 3,
|
||||
SAY_EADRIC_HAMMER_RIGHTEOUS = 4,
|
||||
SAY_EADRIC_KILL_PLAYER = 5, // "You! You need more practice." && "Nay, nay, and I say yet again nay! Not good enough."
|
||||
SAY_EADRIC_DEFEATED = 6,
|
||||
|
||||
// Confessor Paletress
|
||||
SAY_PALETRESS_INTRO_1 = 0,
|
||||
SAY_PALETRESS_INTRO_2 = 1,
|
||||
SAY_PALETRESS_AGGRO = 2,
|
||||
SAY_PALETRESS_MEMORY_SUMMON = 3,
|
||||
SAY_PALETRESS_MEMORY_DEATH = 4,
|
||||
SAY_PALETRESS_KILL_PLAYER = 5, // "Take your rest. "&& "Be at ease."
|
||||
SAY_PALETRESS_DEFEATED = 6,
|
||||
|
||||
// Tirion
|
||||
TEXT_WELCOME = 21,
|
||||
TEXT_WELCOME_2 = 22,
|
||||
TEXT_BEGIN = 23,
|
||||
TEXT_GRATZ_SLAIN_CHAMPIONS = 24,
|
||||
TEXT_INTRODUCE_EADRIC = 25,
|
||||
TEXT_INTRODUCE_PALETRESS = 26,
|
||||
TEXT_CHEER_EADRIC_1 = 27,
|
||||
TEXT_CHEER_EADRIC_2 = 28,
|
||||
TEXT_EADRIC_SAY_1 = 39,
|
||||
TEXT_CHEER_PALETRESS_1 = 29,
|
||||
TEXT_CHEER_PALETRESS_2 = 30,
|
||||
TEXT_PALETRESS_SAY_1 = 37,
|
||||
TEXT_PALETRESS_SAY_2 = 38,
|
||||
TEXT_YOU_MAY_BEGIN = 41,
|
||||
|
||||
// Tirion - The Black Knight Interactions
|
||||
TEXT_BK_INTRO = 31,
|
||||
TEXT_BK_RAFTERS = 32,
|
||||
TEXT_BK_SPOILED = 33,
|
||||
TEXT_BK_MEANING = 34,
|
||||
TEXT_BK_LICH = 35,
|
||||
TEXT_BK_TASK = 36,
|
||||
|
||||
TEXT_EADRIC_AGGRO = 42,
|
||||
TEXT_EADRIC_HAMMER = 43,
|
||||
TEXT_EADRIC_SLAIN_1 = 44,
|
||||
TEXT_EADRIC_SLAIN_2 = 45,
|
||||
TEXT_EADRIC_DEATH = 46,
|
||||
|
||||
TEXT_PALETRESS_AGGRO = 47,
|
||||
TEXT_PALETRESS_MEMORY_SUMMON = 48,
|
||||
TEXT_PALETRESS_MEMORY_DEFEATED = 51,
|
||||
TEXT_PALETRESS_SLAIN_1 = 49,
|
||||
TEXT_PALETRESS_SLAIN_2 = 50,
|
||||
TEXT_PALETRESS_DEATH = 52,
|
||||
|
||||
TEXT_BK_AGGRO = 53,
|
||||
TEXT_BK_SLAIN_1 = 57,
|
||||
TEXT_BK_SLAIN_2 = 58,
|
||||
TEXT_BK_SKELETON_RES = 54,
|
||||
TEXT_BK_GHOST_RES = 55,
|
||||
TEXT_BK_DEATH = 56,
|
||||
// The Black Knight
|
||||
SAY_BK_INTRO_1 = 0,
|
||||
SAY_BK_INTRO_2 = 1,
|
||||
SAY_BK_INTRO_3 = 2,
|
||||
SAY_BK_AGGRO = 3,
|
||||
SAY_BK_PHASE_2 = 4, // Skeleton
|
||||
SAY_BK_PHASE_3 = 5, // Ghost
|
||||
SAY_BK_KILL_PLAYER = 6, // "Pathetic." && "A waste of flesh."
|
||||
SAY_BK_DEATH = 7,
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
|
||||
@@ -277,12 +277,6 @@ public:
|
||||
_experimentState = (data ? 1 : 0);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (instance->CheckRequiredBosses(DATA_PROFESSOR_PUTRICIDE))
|
||||
BossAI::AttackStart(who);
|
||||
}
|
||||
|
||||
bool CanAIAttack(Unit const* target) const override
|
||||
{
|
||||
return me->IsVisible() && target->GetPositionZ() > 388.0f && target->GetPositionZ() < 410.0f && target->GetPositionY() > 3157.1f && target->GetExactDist2dSq(4356.0f, 3211.0f) < 80.0f * 80.0f;
|
||||
|
||||
@@ -1007,13 +1007,6 @@ public:
|
||||
me->SendMovementFlagUpdate();
|
||||
}
|
||||
|
||||
void AttackStart(Unit* victim) override
|
||||
{
|
||||
if (me->HasReactState(REACT_PASSIVE) || me->IsImmuneToAll())
|
||||
return;
|
||||
BossAI::AttackStart(victim);
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
_JustDied();
|
||||
@@ -1039,13 +1032,6 @@ public:
|
||||
|
||||
void JustEngagedWith(Unit* /*attacker*/) override
|
||||
{
|
||||
if (me->HasReactState(REACT_PASSIVE) || me->IsImmuneToAll())
|
||||
{
|
||||
me->CombatStop(false);
|
||||
me->SetImmuneToAll(true);
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
return;
|
||||
}
|
||||
_JustEngagedWith();
|
||||
me->LowerPlayerDamageReq(me->GetMaxHealth());
|
||||
if (Creature* crok = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_CROK_SCOURGEBANE)))
|
||||
|
||||
@@ -1457,7 +1457,7 @@ public:
|
||||
|
||||
bool CheckRequiredBosses(uint32 bossId, Player const* player) const override
|
||||
{
|
||||
if (player->GetSession() && player->GetSession()->GetSecurity() >= SEC_MODERATOR)
|
||||
if (player && player->GetSession() && player->GetSession()->GetSecurity() >= SEC_MODERATOR)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -56,16 +56,19 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
_Reset();
|
||||
_spoken = false;
|
||||
|
||||
ScheduleHealthCheckEvent(80, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
});
|
||||
ScheduleHealthCheckEvent({ 80, 50, 25 }, [&] {
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
ScheduleHealthCheckEvent(50, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(25, [&] {
|
||||
TeleportAndCastExplosion();
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
});
|
||||
|
||||
ScheduleHealthCheckEvent(20, [&] {
|
||||
@@ -79,22 +82,6 @@ struct boss_talon_king_ikiss : public BossAI
|
||||
return _spoken;
|
||||
}
|
||||
|
||||
void TeleportAndCastExplosion()
|
||||
{
|
||||
me->InterruptNonMeleeSpells(false);
|
||||
DoCastSelf(SPELL_ARCANE_BUBBLE, true);
|
||||
DoCastAOE(SPELL_BLINK);
|
||||
Talk(EMOTE_ARCANE_EXP);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext)
|
||||
{
|
||||
DoCastAOE(SPELL_ARCANE_EXPLOSION);
|
||||
}).Schedule(6500ms, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->GetThreatMgr().ResetAllThreat();
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!_spoken && who->IsPlayer())
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "shadow_labyrinth.h"
|
||||
|
||||
enum eEnums
|
||||
@@ -35,7 +34,12 @@ enum eEnums
|
||||
|
||||
EVENT_SPELL_CORROSIVE = 1,
|
||||
EVENT_SPELL_FEAR = 2,
|
||||
EVENT_SPELL_ENRAGE = 3
|
||||
EVENT_SPELL_ENRAGE = 3,
|
||||
|
||||
PATH_ID_START = 1873100,
|
||||
PATH_ID_PATHING = 1873101,
|
||||
|
||||
SOUND_INTRO = 9349
|
||||
};
|
||||
|
||||
class boss_ambassador_hellmaw : public CreatureScript
|
||||
@@ -48,9 +52,9 @@ public:
|
||||
return GetShadowLabyrinthAI<boss_ambassador_hellmawAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_ambassador_hellmawAI : public npc_escortAI
|
||||
struct boss_ambassador_hellmawAI : public ScriptedAI
|
||||
{
|
||||
boss_ambassador_hellmawAI(Creature* creature) : npc_escortAI(creature)
|
||||
boss_ambassador_hellmawAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
instance = creature->GetInstanceScript();
|
||||
}
|
||||
@@ -59,64 +63,102 @@ public:
|
||||
EventMap events;
|
||||
bool isBanished;
|
||||
|
||||
void DoAction(int32 param) override
|
||||
void InitializeAI() override
|
||||
{
|
||||
if (param != 1)
|
||||
return;
|
||||
Reset();
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_BANISH);
|
||||
Talk(SAY_INTRO);
|
||||
Start(true, false, ObjectGuid::Empty, nullptr, false, true);
|
||||
isBanished = false;
|
||||
if (instance && instance->GetData(TYPE_RITUALISTS) != DONE)
|
||||
{
|
||||
isBanished = true;
|
||||
me->SetImmuneToAll(true);
|
||||
|
||||
me->m_Events.AddEventAtOffset([this]()
|
||||
{
|
||||
DoCastSelf(SPELL_BANISH, true);
|
||||
}, 500ms);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->GetMotionMaster()->MovePath(PATH_ID_START, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
isBanished = false;
|
||||
me->SetImmuneToAll(false);
|
||||
if (instance)
|
||||
{
|
||||
instance->SetData(TYPE_HELLMAW, NOT_STARTED);
|
||||
if (instance->GetData(TYPE_OVERSEER) != DONE)
|
||||
{
|
||||
isBanished = true;
|
||||
me->CastSpell(me, SPELL_BANISH, true);
|
||||
}
|
||||
else
|
||||
Start(true, false, ObjectGuid::Empty, nullptr, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param != 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
me->RemoveAurasDueToSpell(SPELL_BANISH);
|
||||
Talk(SAY_INTRO);
|
||||
DoPlaySoundToSet(me, SOUND_INTRO);
|
||||
isBanished = false;
|
||||
me->SetImmuneToAll(false);
|
||||
me->GetMotionMaster()->MovePath(PATH_ID_START, false);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit*) override
|
||||
{
|
||||
if (isBanished)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_SPELL_CORROSIVE, urand(5000, 10000));
|
||||
events.ScheduleEvent(EVENT_SPELL_FEAR, urand(15000, 20000));
|
||||
if (IsHeroic())
|
||||
{
|
||||
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 180000);
|
||||
}
|
||||
|
||||
if (instance)
|
||||
{
|
||||
instance->SetData(TYPE_HELLMAW, IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (isBanished)
|
||||
{
|
||||
return;
|
||||
npc_escortAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* who) override
|
||||
{
|
||||
if (isBanished)
|
||||
{
|
||||
return;
|
||||
npc_escortAI::AttackStart(who);
|
||||
}
|
||||
|
||||
ScriptedAI::AttackStart(who);
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 /*waypointId*/) override
|
||||
void PathEndReached(uint32 pathId) override
|
||||
{
|
||||
if (pathId == PATH_ID_START)
|
||||
{
|
||||
me->m_Events.AddEventAtOffset([this]()
|
||||
{
|
||||
me->GetMotionMaster()->MovePath(PATH_ID_PATHING, true);
|
||||
}, 20s);
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
@@ -132,19 +174,63 @@ public:
|
||||
instance->SetData(TYPE_HELLMAW, DONE);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
bool CanAIAttack(Unit const* /*unit*/) const override
|
||||
{
|
||||
npc_escortAI::UpdateAI(diff);
|
||||
return !isBanished;
|
||||
}
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (isBanished)
|
||||
void DoMeleeAttackIfReady(bool ignoreCasting)
|
||||
{
|
||||
if (!ignoreCasting && me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
Unit* victim = me->GetVictim();
|
||||
if (!victim || !victim->IsInWorld())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!me->IsWithinMeleeRange(victim))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure our attack is ready and we aren't currently casting before checking distance
|
||||
if (me->isAttackReady())
|
||||
{
|
||||
// xinef: prevent base and off attack in same time, delay attack at 0.2 sec
|
||||
if (me->haveOffhandWeapon())
|
||||
{
|
||||
if (me->getAttackTimer(OFF_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
{
|
||||
me->setAttackTimer(OFF_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
me->AttackerStateUpdate(victim, BASE_ATTACK, false, ignoreCasting);
|
||||
me->resetAttackTimer();
|
||||
}
|
||||
|
||||
if (me->haveOffhandWeapon() && me->isAttackReady(OFF_ATTACK))
|
||||
{
|
||||
// xinef: delay main hand attack if both will hit at the same time (players code)
|
||||
if (me->getAttackTimer(BASE_ATTACK) < ATTACK_DISPLAY_DELAY)
|
||||
{
|
||||
me->setAttackTimer(BASE_ATTACK, ATTACK_DISPLAY_DELAY);
|
||||
}
|
||||
|
||||
me->AttackerStateUpdate(victim, OFF_ATTACK, false, ignoreCasting);
|
||||
me->resetAttackTimer(OFF_ATTACK);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
@@ -161,7 +247,7 @@ public:
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
DoMeleeAttackIfReady(me->FindCurrentSpellBySpellId(SPELL_CORROSIVE_ACID) != nullptr);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -39,13 +39,13 @@ public:
|
||||
ObjectGuid m_uiRefectoryDoorGUID;
|
||||
ObjectGuid m_uiScreamingHallDoorGUID;
|
||||
|
||||
uint32 m_uiFelOverseerCount;
|
||||
uint32 _ritualistsAliveCount;
|
||||
|
||||
void Initialize() override
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
m_uiFelOverseerCount = 0;
|
||||
_ritualistsAliveCount = 0;
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const override
|
||||
@@ -76,11 +76,13 @@ public:
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_FEL_OVERSEER:
|
||||
case NPC_CABAL_RITUALIST:
|
||||
if (creature->IsAlive())
|
||||
++m_uiFelOverseerCount;
|
||||
++_ritualistsAliveCount;
|
||||
break;
|
||||
case NPC_HELLMAW:
|
||||
m_uiHellmawGUID = creature->GetGUID();
|
||||
@@ -88,19 +90,26 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void OnUnitDeath(Unit* unit) override
|
||||
{
|
||||
InstanceScript::OnUnitDeath(unit);
|
||||
|
||||
if (unit->GetEntry() == NPC_CABAL_RITUALIST)
|
||||
if (!--_ritualistsAliveCount)
|
||||
{
|
||||
m_auiEncounter[TYPE_RITUALISTS] = DONE;
|
||||
SaveToDB();
|
||||
if (Creature* cr = instance->GetCreature(m_uiHellmawGUID))
|
||||
{
|
||||
cr->AI()->DoAction(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 uiData) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_OVERSEER:
|
||||
if (!--m_uiFelOverseerCount)
|
||||
{
|
||||
m_auiEncounter[type] = DONE;
|
||||
if (Creature* cr = instance->GetCreature(m_uiHellmawGUID))
|
||||
cr->AI()->DoAction(1);
|
||||
}
|
||||
break;
|
||||
|
||||
case DATA_BLACKHEARTTHEINCITEREVENT:
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(m_uiRefectoryDoorGUID);
|
||||
@@ -125,7 +134,7 @@ public:
|
||||
|
||||
uint32 GetData(uint32 type) const override
|
||||
{
|
||||
if (type == TYPE_OVERSEER)
|
||||
if (type == TYPE_RITUALISTS)
|
||||
return m_auiEncounter[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
enum slData
|
||||
{
|
||||
TYPE_OVERSEER = 0,
|
||||
TYPE_RITUALISTS = 0,
|
||||
TYPE_HELLMAW = 1,
|
||||
DATA_BLACKHEARTTHEINCITEREVENT = 2,
|
||||
DATA_GRANDMASTERVORPILEVENT = 3,
|
||||
@@ -37,7 +37,7 @@ enum slData
|
||||
|
||||
enum slNPCandGO
|
||||
{
|
||||
NPC_FEL_OVERSEER = 18796,
|
||||
NPC_CABAL_RITUALIST = 18794,
|
||||
NPC_HELLMAW = 18731,
|
||||
|
||||
REFECTORY_DOOR = 183296, //door opened when blackheart the inciter dies
|
||||
|
||||
@@ -29,11 +29,7 @@ enum HydromancerThespia
|
||||
|
||||
SPELL_LIGHTNING_CLOUD = 25033,
|
||||
SPELL_LUNG_BURST = 31481,
|
||||
SPELL_ENVELOPING_WINDS = 31718,
|
||||
|
||||
EVENT_SPELL_LIGHTNING = 1,
|
||||
EVENT_SPELL_LUNG = 2,
|
||||
EVENT_SPELL_ENVELOPING = 3
|
||||
SPELL_ENVELOPING_WINDS = 31718
|
||||
};
|
||||
|
||||
struct boss_hydromancer_thespia : public BossAI
|
||||
@@ -44,47 +40,39 @@ struct boss_hydromancer_thespia : public BossAI
|
||||
{
|
||||
_JustDied();
|
||||
Talk(SAY_DEAD);
|
||||
|
||||
instance->DoForAllMinions(DATA_HYDROMANCER_THESPIA, [&](Creature* creature) {
|
||||
creature->DespawnOrUnsummon();
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_SPELL_LIGHTNING, 9800);
|
||||
events.ScheduleEvent(EVENT_SPELL_LUNG, 13300);
|
||||
events.ScheduleEvent(EVENT_SPELL_ENVELOPING, 14500);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
scheduler.Schedule(9800ms, [this](TaskContext context)
|
||||
{
|
||||
case EVENT_SPELL_LIGHTNING:
|
||||
Talk(SAY_SPELL);
|
||||
DoCastRandomTarget(SPELL_LIGHTNING_CLOUD);
|
||||
events.RepeatEvent(urand(12100, 14500));
|
||||
break;
|
||||
case EVENT_SPELL_LUNG:
|
||||
context.Repeat(12100ms, 14500ms);
|
||||
}).Schedule(13300ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_LUNG_BURST);
|
||||
events.RepeatEvent(urand(21800, 25400));
|
||||
break;
|
||||
case EVENT_SPELL_ENVELOPING:
|
||||
context.Repeat(21800ms, 25400ms);
|
||||
}).Schedule(14500ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_ENVELOPING_WINDS);
|
||||
events.RepeatEvent(urand(30000, 40000));
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
context.Repeat(30s, 40s);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -33,20 +33,22 @@ enum MekgineerSteamrigger
|
||||
SPELL_REPAIR_N = 31532,
|
||||
SPELL_REPAIR_H = 37936,
|
||||
|
||||
NPC_STREAMRIGGER_MECHANIC = 17951,
|
||||
SPELL_SUMMON_MECHANICS_1 = 31528,
|
||||
SPELL_SUMMON_MECHANICS_2 = 31529,
|
||||
SPELL_SUMMON_MECHANICS_3 = 31530,
|
||||
|
||||
EVENT_CHECK_HP25 = 1,
|
||||
EVENT_CHECK_HP50 = 2,
|
||||
EVENT_CHECK_HP75 = 3,
|
||||
EVENT_SPELL_SHRINK = 4,
|
||||
EVENT_SPELL_SAW = 5,
|
||||
EVENT_SPELL_NET = 6,
|
||||
EVENT_ENRAGE = 7
|
||||
NPC_STREAMRIGGER_MECHANIC = 17951
|
||||
};
|
||||
|
||||
struct boss_mekgineer_steamrigger : public BossAI
|
||||
{
|
||||
boss_mekgineer_steamrigger(Creature* creature) : BossAI(creature, DATA_MEKGINEER_STEAMRIGGER) { }
|
||||
boss_mekgineer_steamrigger(Creature* creature) : BossAI(creature, DATA_MEKGINEER_STEAMRIGGER)
|
||||
{
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void JustDied(Unit* /*killer*/) override
|
||||
{
|
||||
@@ -57,131 +59,73 @@ struct boss_mekgineer_steamrigger : public BossAI
|
||||
void KilledUnit(Unit* victim) override
|
||||
{
|
||||
if (victim->IsPlayer())
|
||||
{
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_SPELL_SHRINK, 26550);
|
||||
events.ScheduleEvent(EVENT_SPELL_SAW, 6050, 17650);
|
||||
events.ScheduleEvent(EVENT_SPELL_NET, 14400);
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 300000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HP75, 5000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HP50, 5000);
|
||||
events.ScheduleEvent(EVENT_CHECK_HP25, 5000);
|
||||
}
|
||||
|
||||
void SummonMechanics()
|
||||
{
|
||||
Talk(SAY_MECHANICS);
|
||||
|
||||
me->SummonCreature(NPC_STREAMRIGGER_MECHANIC, me->GetPositionX() + 15.0f, me->GetPositionY() + 15.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
me->SummonCreature(NPC_STREAMRIGGER_MECHANIC, me->GetPositionX() - 15.0f, me->GetPositionY() + 15.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
me->SummonCreature(NPC_STREAMRIGGER_MECHANIC, me->GetPositionX() - 15.0f, me->GetPositionY() - 15.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
if (urand(0, 1))
|
||||
me->SummonCreature(NPC_STREAMRIGGER_MECHANIC, me->GetPositionX() + 15.0f, me->GetPositionY() - 15.0f, me->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* cr) override
|
||||
{
|
||||
cr->GetMotionMaster()->MoveFollow(me, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (uint32 eventId = events.ExecuteEvent())
|
||||
scheduler.Schedule(26550ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_SUPER_SHRINK_RAY);
|
||||
context.Repeat(35100ms, 54100ms);
|
||||
}).Schedule(6050ms, 17650ms, [this](TaskContext context)
|
||||
{
|
||||
if (DoCastRandomTarget(SPELL_SAW_BLADE, 1) != SPELL_CAST_OK)
|
||||
{
|
||||
DoCastVictim(SPELL_SAW_BLADE);
|
||||
}
|
||||
|
||||
context.Repeat(6050ms, 17650ms);
|
||||
}).Schedule(14400ms, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_ELECTRIFIED_NET);
|
||||
context.Repeat(21800ms, 34200ms);
|
||||
}).Schedule(5min, [this](TaskContext /*context*/)
|
||||
{
|
||||
case EVENT_SPELL_SHRINK:
|
||||
me->CastSpell(me->GetVictim(), SPELL_SUPER_SHRINK_RAY, false);
|
||||
events.Repeat(35100ms, 54100ms);
|
||||
break;
|
||||
case EVENT_SPELL_SAW:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 1))
|
||||
me->CastSpell(target, SPELL_SAW_BLADE, false);
|
||||
else
|
||||
me->CastSpell(me->GetVictim(), SPELL_SAW_BLADE, false);
|
||||
events.Repeat(6050ms, 17650ms);
|
||||
break;
|
||||
case EVENT_SPELL_NET:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0))
|
||||
me->CastSpell(target, SPELL_ELECTRIFIED_NET, false);
|
||||
events.Repeat(21800ms, 34200ms);
|
||||
break;
|
||||
case EVENT_ENRAGE:
|
||||
DoCastSelf(SPELL_ENRAGE, true);
|
||||
break;
|
||||
case EVENT_CHECK_HP25:
|
||||
case EVENT_CHECK_HP50:
|
||||
case EVENT_CHECK_HP75:
|
||||
if (me->HealthBelowPct(eventId * 25))
|
||||
{
|
||||
SummonMechanics();
|
||||
return;
|
||||
}
|
||||
events.RepeatEvent(2000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct npc_steamrigger_mechanic : public ScriptedAI
|
||||
{
|
||||
npc_steamrigger_mechanic(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_scheduler.CancelAll();
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* victim) override
|
||||
{
|
||||
ScriptedAI::JustEngagedWith(victim);
|
||||
|
||||
_scheduler.Schedule(2s, [this](TaskContext context)
|
||||
{
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
{
|
||||
if (Creature* boss = instance->GetCreature(DATA_MEKGINEER_STEAMRIGGER))
|
||||
{
|
||||
if (me->IsWithinDistInMap(boss, 13.0f))
|
||||
{
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING))
|
||||
{
|
||||
me->CastSpell(me, DUNGEON_MODE(SPELL_REPAIR_N, SPELL_REPAIR_H), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.Repeat();
|
||||
});
|
||||
|
||||
if (!IsHeroic())
|
||||
{
|
||||
ScheduleHealthCheckEvent({ 75, 50, 25 }, [&] {
|
||||
Talk(SAY_MECHANICS);
|
||||
|
||||
for (auto const& spell : { SPELL_SUMMON_MECHANICS_1, SPELL_SUMMON_MECHANICS_2, SPELL_SUMMON_MECHANICS_3 })
|
||||
{
|
||||
DoCastAOE(spell, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
scheduler.Schedule(15600ms, [this](TaskContext context)
|
||||
{
|
||||
if (roll_chance_i(15))
|
||||
{
|
||||
Talk(SAY_MECHANICS);
|
||||
}
|
||||
|
||||
DoCastAOE(RAND(SPELL_SUMMON_MECHANICS_1, SPELL_SUMMON_MECHANICS_2, SPELL_SUMMON_MECHANICS_3), true);
|
||||
context.Repeat(15600ms, 25400ms);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* /*who*/) override {}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
void JustSummoned(Creature* creature) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
_scheduler.Update(diff,
|
||||
std::bind(&BossAI::DoMeleeAttackIfReady, this));
|
||||
if (creature->GetEntry() == NPC_STREAMRIGGER_MECHANIC)
|
||||
{
|
||||
creature->GetMotionMaster()->MoveFollow(me, 5.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
TaskScheduler _scheduler;
|
||||
};
|
||||
|
||||
void AddSC_boss_mekgineer_steamrigger()
|
||||
{
|
||||
RegisterSteamvaultCreatureAI(boss_mekgineer_steamrigger);
|
||||
RegisterSteamvaultCreatureAI(npc_steamrigger_mechanic);
|
||||
}
|
||||
|
||||
@@ -17,44 +17,110 @@
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "steam_vault.h"
|
||||
|
||||
enum NagaDistiller
|
||||
enum Texts
|
||||
{
|
||||
SAY_INTRO = 0,
|
||||
SAY_REGEN = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
SAY_INTRO = 0,
|
||||
SAY_REGEN = 1,
|
||||
SAY_AGGRO = 2,
|
||||
SAY_SLAY = 3,
|
||||
SAY_DEATH = 4,
|
||||
EMOTE_DISTILLER = 5
|
||||
};
|
||||
|
||||
SPELL_SPELL_REFLECTION = 31534,
|
||||
SPELL_IMPALE = 39061,
|
||||
SPELL_HEAD_CRACK = 16172,
|
||||
SPELL_WARLORDS_RAGE = 37081,
|
||||
SPELL_WARLORDS_RAGE_NAGA = 31543,
|
||||
SPELL_WARLORDS_RAGE_PROC = 36453,
|
||||
enum Spells
|
||||
{
|
||||
SPELL_SPELL_REFLECTION = 31534,
|
||||
SPELL_IMPALE = 39061,
|
||||
SPELL_HEAD_CRACK = 16172,
|
||||
SPELL_WARLORDS_RAGE = 37081,
|
||||
SPELL_WARLORDS_RAGE_DISTILLER = 31543,
|
||||
SPELL_WARLORDS_RAGE_PROC = 36453
|
||||
};
|
||||
|
||||
NPC_NAGA_DISTILLER = 17954,
|
||||
|
||||
EVENT_SPELL_REFLECTION = 1,
|
||||
EVENT_SPELL_IMPALE = 2,
|
||||
EVENT_SPELL_HEAD_CRACK = 3,
|
||||
EVENT_SPELL_RAGE = 4
|
||||
enum Misc
|
||||
{
|
||||
POINT_DISTILLER = 1
|
||||
};
|
||||
|
||||
struct boss_warlord_kalithresh : public BossAI
|
||||
{
|
||||
boss_warlord_kalithresh(Creature* creature) : BossAI(creature, DATA_WARLORD_KALITHRESH) { }
|
||||
boss_warlord_kalithresh(Creature* creature) : BossAI(creature, DATA_WARLORD_KALITHRESH), _introDone(false) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
_Reset();
|
||||
instance->DoForAllMinions(DATA_WARLORD_KALITHRESH, [&](Creature* minion) {
|
||||
minion->SetReactState(REACT_PASSIVE);
|
||||
minion->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
});
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
{
|
||||
if (!_introDone && who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 35.0f))
|
||||
{
|
||||
Talk(SAY_INTRO);
|
||||
_introDone = true;
|
||||
}
|
||||
|
||||
ScriptedAI::MoveInLineOfSight(who);
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* /*who*/) override
|
||||
{
|
||||
Talk(SAY_AGGRO);
|
||||
_JustEngagedWith();
|
||||
events.ScheduleEvent(EVENT_SPELL_REFLECTION, 20000, 36000);
|
||||
events.ScheduleEvent(EVENT_SPELL_IMPALE, 7000, 14000);
|
||||
events.ScheduleEvent(EVENT_SPELL_HEAD_CRACK, 15000);
|
||||
events.ScheduleEvent(EVENT_SPELL_RAGE, 20000);
|
||||
|
||||
scheduler.Schedule(20s, 36s, [this](TaskContext context)
|
||||
{
|
||||
DoCastSelf(SPELL_SPELL_REFLECTION);
|
||||
context.Repeat();
|
||||
}).Schedule(7s, 14s, [this](TaskContext context)
|
||||
{
|
||||
DoCastRandomTarget(SPELL_IMPALE, 0, 10.0f);
|
||||
context.Repeat(7500ms, 12500ms);
|
||||
}).Schedule(15s, [this](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_HEAD_CRACK);
|
||||
context.Repeat(45s, 55s);
|
||||
}).Schedule(20s, [this](TaskContext context)
|
||||
{
|
||||
Talk(SAY_REGEN);
|
||||
Talk(EMOTE_DISTILLER);
|
||||
|
||||
if (Creature* distiller = me->FindNearestCreature(NPC_NAGA_DISTILLER, 8.0f))
|
||||
{
|
||||
distiller->AI()->DoCast(me, SPELL_WARLORDS_RAGE_DISTILLER, true);
|
||||
distiller->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Creature* distiller = me->FindNearestCreature(NPC_NAGA_DISTILLER, 100.0f))
|
||||
{
|
||||
me->GetMotionMaster()->MoveFollow(distiller, 8.0f, 0.0f);
|
||||
|
||||
scheduler.Schedule(1s, [this](TaskContext chaseContext)
|
||||
{
|
||||
if (Creature* distiller = me->FindNearestCreature(NPC_NAGA_DISTILLER, 8.0f))
|
||||
{
|
||||
distiller->AI()->DoCast(me, SPELL_WARLORDS_RAGE_DISTILLER, true);
|
||||
distiller->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->ResumeChasingVictim();
|
||||
}
|
||||
else
|
||||
{
|
||||
chaseContext.Repeat();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
context.Repeat(45s);
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* victim) override
|
||||
@@ -69,85 +135,39 @@ struct boss_warlord_kalithresh : public BossAI
|
||||
{
|
||||
Talk(SAY_DEATH);
|
||||
_JustDied();
|
||||
instance->DoForAllMinions(DATA_WARLORD_KALITHRESH, [&](Creature* minion) {
|
||||
minion->KillSelf();
|
||||
});
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_SPELL_REFLECTION:
|
||||
me->CastSpell(me, SPELL_SPELL_REFLECTION, false);
|
||||
events.Repeat(20s, 36s);
|
||||
break;
|
||||
case EVENT_SPELL_IMPALE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 10.0f, true))
|
||||
me->CastSpell(target, SPELL_IMPALE, false);
|
||||
events.Repeat(7500ms, 12500ms);
|
||||
break;
|
||||
case EVENT_SPELL_HEAD_CRACK:
|
||||
DoCastVictim(SPELL_HEAD_CRACK);
|
||||
events.Repeat(45s, 55s);
|
||||
break;
|
||||
case EVENT_SPELL_RAGE:
|
||||
if (Creature* distiller = me->FindNearestCreature(NPC_NAGA_DISTILLER, 100.0f))
|
||||
{
|
||||
Talk(SAY_REGEN);
|
||||
//me->CastSpell(me, SPELL_WARLORDS_RAGE, false);
|
||||
distiller->AI()->DoAction(1);
|
||||
}
|
||||
events.RepeatEvent(45000);
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
private:
|
||||
bool _introDone;
|
||||
};
|
||||
|
||||
struct npc_naga_distiller : public NullCreatureAI
|
||||
// 31543 - Warlord's Rage
|
||||
class spell_warlords_rage : public AuraScript
|
||||
{
|
||||
npc_naga_distiller(Creature* creature) : NullCreatureAI(creature) { }
|
||||
PrepareAuraScript(spell_warlords_rage);
|
||||
|
||||
uint32 spellTimer;
|
||||
|
||||
void Reset() override
|
||||
void HandleAfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||
{
|
||||
spellTimer = 0;
|
||||
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
}
|
||||
|
||||
void DoAction(int32 param) override
|
||||
{
|
||||
if (param != 1)
|
||||
return;
|
||||
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->RemoveUnitFlag(UNIT_FLAG_NON_ATTACKABLE);
|
||||
me->CastSpell(me, SPELL_WARLORDS_RAGE_NAGA, true);
|
||||
spellTimer = 1;
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (spellTimer)
|
||||
if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
|
||||
{
|
||||
spellTimer += diff;
|
||||
if (spellTimer >= 12000)
|
||||
if (GetTarget())
|
||||
{
|
||||
if (Creature* kali = me->FindNearestCreature(NPC_WARLORD_KALITHRESH, 100.0f))
|
||||
kali->CastSpell(kali, SPELL_WARLORDS_RAGE_PROC, true);
|
||||
me->KillSelf();
|
||||
GetTarget()->CastSpell(GetTarget(), SPELL_WARLORDS_RAGE_PROC, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
AfterEffectRemove += AuraEffectRemoveFn(spell_warlords_rage::HandleAfterRemove, EFFECT_0, SPELL_AURA_DUMMY, AURA_EFFECT_HANDLE_REAL);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_boss_warlord_kalithresh()
|
||||
{
|
||||
RegisterSteamvaultCreatureAI(boss_warlord_kalithresh);
|
||||
RegisterSteamvaultCreatureAI(npc_naga_distiller);
|
||||
RegisterSpellScript(spell_warlords_rage);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,13 @@ enum MainChambersAccessPanelSays
|
||||
SAY_LOUD_RUMBLE = 1
|
||||
};
|
||||
|
||||
MinionData const minionData[] =
|
||||
{
|
||||
{ NPC_NAGA_DISTILLER, DATA_WARLORD_KALITHRESH },
|
||||
{ NPC_THESPIA_WATER_ELEMENTAL, DATA_HYDROMANCER_THESPIA },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
class go_main_chambers_access_panel : public GameObjectScript
|
||||
{
|
||||
public:
|
||||
@@ -91,14 +98,16 @@ public:
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_MEKGINEER_STEAMRIGGER, DATA_MEKGINEER_STEAMRIGGER },
|
||||
{ NPC_DOOR_CONTROLLER, DATA_DOOR_CONTROLLER }
|
||||
{ NPC_DOOR_CONTROLLER, DATA_DOOR_CONTROLLER },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
ObjectData const objectData[] =
|
||||
{
|
||||
{ GO_ACCESS_PANEL_HYDRO, DATA_ACCESS_PANEL_HYDROMANCER },
|
||||
{ GO_ACCESS_PANEL_MEK, DATA_ACCESS_PANEL_MEKGINEER },
|
||||
{ GO_MAIN_CHAMBERS_DOOR, DATA_MAIN_CHAMBERS_DOOR }
|
||||
{ GO_MAIN_CHAMBERS_DOOR, DATA_MAIN_CHAMBERS_DOOR },
|
||||
{ 0, 0, }
|
||||
};
|
||||
|
||||
class instance_steam_vault : public InstanceMapScript
|
||||
@@ -113,6 +122,7 @@ public:
|
||||
SetHeaders(DataHeaders);
|
||||
SetBossNumber(EncounterCount);
|
||||
LoadObjectData(creatureData, objectData);
|
||||
LoadMinionData(minionData);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
|
||||
@@ -51,6 +51,12 @@ enum steamVaultNPCGO
|
||||
NPC_DOOR_CONTROLLER = 20926
|
||||
};
|
||||
|
||||
enum Creatures
|
||||
{
|
||||
NPC_NAGA_DISTILLER = 17954,
|
||||
NPC_THESPIA_WATER_ELEMENTAL = 17917
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
inline AI* GetSteamVaultAI(T* obj)
|
||||
{
|
||||
|
||||
@@ -43,7 +43,10 @@ enum DeathKnightSpells
|
||||
SPELL_DK_DISMISS_GARGOYLE = 50515,
|
||||
SPELL_DK_SANCTUARY = 54661,
|
||||
SPELL_DK_NIGHT_OF_THE_DEAD = 62137,
|
||||
SPELL_DK_PET_SCALING = 61017
|
||||
SPELL_DK_PET_SCALING = 61017,
|
||||
// Risen Ally
|
||||
SPELL_DK_RAISE_ALLY = 46619,
|
||||
SPELL_GHOUL_FRENZY = 62218,
|
||||
};
|
||||
|
||||
class npc_pet_dk_ebon_gargoyle : public CreatureScript
|
||||
@@ -255,6 +258,38 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class npc_pet_dk_risen_ally : public CreatureScript
|
||||
{
|
||||
public:
|
||||
npc_pet_dk_risen_ally() : CreatureScript("npc_pet_dk_risen_ally") { }
|
||||
|
||||
struct npc_pet_dk_risen_allyAI : public PossessedAI
|
||||
{
|
||||
npc_pet_dk_risen_allyAI(Creature* c) : PossessedAI(c) { }
|
||||
|
||||
void OnCharmed(bool apply) override
|
||||
{
|
||||
if (!apply)
|
||||
{
|
||||
if (Unit* owner = me->GetCharmerOrOwner())
|
||||
{
|
||||
if (Player* player = owner->ToPlayer())
|
||||
{
|
||||
player->RemoveAurasDueToSpell(SPELL_DK_RAISE_ALLY); // Remove Raise Ally aura
|
||||
player->RemoveAurasDueToSpell(SPELL_GHOUL_FRENZY); // Remove Frenzy aura
|
||||
//player->ClearResurrectRequestData();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
{
|
||||
return new npc_pet_dk_risen_allyAI (pCreature);
|
||||
}
|
||||
};
|
||||
|
||||
class npc_pet_dk_army_of_the_dead : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -335,6 +370,7 @@ void AddSC_deathknight_pet_scripts()
|
||||
{
|
||||
new npc_pet_dk_ebon_gargoyle();
|
||||
new npc_pet_dk_ghoul();
|
||||
new npc_pet_dk_risen_ally();
|
||||
new npc_pet_dk_army_of_the_dead();
|
||||
new npc_pet_dk_dancing_rune_weapon();
|
||||
RegisterSpellScript(spell_pet_dk_gargoyle_strike);
|
||||
|
||||
@@ -72,7 +72,11 @@ enum DeathKnightSpells
|
||||
SPELL_DK_UNHOLY_PRESENCE = 48265,
|
||||
SPELL_DK_UNHOLY_PRESENCE_TRIGGERED = 49772,
|
||||
SPELL_DK_WILL_OF_THE_NECROPOLIS_TALENT_R1 = 49189,
|
||||
SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284
|
||||
SPELL_DK_WILL_OF_THE_NECROPOLIS_AURA_R1 = 52284,
|
||||
// Risen Ally
|
||||
SPELL_DK_RAISE_ALLY = 46619,
|
||||
SPELL_DK_THRASH = 47480,
|
||||
SPELL_GHOUL_FRENZY = 62218,
|
||||
};
|
||||
|
||||
enum DeathKnightSpellIcons
|
||||
@@ -82,7 +86,8 @@ enum DeathKnightSpellIcons
|
||||
|
||||
enum Misc
|
||||
{
|
||||
NPC_DK_GHOUL = 26125
|
||||
NPC_DK_GHOUL = 26125,
|
||||
NPC_RISEN_ALLY = 30230
|
||||
};
|
||||
|
||||
// 50526 - Wandering Plague
|
||||
@@ -1496,6 +1501,53 @@ class spell_dk_ghoul_explode : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
// 47480 - Thrash
|
||||
class spell_dk_ghoul_thrash : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_dk_ghoul_thrash);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_GHOUL_FRENZY });
|
||||
}
|
||||
|
||||
void CalcDamage(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
/*
|
||||
Causes more damage per frenzy point:
|
||||
1 point : (Attack power * 40 * 0.01 + Attack power * 0.05)-(Attack power * 40 * 0.01 + Attack power * 0.10) damage
|
||||
2 points : (Attack power * 40 * 0.01 + Attack power * 0.10)-(Attack power * 40 * 0.01 + Attack power * 0.20) damage
|
||||
3 points : (Attack power * 40 * 0.01 + Attack power * 0.15)-(Attack power * 40 * 0.01 + Attack power * 0.30) damage
|
||||
4 points : (Attack power * 40 * 0.01 + Attack power * 0.20)-(Attack power * 40 * 0.01 + Attack power * 0.40) damage
|
||||
5 points : (Attack power * 40 * 0.01 + Attack power * 0.25)-(Attack power * 40 * 0.01 + Attack power * 0.50) damage
|
||||
*/
|
||||
|
||||
if (Aura* frenzy = GetCaster()->GetAura(SPELL_GHOUL_FRENZY))
|
||||
{
|
||||
float APBonus = GetCaster()->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||
float fixedDamageBonus = APBonus * GetEffectValue() * 0.01f;
|
||||
APBonus *= 0.05f * frenzy->GetStackAmount();
|
||||
|
||||
SetEffectValue(fixedDamageBonus + urand(int32(APBonus), int32(APBonus * 2.f)));
|
||||
|
||||
if (Unit* caster = GetCaster())
|
||||
{
|
||||
caster->RemoveAurasDueToSpell(SPELL_GHOUL_FRENZY);
|
||||
|
||||
if (Unit* charmer = caster->GetCharmer())
|
||||
{
|
||||
charmer->RemoveAurasDueToSpell(SPELL_GHOUL_FRENZY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectLaunchTarget += SpellEffectFn(spell_dk_ghoul_thrash::CalcDamage, EFFECT_0, SPELL_EFFECT_SCHOOL_DAMAGE);
|
||||
}
|
||||
};
|
||||
|
||||
// 48792 - Icebound Fortitude
|
||||
class spell_dk_icebound_fortitude : public AuraScript
|
||||
{
|
||||
@@ -2184,4 +2236,5 @@ void AddSC_deathknight_spell_scripts()
|
||||
RegisterSpellScript(spell_dk_spell_deflection);
|
||||
RegisterSpellScript(spell_dk_vampiric_blood);
|
||||
RegisterSpellScript(spell_dk_will_of_the_necropolis);
|
||||
RegisterSpellScript(spell_dk_ghoul_thrash);
|
||||
}
|
||||
|
||||
@@ -4792,6 +4792,41 @@ class spell_freezing_circle : public SpellScript
|
||||
}
|
||||
};
|
||||
|
||||
enum Threshalisk
|
||||
{
|
||||
SPELL_THRESHALISK_CHARGE = 35385,
|
||||
SPELL_RUSHING_CHARGE = 35382,
|
||||
};
|
||||
|
||||
class spell_gen_threshalisk_charge : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_gen_threshalisk_charge);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_THRESHALISK_CHARGE });
|
||||
}
|
||||
|
||||
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (Creature* caster = GetCaster()->ToCreature())
|
||||
{
|
||||
if (Unit* victim = caster->GetVictim())
|
||||
{
|
||||
if (caster->GetReactState() != REACT_PASSIVE)
|
||||
{
|
||||
caster->CastSpell(victim, GetSpellInfo()->Effects[EFFECT_1].TriggerSpell, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHit += SpellEffectFn(spell_gen_threshalisk_charge::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_generic_spell_scripts()
|
||||
{
|
||||
RegisterSpellScript(spell_silithyst);
|
||||
@@ -4934,4 +4969,5 @@ void AddSC_generic_spell_scripts()
|
||||
RegisterSpellScriptWithArgs(spell_gen_apply_aura_after_expiration, "spell_itch_aq40", SPELL_VEKNISS_CATALYST, EFFECT_0, SPELL_AURA_DUMMY);
|
||||
RegisterSpellScript(spell_gen_basic_campfire);
|
||||
RegisterSpellScript(spell_freezing_circle);
|
||||
RegisterSpellScript(spell_gen_threshalisk_charge);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user