Merge branch 'master' into Playerbot

This commit is contained in:
Yunfan Li
2023-07-18 17:59:18 +08:00
23 changed files with 759 additions and 666 deletions

View File

@@ -128,12 +128,15 @@ public:
dbPortOutput = Acore::StringFormat("Realm Id: %u not found in `realmlist` table. Please check your setup", realm.Id.Realm);
}
handler->PSendSysMessage("%s", GitRevision::GetFullVersion());
HandleServerInfoCommand(handler);
handler->PSendSysMessage("Using SSL version: %s (library: %s)", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_VERSION));
handler->PSendSysMessage("Using Boost version: %i.%i.%i", BOOST_VERSION / 100000, BOOST_VERSION / 100 % 1000, BOOST_VERSION % 100);
handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion());
handler->PSendSysMessage("Using CMake version: %s", GitRevision::GetCMakeVersion());
handler->PSendSysMessage("Using MySQL version: %u", MySQL::GetLibraryVersion());
handler->PSendSysMessage("Found MySQL Executable: %s", GitRevision::GetMySQLExecutable());
handler->PSendSysMessage("Compiled on: %s", GitRevision::GetHostOSVersion());
handler->PSendSysMessage("Worldserver listening connections on port %" PRIu16, worldPort);
@@ -210,13 +213,36 @@ public:
availableLocales += " ";
}
handler->PSendSysMessage("Using %s DBC Locale as default. All available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str());
handler->PSendSysMessage("Default DBC locale: %s.\nAll available DBC locales: %s", localeNames[defaultLocale], availableLocales.c_str());
handler->PSendSysMessage("Using World DB: %s", sWorld->GetDBVersion());
#ifdef MOD_PLAYERBOTS
handler->PSendSysMessage("Using Playerbots DB Revision: %s", sWorld->GetPlayerbotsDBRevision());
#endif
std::string lldb = "No updates found!";
if (QueryResult resL = LoginDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1"))
{
Field* fields = resL->Fetch();
lldb = fields[0].Get<std::string>();
}
std::string lcdb = "No updates found!";
if (QueryResult resC = CharacterDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1"))
{
Field* fields = resC->Fetch();
lcdb = fields[0].Get<std::string>();
}
std::string lwdb = "No updates found!";
if (QueryResult resW = WorldDatabase.Query("SELECT name FROM updates ORDER BY name DESC LIMIT 1"))
{
Field* fields = resW->Fetch();
lwdb = fields[0].Get<std::string>();
}
handler->PSendSysMessage("Latest LoginDatabase update: %s", lldb.c_str());
handler->PSendSysMessage("Latest CharacterDatabase update: %s", lcdb.c_str());
handler->PSendSysMessage("Latest WorldDatabase update: %s", lwdb.c_str());
handler->PSendSysMessage("LoginDatabase queue size: %zu", LoginDatabase.QueueSize());
handler->PSendSysMessage("CharacterDatabase queue size: %zu", CharacterDatabase.QueueSize());
handler->PSendSysMessage("WorldDatabase queue size: %zu", WorldDatabase.QueueSize());

View File

@@ -19,15 +19,18 @@
#include "ScriptedCreature.h"
#include "karazhan.h"
enum Curator
enum Text
{
SAY_AGGRO = 0,
SAY_SUMMON = 1,
SAY_EVOCATE = 2,
SAY_ENRAGE = 3,
SAY_KILL = 4,
SAY_DEATH = 5,
SAY_DEATH = 5
};
enum Spells
{
SPELL_HATEFUL_BOLT = 30383,
SPELL_EVOCATION = 30254,
SPELL_ARCANE_INFUSION = 30403,
@@ -36,140 +39,112 @@ enum Curator
SPELL_SUMMON_ASTRAL_FLARE1 = 30236,
SPELL_SUMMON_ASTRAL_FLARE2 = 30239,
SPELL_SUMMON_ASTRAL_FLARE3 = 30240,
SPELL_SUMMON_ASTRAL_FLARE4 = 30241,
EVENT_KILL_TALK = 1,
EVENT_SPELL_HATEFUL_BOLT = 2,
EVENT_SPELL_EVOCATION = 3,
EVENT_SPELL_ASTRAL_FLARE = 4,
EVENT_SPELL_BERSERK = 5,
EVENT_CHECK_HEALTH = 6
SPELL_SUMMON_ASTRAL_FLARE4 = 30241
};
class boss_curator : public CreatureScript
struct boss_curator : public BossAI
{
public:
boss_curator() : CreatureScript("boss_curator") { }
boss_curator(Creature* creature) : BossAI(creature, DATA_CURATOR) { }
struct boss_curatorAI : public BossAI
void Reset() override
{
boss_curatorAI(Creature* creature) : BossAI(creature, DATA_CURATOR) { }
BossAI::Reset();
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true);
ScheduleHealthCheckEvent(15, [&] {
DoCastSelf(SPELL_ARCANE_INFUSION, true);
Talk(SAY_ENRAGE);
});
}
void Reset() override
{
BossAI::Reset();
me->ApplySpellImmune(0, IMMUNITY_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_MANA_LEECH, true);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_POWER_BURN, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_POWER_BURN, true);
}
void KilledUnit(Unit* /*victim*/) override
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 5000);
}
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, 10000);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 6000);
events.ScheduleEvent(EVENT_SPELL_BERSERK, 600000);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
DoZoneInCombat();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (Unit* target = summon->SelectNearbyTarget(nullptr, 40.0f))
{
summon->AI()->AttackStart(target);
summon->AddThreat(target, 1000.0f);
}
summon->SetInCombatWithZone();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (me->HealthBelowPct(16))
{
events.CancelEvent(EVENT_SPELL_ASTRAL_FLARE);
me->CastSpell(me, SPELL_ARCANE_INFUSION, true);
Talk(SAY_ENRAGE);
break;
}
events.ScheduleEvent(EVENT_CHECK_HEALTH, 1000);
break;
case EVENT_SPELL_BERSERK:
Talk(SAY_ENRAGE);
me->InterruptNonMeleeSpells(true);
me->CastSpell(me, SPELL_ASTRAL_DECONSTRUCTION, true);
break;
case EVENT_SPELL_HATEFUL_BOLT:
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, urand(1, 2), 40.0f))
me->CastSpell(target, SPELL_HATEFUL_BOLT, false);
events.ScheduleEvent(EVENT_SPELL_HATEFUL_BOLT, urand(5000, 7500) * (events.GetNextEventTime(EVENT_SPELL_BERSERK) == 0 ? 1 : 2));
break;
case EVENT_SPELL_ASTRAL_FLARE:
{
me->CastSpell(me, RAND(SPELL_SUMMON_ASTRAL_FLARE1, SPELL_SUMMON_ASTRAL_FLARE2, SPELL_SUMMON_ASTRAL_FLARE3, SPELL_SUMMON_ASTRAL_FLARE4), false);
int32 mana = CalculatePct(me->GetMaxPower(POWER_MANA), 10);
me->ModifyPower(POWER_MANA, -mana);
if (me->GetPowerPct(POWER_MANA) < 10.0f)
{
Talk(SAY_EVOCATE);
me->CastSpell(me, SPELL_EVOCATION, false);
events.DelayEvents(20000);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 20000);
}
else
{
if (roll_chance_i(50))
Talk(SAY_SUMMON);
events.ScheduleEvent(EVENT_SPELL_ASTRAL_FLARE, 10000);
}
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
void KilledUnit(Unit* victim) override
{
return GetKarazhanAI<boss_curatorAI>(creature);
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_KILL);
}
}
void JustDied(Unit* killer) override
{
BossAI::JustDied(killer);
Talk(SAY_DEATH);
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
DoZoneInCombat();
scheduler.Schedule(10min, [this](TaskContext /*context*/)
{
Talk(SAY_ENRAGE);
me->InterruptNonMeleeSpells(true);
DoCastSelf(SPELL_ASTRAL_DECONSTRUCTION, true);
}).Schedule(10s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::MaxThreat, 0, 45.0f, true, false))
{
DoCast(target, SPELL_HATEFUL_BOLT);
}
else
{
DoCastVictim(SPELL_HATEFUL_BOLT);
}
context.Repeat(7s, 15s);
}).Schedule(6s, [this](TaskContext context)
{
if (me->HealthAbovePct(15))
{
if (roll_chance_i(50))
{
Talk(SAY_SUMMON);
}
DoCastSelf(RAND(SPELL_SUMMON_ASTRAL_FLARE1, SPELL_SUMMON_ASTRAL_FLARE2, SPELL_SUMMON_ASTRAL_FLARE3, SPELL_SUMMON_ASTRAL_FLARE4));
int32 mana = CalculatePct(me->GetMaxPower(POWER_MANA), 10);
me->ModifyPower(POWER_MANA, -mana);
if (me->GetPowerPct(POWER_MANA) < 10.0f)
{
Talk(SAY_EVOCATE);
DoCastSelf(SPELL_EVOCATION);
scheduler.DelayAll(20s);
context.Repeat(20s);
}
else
{
context.Repeat(10s);
}
}
});
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
if (Unit* target = summon->SelectNearbyTarget(nullptr, 40.0f))
{
summon->AI()->AttackStart(target);
summon->AddThreat(target, 1000.0f);
}
summon->SetInCombatWithZone();
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
};
void AddSC_boss_curator()
{
new boss_curator();
RegisterKarazhanCreatureAI(boss_curator);
}

