diff options
author | Keader <keader.android@gmail.com> | 2017-12-18 08:39:35 -0300 |
---|---|---|
committer | funjoker <funjoker109@gmail.com> | 2021-04-15 05:53:27 +0200 |
commit | bd62bfc05900e81b39ec4b7ae8555b1bffde5873 (patch) | |
tree | eaea3c2fc103824bfebfdf6bafbe67cb5305c290 | |
parent | 24440866303bdce004b454bde8ccaeedc793e1bc (diff) |
Scripts/Naxxramas: Fixed blizzards following same player in Sapphiron encounter (#21068)
Closes #18765
(cherry picked from commit 143b2aeac06348c1d08f47f60ad32a306587cb50)
-rw-r--r-- | sql/updates/world/master/2021_03_15_03_world_2017_12_18_00_world.sql | 1 | ||||
-rw-r--r-- | src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp | 100 |
2 files changed, 89 insertions, 12 deletions
diff --git a/sql/updates/world/master/2021_03_15_03_world_2017_12_18_00_world.sql b/sql/updates/world/master/2021_03_15_03_world_2017_12_18_00_world.sql new file mode 100644 index 00000000000..27f2f8a0dc6 --- /dev/null +++ b/sql/updates/world/master/2021_03_15_03_world_2017_12_18_00_world.sql @@ -0,0 +1 @@ +UPDATE `creature_template` SET `difficulty_entry_1`=0, `ScriptName`='npc_sapphiron_blizzard' WHERE `entry`=16474; diff --git a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp index 6c50c638cb3..617c3ad17e6 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_sapphiron.cpp @@ -78,11 +78,6 @@ enum Events EVENT_CHECK_RESISTS }; -enum Actions -{ - ACTION_BIRTH = 1 -}; - enum Misc { NPC_BLIZZARD = 16474, @@ -91,11 +86,35 @@ enum Misc // The Hundred Club DATA_THE_HUNDRED_CLUB = 21462147, - MAX_FROST_RESISTANCE = 100 + MAX_FROST_RESISTANCE = 100, + ACTION_BIRTH = 1, + DATA_BLIZZARD_TARGET }; typedef std::map<ObjectGuid, ObjectGuid> IceBlockMap; +class BlizzardTargetSelector +{ +public: + BlizzardTargetSelector(std::vector<Unit*> const& blizzards) : _blizzards(blizzards) { } + + bool operator()(Unit* unit) const + { + if (unit->GetTypeId() != TYPEID_PLAYER) + return false; + + // Check if unit is target of some blizzard + for (Unit* blizzard : _blizzards) + if (blizzard->GetAI()->GetGUID(DATA_BLIZZARD_TARGET) == unit->GetGUID()) + return false; + + return true; + } + +private: + std::vector<Unit*> const& _blizzards; +}; + class boss_sapphiron : public CreatureScript { public: @@ -229,6 +248,24 @@ class boss_sapphiron : public CreatureScript return 0; } + ObjectGuid GetGUID(int32 data) const override + { + if (data == DATA_BLIZZARD_TARGET) + { + // Filtering blizzards from summon list + std::vector<Unit*> blizzards; + for (ObjectGuid summonGuid : summons) + if (summonGuid.GetEntry() == NPC_BLIZZARD) + if (Unit* temp = ObjectAccessor::GetUnit(*me, summonGuid)) + blizzards.push_back(temp); + + if (Unit* newTarget = me->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, BlizzardTargetSelector(blizzards))) + return newTarget->GetGUID(); + } + + return ObjectGuid::Empty; + } + void UpdateAI(uint32 diff) override { events.Update(diff); @@ -372,7 +409,7 @@ class boss_sapphiron : public CreatureScript } private: - std::vector<ObjectGuid> _iceboltTargets; + GuidVector _iceboltTargets; ObjectGuid _buffet; bool _delayedDrain; bool _canTheHundredClub; @@ -384,6 +421,41 @@ class boss_sapphiron : public CreatureScript } }; +struct npc_sapphiron_blizzard : public ScriptedAI +{ + npc_sapphiron_blizzard(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + me->SetReactState(REACT_PASSIVE); + _scheduler.Schedule(Seconds(3), [this](TaskContext chill) + { + DoCastSelf(me->m_spells[0], true); + chill.Repeat(); + }); + } + + ObjectGuid GetGUID(int32 data) const override + { + return data == DATA_BLIZZARD_TARGET ? _targetGuid : ObjectGuid::Empty; + } + + void SetGUID(ObjectGuid guid, int32 data) override + { + if (data == DATA_BLIZZARD_TARGET) + _targetGuid = guid; + } + + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); + } + +private: + TaskScheduler _scheduler; + ObjectGuid _targetGuid; +}; + class go_sapphiron_birth : public GameObjectScript { public: @@ -434,11 +506,12 @@ class spell_sapphiron_change_blizzard_target : public SpellScriptLoader TempSummon* me = GetTarget()->ToTempSummon(); if (Creature* owner = me ? me->GetSummonerCreatureBase() : nullptr) { - Unit* newTarget = owner->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true); - if (!newTarget) - newTarget = owner->getAttackerForHelper(); - if (newTarget) + me->GetAI()->SetGUID(ObjectGuid::Empty, DATA_BLIZZARD_TARGET); + if (Unit* newTarget = ObjectAccessor::GetUnit(*owner, owner->AI()->GetGUID(DATA_BLIZZARD_TARGET))) + { + me->GetAI()->SetGUID(newTarget->GetGUID(), DATA_BLIZZARD_TARGET); me->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f); + } else { me->StopMoving(); @@ -531,8 +604,10 @@ class spell_sapphiron_summon_blizzard : public SpellScriptLoader blizzard->CastSpell(nullptr, blizzard->m_spells[0], TRIGGERED_NONE); if (Creature* creatureCaster = GetCaster()->ToCreature()) { - if (Unit* newTarget = creatureCaster->AI()->SelectTarget(SELECT_TARGET_RANDOM, 1, 0.0f, true)) + blizzard->AI()->SetGUID(ObjectGuid::Empty, DATA_BLIZZARD_TARGET); + if (Unit* newTarget = ObjectAccessor::GetUnit(*creatureCaster, creatureCaster->AI()->GetGUID(DATA_BLIZZARD_TARGET))) { + blizzard->AI()->SetGUID(newTarget->GetGUID(), DATA_BLIZZARD_TARGET); blizzard->GetMotionMaster()->MoveFollow(newTarget, 0.1f, 0.0f); return; } @@ -567,6 +642,7 @@ class achievement_the_hundred_club : public AchievementCriteriaScript void AddSC_boss_sapphiron() { new boss_sapphiron(); + RegisterNaxxramasCreatureAI(npc_sapphiron_blizzard); new go_sapphiron_birth(); new spell_sapphiron_change_blizzard_target(); new spell_sapphiron_icebolt(); |