Merge branch 'master' into Playerbot-updated
This commit is contained in:
@@ -99,7 +99,8 @@ public:
|
||||
{ "objectcount", HandleDebugObjectCountCommand, SEC_ADMINISTRATOR, Console::Yes},
|
||||
{ "dummy", HandleDebugDummyCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "mapdata", HandleDebugMapDataCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "boundary", HandleDebugBoundaryCommand, SEC_ADMINISTRATOR, Console::No }
|
||||
{ "boundary", HandleDebugBoundaryCommand, SEC_ADMINISTRATOR, Console::No },
|
||||
{ "visibilitydata", HandleDebugVisibilityDataCommand, SEC_ADMINISTRATOR, Console::No }
|
||||
};
|
||||
static ChatCommandTable commandTable =
|
||||
{
|
||||
@@ -1403,6 +1404,36 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HandleDebugVisibilityDataCommand(ChatHandler* handler)
|
||||
{
|
||||
Player* player = handler->GetPlayer();
|
||||
if (!player)
|
||||
return false;
|
||||
|
||||
std::array<uint32, NUM_CLIENT_OBJECT_TYPES> objectByTypeCount = {};
|
||||
|
||||
ObjectVisibilityContainer const& objectVisibilityContainer = player->GetObjectVisibilityContainer();
|
||||
for (auto const& kvPair : *objectVisibilityContainer.GetVisibleWorldObjectsMap())
|
||||
{
|
||||
WorldObject const* obj = kvPair.second;
|
||||
++objectByTypeCount[obj->GetTypeId()];
|
||||
}
|
||||
|
||||
uint32 zoneWideVisibleObjectsInZone = 0;
|
||||
if (ZoneWideVisibleWorldObjectsSet const* farVisibleSet = player->GetMap()->GetZoneWideVisibleWorldObjectsForZone(player->GetZoneId()))
|
||||
zoneWideVisibleObjectsInZone = farVisibleSet->size();
|
||||
|
||||
handler->PSendSysMessage("Visibility Range: {}", player->GetVisibilityRange());
|
||||
handler->PSendSysMessage("Visible Creatures: {}", objectByTypeCount[TYPEID_UNIT]);
|
||||
handler->PSendSysMessage("Visible Players: {}", objectByTypeCount[TYPEID_PLAYER]);
|
||||
handler->PSendSysMessage("Visible GameObjects: {}", objectByTypeCount[TYPEID_GAMEOBJECT]);
|
||||
handler->PSendSysMessage("Visible DynamicObjects: {}", objectByTypeCount[TYPEID_DYNAMICOBJECT]);
|
||||
handler->PSendSysMessage("Visible Corpses: {}", objectByTypeCount[TYPEID_CORPSE]);
|
||||
handler->PSendSysMessage("Players we are visible to: {}", objectVisibilityContainer.GetVisiblePlayersMap().size());
|
||||
handler->PSendSysMessage("Zone wide visible objects in zone: {}", zoneWideVisibleObjectsInZone);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_debug_commandscript()
|
||||
|
||||
@@ -71,8 +71,6 @@ public:
|
||||
if (counter == 0)
|
||||
handler->SendSysMessage(LANG_NOEVENTFOUND);
|
||||
|
||||
handler->SetSentErrorMessage(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "GameTime.h"
|
||||
#include "GitRevision.h"
|
||||
#include "Log.h"
|
||||
#include "MapMgr.h"
|
||||
#include "ModuleMgr.h"
|
||||
#include "MotdMgr.h"
|
||||
#include "MySQLThreading.h"
|
||||
@@ -101,7 +102,10 @@ public:
|
||||
// Triggering corpses expire check in world
|
||||
static bool HandleServerCorpsesCommand(ChatHandler* /*handler*/)
|
||||
{
|
||||
sWorld->RemoveOldCorpses();
|
||||
sMapMgr->DoForAllMaps([](Map* map)
|
||||
{
|
||||
map->RemoveOldCorpses();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1001,20 +1001,25 @@ class spell_chapter2_persuasive_strike : public SpellScript
|
||||
creature->AI()->Talk(SAY_PERSUADED3, 24s);
|
||||
creature->AI()->Talk(SAY_PERSUADED4, 32s);
|
||||
|
||||
creature->m_Events.AddEventAtOffset([creature, player]
|
||||
ObjectGuid playerGuid = player->GetGUID();
|
||||
|
||||
creature->m_Events.AddEventAtOffset([creature, playerGuid]
|
||||
{
|
||||
if (player)
|
||||
sCreatureTextMgr->SendChat(creature, SAY_PERSUADED5, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, player);
|
||||
if (Player* caster = ObjectAccessor::GetPlayer(*creature, playerGuid))
|
||||
sCreatureTextMgr->SendChat(creature, SAY_PERSUADED5, nullptr, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, caster);
|
||||
}, 40s);
|
||||
|
||||
creature->m_Events.AddEventAtOffset([creature, player]
|
||||
creature->m_Events.AddEventAtOffset([creature, playerGuid]
|
||||
{
|
||||
creature->AI()->Talk(SAY_PERSUADED6);
|
||||
if (player)
|
||||
|
||||
if (Player* caster = ObjectAccessor::GetPlayer(*creature, playerGuid))
|
||||
{
|
||||
Unit::Kill(player, creature);
|
||||
player->GroupEventHappens(QUEST_HOW_TO_WIN_FRIENDS, creature);
|
||||
Unit::Kill(caster, creature);
|
||||
caster->GroupEventHappens(QUEST_HOW_TO_WIN_FRIENDS, creature);
|
||||
}
|
||||
else
|
||||
creature->KillSelf();
|
||||
}, 48s);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -26,14 +26,17 @@
|
||||
|
||||
enum ANData
|
||||
{
|
||||
DATA_KRIKTHIR_THE_GATEWATCHER_EVENT = 0,
|
||||
DATA_HADRONOX_EVENT = 1,
|
||||
DATA_KRIKTHIR = 0,
|
||||
DATA_HADRONOX = 1,
|
||||
DATA_ANUBARAK_EVENT = 2,
|
||||
MAX_ENCOUNTERS = 3
|
||||
};
|
||||
|
||||
enum ANIds
|
||||
{
|
||||
NPC_WATCHER_NARJIL = 28729,
|
||||
NPC_WATCHER_GASHRA = 28730,
|
||||
NPC_WATCHER_SILTHIK = 28731,
|
||||
NPC_SKITTERING_SWARMER = 28735,
|
||||
NPC_SKITTERING_INFECTIOR = 28736,
|
||||
NPC_KRIKTHIR_THE_GATEWATCHER = 28684,
|
||||
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
struct boss_hadronoxAI : public BossAI
|
||||
{
|
||||
boss_hadronoxAI(Creature* creature) : BossAI(creature, DATA_HADRONOX_EVENT)
|
||||
boss_hadronoxAI(Creature* creature) : BossAI(creature, DATA_HADRONOX)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
{
|
||||
if (param == ACTION_START_EVENT)
|
||||
{
|
||||
instance->SetBossState(DATA_HADRONOX_EVENT, IN_PROGRESS);
|
||||
instance->SetBossState(DATA_HADRONOX, IN_PROGRESS);
|
||||
me->setActive(true);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE1, 20s);
|
||||
events.ScheduleEvent(EVENT_HADRONOX_MOVE2, 40s);
|
||||
@@ -342,7 +342,7 @@ public:
|
||||
PreventDefaultAction();
|
||||
Unit* owner = GetUnitOwner();
|
||||
if (InstanceScript* instance = owner->GetInstanceScript())
|
||||
if (instance->GetBossState(DATA_HADRONOX_EVENT) != DONE)
|
||||
if (!instance->IsBossDone(DATA_HADRONOX))
|
||||
{
|
||||
if (!owner->HasAura(SPELL_WEB_FRONT_DOORS))
|
||||
owner->CastSpell(owner, _spellEntry, true);
|
||||
|
||||
+79
-96
@@ -29,24 +29,8 @@ enum Spells
|
||||
SPELL_FRENZY = 28747
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_KRIK_START_WAVE = 1,
|
||||
EVENT_KRIK_SUMMON = 2,
|
||||
EVENT_KRIK_MIND_FLAY = 3,
|
||||
EVENT_KRIK_CURSE = 4,
|
||||
EVENT_KRIK_HEALTH_CHECK = 5,
|
||||
EVENT_KRIK_ENTER_COMBAT = 6,
|
||||
EVENT_KILL_TALK = 7,
|
||||
EVENT_CALL_ADDS = 8,
|
||||
EVENT_KRIK_CHECK_EVADE = 9
|
||||
};
|
||||
|
||||
enum Npcs
|
||||
{
|
||||
NPC_WATCHER_NARJIL = 28729,
|
||||
NPC_WATCHER_GASHRA = 28730,
|
||||
NPC_WATCHER_SILTHIK = 28731,
|
||||
NPC_WARRIOR = 28732,
|
||||
NPC_SKIRMISHER = 28734,
|
||||
NPC_SHADOWCASTER = 28733
|
||||
@@ -62,6 +46,12 @@ enum Yells
|
||||
SAY_SEND_GROUP = 5
|
||||
};
|
||||
|
||||
enum MiscActions
|
||||
{
|
||||
ACTION_MINION_ENGAGED = 1,
|
||||
GROUP_SWARM = 1
|
||||
};
|
||||
|
||||
class boss_krik_thir : public CreatureScript
|
||||
{
|
||||
public:
|
||||
@@ -69,18 +59,21 @@ public:
|
||||
|
||||
struct boss_krik_thirAI : public BossAI
|
||||
{
|
||||
boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR_THE_GATEWATCHER_EVENT)
|
||||
boss_krik_thirAI(Creature* creature) : BossAI(creature, DATA_KRIKTHIR)
|
||||
{
|
||||
_initTalk = false;
|
||||
}
|
||||
_canTalk = true;
|
||||
_minionInCombat = false;
|
||||
|
||||
EventMap events2;
|
||||
bool _initTalk;
|
||||
scheduler.SetValidator([this]
|
||||
{
|
||||
return !me->HasUnitState(UNIT_STATE_CASTING);
|
||||
});
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
BossAI::Reset();
|
||||
events2.Reset();
|
||||
|
||||
me->SummonCreature(NPC_WATCHER_NARJIL, 511.8f, 666.493f, 776.278f, 0.977f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SHADOWCASTER, 511.63f, 672.44f, 775.71f, 0.90f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
@@ -91,6 +84,22 @@ public:
|
||||
me->SummonCreature(NPC_WATCHER_SILTHIK, 543.826f, 665.123f, 776.245f, 1.55f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SKIRMISHER, 547.5f, 669.96f, 776.1f, 2.3f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
me->SummonCreature(NPC_SHADOWCASTER, 548.64f, 664.27f, 776.74f, 1.77f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
|
||||
ScheduleHealthCheckEvent(25, [&] {
|
||||
DoCastSelf(SPELL_FRENZY, true);
|
||||
|
||||
scheduler.CancelGroup(GROUP_SWARM);
|
||||
|
||||
scheduler.Schedule(7s, 17s, GROUP_SWARM, [&](TaskContext context)
|
||||
{
|
||||
Talk(SAY_SWARM);
|
||||
DoCastAOE(SPELL_SWARM);
|
||||
context.Repeat(20s);
|
||||
});
|
||||
});
|
||||
|
||||
_canTalk = true;
|
||||
_minionInCombat = false;
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) override
|
||||
@@ -103,21 +112,25 @@ public:
|
||||
_initTalk = true;
|
||||
Talk(SAY_PREFIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
if (events.Empty() && who->GetPositionZ() < 785.0f)
|
||||
void DoAction(int32 actionId) override
|
||||
{
|
||||
if (actionId == ACTION_MINION_ENGAGED && !_minionInCombat)
|
||||
{
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 10s);
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 40s);
|
||||
events2.ScheduleEvent(EVENT_KRIK_START_WAVE, 70s);
|
||||
events2.ScheduleEvent(EVENT_KRIK_ENTER_COMBAT, 100s);
|
||||
events2.ScheduleEvent(EVENT_KRIK_CHECK_EVADE, 5s);
|
||||
_minionInCombat = true;
|
||||
|
||||
events.ScheduleEvent(EVENT_KRIK_HEALTH_CHECK, 1s);
|
||||
events.ScheduleEvent(EVENT_KRIK_MIND_FLAY, 13s);
|
||||
events.ScheduleEvent(EVENT_KRIK_SUMMON, 17s);
|
||||
events.ScheduleEvent(EVENT_KRIK_CURSE, 8s);
|
||||
events.ScheduleEvent(EVENT_CALL_ADDS, 1s);
|
||||
me->setActive(true);
|
||||
for (Seconds const& timer : { 10s, 40s, 70s })
|
||||
{
|
||||
me->m_Events.AddEventAtOffset([this] {
|
||||
me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true);
|
||||
Talk(SAY_SEND_GROUP);
|
||||
}, timer);
|
||||
}
|
||||
|
||||
me->m_Events.AddEventAtOffset([this] {
|
||||
me->SetInCombatWithZone();
|
||||
}, 100s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +145,28 @@ public:
|
||||
{
|
||||
BossAI::JustEngagedWith(who);
|
||||
Talk(SAY_AGGRO);
|
||||
events2.Reset();
|
||||
|
||||
me->m_Events.KillAllEvents(false);
|
||||
|
||||
scheduler.Schedule(8s, 14s, [&](TaskContext context)
|
||||
{
|
||||
DoCastVictim(SPELL_MIND_FLAY);
|
||||
if (!IsInFrenzy())
|
||||
context.Repeat(8s, 14s);
|
||||
else
|
||||
context.Repeat(5s, 9s);
|
||||
}).Schedule(10s, 13s, GROUP_SWARM, [&](TaskContext context)
|
||||
{
|
||||
Talk(SAY_SWARM);
|
||||
DoCastAOE(SPELL_SWARM);
|
||||
context.Repeat(26s, 30s);
|
||||
});
|
||||
|
||||
ScheduleTimedEvent(27s, 35s, [&] {
|
||||
DoCastRandomTarget(SPELL_CURSE_OF_FATIGUE);
|
||||
}, 27s, 35s);
|
||||
|
||||
summons.DoZoneInCombat();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer) override
|
||||
@@ -141,12 +175,15 @@ public:
|
||||
Talk(SAY_DEATH);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* ) override
|
||||
void KilledUnit(Unit* /*victim*/) override
|
||||
{
|
||||
if (events.GetNextEventTime(EVENT_KILL_TALK) == 0)
|
||||
if (_canTalk)
|
||||
{
|
||||
_canTalk = false;
|
||||
Talk(SAY_SLAY);
|
||||
events.ScheduleEvent(EVENT_KILL_TALK, 6s);
|
||||
me->m_Events.AddEventAtOffset([&] {
|
||||
_canTalk = true;
|
||||
}, 6s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,66 +198,12 @@ public:
|
||||
summons.Despawn(summon);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
events2.Update(diff);
|
||||
switch (events2.ExecuteEvent())
|
||||
{
|
||||
case EVENT_KRIK_START_WAVE:
|
||||
me->CastCustomSpell(SPELL_SUBBOSS_AGGRO_TRIGGER, SPELLVALUE_MAX_TARGETS, 1, me, true);
|
||||
Talk(SAY_SEND_GROUP);
|
||||
break;
|
||||
case EVENT_KRIK_ENTER_COMBAT:
|
||||
me->SetInCombatWithZone();
|
||||
break;
|
||||
case EVENT_KRIK_CHECK_EVADE:
|
||||
if (!SelectTargetFromPlayerList(100.0f))
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
events2.ScheduleEvent(EVENT_KRIK_CHECK_EVADE, 5s);
|
||||
break;
|
||||
}
|
||||
private:
|
||||
bool _initTalk;
|
||||
bool _canTalk;
|
||||
bool _minionInCombat;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
if (me->HasUnitState(UNIT_STATE_CASTING))
|
||||
return;
|
||||
|
||||
switch (events.ExecuteEvent())
|
||||
{
|
||||
case EVENT_KRIK_HEALTH_CHECK:
|
||||
if (HealthBelowPct(10))
|
||||
{
|
||||
me->CastSpell(me, SPELL_FRENZY, true);
|
||||
break;
|
||||
}
|
||||
events.ScheduleEvent(EVENT_KRIK_HEALTH_CHECK, 1s);
|
||||
break;
|
||||
case EVENT_KRIK_SUMMON:
|
||||
Talk(SAY_SWARM);
|
||||
me->CastSpell(me, SPELL_SWARM, false);
|
||||
events.ScheduleEvent(EVENT_KRIK_SUMMON, 20s);
|
||||
break;
|
||||
case EVENT_KRIK_MIND_FLAY:
|
||||
me->CastSpell(me->GetVictim(), SPELL_MIND_FLAY, false);
|
||||
events.ScheduleEvent(EVENT_KRIK_MIND_FLAY, 15s);
|
||||
break;
|
||||
case EVENT_KRIK_CURSE:
|
||||
if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 100, true))
|
||||
me->CastSpell(target, SPELL_CURSE_OF_FATIGUE, true);
|
||||
events.ScheduleEvent(EVENT_KRIK_CURSE, 10s);
|
||||
break;
|
||||
case EVENT_CALL_ADDS:
|
||||
summons.DoZoneInCombat();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
[[nodiscard]] bool IsInFrenzy() const { return me->HasAura(SPELL_FRENZY); }
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
DoorData const doorData[] =
|
||||
{
|
||||
{ GO_KRIKTHIR_DOORS, DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, DOOR_TYPE_PASSAGE },
|
||||
{ GO_KRIKTHIR_DOORS, DATA_KRIKTHIR, DOOR_TYPE_PASSAGE },
|
||||
{ GO_ANUBARAK_DOORS1, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM },
|
||||
{ GO_ANUBARAK_DOORS2, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM },
|
||||
{ GO_ANUBARAK_DOORS3, DATA_ANUBARAK_EVENT, DOOR_TYPE_ROOM },
|
||||
@@ -34,15 +34,25 @@ DoorData const doorData[] =
|
||||
|
||||
ObjectData const creatureData[] =
|
||||
{
|
||||
{ NPC_KRIKTHIR_THE_GATEWATCHER, DATA_KRIKTHIR_THE_GATEWATCHER_EVENT },
|
||||
{ NPC_HADRONOX, DATA_HADRONOX_EVENT },
|
||||
{ 0, 0 }
|
||||
{ NPC_KRIKTHIR_THE_GATEWATCHER, DATA_KRIKTHIR },
|
||||
{ NPC_HADRONOX, DATA_HADRONOX },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
ObjectData const summonData[] =
|
||||
{
|
||||
{ NPC_SKITTERING_SWARMER, DATA_KRIKTHIR },
|
||||
{ NPC_SKITTERING_INFECTIOR, DATA_KRIKTHIR },
|
||||
{ NPC_ANUB_AR_CHAMPION, DATA_HADRONOX },
|
||||
{ NPC_ANUB_AR_NECROMANCER, DATA_HADRONOX },
|
||||
{ NPC_ANUB_AR_CRYPTFIEND, DATA_HADRONOX },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
BossBoundaryData const boundaries =
|
||||
{
|
||||
{ DATA_KRIKTHIR_THE_GATEWATCHER_EVENT, new RectangleBoundary(400.0f, 580.0f, 623.5f, 810.0f) },
|
||||
{ DATA_HADRONOX_EVENT, new ZRangeBoundary(666.0f, 776.0f) },
|
||||
{ DATA_KRIKTHIR, new RectangleBoundary(400.0f, 580.0f, 623.5f, 810.0f) },
|
||||
{ DATA_HADRONOX, new ZRangeBoundary(666.0f, 776.0f) },
|
||||
{ DATA_ANUBARAK_EVENT, new CircleBoundary(Position(550.6178f, 253.5917f), 26.0f) }
|
||||
};
|
||||
|
||||
@@ -60,52 +70,14 @@ public:
|
||||
LoadBossBoundaries(boundaries);
|
||||
LoadDoorData(doorData);
|
||||
LoadObjectData(creatureData, nullptr);
|
||||
LoadSummonData(summonData);
|
||||
};
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
void OnCreatureEvade(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_SKITTERING_SWARMER:
|
||||
case NPC_SKITTERING_INFECTIOR:
|
||||
if (Creature* krikthir = GetCreature((DATA_KRIKTHIR_THE_GATEWATCHER_EVENT)))
|
||||
krikthir->AI()->JustSummoned(creature);
|
||||
break;
|
||||
case NPC_ANUB_AR_CHAMPION:
|
||||
case NPC_ANUB_AR_NECROMANCER:
|
||||
case NPC_ANUB_AR_CRYPTFIEND:
|
||||
if (Creature* hadronox = GetCreature(DATA_HADRONOX_EVENT))
|
||||
hadronox->AI()->JustSummoned(creature);
|
||||
break;
|
||||
}
|
||||
|
||||
InstanceScript::OnCreatureCreate(creature);
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_KRIKTHIR_DOORS:
|
||||
case GO_ANUBARAK_DOORS1:
|
||||
case GO_ANUBARAK_DOORS2:
|
||||
case GO_ANUBARAK_DOORS3:
|
||||
AddDoor(go);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectRemove(GameObject* go) override
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_KRIKTHIR_DOORS:
|
||||
case GO_ANUBARAK_DOORS1:
|
||||
case GO_ANUBARAK_DOORS2:
|
||||
case GO_ANUBARAK_DOORS3:
|
||||
RemoveDoor(go);
|
||||
break;
|
||||
}
|
||||
if (creature->EntryEquals(NPC_WATCHER_NARJIL, NPC_WATCHER_GASHRA, NPC_WATCHER_SILTHIK))
|
||||
if (Creature* krikthir = GetCreature(DATA_KRIKTHIR))
|
||||
krikthir->AI()->EnterEvadeMode();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -75,8 +75,6 @@ enum DrakeGiverTexts
|
||||
class npc_oculus_drakegiver : public CreatureScript
|
||||
{
|
||||
public:
|
||||
std::unordered_map<ObjectGuid, bool>openedMenu;
|
||||
|
||||
npc_oculus_drakegiver() : CreatureScript("npc_oculus_drakegiver") { }
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
@@ -193,20 +191,8 @@ public:
|
||||
SendGossipMenuFor(player, GOSSIP_TEXTID_VERDISA1, creature->GetGUID());
|
||||
break;
|
||||
case NPC_BELGARISTRASZ:
|
||||
if (HAS_ESSENCE(player))
|
||||
{
|
||||
openedMenu[player->GetGUID()] = true;
|
||||
}
|
||||
|
||||
if (!openedMenu[player->GetGUID()])
|
||||
{
|
||||
AddGossipItemFor(player, 9708, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
SendGossipMenuFor(player, GOSSIP_TEXTID_DRAKES, creature->GetGUID());
|
||||
}
|
||||
else
|
||||
{
|
||||
OnGossipSelect(player, creature, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
}
|
||||
AddGossipItemFor(player, 9708, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
SendGossipMenuFor(player, GOSSIP_TEXTID_DRAKES, creature->GetGUID());
|
||||
break;
|
||||
case NPC_ETERNOS:
|
||||
AddGossipItemFor(player, 9574, 0, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||
@@ -277,7 +263,6 @@ public:
|
||||
switch (uiAction)
|
||||
{
|
||||
case GOSSIP_ACTION_INFO_DEF:
|
||||
openedMenu[player->GetGUID()] = true;
|
||||
if (player->HasItemCount(ITEM_AMBER_ESSENCE))
|
||||
{
|
||||
AddGossipItemFor(player, 9575, 1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
|
||||
|
||||
@@ -2124,6 +2124,25 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// 45612 - Necropolis Beam
|
||||
class spell_necropolis_beam: public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_necropolis_beam);
|
||||
|
||||
void SetDest(SpellDestination& dest)
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
float floorZ = caster->GetMapHeight(caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ());
|
||||
if (floorZ > INVALID_HEIGHT)
|
||||
dest._position.m_positionZ = floorZ;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_necropolis_beam::SetDest, EFFECT_0, TARGET_DEST_CASTER);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_borean_tundra()
|
||||
{
|
||||
RegisterSpellScript(spell_q11919_q11940_drake_hunt_aura);
|
||||
@@ -2148,4 +2167,5 @@ void AddSC_borean_tundra()
|
||||
RegisterSpellScript(spell_q11719_bloodspore_ruination_45997);
|
||||
new npc_bloodmage_laurith();
|
||||
RegisterCreatureAI(npc_jenny);
|
||||
RegisterSpellScript(spell_necropolis_beam);
|
||||
}
|
||||
|
||||
@@ -2240,6 +2240,27 @@ class spell_dragonblight_corrosive_spit : public AuraScript
|
||||
}
|
||||
};
|
||||
|
||||
// 48297 - Hand Over Reins
|
||||
enum HandOverReins
|
||||
{
|
||||
SPELL_ONSLAUGHT_RIDING_CROP = 48290
|
||||
};
|
||||
|
||||
class spell_handover_reins : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_handover_reins);
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
GetCaster()->RemoveAura(SPELL_ONSLAUGHT_RIDING_CROP);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_handover_reins::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_dragonblight()
|
||||
{
|
||||
new npc_conversing_with_the_depths_trigger();
|
||||
@@ -2267,4 +2288,5 @@ void AddSC_dragonblight()
|
||||
RegisterSpellScript(spell_q12096_q12092_bark);
|
||||
new npc_torturer_lecraft();
|
||||
RegisterSpellScript(spell_dragonblight_corrosive_spit);
|
||||
RegisterSpellScript(spell_handover_reins);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "ScriptedGossip.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
|
||||
class npc_attracted_reef_bull : public CreatureScript
|
||||
{
|
||||
@@ -393,6 +394,36 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum HawkHunting
|
||||
{
|
||||
SPELL_HAWK_HUNTING_ITEM = 44408
|
||||
};
|
||||
|
||||
// 44407 - Spell hawk Hunting
|
||||
class spell_hawk_hunting : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_hawk_hunting);
|
||||
|
||||
bool Validate(SpellInfo const* /*spellInfo*/) override
|
||||
{
|
||||
return ValidateSpellInfo({ SPELL_HAWK_HUNTING_ITEM });
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
if (!GetCaster())
|
||||
return;
|
||||
|
||||
GetCaster()->CastSpell(GetCaster(), SPELL_HAWK_HUNTING_ITEM, true);
|
||||
GetHitUnit()->ToCreature()->DespawnOrUnsummon();
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_hawk_hunting::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_howling_fjord()
|
||||
{
|
||||
new npc_attracted_reef_bull();
|
||||
@@ -400,4 +431,5 @@ void AddSC_howling_fjord()
|
||||
new npc_apothecary_hanes();
|
||||
new npc_plaguehound_tracker();
|
||||
new npc_razael_and_lyana();
|
||||
RegisterSpellScript(spell_hawk_hunting);
|
||||
}
|
||||
|
||||
@@ -1167,6 +1167,31 @@ public:
|
||||
return new npc_vehicle_d16_propelled_deliveryAI(creature);
|
||||
}
|
||||
};
|
||||
|
||||
enum StormcrestEagle
|
||||
{
|
||||
NPC_STORMCREST_EAGLE = 29854
|
||||
};
|
||||
|
||||
// 56393 - Feed Stormcrest Eagle
|
||||
class spell_feed_stormcrest_eagle : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_feed_stormcrest_eagle);
|
||||
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
if (GetCaster()->FindNearestCreature(NPC_STORMCREST_EAGLE, 15.0f, true))
|
||||
return SPELL_CAST_OK;
|
||||
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_feed_stormcrest_eagle::CheckCast);
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_storm_peaks()
|
||||
{
|
||||
new npc_frosthound();
|
||||
@@ -1183,4 +1208,5 @@ void AddSC_storm_peaks()
|
||||
RegisterSpellScript(spell_close_rift_aura);
|
||||
new npc_vehicle_d16_propelled_delivery();
|
||||
RegisterSpellScript(spell_q12823_remove_collapsing_cave_aura);
|
||||
RegisterSpellScript(spell_feed_stormcrest_eagle);
|
||||
}
|
||||
|
||||
@@ -1527,12 +1527,27 @@ class spell_q12805_lifeblood_dummy : public SpellScript
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
{
|
||||
Player* caster = GetCaster()->ToPlayer();
|
||||
if (Creature* target = GetHitCreature())
|
||||
Creature* target = GetHitCreature();
|
||||
|
||||
if (!target)
|
||||
return;
|
||||
|
||||
if (Group* group = caster->GetGroup())
|
||||
{
|
||||
caster->KilledMonsterCredit(NPC_SHARD_KILL_CREDIT);
|
||||
target->CastSpell(target, uint32(GetEffectValue()), true);
|
||||
target->DespawnOrUnsummon(2000);
|
||||
ObjectGuid targetGUID = target->GetGUID();
|
||||
group->DoForAllMembers([targetGUID](Player* player)
|
||||
{
|
||||
if (Creature* shard = ObjectAccessor::GetCreature(*player, targetGUID))
|
||||
if (player->IsAtGroupRewardDistance(shard))
|
||||
player->KilledMonsterCredit(NPC_SHARD_KILL_CREDIT);
|
||||
|
||||
});
|
||||
}
|
||||
else
|
||||
caster->KilledMonsterCredit(NPC_SHARD_KILL_CREDIT);
|
||||
|
||||
target->CastSpell(target, uint32(GetEffectValue()), true);
|
||||
target->DespawnOrUnsummon(2000);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
|
||||
@@ -92,6 +92,7 @@ struct npc_herald_of_the_lich_king : public ScriptedAI
|
||||
Talk(HERALD_OF_THE_LICH_KING_SAY_ATTACK_END);
|
||||
ChangeZoneEventStatus(false);
|
||||
UpdateWeather(false);
|
||||
me->DespawnOrUnsummon();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,7 +362,6 @@ struct npc_necrotic_shard : public ScriptedAI
|
||||
{
|
||||
scheduler.Schedule(5s, [this](TaskContext context) // Spawn Cultists every 60 minutes.
|
||||
{
|
||||
me->SetFullHealth();
|
||||
DespawnShadowsOfDoom(); // Despawn all remaining Shadows before respawning the Cultists?
|
||||
SummonCultists();
|
||||
context.Repeat(1h);
|
||||
@@ -519,7 +519,8 @@ struct npc_necrotic_shard : public ScriptedAI
|
||||
// Buff Players.
|
||||
DoCastSelf(SPELL_SOUL_REVIVAL, true);
|
||||
// Sending the Death Bolt.
|
||||
DoCastAOE(SPELL_COMMUNIQUE_CAMP_TO_RELAY_DEATH, true);
|
||||
if (Creature* relay = GetClosestCreatureWithEntry(me, NPC_NECROPOLIS_RELAY, 200.0f))
|
||||
me->CastSpell(relay, SPELL_COMMUNIQUE_CAMP_TO_RELAY_DEATH, true);
|
||||
DespawnCultists(); // Despawn remaining Cultists (should never happen).
|
||||
DespawnEventDoodads();
|
||||
sWorldState->Save(SAVE_ID_SCOURGE_INVASION);
|
||||
|
||||
Reference in New Issue
Block a user