Merge branch 'master' into Playerbot
This commit is contained in:
@@ -7,36 +7,53 @@
|
||||
|
||||
namespace Razuvious {
|
||||
|
||||
enum RazuviousSays
|
||||
enum Says
|
||||
{
|
||||
RAZUVIOUS_SAY_AGGRO = 0,
|
||||
RAZUVIOUS_SAY_SLAY = 1,
|
||||
RAZUVIOUS_SAY_TAUNTED = 2,
|
||||
RAZUVIOUS_SAY_DEATH = 3
|
||||
SAY_AGGRO = 0,
|
||||
SAY_SLAY = 1,
|
||||
SAY_TAUNTED = 2,
|
||||
SAY_DEATH = 3,
|
||||
SAY_PATHETIC = 4,
|
||||
SAY_TARGET_DUMMY = 5,
|
||||
SAY_DEATH_KNIGHT_UNDERSTUDY = 0,
|
||||
};
|
||||
|
||||
enum RazuviousSpells
|
||||
enum Spells
|
||||
{
|
||||
SPELL_UNBALANCING_STRIKE = 26613,
|
||||
SPELL_DISRUPTING_SHOUT_10 = 55543,
|
||||
SPELL_DISRUPTING_SHOUT_25 = 29107,
|
||||
SPELL_JAGGED_KNIFE = 55550,
|
||||
SPELL_HOPELESS = 29125,
|
||||
|
||||
RAZUVIOUS_SPELL_TAUNT = 29060
|
||||
SPELL_TAUNT = 29060
|
||||
};
|
||||
|
||||
enum RazuviousEvents
|
||||
enum Events
|
||||
{
|
||||
EVENT_UNBALANCING_STRIKE = 1,
|
||||
EVENT_DISRUPTING_SHOUT = 2,
|
||||
EVENT_JAGGED_KNIFE = 3
|
||||
};
|
||||
|
||||
enum RazuviousMisc
|
||||
enum NPCs
|
||||
{
|
||||
NPC_DEATH_KNIGHT_UNDERSTUDY = 16803,
|
||||
NPC_RAZUVIOUS = 16061
|
||||
NPC_TARGET_DUMMY = 16211,
|
||||
};
|
||||
|
||||
enum Actions
|
||||
{
|
||||
ACTION_FACE_ME = 0,
|
||||
ACTION_TALK = 1,
|
||||
ACTION_EMOTE = 2,
|
||||
ACTION_SALUTE = 3,
|
||||
ACTION_BACK_TO_TRAINING = 4,
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
GROUP_OOC_RP = 0,
|
||||
POINT_DEATH_KNIGHT = 0,
|
||||
};
|
||||
|
||||
class boss_razuvious : public CreatureScript
|
||||
@@ -82,13 +99,106 @@ public:
|
||||
summons.DespawnAll();
|
||||
events.Reset();
|
||||
SpawnHelpers();
|
||||
ScheduleRP();
|
||||
}
|
||||
|
||||
void ScheduleInteractWithDeathKnight()
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
me->SetFacingToObject(understudy);
|
||||
|
||||
scheduler.Schedule(2s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (roll_chance_i(75))
|
||||
{
|
||||
bool longText = roll_chance_i(50);
|
||||
Talk(longText ? SAY_TARGET_DUMMY : SAY_PATHETIC);
|
||||
scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
understudy->AI()->DoAction(ACTION_TALK);
|
||||
});
|
||||
if (longText)
|
||||
scheduler.DelayGroup(GROUP_OOC_RP, 5s);
|
||||
}
|
||||
else
|
||||
{
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
|
||||
scheduler.Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
{
|
||||
if (roll_chance_i(25))
|
||||
understudy->AI()->DoAction(ACTION_EMOTE);
|
||||
else
|
||||
understudy->AI()->DoAction(ACTION_TALK);
|
||||
}
|
||||
});
|
||||
}
|
||||
}).Schedule(4s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
understudy->AI()->DoAction(ACTION_FACE_ME);
|
||||
}).Schedule(10s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
understudy->AI()->DoAction(ACTION_SALUTE);
|
||||
}).Schedule(13s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
me->ResumeMovement();
|
||||
}).Schedule(16s, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
understudy->AI()->DoAction(ACTION_BACK_TO_TRAINING);
|
||||
ScheduleRP();
|
||||
});
|
||||
}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id) override
|
||||
{
|
||||
if (type == POINT_MOTION_TYPE && id == POINT_DEATH_KNIGHT)
|
||||
{
|
||||
ScheduleInteractWithDeathKnight();
|
||||
}
|
||||
}
|
||||
|
||||
void ScheduleRP()
|
||||
{
|
||||
_rpBuddyGUID = Acore::Containers::SelectRandomContainerElement(summons);
|
||||
scheduler.Schedule(60s, 80s, GROUP_OOC_RP, [this](TaskContext context)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
{
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
{
|
||||
if (me->GetDistance2d(understudy) <= 6.0f)
|
||||
{
|
||||
me->PauseMovement();
|
||||
scheduler.Schedule(500ms, GROUP_OOC_RP, [this](TaskContext /*context*/)
|
||||
{
|
||||
if (_rpBuddyGUID)
|
||||
if (Creature* understudy = ObjectAccessor::GetCreature(*me, _rpBuddyGUID))
|
||||
me->GetMotionMaster()->MovePoint(POINT_DEATH_KNIGHT, understudy->GetNearPosition(3.2f, understudy->GetRelativeAngle(me)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
context.Repeat(2s);
|
||||
});
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
{
|
||||
if (roll_chance_i(30))
|
||||
{
|
||||
Talk(RAZUVIOUS_SAY_SLAY);
|
||||
Talk(SAY_SLAY);
|
||||
}
|
||||
if (who->GetTypeId() == TYPEID_PLAYER && pInstance)
|
||||
{
|
||||
@@ -108,22 +218,23 @@ public:
|
||||
void JustDied(Unit* killer) override
|
||||
{
|
||||
BossAI::JustDied(killer);
|
||||
Talk(RAZUVIOUS_SAY_DEATH);
|
||||
Talk(SAY_DEATH);
|
||||
me->CastSpell(me, SPELL_HOPELESS, true);
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id == RAZUVIOUS_SPELL_TAUNT)
|
||||
if (spell->Id == SPELL_TAUNT)
|
||||
{
|
||||
Talk(RAZUVIOUS_SAY_TAUNTED, caster);
|
||||
Talk(SAY_TAUNTED, caster);
|
||||
}
|
||||
}
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(RAZUVIOUS_SAY_AGGRO);
|
||||
scheduler.CancelGroup(GROUP_OOC_RP);
|
||||
Talk(SAY_AGGRO);
|
||||
events.ScheduleEvent(EVENT_UNBALANCING_STRIKE, 20s);
|
||||
events.ScheduleEvent(EVENT_DISRUPTING_SHOUT, 15s);
|
||||
events.ScheduleEvent(EVENT_JAGGED_KNIFE, 10s);
|
||||
@@ -132,6 +243,9 @@ public:
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!me->IsInCombat())
|
||||
scheduler.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
@@ -159,6 +273,9 @@ public:
|
||||
}
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectGuid _rpBuddyGUID;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -167,20 +284,65 @@ class boss_razuvious_minion : public CreatureScript
|
||||
public:
|
||||
boss_razuvious_minion() : CreatureScript("boss_razuvious_minion") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* pCreature) const override
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return GetNaxxramasAI<boss_razuvious_minionAI>(pCreature);
|
||||
return GetNaxxramasAI<boss_razuvious_minionAI>(creature);
|
||||
}
|
||||
|
||||
struct boss_razuvious_minionAI : public ScriptedAI
|
||||
{
|
||||
explicit boss_razuvious_minionAI(Creature* c) : ScriptedAI(c) { }
|
||||
|
||||
EventMap events;
|
||||
explicit boss_razuvious_minionAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
events.Reset();
|
||||
scheduler.CancelAll();
|
||||
ScheduleAttackDummy();
|
||||
}
|
||||
|
||||
void ScheduleAttackDummy()
|
||||
{
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_READY1H);
|
||||
if (Creature* targetDummy = me->FindNearestCreature(NPC_TARGET_DUMMY, 10.0f))
|
||||
{
|
||||
me->SetFacingToObject(targetDummy);
|
||||
}
|
||||
scheduler.Schedule(6s, 9s, GROUP_OOC_RP, [this](TaskContext context)
|
||||
{
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_ATTACK1H);
|
||||
context.Repeat(6s, 9s);
|
||||
});
|
||||
}
|
||||
|
||||
void DoAction(int32 action) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_FACE_ME:
|
||||
scheduler.CancelGroup(GROUP_OOC_RP);
|
||||
me->SetSheath(SHEATH_STATE_UNARMED);
|
||||
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
{
|
||||
if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
|
||||
{
|
||||
me->SetFacingToObject(creature);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_TALK:
|
||||
Talk(SAY_DEATH_KNIGHT_UNDERSTUDY);
|
||||
break;
|
||||
case ACTION_EMOTE:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
|
||||
break;
|
||||
case ACTION_SALUTE:
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_SALUTE);
|
||||
break;
|
||||
case ACTION_BACK_TO_TRAINING:
|
||||
me->SetSheath(SHEATH_STATE_MELEE);
|
||||
ScheduleAttackDummy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* who) override
|
||||
@@ -193,18 +355,23 @@ public:
|
||||
|
||||
void JustEngagedWith(Unit* who) override
|
||||
{
|
||||
if (Creature* cr = me->FindNearestCreature(NPC_RAZUVIOUS, 100.0f))
|
||||
scheduler.CancelGroup(GROUP_OOC_RP);
|
||||
if (InstanceScript* instance = me->GetInstanceScript())
|
||||
{
|
||||
cr->SetInCombatWithZone();
|
||||
cr->AI()->AttackStart(who);
|
||||
if (Creature* creature = instance->GetCreature(DATA_RAZUVIOUS))
|
||||
{
|
||||
creature->SetInCombatWithZone();
|
||||
creature->AI()->AttackStart(who);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
scheduler.Update(diff);
|
||||
|
||||
if (UpdateVictim())
|
||||
{
|
||||
events.Update(diff);
|
||||
if (!me->HasUnitState(UNIT_STATE_CASTING) || !me->IsCharmed())
|
||||
{
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
@@ -52,6 +52,17 @@ inline uint8 GetEruptionSection(float x, float y)
|
||||
return 3;
|
||||
}
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_RAZUVIOUS, DATA_RAZUVIOUS },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
ObjectData const gameObjectData[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
class instance_naxxramas : public InstanceMapScript
|
||||
{
|
||||
public:
|
||||
@@ -68,6 +79,7 @@ public:
|
||||
{
|
||||
SetHeaders(DataHeader);
|
||||
SetBossNumber(MAX_ENCOUNTERS);
|
||||
LoadObjectData(creatureData, gameObjectData);
|
||||
for (auto& i : HeiganEruption)
|
||||
i.clear();
|
||||
|
||||
@@ -253,6 +265,8 @@ public:
|
||||
_lichkingGUID = creature->GetGUID();
|
||||
return;
|
||||
}
|
||||
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo) override
|
||||
@@ -498,6 +512,8 @@ public:
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
InstanceScript::OnGameObjectCreate(pGo);
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* pGo) override
|
||||
|
||||
@@ -58,26 +58,27 @@ enum NXData
|
||||
DATA_STALAGG_BOSS = 108,
|
||||
DATA_FEUGEN_BOSS = 109,
|
||||
DATA_THADDIUS_GATE = 110,
|
||||
DATA_GOTHIK_BOSS = 111,
|
||||
DATA_GOTHIK_ENTER_GATE = 112,
|
||||
DATA_GOTHIK_INNER_GATE = 113,
|
||||
DATA_GOTHIK_EXIT_GATE = 114,
|
||||
DATA_HORSEMEN_GATE = 115,
|
||||
DATA_LICH_KING_BOSS = 116,
|
||||
DATA_KELTHUZAD_FLOOR = 117,
|
||||
DATA_ABOMINATION_KILLED = 118,
|
||||
DATA_FRENZY_REMOVED = 119,
|
||||
DATA_CHARGES_CROSSED = 120,
|
||||
DATA_SPORE_KILLED = 121,
|
||||
DATA_HUNDRED_CLUB = 122,
|
||||
DATA_DANCE_FAIL = 123,
|
||||
DATA_IMMORTAL_FAIL = 124,
|
||||
DATA_KELTHUZAD_GATE = 125,
|
||||
DATA_HAD_THADDIUS_GREET = 126,
|
||||
DATA_KELTHUZAD_PORTAL_1 = 127,
|
||||
DATA_KELTHUZAD_PORTAL_2 = 128,
|
||||
DATA_KELTHUZAD_PORTAL_3 = 129,
|
||||
DATA_KELTHUZAD_PORTAL_4 = 130
|
||||
DATA_RAZUVIOUS = 111,
|
||||
DATA_GOTHIK_BOSS = 112,
|
||||
DATA_GOTHIK_ENTER_GATE = 113,
|
||||
DATA_GOTHIK_INNER_GATE = 114,
|
||||
DATA_GOTHIK_EXIT_GATE = 115,
|
||||
DATA_HORSEMEN_GATE = 116,
|
||||
DATA_LICH_KING_BOSS = 117,
|
||||
DATA_KELTHUZAD_FLOOR = 118,
|
||||
DATA_ABOMINATION_KILLED = 119,
|
||||
DATA_FRENZY_REMOVED = 120,
|
||||
DATA_CHARGES_CROSSED = 121,
|
||||
DATA_SPORE_KILLED = 122,
|
||||
DATA_HUNDRED_CLUB = 123,
|
||||
DATA_DANCE_FAIL = 124,
|
||||
DATA_IMMORTAL_FAIL = 125,
|
||||
DATA_KELTHUZAD_GATE = 126,
|
||||
DATA_HAD_THADDIUS_GREET = 127,
|
||||
DATA_KELTHUZAD_PORTAL_1 = 128,
|
||||
DATA_KELTHUZAD_PORTAL_2 = 129,
|
||||
DATA_KELTHUZAD_PORTAL_3 = 130,
|
||||
DATA_KELTHUZAD_PORTAL_4 = 131
|
||||
};
|
||||
|
||||
enum NXGOs
|
||||
@@ -137,6 +138,9 @@ enum NXNPCs
|
||||
NPC_STALAGG = 15929,
|
||||
NPC_FEUGEN = 15930,
|
||||
|
||||
// Razuvious
|
||||
NPC_RAZUVIOUS = 16061,
|
||||
|
||||
// Four horseman
|
||||
NPC_BARON_RIVENDARE = 30549,
|
||||
NPC_SIR_ZELIEK = 16063,
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "TaskScheduler.h"
|
||||
#include "World.h"
|
||||
|
||||
// Ours
|
||||
@@ -506,108 +507,113 @@ enum MinigobData
|
||||
SPELL_IMPROVED_BLINK = 61995,
|
||||
|
||||
EVENT_SELECT_TARGET = 1,
|
||||
EVENT_BLINK = 2,
|
||||
EVENT_DESPAWN_VISUAL = 3,
|
||||
EVENT_DESPAWN = 4,
|
||||
EVENT_POLYMORPH = 2,
|
||||
EVENT_LAUGH = 3,
|
||||
EVENT_MOVE = 4,
|
||||
EVENT_DESPAWN_VISUAL = 5,
|
||||
EVENT_DESPAWN = 6,
|
||||
|
||||
MAIL_MINIGOB_ENTRY = 264,
|
||||
MAIL_DELIVER_DELAY_MIN = 5 * MINUTE,
|
||||
MAIL_DELIVER_DELAY_MAX = 15 * MINUTE
|
||||
};
|
||||
|
||||
class npc_minigob_manabonk : public CreatureScript
|
||||
struct npc_minigob_manabonk : public ScriptedAI
|
||||
{
|
||||
public:
|
||||
npc_minigob_manabonk() : CreatureScript("npc_minigob_manabonk") {}
|
||||
|
||||
struct npc_minigob_manabonkAI : public ScriptedAI
|
||||
npc_minigob_manabonk(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
npc_minigob_manabonkAI(Creature* creature) : ScriptedAI(creature)
|
||||
{
|
||||
me->setActive(true);
|
||||
}
|
||||
me->setActive(true);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetVisible(false);
|
||||
events.ScheduleEvent(EVENT_SELECT_TARGET, IN_MILLISECONDS);
|
||||
}
|
||||
void Reset() override
|
||||
{
|
||||
me->SetVisible(false);
|
||||
events.ScheduleEvent(EVENT_SELECT_TARGET, 1s);
|
||||
}
|
||||
|
||||
Player* SelectTargetInDalaran()
|
||||
{
|
||||
std::list<Player*> PlayerInDalaranList;
|
||||
PlayerInDalaranList.clear();
|
||||
Player* SelectTargetInDalaran()
|
||||
{
|
||||
std::list<Player*> playerInDalaranList;
|
||||
playerInDalaranList.clear();
|
||||
|
||||
Map::PlayerList const& players = me->GetMap()->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if (Player* player = itr->GetSource()->ToPlayer())
|
||||
if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
|
||||
PlayerInDalaranList.push_back(player);
|
||||
|
||||
if (PlayerInDalaranList.empty())
|
||||
return nullptr;
|
||||
return Acore::Containers::SelectRandomContainerElement(PlayerInDalaranList);
|
||||
}
|
||||
|
||||
void SendMailToPlayer(Player* player)
|
||||
{
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
|
||||
MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
me->GetMap()->DoForAllPlayers([&](Player* player)
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SELECT_TARGET:
|
||||
me->SetVisible(true);
|
||||
DoCast(me, SPELL_TELEPORT_VISUAL);
|
||||
if (Player* player = SelectTargetInDalaran())
|
||||
{
|
||||
me->NearTeleportTo(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), 0.0f);
|
||||
DoCast(player, SPELL_MANABONKED);
|
||||
SendMailToPlayer(player);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_BLINK, 3ms);
|
||||
break;
|
||||
case EVENT_BLINK:
|
||||
{
|
||||
DoCast(me, SPELL_IMPROVED_BLINK);
|
||||
Position pos = me->GetRandomNearPosition((urand(15, 40)));
|
||||
me->GetMotionMaster()->MovePoint(0, pos.m_positionX, pos.m_positionY, pos.m_positionZ);
|
||||
events.ScheduleEvent(EVENT_DESPAWN, 3ms);
|
||||
events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3ms);
|
||||
break;
|
||||
}
|
||||
case EVENT_DESPAWN_VISUAL:
|
||||
DoCast(me, SPELL_TELEPORT_VISUAL);
|
||||
break;
|
||||
case EVENT_DESPAWN:
|
||||
if (player->GetZoneId() == ZONE_DALARAN && !player->IsFlying() && !player->IsMounted() && !player->IsGameMaster())
|
||||
playerInDalaranList.push_back(player);
|
||||
});
|
||||
|
||||
if (playerInDalaranList.empty())
|
||||
return nullptr;
|
||||
return Acore::Containers::SelectRandomContainerElement(playerInDalaranList);
|
||||
}
|
||||
|
||||
void SendMailToPlayer(Player* player)
|
||||
{
|
||||
CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
|
||||
int16 deliverDelay = irand(MAIL_DELIVER_DELAY_MIN, MAIL_DELIVER_DELAY_MAX);
|
||||
MailDraft(MAIL_MINIGOB_ENTRY, true).SendMailTo(trans, MailReceiver(player), MailSender(MAIL_CREATURE, me->GetEntry()), MAIL_CHECK_MASK_NONE, deliverDelay);
|
||||
CharacterDatabase.CommitTransaction(trans);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
if (!sWorld->getBoolConfig(CONFIG_MINIGOB_MANABONK))
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while (uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_SELECT_TARGET:
|
||||
me->SetVisible(true);
|
||||
DoCastSelf(SPELL_TELEPORT_VISUAL);
|
||||
if (Player* player = SelectTargetInDalaran())
|
||||
{
|
||||
playerGUID = player->GetGUID();
|
||||
Position pos = player->GetPosition();
|
||||
me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation());
|
||||
me->GetMotionMaster()->MoveRandom(10);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_POLYMORPH, 30s);
|
||||
break;
|
||||
case EVENT_POLYMORPH:
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, playerGUID))
|
||||
{
|
||||
DoCast(player, SPELL_MANABONKED);
|
||||
SendMailToPlayer(player);
|
||||
}
|
||||
else
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_LAUGH, 2s);
|
||||
break;
|
||||
case EVENT_LAUGH:
|
||||
me->GetMotionMaster()->MoveIdle();
|
||||
me->HandleEmoteCommand(EMOTE_ONESHOT_LAUGH_NO_SHEATHE);
|
||||
events.ScheduleEvent(EVENT_MOVE, 4s);
|
||||
break;
|
||||
case EVENT_MOVE:
|
||||
{
|
||||
Position pos = me->GetRandomNearPosition((urand(15, 40)));
|
||||
me->GetMotionMaster()->MovePoint(0, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), true);
|
||||
}
|
||||
events.ScheduleEvent(EVENT_DESPAWN_VISUAL, 3s);
|
||||
events.ScheduleEvent(EVENT_DESPAWN, 4s);
|
||||
break;
|
||||
case EVENT_DESPAWN_VISUAL:
|
||||
DoCastSelf(SPELL_IMPROVED_BLINK);
|
||||
break;
|
||||
case EVENT_DESPAWN:
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap events;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
{
|
||||
return new npc_minigob_manabonkAI(creature);
|
||||
}
|
||||
private:
|
||||
ObjectGuid playerGUID;
|
||||
};
|
||||
|
||||
class npc_dalaran_mage : public CreatureScript
|
||||
@@ -861,8 +867,6 @@ void AddSC_dalaran()
|
||||
new npc_dalaran_mage();
|
||||
new npc_dalaran_warrior();
|
||||
RegisterCreatureAI(npc_cosmetic_toy_plane);
|
||||
|
||||
// theirs
|
||||
new npc_mageguard_dalaran();
|
||||
new npc_minigob_manabonk();
|
||||
RegisterCreatureAI(npc_minigob_manabonk);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user