aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeader <keader.android@gmail.com>2019-06-20 21:11:56 -0300
committerShauren <shauren.trinity@gmail.com>2021-12-11 21:37:53 +0100
commitba606753bdb512ce265b6fed50e54ca1ded3c3ef (patch)
treebaa95e7c64ee6babc9b67aaa0e18038177e3e81b /src
parent5979afd77852c17ab73971fe4bf1e28fa09c87a0 (diff)
Scripts/Icecrown Citadel: Fixed some bugs on Blood Orb object and trash mobs around him
Followup: 394b119664bc16dc5376f1404925b6d0b5a26876 (cherry picked from commit 3b0743ea67687937a1e6ba75ae9ef5e7fb996355) (cherry picked from commit f9a366628a17263852634a1095edcdb79a8b383e)
Diffstat (limited to 'src')
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp137
1 files changed, 92 insertions, 45 deletions
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
index dd94a92ac6f..4247ad8b670 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp
@@ -1854,14 +1854,14 @@ struct npc_entrance_faction_leader : public ScriptedAI
class MinionSearch
{
public:
- MinionSearch(bool checkCasting) : _checkCasting(checkCasting) { }
+ MinionSearch(Unit* owner, bool checkCasting) : _owner(owner), _checkCasting(checkCasting) { }
- bool operator()(Unit* unit) const
+ bool operator()(Creature* target) const
{
- if (!unit->IsAlive() || (_checkCasting && unit->HasUnitState(UNIT_STATE_CASTING)))
+ if (!target->IsAlive() || (_checkCasting && target->HasUnitState(UNIT_STATE_CASTING)) || target->GetWaypointPath() || _owner->GetDistance(target) > 10.0f)
return false;
- switch (unit->GetEntry())
+ switch (target->GetEntry())
{
case NPC_DARKFALLEN_BLOOD_KNIGHT:
case NPC_DARKFALLEN_NOBLE:
@@ -1876,6 +1876,7 @@ public:
private:
// Need check to not use polymorph in a casting creature
+ Unit* _owner;
bool _checkCasting;
};
@@ -1895,23 +1896,29 @@ struct npc_icc_orb_controller : public ScriptedAI
void Reset() override
{
- _minionGuids.clear();
- std::vector<Creature*> creatures;
- MinionSearch check(false);
- Trinity::CreatureListSearcher<MinionSearch> searcher(me, creatures, check);
- Cell::VisitGridObjects(me, searcher, 10.0f);
-
- for (Creature* creature : creatures)
+ _scheduler.Schedule(1s, [this](TaskContext /*initialize*/)
{
- creature->AI()->SetGUID(me->GetGUID(), DATA_GUID);
- _minionGuids.push_back(creature->GetGUID());
- }
+ std::vector<Creature*> creatures;
+ MinionSearch check(me, false);
+ Trinity::CreatureListSearcher<MinionSearch> searcher(me, creatures, check);
+ Cell::VisitGridObjects(me, searcher, 10.0f);
- if (creatures.empty())
- return;
+ if (creatures.empty())
+ return;
+
+ for (Creature* creature : creatures)
+ {
+ creature->AI()->SetGUID(me->GetGUID(), DATA_GUID);
+ _minionGuids.push_back(creature->GetGUID());
+ }
- _isLongRepeat = false;
- _scheduler.Schedule(1s, [this](TaskContext visual)
+ ScheduleVisualChannel(false);
+ });
+ }
+
+ void ScheduleVisualChannel(bool evading)
+ {
+ _scheduler.Schedule(evading ? 5s : 1s, [this](TaskContext visual)
{
ObjectGuid guid = Trinity::Containers::SelectRandomContainerElement(_minionGuids);
if (Unit* minion = ObjectAccessor::GetUnit(*me, guid))
@@ -1921,39 +1928,67 @@ struct npc_icc_orb_controller : public ScriptedAI
});
}
+ void UpdateValidGuids()
+ {
+ for (GuidVector::iterator itr = _minionGuids.begin(); itr != _minionGuids.end();)
+ {
+ if (Unit* minion = ObjectAccessor::GetUnit(*me, (*itr)))
+ {
+ if (!minion->IsAlive())
+ {
+ itr = _minionGuids.erase(itr);
+ continue;
+ }
+
+ ++itr;
+ }
+ // Is not in world anymore
+ else
+ itr = _minionGuids.erase(itr);
+ }
+ }
+
void SpellHit(Unit* caster, SpellInfo const* spell) override
{
if (spell->Id == SPELL_ORB_CONTROLLER_ACTIVE)
- {
if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 5.0f))
orb->AI()->SetGUID(caster->GetGUID(), DATA_GUID);
- }
}
- void DoAction(int32 action) override
+ void SetGUID(ObjectGuid const& guid, int32 id) override
{
- if (action == ACTION_COMBAT && !_isInCombat)
- {
- _isInCombat = true;
- _scheduler.CancelAll();
- if (_minionGuids.empty())
- return;
+ if (id != ACTION_COMBAT || _isInCombat)
+ return;
- if (Unit* minion = ObjectAccessor::GetUnit(*me, Trinity::Containers::SelectRandomContainerElement(_minionGuids)))
- minion->CastSpell(me, SPELL_SIPHON_ESSENCE);
+ Creature* darkfallen = ObjectAccessor::GetCreature(*me, guid);
+ if (!darkfallen)
+ return;
- for (ObjectGuid guid : _minionGuids)
- {
- if (Creature* minion = ObjectAccessor::GetCreature(*me, guid))
- if (minion->IsAIEnabled() && !minion->IsInCombat())
- minion->AI()->DoZoneInCombat();
- }
+ _isInCombat = true;
+ _scheduler.CancelAll();
+ if (_minionGuids.empty())
+ return;
+
+ for (ObjectGuid guid : _minionGuids)
+ {
+ if (Creature* minion = ObjectAccessor::GetCreature(*me, guid))
+ if (minion->IsAIEnabled() && !minion->IsInCombat())
+ minion->AI()->DoZoneInCombat(darkfallen);
}
- else if (action == ACTION_EVADE && _isInCombat)
+
+ if (Unit* minion = ObjectAccessor::GetUnit(*me, Trinity::Containers::SelectRandomContainerElement(_minionGuids)))
+ minion->CastSpell(nullptr, SPELL_SIPHON_ESSENCE);
+ }
+
+ void DoAction(int32 action) override
+ {
+ if (action == ACTION_EVADE && _isInCombat)
{
_isInCombat = false;
- // Update Darkfallens
- Reset();
+ UpdateValidGuids();
+ ScheduleVisualChannel(true);
+ if (GameObject* orb = me->FindNearestGameObject(GO_EMPOWERING_BLOOD_ORB, 5.0f))
+ orb->AddFlag(GO_FLAG_NOT_SELECTABLE);
}
}
@@ -1991,7 +2026,7 @@ struct DarkFallenAI : public ScriptedAI
if (roll_chance_i(20))
{
std::vector<Creature*> creatures;
- MinionSearch check(true);
+ MinionSearch check(me, true);
Trinity::CreatureListSearcher<MinionSearch> searcher(me, creatures, check);
Cell::VisitGridObjects(me, searcher, 10.0f);
if (!creatures.empty())
@@ -2014,7 +2049,7 @@ struct DarkFallenAI : public ScriptedAI
Scheduler.CancelAll();
ScheduleSpells();
if (Unit* trigger = ObjectAccessor::GetUnit(*me, TriggerGuid))
- trigger->GetAI()->DoAction(ACTION_COMBAT);
+ trigger->GetAI()->SetGUID(me->GetGUID(), ACTION_COMBAT);
}
void DoAction(int32 action) override
@@ -2030,9 +2065,9 @@ struct DarkFallenAI : public ScriptedAI
TriggerGuid = guid;
}
- void JustReachedHome() override
+ void EnterEvadeMode(EvadeReason why) override
{
- ScriptedAI::JustReachedHome();
+ ScriptedAI::EnterEvadeMode(why);
if (Unit* trigger = ObjectAccessor::GetUnit(*me, TriggerGuid))
trigger->GetAI()->DoAction(ACTION_EVADE);
}
@@ -2214,6 +2249,12 @@ struct go_empowering_blood_orb : public GameObjectAI
{
go_empowering_blood_orb(GameObject* go) : GameObjectAI(go) { }
+ void Reset() override
+ {
+ if (Creature* trigger = me->SummonCreature(NPC_ORB_VISUAL_STALKER, me->GetPosition(), TEMPSUMMON_MANUAL_DESPAWN))
+ _triggerGuid = trigger->GetGUID();
+ }
+
bool GossipHello(Player* player) override
{
me->CastSpell(player, SPELL_EMPOWERED_BLOOD, true);
@@ -2226,8 +2267,8 @@ struct go_empowering_blood_orb : public GameObjectAI
me->AddFlag(GO_FLAG_IN_USE);
me->SetGoAnimProgress(255);
me->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE);
- if (Creature* target = me->FindNearestCreature(NPC_ORB_VISUAL_STALKER, 10.0f, true))
- target->KillSelf();
+ if (Creature* trigger = ObjectAccessor::GetCreature(*me, _triggerGuid))
+ trigger->DespawnOrUnsummon();
_scheduler.Schedule(3s, [this](TaskContext /*context*/)
{
me->Delete();
@@ -2251,6 +2292,7 @@ struct go_empowering_blood_orb : public GameObjectAI
private:
TaskScheduler _scheduler;
+ ObjectGuid _triggerGuid;
};
// 70227 - Empowered Blood
@@ -2314,7 +2356,7 @@ class spell_icc_siphon_essence : public AuraScript
void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
{
- if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetTarget()->IsAIEnabled())
+ if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_CANCEL && GetTarget()->IsAIEnabled())
GetTarget()->GetAI()->DoAction(ACTION_SIPHON_INTERRUPTED);
}
@@ -2336,6 +2378,11 @@ class spell_darkfallen_blood_mirror : public SpellScript
void FilterTargets(std::list<WorldObject*>& targets)
{
+ targets.remove_if([](WorldObject* target)
+ {
+ return target->GetTypeId() != TYPEID_PLAYER;
+ });
+
if (targets.size() < 2)
return;