View File

@@ -19,48 +19,61 @@
#include "ScriptedCreature.h"
#include "karazhan.h"
enum MaidenOfVirtue
enum Text
{
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_REPENTANCE = 2,
SAY_DEATH = 3,
SAY_AGGRO = 0,
SAY_SLAY = 1,
SAY_REPENTANCE = 2,
SAY_DEATH = 3
};
SPELL_REPENTANCE = 29511,
SPELL_HOLY_FIRE = 29522,
SPELL_HOLY_WRATH = 32445,
SPELL_HOLY_GROUND = 29523,
SPELL_BERSERK = 26662,
EVENT_SPELL_REPENTANCE = 1,
EVENT_SPELL_HOLY_FIRE = 2,
EVENT_SPELL_HOLY_WRATH = 3,
EVENT_SPELL_ENRAGE = 4,
EVENT_KILL_TALK = 5
enum Spells
{
SPELL_REPENTANCE = 29511,
SPELL_HOLY_FIRE = 29522,
SPELL_HOLY_WRATH = 32445,
SPELL_HOLY_GROUND = 29523,
SPELL_BERSERK = 26662
};
struct boss_maiden_of_virtue : public BossAI
{
boss_maiden_of_virtue(Creature* creature) : BossAI(creature, DATA_MAIDEN) { }
void Reset() override
{
BossAI::Reset();
}
void JustEngagedWith(Unit* who) override
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
DoCastAOE(SPELL_HOLY_GROUND, true);
events.ScheduleEvent(EVENT_SPELL_REPENTANCE, 25s);
events.ScheduleEvent(EVENT_SPELL_HOLY_FIRE, 8s);
events.ScheduleEvent(EVENT_SPELL_HOLY_WRATH, 15s);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 10min);
scheduler.Schedule(25s, [this](TaskContext context)
{
DoCastAOE(SPELL_REPENTANCE, true);
Talk(SAY_REPENTANCE);
context.Repeat(25s, 35s);
}).Schedule(8s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_HOLY_FIRE, 0, 50.0f);
context.Repeat(8s, 18s);
}).Schedule(15s, [this](TaskContext context)
{
DoCastRandomTarget(SPELL_HOLY_WRATH, 0, 80.0f);
context.Repeat(20s, 25s);
}).Schedule(10min, [this](TaskContext /*context*/)
{
DoCastSelf(SPELL_BERSERK, true);
});
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* victim) override
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_SLAY);
events.ScheduleEvent(EVENT_KILL_TALK, 5s);
}
}
@@ -75,30 +88,10 @@ struct boss_maiden_of_virtue : public BossAI
if (!UpdateVictim())
return;
events.Update(diff);
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
switch (events.ExecuteEvent())
{
case EVENT_SPELL_REPENTANCE:
DoCastAOE(SPELL_REPENTANCE, true);
Talk(SAY_REPENTANCE);
events.Repeat(25s, 35s);
break;
case EVENT_SPELL_HOLY_FIRE:
DoCastRandomTarget(SPELL_HOLY_FIRE, 0, 50.0f);
events.Repeat(8s, 18s);
break;
case EVENT_SPELL_HOLY_WRATH:
DoCastRandomTarget(SPELL_HOLY_WRATH, 0, 80.0f);
events.Repeat(20s, 25s);
break;
case EVENT_SPELL_ENRAGE:
DoCastSelf(SPELL_BERSERK, true);
break;
}
DoMeleeAttackIfReady();
}
};

