diff options
-rw-r--r-- | src/server/scripts/Northrend/zone_howling_fjord.cpp | 232 |
1 files changed, 135 insertions, 97 deletions
diff --git a/src/server/scripts/Northrend/zone_howling_fjord.cpp b/src/server/scripts/Northrend/zone_howling_fjord.cpp index df1bb427c03..b9f17672f0c 100644 --- a/src/server/scripts/Northrend/zone_howling_fjord.cpp +++ b/src/server/scripts/Northrend/zone_howling_fjord.cpp @@ -15,26 +15,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Sholazar_Basin -SD%Complete: 100 -SDComment: Quest support: 11253, 11241. -SDCategory: howling_fjord -EndScriptData */ - -/* ContentData -npc_apothecary_hanes -EndContentData */ - #include "ScriptMgr.h" #include "MotionMaster.h" #include "ObjectAccessor.h" #include "Player.h" +#include "QuestDef.h" +#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" #include "ScriptedGossip.h" #include "SpellInfo.h" #include "SpellScript.h" #include "TemporarySummon.h" +#include "Vehicle.h" /*###### ## npc_apothecary_hanes @@ -346,126 +338,172 @@ public: enum Daegarnn { - QUEST_DEFEAT_AT_RING = 11300, - - NPC_FIRJUS = 24213, - NPC_JLARBORN = 24215, - NPC_YOROS = 24214, - NPC_OLUF = 23931, - - NPC_PRISONER_1 = 24253, // looks the same but has different abilities - NPC_PRISONER_2 = 24254, - NPC_PRISONER_3 = 24255, - SAY_TEXT = 0 + QUEST_DEFEAT_AT_RING = 11300, + NPC_FIRJUS = 24213, + NPC_JLARBORN = 24215, + NPC_YOROS = 24214, + NPC_OLUF = 23931, + NPC_PRISONER_1 = 24253, // looks the same but has different abilities + NPC_PRISONER_2 = 24254, + NPC_PRISONER_3 = 24255, + SAY_TEXT = 0 }; -static float afSummon[] = {838.81f, -4678.06f, -94.182f}; -static float afCenter[] = {801.88f, -4721.87f, -96.143f}; +static Position const daegarnSummonPosition = { 838.81f, -4678.06f, -94.182f, 0.0f }; +static Position const daegarnCenterPosition = { 801.88f, -4721.87f, -96.143f, 0.0f }; -class npc_daegarn : public CreatureScript +/// @todo make prisoners help (unclear if summoned or using npc's from surrounding cages (summon inside small cages?)) +struct npc_daegarn : public ScriptedAI { -public: - npc_daegarn() : CreatureScript("npc_daegarn") { } + npc_daegarn(Creature* creature) : ScriptedAI(creature), _eventInProgress(false), _summons(creature) + { + } - /// @todo make prisoners help (unclear if summoned or using npc's from surrounding cages (summon inside small cages?)) - struct npc_daegarnAI : public ScriptedAI + void Reset() override { - npc_daegarnAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - } + _eventInProgress = false; + _playerGUID.Clear(); + _scheduler.CancelAll(); + _summons.DespawnAll(); - void Initialize() + _scheduler.Schedule(40s, [this](TaskContext context) { - bEventInProgress = false; - uiPlayerGUID.Clear(); - } + Talk(SAY_TEXT); + context.Repeat(40s); + }); + } - bool bEventInProgress; - ObjectGuid uiPlayerGUID; - TaskScheduler _scheduler; + void EnterEvadeMode(EvadeReason why) override + { + if (!_EnterEvadeMode(why)) + return; - void Reset() override + if (!me->GetVehicle()) { - Initialize(); - _scheduler.Schedule(40s, [this](TaskContext sayContext) + if (Unit* owner = me->GetCharmerOrOwner()) { - if (!bEventInProgress) - { - Talk(SAY_TEXT); - sayContext.Repeat(40s); - } - }); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, me->GetFollowAngle()); + } + else + { + me->AddUnitState(UNIT_STATE_EVADE); + me->GetMotionMaster()->MoveTargetedHome(); + } } - void StartEvent(ObjectGuid uiGUID) - { - if (bEventInProgress) - return; + if (me->IsVehicle()) + me->GetVehicleKit()->Reset(true); + } - uiPlayerGUID = uiGUID; + void UpdateAI(uint32 diff) override + { + _scheduler.Update(diff); - bEventInProgress = true; - SummonGladiator(NPC_FIRJUS); - } - - void UpdateAI(uint32 diff) override - { - if (bEventInProgress && !UpdateVictim()) - return; + if (!UpdateVictim()) + return; - _scheduler.Update(diff); - DoMeleeAttackIfReady(); - } + DoMeleeAttackIfReady(); + } - void JustSummoned(Creature* summon) override + void JustSummoned(Creature* summon) override + { + _summons.Summon(summon); + + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) { - if (Player* player = ObjectAccessor::GetPlayer(*me, uiPlayerGUID)) + if (player->IsAlive()) { - if (player->IsAlive()) - { - summon->SetWalk(false); - summon->GetMotionMaster()->MovePoint(0, afCenter[0], afCenter[1], afCenter[2]); - summon->AI()->AttackStart(player); - return; - } + summon->SetWalk(false); + summon->SetHomePosition(daegarnCenterPosition); + summon->GetMotionMaster()->MovePoint(0, daegarnCenterPosition); + return; } - - Reset(); } - void SummonGladiator(uint32 uiEntry) + Reset(); + } + + void SummonedCreatureDespawn(Creature* summon) override + { + _summons.Despawn(summon); + } + + void SummonedCreatureDies(Creature* summon, Unit* /*killer*/) override + { + uint32 entry = 0; + + _summons.Despawn(summon); + + // will eventually reset the event if something goes wrong + switch (summon->GetEntry()) { - me->SummonCreature(uiEntry, afSummon[0], afSummon[1], afSummon[2], 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30*IN_MILLISECONDS); + case NPC_FIRJUS: + entry = NPC_JLARBORN; + break; + case NPC_JLARBORN: + entry = NPC_YOROS; + break; + case NPC_YOROS: + entry = NPC_OLUF; + break; + case NPC_OLUF: + Reset(); + return; } - void SummonedCreatureDies(Creature* summoned, Unit* /*killer*/) override + SummonGladiator(entry); + } + + void QuestAccept(Player* player, Quest const* quest) override + { + if (quest->GetQuestId() == QUEST_DEFEAT_AT_RING) { - uint32 uiEntry = 0; + if (_eventInProgress) + return; + + _eventInProgress = true; + _playerGUID = player->GetGUID(); + _scheduler.CancelAll(); + _summons.DespawnAll(); - // will eventually reset the event if something goes wrong - switch (summoned->GetEntry()) + _scheduler.Schedule(5s, [this](TaskContext context) { - case NPC_FIRJUS: uiEntry = NPC_JLARBORN; break; - case NPC_JLARBORN: uiEntry = NPC_YOROS; break; - case NPC_YOROS: uiEntry = NPC_OLUF; break; - case NPC_OLUF: Reset(); return; - } + bool reset = true; + if (Player* player = ObjectAccessor::GetPlayer(*me, _playerGUID)) + { + if (player->IsAlive() && player->IsEngaged()) + { + for (auto itr = _summons.begin(); !reset && itr != _summons.end(); ++itr) + { + Creature* summon = ObjectAccessor::GetCreature(*me, *_summons.begin()); + if (summon && player->IsEngagedBy(summon)) + { + context.Repeat(5s); + reset = false; + } + } + } + } - SummonGladiator(uiEntry); - } + if (reset) + Reset(); + }); - void QuestAccept(Player* player, Quest const* quest) override - { - if (quest->GetQuestId() == QUEST_DEFEAT_AT_RING) - StartEvent(player->GetGUID()); + SummonGladiator(NPC_FIRJUS); } - }; + } - CreatureAI* GetAI(Creature* creature) const override +private: + void SummonGladiator(uint32 entry) { - return new npc_daegarnAI(creature); + me->SummonCreature(entry, daegarnSummonPosition, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30 * IN_MILLISECONDS); } + + bool _eventInProgress; + ObjectGuid _playerGUID; + TaskScheduler _scheduler; + SummonList _summons; }; enum MindlessAbomination @@ -633,7 +671,7 @@ void AddSC_howling_fjord() { new npc_apothecary_hanes(); new npc_razael_and_lyana(); - new npc_daegarn(); + RegisterCreatureAI(npc_daegarn); new npc_mindless_abomination(); new spell_mindless_abomination_explosion_fx_master(); new npc_riven_widow_cocoon(); |