fix(Scripts/Karazhan): Implement Nightbane summon emote and despawn on evade (#17690)

* fix(Scripts/Karazhan): Implement summon emote and despawn on evade

* missing flag
This commit is contained in:
Andrew
2023-11-13 01:39:14 -03:00
committed by GitHub
parent 975a6fccab
commit bbedb91e2c
2 changed files with 47 additions and 58 deletions
@@ -0,0 +1,2 @@
--
UPDATE `creature_template` SET `unit_flags` = `unit_flags`|256 WHERE `entry` = 17225;
@@ -15,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>. * with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* ScriptData
SDName: Boss_Nightbane
SD%Complete: 80
SDComment: SDComment: Timers may incorrect
SDCategory: Karazhan
EndScriptData */
#include "Player.h" #include "Player.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
@@ -46,7 +39,7 @@ enum Spells
enum Says enum Says
{ {
EMOTE_SUMMON = 0, // Not used in script EMOTE_SUMMON = 0,
YELL_AGGRO = 1, YELL_AGGRO = 1,
YELL_FLY_PHASE = 2, YELL_FLY_PHASE = 2,
YELL_LAND_PHASE = 3, YELL_LAND_PHASE = 3,
@@ -59,6 +52,11 @@ enum Groups
GROUP_FLYING = 1 GROUP_FLYING = 1
}; };
enum Points
{
POINT_DESPAWN = 10 // Other points used dynamically throughout the script
};
float IntroWay[8][3] = float IntroWay[8][3] =
{ {
{-11053.37f, -1794.48f, 149.00f}, {-11053.37f, -1794.48f, 149.00f},
@@ -77,61 +75,45 @@ struct boss_nightbane : public BossAI
{ {
_intro = true; _intro = true;
_skeletonCount = 5; _skeletonCount = 5;
scheduler.SetValidator([this] _movePhase = 0;
{
return !me->HasUnitState(UNIT_STATE_CASTING);
});
} }
void Reset() override void Reset() override
{ {
BossAI::Reset(); BossAI::Reset();
_skeletonscheduler.CancelAll(); _skeletonscheduler.CancelAll();
if (!_intro)
{
//when boss is reset and we're past the intro
//cannot despawn, but have to move to a location where he normally is
//me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0);
Position preSpawnPosis = me->GetHomePosition();
EnterEvadeMode();
me->NearTeleportTo(preSpawnPosis);
me->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
_intro = true;
Phase = 1;
MovePhase = 0;
}
me->SetSpeed(MOVE_RUN, 2.0f); me->SetSpeed(MOVE_RUN, 2.0f);
me->SetDisableGravity(_intro); me->SetDisableGravity(_intro);
me->SetWalk(false); me->SetWalk(false);
me->setActive(true); me->setActive(true);
if (instance)
{
if (instance->GetData(DATA_NIGHTBANE) == DONE)
me->DisappearAndDie();
else
instance->SetData(DATA_NIGHTBANE, NOT_STARTED);
}
HandleTerraceDoors(true); HandleTerraceDoors(true);
_flying = false; _flying = false;
_movement = false; _movement = false;
_intro = true;
Phase = 1;
_movePhase = 0;
ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{ ScheduleHealthCheckEvent({ 75, 50, 25 }, [&]{
TakeOff(); TakeOff();
}); });
} }
void HandleTerraceDoors(bool open) void EnterEvadeMode(EvadeReason why) override
{ {
if (instance) BossAI::EnterEvadeMode(why);
me->SetDisableGravity(true);
me->SendMovementFlagUpdate();
me->GetMotionMaster()->MoveTakeoff(POINT_DESPAWN, -11013.246f, -1770.5212f, 166.50139f);
}
void HandleTerraceDoors(bool open)
{ {
instance->HandleGameObject(instance->GetGuidData(DATA_MASTERS_TERRACE_DOOR_1), open); instance->HandleGameObject(instance->GetGuidData(DATA_MASTERS_TERRACE_DOOR_1), open);
instance->HandleGameObject(instance->GetGuidData(DATA_MASTERS_TERRACE_DOOR_2), open); instance->HandleGameObject(instance->GetGuidData(DATA_MASTERS_TERRACE_DOOR_2), open);
} }
}
void JustEngagedWith(Unit* who) override void JustEngagedWith(Unit* who) override
{ {
@@ -143,7 +125,8 @@ struct boss_nightbane : public BossAI
ScheduleGround(); ScheduleGround();
} }
void ScheduleGround() { void ScheduleGround()
{
scheduler.Schedule(30s, GROUP_GROUND, [this](TaskContext context) scheduler.Schedule(30s, GROUP_GROUND, [this](TaskContext context)
{ {
DoCastAOE(SPELL_BELLOWING_ROAR); DoCastAOE(SPELL_BELLOWING_ROAR);
@@ -173,7 +156,8 @@ struct boss_nightbane : public BossAI
}); });
} }
void ScheduleFly() { void ScheduleFly()
{
_skeletonSpawnCounter = 0; _skeletonSpawnCounter = 0;
scheduler.Schedule(2s, GROUP_FLYING, [this](TaskContext) scheduler.Schedule(2s, GROUP_FLYING, [this](TaskContext)
@@ -230,18 +214,21 @@ struct boss_nightbane : public BossAI
if (type != POINT_MOTION_TYPE) if (type != POINT_MOTION_TYPE)
return; return;
if (id == POINT_DESPAWN)
{
me->DespawnOnEvade();
}
if (_intro) if (_intro)
{ {
if (id >= 8) if (id >= 8)
{ {
//me->SetHomePosition(IntroWay[7][0], IntroWay[7][1], IntroWay[7][2], 0); me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
//doesn't need home position because we have to "despawn" boss on reset
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE);
me->SetInCombatWithZone(); me->SetInCombatWithZone();
return; return;
} }
MovePhase = id + 1; _movePhase = id + 1;
return; return;
} }
@@ -256,7 +243,7 @@ struct boss_nightbane : public BossAI
} }
if (id < 8) if (id < 8)
MovePhase = id + 1; _movePhase = id + 1;
else else
{ {
Phase = 1; Phase = 1;
@@ -325,9 +312,9 @@ struct boss_nightbane : public BossAI
{ {
if (_intro) if (_intro)
{ {
if (MovePhase) if (_movePhase)
{ {
if (MovePhase >= 7) if (_movePhase >= 7)
{ {
me->SetDisableGravity(false); me->SetDisableGravity(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
@@ -335,25 +322,26 @@ struct boss_nightbane : public BossAI
} }
else else
{ {
me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]); me->GetMotionMaster()->MovePoint(_movePhase, IntroWay[_movePhase][0], IntroWay[_movePhase][1], IntroWay[_movePhase][2]);
} }
MovePhase = 0; _movePhase = 0;
} }
return; return;
} }
if (_flying && MovePhase) if (_flying && _movePhase)
{ {
if (MovePhase >= 7) if (_movePhase >= 7)
{ {
me->SetDisableGravity(false); me->SetDisableGravity(false);
me->HandleEmoteCommand(EMOTE_ONESHOT_LAND); me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
me->RemoveUnitFlag(UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_IMMUNE_TO_PC);
me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]); me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
} }
else else
me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]); me->GetMotionMaster()->MovePoint(_movePhase, IntroWay[_movePhase][0], IntroWay[_movePhase][1], IntroWay[_movePhase][2]);
MovePhase = 0; _movePhase = 0;
} }
if (!UpdateVictim()) if (!UpdateVictim())
@@ -387,7 +375,7 @@ private:
bool _flying; bool _flying;
bool _movement; bool _movement;
uint32 MovePhase; uint32 _movePhase;
uint8 _skeletonCount; uint8 _skeletonCount;
uint8 _skeletonSpawnCounter; uint8 _skeletonSpawnCounter;
}; };
@@ -397,17 +385,16 @@ class go_blackened_urn : public GameObjectScript
public: public:
go_blackened_urn() : GameObjectScript("go_blackened_urn") { } go_blackened_urn() : GameObjectScript("go_blackened_urn") { }
//if we summon an entity instead of using a sort of invisible entity, we could unsummon boss on reset
//right now that doesn't work because of how the urn works
bool OnGossipHello(Player* /*player*/, GameObject* go) override bool OnGossipHello(Player* /*player*/, GameObject* go) override
{ {
if (InstanceScript* instance = go->GetInstanceScript()) if (InstanceScript* instance = go->GetInstanceScript())
{ {
if (instance->GetData(DATA_NIGHTBANE) != DONE && !go->FindNearestCreature(NPC_NIGHTBANE, 40.0f)) if (instance->GetData(DATA_NIGHTBANE) != DONE && !go->FindNearestCreature(NPC_NIGHTBANE, 40.0f))
{ {
if (Creature* cr = instance->GetCreature(DATA_NIGHTBANE)) if (Creature* nightbane = instance->GetCreature(DATA_NIGHTBANE))
{ {
cr->GetMotionMaster()->MovePoint(0, IntroWay[0][0], IntroWay[0][1], IntroWay[0][2]); nightbane->GetMotionMaster()->MovePoint(0, IntroWay[0][0], IntroWay[0][1], IntroWay[0][2]);
nightbane->AI()->Talk(EMOTE_SUMMON);
} }
} }
} }