View File

@@ -41,7 +41,7 @@ enum Spells
SPELL_FRENZY = 37023,
SPELL_DUAL_WIELD = 29651,
SPELL_BERSERK = 26662,
SPELL_VANISH_TELEPORT = 29431,
SPELL_VANISH_TELEPORT = 29431
};
enum Misc
@@ -52,9 +52,8 @@ enum Misc
EVENT_SPELL_GARROTE = 4,
EVENT_SPELL_BLIND = 5,
EVENT_SPELL_GOUGE = 6,
EVENT_CHECK_HEALTH = 7,
EVENT_SPELL_ENRAGE = 8,
EVENT_KILL_TALK = 9,
EVENT_SPELL_ENRAGE = 7,
EVENT_KILL_TALK = 8,
ACTIVE_GUEST_COUNT = 4,
MAX_GUEST_COUNT = 6
@@ -65,17 +64,13 @@ const Position GuestsPosition[4] =
{-10987.38f, -1883.38f, 81.73f, 1.50f},
{-10989.60f, -1881.27f, 81.73f, 0.73f},
{-10978.81f, -1884.08f, 81.73f, 1.50f},
{-10976.38f, -1882.59f, 81.73f, 2.31f},
{-10976.38f, -1882.59f, 81.73f, 2.31f}
};
const uint32 GuestEntries[6] =
{
17007,
19872,
19873,
19874,
19875,
19876,
17007, 19872, 19873,
19874, 19875, 19876
};
struct boss_moroes : public BossAI
@@ -109,11 +104,13 @@ struct boss_moroes : public BossAI
uint8 rand2 = RAND(0x08, 0x10, 0x20);
_activeGuests &= ~(rand1 | rand2);
}
for (uint8 i = 0; i < MAX_GUEST_COUNT; ++i)
{
if ((1 << i) & _activeGuests)
{
me->SummonCreature(GuestEntries[i], GuestsPosition[summons.size()], TEMPSUMMON_MANUAL_DESPAWN);
}
}
_events2.Reset();
_events2.ScheduleEvent(EVENT_GUEST_TALK, 10s);
}
@@ -128,24 +125,32 @@ struct boss_moroes : public BossAI
{
BossAI::JustEngagedWith(who);
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_SPELL_VANISH, 30s);
events.ScheduleEvent(EVENT_SPELL_BLIND, 20s);
events.ScheduleEvent(EVENT_SPELL_GOUGE, 13s);
events.ScheduleEvent(EVENT_CHECK_HEALTH, 5s);
events.ScheduleEvent(EVENT_SPELL_ENRAGE, 10min);
_events2.Reset();
me->CallForHelp(20.0f);
DoZoneInCombat();
}
void KilledUnit(Unit* /*victim*/) override
void DamageTaken(Unit*, uint32& /*damage*/, DamageEffectType, SpellSchoolMask) override
{
if (HealthBelowPct(30))
{
DoCastSelf(SPELL_FRENZY, true);
}
}
void KilledUnit(Unit* victim) override
{
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 5s);
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_KILL);
events.ScheduleEvent(EVENT_KILL_TALK, 5s);
}
}
}
@@ -160,9 +165,12 @@ struct boss_moroes : public BossAI
{
std::list<Creature*> guestList;
for (SummonList::const_iterator i = summons.begin(); i != summons.end(); ++i)
{
if (Creature* summon = ObjectAccessor::GetCreature(*me, *i))
{
guestList.push_back(summon);
}
}
return Acore::Containers::SelectRandomContainerElement(guestList);
}
@@ -171,15 +179,17 @@ struct boss_moroes : public BossAI
_events2.Update(diff);
switch (_events2.ExecuteEvent())
{
case EVENT_GUEST_TALK:
if (Creature* guest = GetRandomGuest())
guest->AI()->Talk(SAY_GUEST);
_events2.Repeat(5s);
break;
case EVENT_GUEST_TALK2:
Talk(SAY_OUT_OF_COMBAT);
_events2.Repeat(1min, 2min);
break;
case EVENT_GUEST_TALK:
if (Creature* guest = GetRandomGuest())
{
guest->AI()->Talk(SAY_GUEST);
}
_events2.Repeat(5s);
break;
case EVENT_GUEST_TALK2:
Talk(SAY_OUT_OF_COMBAT);
_events2.Repeat(1min, 2min);
break;
}
if (!UpdateVictim())
@@ -191,14 +201,6 @@ struct boss_moroes : public BossAI
switch (events.ExecuteEvent())
{
case EVENT_CHECK_HEALTH:
if (me->HealthBelowPct(31))
{
DoCastSelf(SPELL_FRENZY, true);
break;
}
events.Repeat(1s);
break;
case EVENT_SPELL_ENRAGE:
DoCastSelf(SPELL_BERSERK, true);
break;
@@ -227,9 +229,7 @@ struct boss_moroes : public BossAI
events.SetPhase(0);
break;
}
// Xinef: not in vanish
if (events.GetPhaseMask() == 0)
if (events.GetPhaseMask() == 0) // Xinef: not in vanish
DoMeleeAttackIfReady();
}
@@ -238,41 +238,30 @@ struct boss_moroes : public BossAI
uint8 _activeGuests;
};
class spell_moroes_vanish : public SpellScriptLoader
class spell_moroes_vanish : public SpellScript
{
public:
spell_moroes_vanish() : SpellScriptLoader("spell_moroes_vanish") { }
PrepareSpellScript(spell_moroes_vanish);
class spell_moroes_vanish_SpellScript : public SpellScript
void HandleDummy(SpellEffIndex effIndex)
{
PrepareSpellScript(spell_moroes_vanish_SpellScript);
void HandleDummy(SpellEffIndex effIndex)
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
{
PreventHitDefaultEffect(effIndex);
if (Unit* target = GetHitUnit())
{
Position pos = target->GetFirstCollisionPosition(5.0f, M_PI);
GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true);
GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH);
GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
}
Position pos = target->GetFirstCollisionPosition(5.0f, M_PI);
GetCaster()->CastSpell(target, SPELL_GARROTE_DUMMY, true);
GetCaster()->RemoveAurasDueToSpell(SPELL_VANISH);
GetCaster()->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
}
}
void Register() override
{
OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
SpellScript* GetSpellScript() const override
void Register() override
{
return new spell_moroes_vanish_SpellScript();
OnEffectHitTarget += SpellEffectFn(spell_moroes_vanish::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY);
}
};
void AddSC_boss_moroes()
{
RegisterKarazhanCreatureAI(boss_moroes);
new spell_moroes_vanish();
RegisterSpellScript(spell_moroes_vanish);
}

