fix(Scripts/BlackMorass): Adds should walk towards Medivh. (#14945)

This commit is contained in:
UltraNix
2023-02-12 12:27:25 +01:00
committed by GitHub
parent 726bd6a8c1
commit 48ce957597
7 changed files with 290 additions and 287 deletions
@@ -0,0 +1,2 @@
--
UPDATE `creature_template` SET `ScriptName`='npc_black_morass_summoned_add' WHERE `entry` IN (17835,21818,17892,18994,18995,21137,21136,21138,21139);
+2 -2
View File
@@ -248,14 +248,14 @@ void MotionMaster::MoveRandom(float wanderDistance)
} }
} }
void MotionMaster::MoveTargetedHome() void MotionMaster::MoveTargetedHome(bool walk /*= false*/)
{ {
Clear(false); Clear(false);
if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID()) if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID())
{ {
LOG_DEBUG("movement.motionmaster", "Creature ({}) targeted home", _owner->GetGUID().ToString()); LOG_DEBUG("movement.motionmaster", "Creature ({}) targeted home", _owner->GetGUID().ToString());
Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE); Mutate(new HomeMovementGenerator<Creature>(walk), MOTION_SLOT_ACTIVE);
} }
else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID()) else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID())
{ {
+1 -1
View File
@@ -197,7 +197,7 @@ public:
} }
void MoveIdle(); void MoveIdle();
void MoveTargetedHome(); void MoveTargetedHome(bool walk = false);
void MoveRandom(float wanderDistance = 0.0f); void MoveRandom(float wanderDistance = 0.0f);
void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE); void MoveFollow(Unit* target, float dist, float angle, MovementSlot slot = MOTION_SLOT_ACTIVE);
void MoveChase(Unit* target, std::optional<ChaseRange> dist = {}, std::optional<ChaseAngle> angle = {}); void MoveChase(Unit* target, std::optional<ChaseRange> dist = {}, std::optional<ChaseAngle> angle = {});
@@ -65,7 +65,7 @@ void HomeMovementGenerator<Creature>::_setTargetLocation(Creature* owner)
owner->UpdateAllowedPositionZ(x, y, z); owner->UpdateAllowedPositionZ(x, y, z);
init.MoveTo(x, y, z, DisableMgr::IsPathfindingEnabled(owner->FindMap()), true); init.MoveTo(x, y, z, DisableMgr::IsPathfindingEnabled(owner->FindMap()), true);
init.SetWalk(false); init.SetWalk(_walk);
init.Launch(); init.Launch();
arrived = false; arrived = false;
@@ -29,7 +29,7 @@ template <>
class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, HomeMovementGenerator<Creature> > class HomeMovementGenerator<Creature> : public MovementGeneratorMedium< Creature, HomeMovementGenerator<Creature> >
{ {
public: public:
HomeMovementGenerator() : arrived(false), i_recalculateTravel(false) {} HomeMovementGenerator(bool walk) : arrived(false), i_recalculateTravel(false), _walk(walk) {}
~HomeMovementGenerator() {} ~HomeMovementGenerator() {}
void DoInitialize(Creature*); void DoInitialize(Creature*);
@@ -43,5 +43,6 @@ private:
void _setTargetLocation(Creature*); void _setTargetLocation(Creature*);
bool arrived : 1; bool arrived : 1;
bool i_recalculateTravel : 1; bool i_recalculateTravel : 1;
bool _walk;
}; };
#endif #endif
@@ -17,6 +17,7 @@
#include "the_black_morass.h" #include "the_black_morass.h"
#include "MoveSplineInit.h" #include "MoveSplineInit.h"
#include "SmartAI.h"
#include "ScriptMgr.h" #include "ScriptMgr.h"
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "ScriptedGossip.h" #include "ScriptedGossip.h"
@@ -82,66 +83,60 @@ private:
Creature& _owner; Creature& _owner;
}; };
class npc_medivh_bm : public CreatureScript struct npc_medivh_bm : public ScriptedAI
{ {
public: npc_medivh_bm(Creature* creature) : ScriptedAI(creature)
npc_medivh_bm() : CreatureScript("npc_medivh_bm") { }
CreatureAI* GetAI(Creature* creature) const override
{ {
return GetTheBlackMorassAI<npc_medivh_bmAI>(creature); _instance = creature->GetInstanceScript();
}
struct npc_medivh_bmAI : public ScriptedAI _groundArray.clear();
{ _airArray.clear();
npc_medivh_bmAI(Creature* creature) : ScriptedAI(creature)
{
instance = creature->GetInstanceScript();
groundArray.clear(); _groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ()));
airArray.clear(); _airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ()));
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f, creature->GetPositionY(), creature->GetPositionZ()));
airArray.push_back(G3D::Vector3(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ()));
for (uint8 i = 0; i < 10; ++i) for (uint8 i = 0; i < 10; ++i)
groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 8.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ())); {
_groundArray.push_back(G3D::Vector3(creature->GetPositionX() + 8.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 8.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ()));
}
for (uint8 i = 0; i < 40; ++i) for (uint8 i = 0; i < 40; ++i)
airArray.push_back(G3D::Vector3(creature->GetPositionX() + i * 0.25f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + i * 0.25f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f)); {
for (uint8 i = 40; i < 80; ++i) _airArray.push_back(G3D::Vector3(creature->GetPositionX() + i * 0.25f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + i * 0.25f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f));
airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 10.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f));
} }
InstanceScript* instance; for (uint8 i = 40; i < 80; ++i)
EventMap events; {
Movement::PointsArray groundArray; _airArray.push_back(G3D::Vector3(creature->GetPositionX() + 10.0f * cos(2.0f * M_PI * i / 10.0f), creature->GetPositionY() + 10.0f * std::sin(2.0f * M_PI * i / 10.0f), creature->GetPositionZ() + i / 4.0f));
Movement::PointsArray airArray; }
}
void Reset() override void Reset() override
{ {
events.Reset(); events.Reset();
me->CastSpell(me, SPELL_MANA_SHIELD, true); me->CastSpell(me, SPELL_MANA_SHIELD, true);
if (instance && instance->GetData(TYPE_AEONUS) != DONE) if (_instance->GetData(TYPE_AEONUS) != DONE)
{
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
} }
}
void JustSummoned(Creature* summon) override void JustSummoned(Creature* summon) override
{ {
if (instance) _instance->SetGuidData(DATA_SUMMONED_NPC, summon->GetGUID());
instance->SetGuidData(DATA_SUMMONED_NPC, summon->GetGUID());
if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER) if (summon->GetEntry() == NPC_DP_CRYSTAL_STALKER)
{ {
summon->DespawnOrUnsummon(25000); summon->DespawnOrUnsummon(25000);
summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true); summon->CastSpell(summon, RAND(SPELL_BANISH_PURPLE, SPELL_BANISH_GREEN), true);
summon->GetMotionMaster()->MoveSplinePath(&airArray); summon->GetMotionMaster()->MoveSplinePath(&_airArray);
} }
else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER) else if (summon->GetEntry() == NPC_DP_EMITTER_STALKER)
{ {
summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true); summon->CastSpell(summon, SPELL_BLACK_CRYSTAL, true);
Movement::MoveSplineInit init(summon); Movement::MoveSplineInit init(summon);
init.MovebyPath(groundArray); init.MovebyPath(_groundArray);
init.SetCyclic(); init.SetCyclic();
init.Launch(); init.Launch();
} }
@@ -149,20 +144,20 @@ public:
void SummonedCreatureDespawn(Creature* summon) override void SummonedCreatureDespawn(Creature* summon) override
{ {
if (instance) _instance->SetGuidData(DATA_DELETED_NPC, summon->GetGUID());
instance->SetGuidData(DATA_DELETED_NPC, summon->GetGUID());
} }
void MoveInLineOfSight(Unit* who) override void MoveInLineOfSight(Unit* who) override
{ {
if (!events.Empty() || (instance && instance->GetData(TYPE_AEONUS) == DONE)) if (!events.Empty() || _instance->GetData(TYPE_AEONUS) == DONE)
{
return; return;
}
if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f)) if (who->GetTypeId() == TYPEID_PLAYER && me->IsWithinDistInMap(who, 20.0f))
{ {
Talk(SAY_ENTER); Talk(SAY_ENTER);
if (instance) _instance->SetData(DATA_MEDIVH, 1);
instance->SetData(DATA_MEDIVH, 1);
me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false); me->CastSpell(me, SPELL_MEDIVH_CHANNEL, false);
@@ -205,7 +200,7 @@ public:
case EVENT_CHECK_HEALTH_25: case EVENT_CHECK_HEALTH_25:
case EVENT_CHECK_HEALTH_50: case EVENT_CHECK_HEALTH_50:
case EVENT_CHECK_HEALTH_75: case EVENT_CHECK_HEALTH_75:
if (instance && instance->GetData(DATA_SHIELD_PERCENT) <= eventId * 25) if (_instance->GetData(DATA_SHIELD_PERCENT) <= eventId * 25)
{ {
Talk(eventId + 1); Talk(eventId + 1);
break; break;
@@ -270,7 +265,12 @@ public:
} }
} }
} }
};
private:
InstanceScript* _instance;
EventMap _events;
Movement::PointsArray _groundArray;
Movement::PointsArray _airArray;
}; };
enum timeRift enum timeRift
@@ -279,30 +279,16 @@ enum timeRift
EVENT_CHECK_DEATH = 2 EVENT_CHECK_DEATH = 2
}; };
class npc_time_rift : public CreatureScript struct npc_time_rift : public NullCreatureAI
{ {
public: npc_time_rift(Creature* creature) : NullCreatureAI(creature)
npc_time_rift() : CreatureScript("npc_time_rift") { }
CreatureAI* GetAI(Creature* creature) const override
{ {
return GetTheBlackMorassAI<npc_time_riftAI>(creature); _instance = creature->GetInstanceScript();
} }
struct npc_time_riftAI : public NullCreatureAI
{
npc_time_riftAI(Creature* creature) : NullCreatureAI(creature)
{
instance = creature->GetInstanceScript();
}
EventMap events;
InstanceScript* instance;
ObjectGuid riftKeeperGUID;
void Reset() override void Reset() override
{ {
if (instance && instance->GetData(DATA_RIFT_NUMBER) >= 18) if (_instance->GetData(DATA_RIFT_NUMBER) >= 18)
{ {
me->DespawnOrUnsummon(30000); me->DespawnOrUnsummon(30000);
return; return;
@@ -314,7 +300,7 @@ public:
void SetGUID(ObjectGuid guid, int32) override void SetGUID(ObjectGuid guid, int32) override
{ {
riftKeeperGUID = guid; _riftKeeperGUID = guid;
} }
void DoSummonAtRift(uint32 entry) void DoSummonAtRift(uint32 entry)
@@ -322,13 +308,13 @@ public:
Position pos = me->GetNearPosition(10.0f, 2 * M_PI * rand_norm()); Position pos = me->GetNearPosition(10.0f, 2 * M_PI * rand_norm());
if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 150000)) if (Creature* summon = me->SummonCreature(entry, pos, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 150000))
if (instance) if (_instance)
{ {
if (Unit* medivh = ObjectAccessor::GetUnit(*me, instance->GetGuidData(DATA_MEDIVH))) if (Unit* medivh = ObjectAccessor::GetUnit(*me, _instance->GetGuidData(DATA_MEDIVH)))
{ {
float o = medivh->GetAngle(summon) + frand(-1.0f, 1.0f); float o = medivh->GetAngle(summon) + frand(-1.0f, 1.0f);
summon->SetHomePosition(medivh->GetPositionX() + 14.0f * cos(o), medivh->GetPositionY() + 14.0f * std::sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh)); summon->SetHomePosition(medivh->GetPositionX() + 14.0f * cos(o), medivh->GetPositionY() + 14.0f * std::sin(o), medivh->GetPositionZ(), summon->GetAngle(medivh));
summon->GetMotionMaster()->MoveTargetedHome(); summon->GetMotionMaster()->MoveTargetedHome(true);
summon->SetReactState(REACT_DEFENSIVE); summon->SetReactState(REACT_DEFENSIVE);
} }
} }
@@ -344,8 +330,10 @@ public:
DoSummonAtRift(entry); DoSummonAtRift(entry);
} }
else else
{
DoSummonAtRift(entry); DoSummonAtRift(entry);
} }
}
void UpdateAI(uint32 diff) override void UpdateAI(uint32 diff) override
{ {
@@ -359,33 +347,47 @@ public:
case EVENT_CHECK_DEATH: case EVENT_CHECK_DEATH:
if (!me->HasUnitState(UNIT_STATE_CASTING)) if (!me->HasUnitState(UNIT_STATE_CASTING))
{ {
Creature* riftKeeper = ObjectAccessor::GetCreature(*me, riftKeeperGUID); Creature* riftKeeper = ObjectAccessor::GetCreature(*me, _riftKeeperGUID);
if (!riftKeeper || !riftKeeper->IsAlive()) if (!riftKeeper || !riftKeeper->IsAlive())
{ {
if (instance) _instance->SetData(DATA_RIFT_KILLED, 1);
instance->SetData(DATA_RIFT_KILLED, 1);
me->DespawnOrUnsummon(0); me->DespawnOrUnsummon(0);
break; break;
} }
else else
{
me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false); me->CastSpell(riftKeeper, SPELL_RIFT_CHANNEL, false);
} }
}
events.ScheduleEvent(EVENT_CHECK_DEATH, 500); events.ScheduleEvent(EVENT_CHECK_DEATH, 500);
break; break;
} }
} }
};
private:
EventMap _events;
InstanceScript* _instance;
ObjectGuid _riftKeeperGUID;
}; };
class spell_black_morass_corrupt_medivh : public SpellScriptLoader struct npc_black_morass_summoned_add : public SmartAI
{ {
public: npc_black_morass_summoned_add(Creature* creature) : SmartAI(creature)
spell_black_morass_corrupt_medivh() : SpellScriptLoader("spell_black_morass_corrupt_medivh") { }
class spell_black_morass_corrupt_medivh_AuraScript : public AuraScript
{ {
PrepareAuraScript(spell_black_morass_corrupt_medivh_AuraScript); }
void EnterEvadeMode(EvadeReason why) override
{
SmartAI::EnterEvadeMode(why);
me->GetMotionMaster()->MoveTargetedHome(true);
}
};
class spell_black_morass_corrupt_medivh : public AuraScript
{
PrepareAuraScript(spell_black_morass_corrupt_medivh);
bool Load() override bool Load() override
{ {
@@ -408,22 +410,18 @@ public:
void Register() override void Register() override
{ {
OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh_AuraScript::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL); OnEffectPeriodic += AuraEffectPeriodicFn(spell_black_morass_corrupt_medivh::PeriodicTick, EFFECT_0, SPELL_AURA_PERIODIC_TRIGGER_SPELL);
} }
private: private:
uint8 _ticks = 0; uint8 _ticks = 0;
};
AuraScript* GetAuraScript() const override
{
return new spell_black_morass_corrupt_medivh_AuraScript();
}
}; };
void AddSC_the_black_morass() void AddSC_the_black_morass()
{ {
new npc_medivh_bm(); RegisterTheBlackMorassCreatureAI(npc_medivh_bm);
new npc_time_rift(); RegisterTheBlackMorassCreatureAI(npc_time_rift);
new spell_black_morass_corrupt_medivh(); RegisterTheBlackMorassCreatureAI(npc_black_morass_summoned_add);
RegisterSpellScript(spell_black_morass_corrupt_medivh);
} }
@@ -94,4 +94,6 @@ inline AI* GetTheBlackMorassAI(T* obj)
return GetInstanceAI<AI>(obj, TheBlackMorassScriptName); return GetInstanceAI<AI>(obj, TheBlackMorassScriptName);
} }
#define RegisterTheBlackMorassCreatureAI(ai_name) RegisterCreatureAIWithFactory(ai_name, GetTheBlackMorassAI)
#endif #endif