View File

@@ -15,44 +15,38 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* ScriptData
SDName: Boss_Terestian_Illhoof
SD%Complete: 95
SDComment: Complete! Needs adjustments to use spell though.
SDCategory: Karazhan
EndScriptData */
#include "PassiveAI.h"
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellInfo.h"
#include "karazhan.h"
enum TerestianIllhoof
enum Text
{
SAY_SLAY = 1,
SAY_DEATH = 2,
SAY_AGGRO = 3,
SAY_SACRIFICE = 4,
SAY_SUMMON = 5
SAY_SLAY = 0,
SAY_DEATH = 1,
SAY_AGGRO = 2,
SAY_SACRIFICE = 3,
SAY_SUMMON = 4
};
enum Spells
{
SPELL_SUMMON_DEMONCHAINS = 30120, // Summons demonic chains that maintain the ritual of sacrifice.
SPELL_DEMON_CHAINS = 30206, // Instant - Visual Effect
SPELL_ENRAGE = 23537, // Increases the caster's attack speed by 50% and the Physical damage it deals by 219 to 281 for 10 min.
SPELL_SHADOW_BOLT = 30055, // Hurls a bolt of dark magic at an enemy, inflicting Shadow damage.
SPELL_SACRIFICE = 30115, // Teleports and adds the debuff
SPELL_BERSERK = 32965, // Increases attack speed by 75%. Periodically casts Shadow Bolt Volley.
SPELL_SUMMON_FIENDISIMP = 30184, // Summons a Fiendish Imp.
SPELL_SUMMON_IMP = 30066, // Summons Kil'rek
SPELL_SUMMON_DEMONCHAINS = 30120,
SPELL_DEMON_CHAINS = 30206,
SPELL_ENRAGE = 23537,
SPELL_SHADOW_BOLT = 30055,
SPELL_SACRIFICE = 30115,
SPELL_BERSERK = 32965,
SPELL_SUMMON_FIENDISIMP = 30184,
SPELL_SUMMON_IMP = 30066,
SPELL_FIENDISH_PORTAL = 30171, // Opens portal and summons Fiendish Portal, 2 sec cast
SPELL_FIENDISH_PORTAL_1 = 30179, // Opens portal and summons Fiendish Portal, instant cast
SPELL_FIENDISH_PORTAL = 30171,
SPELL_FIENDISH_PORTAL_1 = 30179,
SPELL_FIREBOLT = 30050, // Blasts a target for 150 Fire damage.
SPELL_BROKEN_PACT = 30065, // All damage taken increased by 25%.
SPELL_AMPLIFY_FLAMES = 30053, // Increases the Fire damage taken by an enemy by 500 for 25 sec.
SPELL_FIREBOLT = 30050,
SPELL_BROKEN_PACT = 30065,
SPELL_AMPLIFY_FLAMES = 30053
};
enum Creatures
@@ -62,390 +56,306 @@ enum Creatures
NPC_PORTAL = 17265
};
class npc_kilrek : public CreatureScript
struct npc_kilrek : public ScriptedAI
{
public:
npc_kilrek() : CreatureScript("npc_kilrek") { }
CreatureAI* GetAI(Creature* creature) const override
npc_kilrek(Creature* creature) : ScriptedAI(creature)
{
return GetKarazhanAI<npc_kilrekAI>(creature);
instance = creature->GetInstanceScript();
}
struct npc_kilrekAI : public ScriptedAI
void Reset() override
{
npc_kilrekAI(Creature* creature) : ScriptedAI(creature)
_scheduler.CancelAll();
TerestianGUID.Clear();
}
void JustEngagedWith(Unit* /*who*/) override
{
_scheduler.Schedule(2s, [this](TaskContext context)
{
instance = creature->GetInstanceScript();
}
me->InterruptNonMeleeSpells(false);
DoCastVictim(SPELL_AMPLIFY_FLAMES);
context.Repeat(10s, 20s);
});
}
InstanceScript* instance;
ObjectGuid TerestianGUID;
uint32 AmplifyTimer;
void Reset() override
void JustDied(Unit* /*killer*/) override
{
ObjectGuid TerestianGuid = instance->GetGuidData(DATA_TERESTIAN);
if (TerestianGuid)
{
TerestianGUID.Clear();
AmplifyTimer = 2000;
}
void JustEngagedWith(Unit* /*who*/) override
{
}
void JustDied(Unit* /*killer*/) override
{
ObjectGuid TerestianGuid = instance->GetGuidData(DATA_TERESTIAN);
if (TerestianGuid)
Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGuid);
if (Terestian && Terestian->IsAlive())
{
Unit* Terestian = ObjectAccessor::GetUnit(*me, TerestianGuid);
if (Terestian && Terestian->IsAlive())
DoCast(Terestian, SPELL_BROKEN_PACT, true);
DoCast(Terestian, SPELL_BROKEN_PACT, true);
}
}
void UpdateAI(uint32 diff) override
{
//Return since we have no target
if (!UpdateVictim())
return;
if (AmplifyTimer <= diff)
{
me->InterruptNonMeleeSpells(false);
DoCastVictim(SPELL_AMPLIFY_FLAMES);
AmplifyTimer = urand(10000, 20000);
}
else
AmplifyTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class npc_demon_chain : public CreatureScript
{
public:
npc_demon_chain() : CreatureScript("npc_demon_chain") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<npc_demon_chainAI>(creature);
me->DespawnOrUnsummon(15000);
}
struct npc_demon_chainAI : public ScriptedAI
void UpdateAI(uint32 diff) override
{
npc_demon_chainAI(Creature* creature) : ScriptedAI(creature) { }
if (!UpdateVictim())
return;
ObjectGuid SacrificeGUID;
_scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
void Reset() override
DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
InstanceScript* instance;
ObjectGuid TerestianGUID;
};
struct npc_demon_chain : public ScriptedAI
{
npc_demon_chain(Creature* creature) : ScriptedAI(creature) { }
void Reset() override
{
sacrificeGUID.Clear();
}
void IsSummonedBy(WorldObject* summoner) override
{
sacrificeGUID = summoner->GetGUID();
DoCastSelf(SPELL_DEMON_CHAINS, true);
}
void JustEngagedWith(Unit* /*who*/) override { }
void AttackStart(Unit* /*who*/) override { }
void MoveInLineOfSight(Unit* /*who*/) override { }
void JustDied(Unit* /*killer*/) override
{
if (sacrificeGUID)
{
SacrificeGUID.Clear();
}
void JustEngagedWith(Unit* /*who*/) override { }
void AttackStart(Unit* /*who*/) override { }
void MoveInLineOfSight(Unit* /*who*/) override { }
void JustDied(Unit* /*killer*/) override
{
if (SacrificeGUID)
Unit* Sacrifice = ObjectAccessor::GetUnit(*me, sacrificeGUID);
if (Sacrifice)
{
Unit* Sacrifice = ObjectAccessor::GetUnit(*me, SacrificeGUID);
if (Sacrifice)
Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE);
Sacrifice->RemoveAurasDueToSpell(SPELL_SACRIFICE);
}
}
};
};
class npc_fiendish_portal : public CreatureScript
{
public:
npc_fiendish_portal() : CreatureScript("npc_fiendish_portal") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<npc_fiendish_portalAI>(creature);
}
struct npc_fiendish_portalAI : public PassiveAI
{
npc_fiendish_portalAI(Creature* creature) : PassiveAI(creature), summons(me) { }
SummonList summons;
void Reset() override
{
DespawnAllImp();
}
void JustSummoned(Creature* summon) override
{
summons.Summon(summon);
DoZoneInCombat(summon);
}
void DespawnAllImp()
{
summons.DespawnAll();
}
};
private:
ObjectGuid sacrificeGUID;
};
class npc_fiendish_imp : public CreatureScript
struct npc_fiendish_portal : public PassiveAI
{
public:
npc_fiendish_imp() : CreatureScript("npc_fiendish_imp") { }
npc_fiendish_portal(Creature* creature) : PassiveAI(creature), summons(me) {}
CreatureAI* GetAI(Creature* creature) const override
void Reset() override
{
return GetKarazhanAI<npc_fiendish_impAI>(creature);
DespawnAllImp();
}
struct npc_fiendish_impAI : public ScriptedAI
void JustSummoned(Creature* summon) override
{
npc_fiendish_impAI(Creature* creature) : ScriptedAI(creature) { }
summons.Summon(summon);
DoZoneInCombat(summon);
}
uint32 FireboltTimer;
void DespawnAllImp()
{
summons.DespawnAll();
}
void Reset() override
private:
SummonList summons;
};
struct npc_fiendish_imp : public ScriptedAI
{
npc_fiendish_imp(Creature* creature) : ScriptedAI(creature) {}
void Reset() override
{
_scheduler.CancelAll();
}
void JustEngagedWith(Unit* /*who*/) override
{
_scheduler.Schedule(2s, [this](TaskContext context)
{
FireboltTimer = 2000;
}
DoCastVictim(SPELL_FIREBOLT);
context.Repeat(2200ms);
});
}
void JustEngagedWith(Unit* /*who*/) override { }
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
void UpdateAI(uint32 diff) override
_scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
DoMeleeAttackIfReady();
}
private:
TaskScheduler _scheduler;
};
struct boss_terestian_illhoof : public BossAI
{
boss_terestian_illhoof(Creature* creature) : BossAI(creature, DATA_TERESTIAN)
{
scheduler.SetValidator([this]
{
//Return since we have no target
if (!UpdateVictim())
return;
return !me->HasUnitState(UNIT_STATE_CASTING);
});
}
if (FireboltTimer <= diff)
void Reset() override
{
_Reset();
SummonKilrek();
portalsCount = 0;
berserk = false;
for (uint8 i = 0; i < 2; ++i)
{
if (portalGUID[i])
{
DoCastVictim(SPELL_FIREBOLT);
FireboltTimer = 2200;
}
else
FireboltTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
class boss_terestian_illhoof : public CreatureScript
{
public:
boss_terestian_illhoof() : CreatureScript("boss_terestian_illhoof") { }
CreatureAI* GetAI(Creature* creature) const override
{
return GetKarazhanAI<boss_terestianAI>(creature);
}
struct boss_terestianAI : public ScriptedAI
{
boss_terestianAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
}
InstanceScript* instance;
ObjectGuid PortalGUID[2];
uint8 PortalsCount;
uint32 SacrificeTimer;
uint32 ShadowboltTimer;
uint32 SummonTimer;
uint32 BerserkTimer;
uint32 SummonKilrekTimer;
bool SummonedPortals;
bool Berserk;
void Reset() override
{
for (uint8 i = 0; i < 2; ++i)
{
if (PortalGUID[i])
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[i]))
{
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[i]))
{
CAST_AI(npc_fiendish_portal::npc_fiendish_portalAI, pPortal->AI())->DespawnAllImp();
pPortal->DespawnOrUnsummon();
}
PortalGUID[i].Clear();
pPortal->AI()->Reset();
pPortal->DespawnOrUnsummon();
}
portalGUID[i].Clear();
}
PortalsCount = 0;
SacrificeTimer = 30000;
ShadowboltTimer = 5000;
SummonTimer = 10000;
BerserkTimer = 600000;
SummonKilrekTimer = 0;
SummonedPortals = false;
Berserk = false;
instance->SetData(DATA_TERESTIAN, NOT_STARTED);
me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);
if (Minion* Kilrek = me->GetFirstMinion())
{
if (!Kilrek->IsAlive())
{
Kilrek->UnSummon();
DoCast(me, SPELL_SUMMON_IMP, true);
}
}
else
DoCast(me, SPELL_SUMMON_IMP, true);
}
}
void JustEngagedWith(Unit* /*who*/) override
void SummonKilrek()
{
me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);
DoCastSelf(SPELL_SUMMON_IMP);
}
void SpellHit(Unit* /*caster*/, SpellInfo const* spell) override
{
if (spell->Id == SPELL_BROKEN_PACT)
{
Talk(SAY_AGGRO);
DoZoneInCombat();
scheduler.Schedule(45s, [this](TaskContext /*context*/) {
SummonKilrek();
});
}
}
void JustSummoned(Creature* summoned) override
void JustEngagedWith(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
DoZoneInCombat();
scheduler.Schedule(30s, [this](TaskContext context)
{
if (summoned->GetEntry() == NPC_PORTAL)
if (Unit * target = SelectTarget(SelectTargetMethod::Random, 0, 100.0f, true, false))
{
PortalGUID[PortalsCount] = summoned->GetGUID();
++PortalsCount;
if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1)
DoCast(target, SPELL_SACRIFICE, true);
target->CastSpell(target, SPELL_SUMMON_DEMONCHAINS, true);
Talk(SAY_SACRIFICE);
context.Repeat(30s);
}
}).Schedule(5s, [this](TaskContext context)
{
DoCastVictim(SPELL_SHADOW_BOLT);
context.Repeat(10s);
}).Schedule(10s, [this](TaskContext context)
{
if (!portalGUID[0])
{
DoCastVictim(SPELL_FIENDISH_PORTAL);
}
if (!portalGUID[1])
{
DoCastVictim(SPELL_FIENDISH_PORTAL_1);
}
if (portalGUID[0] && portalGUID[1])
{
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, portalGUID[urand(0, 1)]))
{
Talk(SAY_SUMMON);
SummonedPortals = true;
pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP);
}
context.Repeat(5s);
}
}).Schedule(10min, [this](TaskContext /*context*/)
{
if (!berserk)
{
DoCastSelf(SPELL_BERSERK);
berserk = true;
}
});
}
void JustSummoned(Creature* summoned) override
{
if (summoned->GetEntry() == NPC_PORTAL)
{
portalGUID[portalsCount] = summoned->GetGUID();
++portalsCount;
if (summoned->GetUInt32Value(UNIT_CREATED_BY_SPELL) == SPELL_FIENDISH_PORTAL_1)
{
Talk(SAY_SUMMON);
}
}
}
void KilledUnit(Unit* /*victim*/) override
void KilledUnit(Unit* victim) override
{
if (victim->GetTypeId() == TYPEID_PLAYER)
{
Talk(SAY_SLAY);
}
}
void JustDied(Unit* /*killer*/) override
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
for (uint8 i = 0; i < 2; ++i)
{
for (uint8 i = 0; i < 2; ++i)
if (portalGUID[i])
{
if (PortalGUID[i])
if (Creature* pPortal = ObjectAccessor::GetCreature((*me), portalGUID[i]))
{
if (Creature* pPortal = ObjectAccessor::GetCreature((*me), PortalGUID[i]))
pPortal->DespawnOrUnsummon();
PortalGUID[i].Clear();
pPortal->AI()->Reset();
pPortal->DespawnOrUnsummon();
}
portalGUID[i].Clear();
}
Talk(SAY_DEATH);
instance->SetData(DATA_TERESTIAN, DONE);
}
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
if (Minion* Kilrek = me->GetFirstMinion())
{
if (!Kilrek->IsAlive())
{
Kilrek->UnSummon();
SummonKilrekTimer = 45000;
}
}
scheduler.Update(diff);
if (me->HasUnitState(UNIT_STATE_CASTING))
return;
if (SummonKilrekTimer <= diff)
{
DoCast(me, SPELL_SUMMON_IMP, true);
me->RemoveAura(SPELL_BROKEN_PACT);
}
else
SummonKilrekTimer -= diff;
DoMeleeAttackIfReady();
}
if (SacrificeTimer <= diff)
{
Unit* target = SelectTarget(SelectTargetMethod::Random, 1, 100, true);
if (target && target->IsAlive())
{
DoCast(target, SPELL_SACRIFICE, true);
DoCast(target, SPELL_SUMMON_DEMONCHAINS, true);
if (Creature* Chains = me->FindNearestCreature(NPC_DEMONCHAINS, 5000))
{
CAST_AI(npc_demon_chain::npc_demon_chainAI, Chains->AI())->SacrificeGUID = target->GetGUID();
Chains->CastSpell(Chains, SPELL_DEMON_CHAINS, true);
Talk(SAY_SACRIFICE);
SacrificeTimer = 30000;
}
}
}
else
SacrificeTimer -= diff;
if (ShadowboltTimer <= diff)
{
DoCast(SelectTarget(SelectTargetMethod::MaxThreat, 0), SPELL_SHADOW_BOLT);
ShadowboltTimer = 10000;
}
else
ShadowboltTimer -= diff;
if (SummonTimer <= diff)
{
if (!PortalGUID[0])
DoCastVictim(SPELL_FIENDISH_PORTAL, false);
if (!PortalGUID[1])
DoCastVictim(SPELL_FIENDISH_PORTAL_1, false);
if (PortalGUID[0] && PortalGUID[1])
{
if (Creature* pPortal = ObjectAccessor::GetCreature(*me, PortalGUID[urand(0, 1)]))
pPortal->CastSpell(me->GetVictim(), SPELL_SUMMON_FIENDISIMP, false);
SummonTimer = 5000;
}
}
else
SummonTimer -= diff;
if (!Berserk)
{
if (BerserkTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
Berserk = true;
}
else
BerserkTimer -= diff;
}
DoMeleeAttackIfReady();
}
};
private:
bool berserk;
ObjectGuid portalGUID[2];
uint8 portalsCount;
};
void AddSC_boss_terestian_illhoof()
{
new boss_terestian_illhoof();
new npc_fiendish_imp();
new npc_fiendish_portal();
new npc_kilrek();
new npc_demon_chain();
RegisterKarazhanCreatureAI(boss_terestian_illhoof);
RegisterKarazhanCreatureAI(npc_fiendish_imp);
RegisterKarazhanCreatureAI(npc_fiendish_portal);
RegisterKarazhanCreatureAI(npc_kilrek);
RegisterKarazhanCreatureAI(npc_demon_chain);
}

View File

@@ -620,28 +620,28 @@ struct npc_eye_tentacle : public ScriptedAI
void Reset() override
{
DoZoneInCombat();
_scheduler.Schedule(500ms, [this](TaskContext /*task*/)
{
DoCastAOE(SPELL_GROUND_RUPTURE);
})
.Schedule(5min, [this](TaskContext /*task*/)
{
me->DespawnOrUnsummon();
})
.Schedule(1s, 5s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NotInStomachSelector()))
{
DoCast(target, SPELL_MIND_FLAY);
}
context.Repeat(10s, 15s);
});
{
DoCastAOE(SPELL_GROUND_RUPTURE);
})
.Schedule(5min, [this](TaskContext /*task*/)
{
me->DespawnOrUnsummon();
});
}
void JustEngagedWith(Unit* /*who*/) override
{
DoZoneInCombat();
_scheduler.Schedule(1s, 5s, [this](TaskContext context)
{
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, NotInStomachSelector()))
{
DoCast(target, SPELL_MIND_FLAY);
}
context.Repeat(10s, 15s);
});
}
void UpdateAI(uint32 diff) override

View File

@@ -18,6 +18,7 @@
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "SpellScript.h"
#include "Unit.h"
#include "sethekk_halls.h"
enum Text
@@ -38,7 +39,26 @@ enum Spells
enum Npc
{
NPC_BROOD_OF_ANZU = 23132
NPC_BROOD_OF_ANZU = 23132,
NPC_HAWK_SPIRIT = 23134,
NPC_FALCON_SPIRIT = 23135,
NPC_EAGLE_SPIRIT = 23136
};
enum Spirits
{
SPELL_HAWK = 40237,
SPELL_FALCON = 40241,
SPELL_EAGLE = 40240,
SPELL_DURATION = 40250,
SPELL_FREEZE_ANIM = 16245,
SPELL_STONEFORM = 40308,
SAY_STONED = 0,
MAX_DRUID_SPELLS = 27
};
struct boss_anzu : public BossAI
@@ -54,15 +74,25 @@ struct boss_anzu : public BossAI
});
}
const Position AnzuSpiritPos[3] =
{
{-96.4816f, 304.236f, 26.5135f, 5.23599f}, // Hawk Spirit
{-72.3434f, 290.861f, 26.4851f, 3.29867f}, // Falcon Spirit
{-99.5906f, 276.661f, 26.8467f, 0.750492f}, // Eagle Spirit
};
uint32 talkTimer;
void SummonedCreatureDies(Creature* summon, Unit*) override
{
summons.Despawn(summon);
summons.RemoveNotExisting();
if (summons.empty())
if (summon->GetEntry() == NPC_BROOD_OF_ANZU)
{
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
summons.Despawn(summon);
summons.RemoveNotExisting();
if (summons.empty())
{
me->RemoveAurasDueToSpell(SPELL_BANISH_SELF);
}
}
}
@@ -78,6 +108,7 @@ struct boss_anzu : public BossAI
void JustEngagedWith(Unit* /*who*/) override
{
_JustEngagedWith();
SummonSpirits();
scheduler.Schedule(14s, [this](TaskContext context)
{
DoCastSelf(SPELL_PARALYZING_SCREECH);
@@ -112,6 +143,13 @@ struct boss_anzu : public BossAI
}
}
void SummonSpirits()
{
me->SummonCreature(NPC_HAWK_SPIRIT, AnzuSpiritPos[0], TEMPSUMMON_MANUAL_DESPAWN);
me->SummonCreature(NPC_FALCON_SPIRIT, AnzuSpiritPos[1], TEMPSUMMON_MANUAL_DESPAWN);
me->SummonCreature(NPC_EAGLE_SPIRIT, AnzuSpiritPos[2], TEMPSUMMON_MANUAL_DESPAWN);
}
void UpdateAI(uint32 diff) override
{
if (talkTimer)
@@ -119,6 +157,7 @@ struct boss_anzu : public BossAI
talkTimer += diff;
if (talkTimer >= 1000 && talkTimer < 10000)
{
me->SetImmuneToAll(true);
Talk(SAY_ANZU_INTRO1);
talkTimer = 10000;
}
@@ -128,6 +167,7 @@ struct boss_anzu : public BossAI
me->RemoveAurasDueToSpell(SPELL_SHADOWFORM);
Talk(SAY_ANZU_INTRO2);
talkTimer = 0;
me->SetInCombatWithZone();
}
}
@@ -142,7 +182,62 @@ struct boss_anzu : public BossAI
}
};
struct npc_anzu_spirit : public ScriptedAI
{
npc_anzu_spirit(Creature* creature) : ScriptedAI(creature) { }
void IsSummonedBy(WorldObject* /*summoner*/) override
{
_scheduler.Schedule(1ms, [this](TaskContext task)
{
// Check for Druid HoTs every 2400ms
if (me->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 64, 0))
{
me->RemoveAurasDueToSpell(SPELL_FREEZE_ANIM);
me->RemoveAurasDueToSpell(SPELL_STONEFORM);
switch (me->GetEntry())
{
case NPC_HAWK_SPIRIT:
DoCastSelf(SPELL_HAWK);
break;
case NPC_FALCON_SPIRIT:
DoCastSelf(SPELL_FALCON);
break;
case NPC_EAGLE_SPIRIT:
DoCastSelf(SPELL_EAGLE);
break;
default:
break;
}
}
else if (!me->HasAura(SPELL_STONEFORM))
{
Talk(SAY_STONED);
DoCastSelf(SPELL_FREEZE_ANIM, true);
DoCastSelf(SPELL_STONEFORM, true);
}
task.Repeat(2400ms);
});
}
void Reset() override
{
_scheduler.CancelAll();
}
void UpdateAI(uint32 diff) override
{
_scheduler.Update(diff);
}
private:
TaskScheduler _scheduler;
};
void AddSC_boss_anzu()
{
RegisterSethekkHallsCreatureAI(boss_anzu);
RegisterSethekkHallsCreatureAI(npc_anzu_spirit);
}

View File

@@ -201,6 +201,8 @@ struct npc_voidtraveler : public ScriptedAI
void Reset() override
{
me->SetReactState(REACT_PASSIVE);
if (TempSummon* summon = me->ToTempSummon())
{
if (Unit* vorpil = summon->GetSummonerUnit())