summaryrefslogtreecommitdiff
path: root/src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp')
-rw-r--r--src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp1160
1 files changed, 1160 insertions, 0 deletions
diff --git a/src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp b/src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
new file mode 100644
index 0000000000..6a096e793d
--- /dev/null
+++ b/src/scripts/EasternKingdoms/ScarletEnclave/chapter1.cpp
@@ -0,0 +1,1160 @@
+/*
+ * Copyright (C)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptMgr.h"
+#include "ScriptedCreature.h"
+#include "ScriptedGossip.h"
+#include "Vehicle.h"
+#include "ObjectMgr.h"
+#include "ScriptedEscortAI.h"
+#include "CombatAI.h"
+#include "PassiveAI.h"
+#include "Player.h"
+#include "SpellInfo.h"
+#include "CreatureTextMgr.h"
+#include "PetAI.h"
+
+// Ours
+enum eyeOfAcherus
+{
+ EVENT_REMOVE_CONTROL = 1,
+ EVENT_SPEAK_1 = 2,
+ EVENT_LAUNCH = 3,
+ EVENT_REGAIN_CONTROL = 4,
+
+ EYE_TEXT_LAUNCH = 0,
+ EYE_TEXT_CONTROL = 1,
+
+ SPELL_EYE_OF_ACHERUS_VISUAL = 51892,
+};
+
+class npc_eye_of_acherus : public CreatureScript
+{
+public:
+ npc_eye_of_acherus() : CreatureScript("npc_eye_of_acherus") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_eye_of_acherusAI(creature);
+ }
+
+ struct npc_eye_of_acherusAI : public NullCreatureAI
+ {
+ npc_eye_of_acherusAI(Creature* creature) : NullCreatureAI(creature) { }
+
+ EventMap events;
+
+ void InitializeAI()
+ {
+ events.Reset();
+ events.ScheduleEvent(EVENT_REMOVE_CONTROL, 500);
+ events.ScheduleEvent(EVENT_SPEAK_1, 4000);
+ events.ScheduleEvent(EVENT_LAUNCH, 7000);
+
+ me->CastSpell(me, SPELL_EYE_OF_ACHERUS_VISUAL, true);
+ }
+
+ void MovementInform(uint32 type, uint32 point)
+ {
+ if (type == ESCORT_MOTION_TYPE && me->movespline->Finalized())
+ events.ScheduleEvent(EVENT_REGAIN_CONTROL, 1000);
+ }
+
+ void SetControl(Player* player, bool on)
+ {
+ WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, me->GetPackGUID().size()+1);
+ data.append(me->GetPackGUID());
+ data << uint8(on ? 1 : 0);
+ player->GetSession()->SendPacket(&data);
+ }
+
+ void JustSummoned(Creature* creature)
+ {
+ if (Unit* target = creature->SelectNearbyTarget())
+ creature->AI()->AttackStart(target);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ events.Update(diff);
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_REMOVE_CONTROL:
+ if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself())
+ SetControl(player, false);
+ break;
+ case EVENT_SPEAK_1:
+ Talk(EYE_TEXT_LAUNCH, me->GetCharmerOrOwnerPlayerOrPlayerItself());
+ break;
+ case EVENT_LAUNCH:
+ {
+ Movement::PointsArray path;
+ path.push_back(G3D::Vector3(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ()));
+ path.push_back(G3D::Vector3(me->GetPositionX()-40.0f, me->GetPositionY(), me->GetPositionZ()+10.0f));
+ path.push_back(G3D::Vector3(1768.0f, -5876.0f, 153.0f));
+ me->GetMotionMaster()->MoveSplinePath(&path);
+ break;
+ }
+ case EVENT_REGAIN_CONTROL:
+ if (Player* player = me->GetCharmerOrOwnerPlayerOrPlayerItself())
+ {
+ SetControl(player, true);
+ Talk(EYE_TEXT_CONTROL, player);
+ }
+ break;
+ }
+ }
+ };
+};
+
+class spell_q12641_death_comes_from_on_high_summon_ghouls : public SpellScriptLoader
+{
+ public:
+ spell_q12641_death_comes_from_on_high_summon_ghouls() : SpellScriptLoader("spell_q12641_death_comes_from_on_high_summon_ghouls") { }
+
+ class spell_q12641_death_comes_from_on_high_summon_ghouls_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12641_death_comes_from_on_high_summon_ghouls_SpellScript);
+
+ void HandleScriptEffect(SpellEffIndex effIndex)
+ {
+ PreventHitEffect(effIndex);
+ if (Unit* target = GetHitUnit())
+ GetCaster()->CastSpell(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 54522, true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12641_death_comes_from_on_high_summon_ghouls_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12641_death_comes_from_on_high_summon_ghouls_SpellScript();
+ }
+};
+
+#define GOSSIP_ACCEPT_DUEL "I challenge you, death knight!"
+
+enum deathsChallenge
+{
+ SPELL_DUEL = 52996,
+ //SPELL_DUEL_TRIGGERED = 52990,
+ SPELL_DUEL_VICTORY = 52994,
+ SPELL_DUEL_FLAG = 52991,
+
+ SAY_DUEL = 0,
+
+ QUEST_DEATH_CHALLENGE = 12733,
+ FACTION_HOSTILE = 2068,
+
+ DATA_IN_PROGRESS = 0,
+
+ EVENT_SPEAK = 1, // 1 - 6
+ EVENT_DUEL_LOST = 7, // 7 - 8
+};
+
+class npc_death_knight_initiate : public CreatureScript
+{
+public:
+ npc_death_knight_initiate() : CreatureScript("npc_death_knight_initiate") { }
+
+ bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action)
+ {
+ player->PlayerTalkClass->ClearMenus();
+ if (action == GOSSIP_ACTION_INFO_DEF)
+ {
+ player->CLOSE_GOSSIP_MENU();
+
+ if (player->IsInCombat() || creature->IsInCombat())
+ return true;
+
+ if (creature->AI()->GetData(DATA_IN_PROGRESS))
+ return true;
+
+ creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15);
+
+ player->CastSpell(creature, SPELL_DUEL, false);
+ player->CastSpell(player, SPELL_DUEL_FLAG, true);
+ }
+ return true;
+ }
+
+ bool OnGossipHello(Player* player, Creature* creature)
+ {
+ if (player->GetQuestStatus(QUEST_DEATH_CHALLENGE) == QUEST_STATUS_INCOMPLETE && creature->IsFullHealth())
+ {
+ if (player->HealthBelowPct(10))
+ return true;
+
+ if (player->IsInCombat() || creature->IsInCombat())
+ return true;
+
+ if (!creature->AI()->GetData(player->GetGUIDLow()))
+ player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ACCEPT_DUEL, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
+
+ player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID());
+ }
+ return true;
+ }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_death_knight_initiateAI(creature);
+ }
+
+ struct npc_death_knight_initiateAI : public CombatAI
+ {
+ npc_death_knight_initiateAI(Creature* creature) : CombatAI(creature) { }
+
+ bool _duelInProgress;
+ uint64 _duelGUID;
+ EventMap events;
+ std::set<uint32> playerGUIDs;
+
+ uint32 GetData(uint32 data) const
+ {
+ if (data == DATA_IN_PROGRESS)
+ return _duelInProgress;
+
+ return playerGUIDs.find(data) != playerGUIDs.end();
+ }
+
+ void Reset()
+ {
+ _duelInProgress = false;
+ _duelGUID = 0;
+ me->RestoreFaction();
+ CombatAI::Reset();
+
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_15);
+ }
+
+ void SpellHit(Unit* caster, const SpellInfo* pSpell)
+ {
+ if (!_duelInProgress && pSpell->Id == SPELL_DUEL)
+ {
+ playerGUIDs.insert(caster->GetGUIDLow());
+ _duelGUID = caster->GetGUID();
+ _duelInProgress = true;
+
+ events.ScheduleEvent(EVENT_SPEAK, 3000);
+ events.ScheduleEvent(EVENT_SPEAK+1, 7000);
+ events.ScheduleEvent(EVENT_SPEAK+2, 8000);
+ events.ScheduleEvent(EVENT_SPEAK+3, 9000);
+ events.ScheduleEvent(EVENT_SPEAK+4, 10000);
+ events.ScheduleEvent(EVENT_SPEAK+5, 11000);
+ }
+ }
+
+ void DamageTaken(Unit* attacker, uint32& damage, DamageEffectType, SpellSchoolMask)
+ {
+ if (attacker && _duelInProgress && attacker->IsControlledByPlayer())
+ {
+ if (attacker->GetCharmerOrOwnerOrOwnGUID() != _duelGUID)
+ damage = 0;
+ else if (damage >= me->GetHealth())
+ {
+ damage = 0;
+ events.ScheduleEvent(EVENT_DUEL_LOST, 2000);
+ events.ScheduleEvent(EVENT_DUEL_LOST+1, 6000);
+ _duelGUID = 0;
+ _duelInProgress = 0;
+
+ attacker->RemoveGameObject(SPELL_DUEL_FLAG, true);
+ attacker->AttackStop();
+ me->CombatStop(false);
+ me->RemoveAllAuras();
+ me->CastSpell(attacker, SPELL_DUEL_VICTORY, true);
+ me->RestoreFaction();
+ }
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ events.Update(diff);
+ switch (events.ExecuteEvent())
+ {
+ case EVENT_SPEAK:
+ Talk(SAY_DUEL, ObjectAccessor::GetPlayer(*me, _duelGUID));
+ break;
+ case EVENT_SPEAK+1:
+ Talk(SAY_DUEL+1, ObjectAccessor::GetPlayer(*me, _duelGUID));
+ break;
+ case EVENT_SPEAK+2:
+ Talk(SAY_DUEL+2, ObjectAccessor::GetPlayer(*me, _duelGUID));
+ break;
+ case EVENT_SPEAK+3:
+ Talk(SAY_DUEL+3, ObjectAccessor::GetPlayer(*me, _duelGUID));
+ break;
+ case EVENT_SPEAK+4:
+ Talk(SAY_DUEL+4, ObjectAccessor::GetPlayer(*me, _duelGUID));
+ break;
+ case EVENT_SPEAK+5:
+ me->setFaction(FACTION_HOSTILE);
+ if (Player* player = ObjectAccessor::GetPlayer(*me, _duelGUID))
+ AttackStart(player);
+ return;
+ case EVENT_DUEL_LOST:
+ me->CastSpell(me, 7267, true);
+ break;
+ case EVENT_DUEL_LOST+1:
+ EnterEvadeMode();
+ return;
+ }
+
+ if (!events.Empty() || !UpdateVictim())
+ return;
+
+ if (_duelInProgress)
+ {
+ if (me->GetVictim()->GetGUID() == _duelGUID && me->GetVictim()->HealthBelowPct(10))
+ {
+ me->GetVictim()->CastSpell(me->GetVictim(), 7267, true); // beg
+ me->GetVictim()->RemoveGameObject(SPELL_DUEL_FLAG, true);
+ EnterEvadeMode();
+ return;
+ }
+ }
+
+ CombatAI::UpdateAI(diff);
+ }
+ };
+};
+
+enum GiftOfTheHarvester
+{
+ NPC_GHOUL = 28845,
+ MAX_GHOULS = 5,
+
+ SPELL_GHOUL_EMERGE = 50142,
+ SPELL_SUMMON_SCARLET_GHOST = 52505,
+ SPELL_GHOUL_SUBMERGE = 26234,
+
+ EVENT_GHOUL_RESTORE_STATE = 1,
+ EVENT_GHOUL_CHECK_COMBAT = 2,
+ EVENT_GHOUL_EMOTE = 3,
+ EVENT_GHOUL_MOVE_TO_PIT = 4,
+
+ SAY_GOTHIK_PIT = 0
+};
+
+class spell_item_gift_of_the_harvester : public SpellScriptLoader
+{
+ public:
+ spell_item_gift_of_the_harvester() : SpellScriptLoader("spell_item_gift_of_the_harvester") { }
+
+ class spell_item_gift_of_the_harvester_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_item_gift_of_the_harvester_SpellScript);
+
+ SpellCastResult CheckRequirement()
+ {
+ std::list<Creature*> ghouls;
+ GetCaster()->GetAllMinionsByEntry(ghouls, NPC_GHOUL);
+ if (ghouls.size() >= MAX_GHOULS)
+ {
+ SetCustomCastResultMessage(SPELL_CUSTOM_ERROR_TOO_MANY_GHOULS);
+ return SPELL_FAILED_CUSTOM_ERROR;
+ }
+
+ return SPELL_CAST_OK;
+ }
+
+ void Register()
+ {
+ OnCheckCast += SpellCheckCastFn(spell_item_gift_of_the_harvester_SpellScript::CheckRequirement);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_item_gift_of_the_harvester_SpellScript();
+ }
+};
+
+class spell_q12698_the_gift_that_keeps_on_giving : public SpellScriptLoader
+{
+ public:
+ spell_q12698_the_gift_that_keeps_on_giving() : SpellScriptLoader("spell_q12698_the_gift_that_keeps_on_giving") { }
+
+ class spell_q12698_the_gift_that_keeps_on_giving_SpellScript : public SpellScript
+ {
+ PrepareSpellScript(spell_q12698_the_gift_that_keeps_on_giving_SpellScript);
+
+ void HandleScriptEffect(SpellEffIndex /*effIndex*/)
+ {
+ if (GetOriginalCaster() && GetHitUnit())
+ GetOriginalCaster()->CastSpell(GetHitUnit(), urand(0, 1) ? GetEffectValue() : SPELL_SUMMON_SCARLET_GHOST, true);
+ }
+
+ void Register()
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_q12698_the_gift_that_keeps_on_giving_SpellScript::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+ };
+
+ SpellScript* GetSpellScript() const
+ {
+ return new spell_q12698_the_gift_that_keeps_on_giving_SpellScript();
+ }
+};
+
+class npc_scarlet_ghoul : public CreatureScript
+{
+public:
+ npc_scarlet_ghoul() : CreatureScript("npc_scarlet_ghoul") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_scarlet_ghoulAI(creature);
+ }
+
+ struct npc_scarlet_ghoulAI : public ScriptedAI
+ {
+ npc_scarlet_ghoulAI(Creature* creature) : ScriptedAI(creature)
+ {
+ }
+
+ EventMap events;
+ uint64 gothikGUID;
+
+ void InitializeAI()
+ {
+ gothikGUID = 0;
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ ScriptedAI::InitializeAI();
+ me->SetReactState(REACT_PASSIVE);
+
+ events.ScheduleEvent(EVENT_GHOUL_EMOTE, 1);
+ events.ScheduleEvent(EVENT_GHOUL_RESTORE_STATE, 3500);
+ }
+
+ void OwnerAttackedBy(Unit* attacker)
+ {
+ if (!me->IsInCombat() && me->GetReactState() == REACT_DEFENSIVE)
+ AttackStart(attacker);
+ }
+
+ void SetGUID(uint64 guid, int32)
+ {
+ gothikGUID = guid;
+ events.ScheduleEvent(EVENT_GHOUL_MOVE_TO_PIT, 3000);
+ me->GetMotionMaster()->Clear(false);
+ }
+
+ void MovementInform(uint32 type, uint32 point)
+ {
+ if (type == POINT_MOTION_TYPE && point == 1)
+ {
+ me->DespawnOrUnsummon(1500);
+ me->CastSpell(me, SPELL_GHOUL_SUBMERGE, true);
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ events.Update(diff);
+ switch (events.GetEvent())
+ {
+ case EVENT_GHOUL_MOVE_TO_PIT:
+ me->GetMotionMaster()->MovePoint(1, 2364.77f, -5776.14f, 151.36f);
+ if (Creature* gothik = ObjectAccessor::GetCreature(*me, gothikGUID))
+ gothik->AI()->DoAction(SAY_GOTHIK_PIT);
+ events.PopEvent();
+ break;
+ case EVENT_GHOUL_EMOTE:
+ me->CastSpell(me, SPELL_GHOUL_EMERGE, true);
+ events.PopEvent();
+ break;
+ case EVENT_GHOUL_RESTORE_STATE:
+ me->SetReactState(REACT_DEFENSIVE);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
+ if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
+ me->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, frand(0.0f, 2*M_PI));
+ events.PopEvent();
+ events.ScheduleEvent(EVENT_GHOUL_CHECK_COMBAT, 1000);
+ return;
+ case EVENT_GHOUL_CHECK_COMBAT:
+ if (!me->IsInCombat())
+ if (Player* owner = me->GetCharmerOrOwnerPlayerOrPlayerItself())
+ if (owner->GetVictim())
+ AttackStart(owner->GetVictim());
+
+ events.RepeatEvent(1000);
+ return;
+ }
+
+ if (!UpdateVictim())
+ return;
+
+ DoMeleeAttackIfReady();
+ }
+ };
+};
+
+class npc_dkc1_gothik : public CreatureScript
+{
+public:
+ npc_dkc1_gothik() : CreatureScript("npc_dkc1_gothik") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_dkc1_gothikAI(creature);
+ }
+
+ struct npc_dkc1_gothikAI : public ScriptedAI
+ {
+ npc_dkc1_gothikAI(Creature* creature) : ScriptedAI(creature) { spoken = 0; }
+
+ int32 spoken;
+
+ void DoAction(int32 action)
+ {
+ if (action == SAY_GOTHIK_PIT && spoken <= 0)
+ {
+ spoken = 5000;
+ Talk(SAY_GOTHIK_PIT);
+ }
+ }
+
+ void MoveInLineOfSight(Unit* who)
+ {
+ ScriptedAI::MoveInLineOfSight(who);
+
+ if (!who->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_NPC) && who->GetEntry() == NPC_GHOUL && me->IsWithinDistInMap(who, 10.0f))
+ if (Unit* owner = who->GetOwner())
+ if (Player* player = owner->ToPlayer())
+ {
+ Creature* creature = who->ToCreature();
+ if (player->GetQuestStatus(12698) == QUEST_STATUS_INCOMPLETE)
+ creature->CastSpell(owner, 52517, true);
+
+ creature->AI()->SetGUID(me->GetGUID());
+ creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (spoken > 0)
+ spoken -= diff;
+
+ ScriptedAI::UpdateAI(diff);
+ }
+ };
+};
+
+class npc_scarlet_cannon : public CreatureScript
+{
+public:
+ npc_scarlet_cannon() : CreatureScript("npc_scarlet_cannon") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_scarlet_cannonAI(creature);
+ }
+
+ struct npc_scarlet_cannonAI : public VehicleAI
+ {
+ npc_scarlet_cannonAI(Creature* creature) : VehicleAI(creature) { summonAttackers = 0; }
+
+ uint32 summonAttackers;
+ void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool apply)
+ {
+ summonAttackers = apply ? 8000 : 0;
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ VehicleAI::UpdateAI(diff);
+
+ if (summonAttackers)
+ {
+ summonAttackers += diff;
+ if (summonAttackers >= 15000)
+ {
+ for (uint8 i = 0; i < 15; ++i)
+ if (Creature* summon = me->SummonCreature(28834 /*NPC_SCARLET_FLEET_DEFENDER*/, 2192.56f+irand(-10, 10), -6147.90f+irand(-10, 10), 5.2f, 4.7f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 45000))
+ {
+ summon->SetHomePosition(me->GetHomePosition());
+ summon->AI()->AttackStart(me);
+ }
+
+ summonAttackers = 1;
+ }
+ }
+ }
+ };
+};
+
+
+// Theirs
+/*######
+##Quest 12848
+######*/
+
+#define GCD_CAST 1
+
+enum UnworthyInitiate
+{
+ SPELL_SOUL_PRISON_CHAIN_SELF = 54612,
+ SPELL_SOUL_PRISON_CHAIN = 54613,
+ SPELL_DK_INITIATE_VISUAL = 51519,
+
+ SPELL_ICY_TOUCH = 52372,
+ SPELL_PLAGUE_STRIKE = 52373,
+ SPELL_BLOOD_STRIKE = 52374,
+ SPELL_DEATH_COIL = 52375,
+
+ SAY_EVENT_START = 0,
+ SAY_EVENT_ATTACK = 1,
+
+ EVENT_ICY_TOUCH = 1,
+ EVENT_PLAGUE_STRIKE = 2,
+ EVENT_BLOOD_STRIKE = 3,
+ EVENT_DEATH_COIL = 4
+};
+
+enum UnworthyInitiatePhase
+{
+ PHASE_CHAINED,
+ PHASE_TO_EQUIP,
+ PHASE_EQUIPING,
+ PHASE_TO_ATTACK,
+ PHASE_ATTACKING,
+};
+
+uint32 acherus_soul_prison[12] =
+{
+ 191577,
+ 191580,
+ 191581,
+ 191582,
+ 191583,
+ 191584,
+ 191585,
+ 191586,
+ 191587,
+ 191588,
+ 191589,
+ 191590
+};
+
+uint32 acherus_unworthy_initiate[5] =
+{
+ 29519,
+ 29520,
+ 29565,
+ 29566,
+ 29567
+};
+
+class npc_unworthy_initiate : public CreatureScript
+{
+public:
+ npc_unworthy_initiate() : CreatureScript("npc_unworthy_initiate") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_unworthy_initiateAI(creature);
+ }
+
+ struct npc_unworthy_initiateAI : public ScriptedAI
+ {
+ npc_unworthy_initiateAI(Creature* creature) : ScriptedAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ if (!me->GetCurrentEquipmentId())
+ me->SetCurrentEquipmentId(me->GetOriginalEquipmentId());
+ }
+
+ uint64 playerGUID;
+ UnworthyInitiatePhase phase;
+ uint32 wait_timer;
+ float anchorX, anchorY;
+ uint64 anchorGUID;
+
+ EventMap events;
+
+ void Reset()
+ {
+ anchorGUID = 0;
+ phase = PHASE_CHAINED;
+ events.Reset();
+ me->setFaction(7);
+ me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ me->SetUInt32Value(UNIT_FIELD_BYTES_1, 8);
+ me->LoadEquipment(0, true);
+ }
+
+ void EnterCombat(Unit* /*who*/)
+ {
+ events.ScheduleEvent(EVENT_ICY_TOUCH, 1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_PLAGUE_STRIKE, 3000, GCD_CAST);
+ events.ScheduleEvent(EVENT_BLOOD_STRIKE, 2000, GCD_CAST);
+ events.ScheduleEvent(EVENT_DEATH_COIL, 5000, GCD_CAST);
+ }
+
+ void MovementInform(uint32 type, uint32 id)
+ {
+ if (type != POINT_MOTION_TYPE)
+ return;
+
+ if (id == 1)
+ {
+ wait_timer = 5000;
+ me->LoadEquipment(1);
+ me->CastSpell(me, SPELL_DK_INITIATE_VISUAL, true);
+
+ if (Player* starter = ObjectAccessor::GetPlayer(*me, playerGUID))
+ sCreatureTextMgr->SendChat(me, SAY_EVENT_ATTACK, NULL, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_NEUTRAL, false, starter);
+
+ phase = PHASE_TO_ATTACK;
+ }
+ }
+
+ void EventStart(Creature* anchor, Player* target)
+ {
+ wait_timer = 5000;
+ phase = PHASE_TO_EQUIP;
+
+ me->SetUInt32Value(UNIT_FIELD_BYTES_1, 0);
+ me->RemoveAurasDueToSpell(SPELL_SOUL_PRISON_CHAIN_SELF);
+ me->RemoveAurasDueToSpell(SPELL_SOUL_PRISON_CHAIN);
+
+ float z;
+ anchor->GetContactPoint(me, anchorX, anchorY, z, 1.0f);
+
+ playerGUID = target->GetGUID();
+ Talk(SAY_EVENT_START, target);
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ switch (phase)
+ {
+ case PHASE_CHAINED:
+ if (!anchorGUID)
+ {
+ if (Creature* anchor = me->FindNearestCreature(29521, 30))
+ {
+ anchor->AI()->SetGUID(me->GetGUID());
+ anchor->CastSpell(me, SPELL_SOUL_PRISON_CHAIN, true);
+ anchorGUID = anchor->GetGUID();
+ }
+
+ float dist = 99.0f;
+ GameObject* prison = NULL;
+
+ for (uint8 i = 0; i < 12; ++i)
+ {
+ if (GameObject* temp_prison = me->FindNearestGameObject(acherus_soul_prison[i], 30))
+ {
+ if (me->IsWithinDist(temp_prison, dist, false))
+ {
+ dist = me->GetDistance2d(temp_prison);
+ prison = temp_prison;
+ }
+ }
+ }
+
+ if (prison)
+ prison->ResetDoorOrButton();
+ }
+ break;
+ case PHASE_TO_EQUIP:
+ if (wait_timer)
+ {
+ if (wait_timer > diff)
+ wait_timer -= diff;
+ else
+ {
+ me->GetMotionMaster()->MovePoint(1, anchorX, anchorY, me->GetPositionZ());
+ //sLog->outDebug(LOG_FILTER_TSCR, "npc_unworthy_initiateAI: move to %f %f %f", anchorX, anchorY, me->GetPositionZ());
+ phase = PHASE_EQUIPING;
+ wait_timer = 0;
+ }
+ }
+ break;
+ case PHASE_TO_ATTACK:
+ if (wait_timer)
+ {
+ if (wait_timer > diff)
+ wait_timer -= diff;
+ else
+ {
+ me->setFaction(14);
+ me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC);
+ phase = PHASE_ATTACKING;
+
+ if (Player* target = ObjectAccessor::GetPlayer(*me, playerGUID))
+ AttackStart(target);
+ wait_timer = 0;
+ }
+ }
+ break;
+ case PHASE_ATTACKING:
+ if (!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ while (uint32 eventId = events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_ICY_TOUCH:
+ DoCastVictim(SPELL_ICY_TOUCH);
+ events.DelayEvents(1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_ICY_TOUCH, 5000, GCD_CAST);
+ break;
+ case EVENT_PLAGUE_STRIKE:
+ DoCastVictim(SPELL_PLAGUE_STRIKE);
+ events.DelayEvents(1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_PLAGUE_STRIKE, 5000, GCD_CAST);
+ break;
+ case EVENT_BLOOD_STRIKE:
+ DoCastVictim(SPELL_BLOOD_STRIKE);
+ events.DelayEvents(1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_BLOOD_STRIKE, 5000, GCD_CAST);
+ break;
+ case EVENT_DEATH_COIL:
+ DoCastVictim(SPELL_DEATH_COIL);
+ events.DelayEvents(1000, GCD_CAST);
+ events.ScheduleEvent(EVENT_DEATH_COIL, 5000, GCD_CAST);
+ break;
+ }
+ }
+
+ DoMeleeAttackIfReady();
+ break;
+ default:
+ break;
+ }
+ }
+ };
+};
+
+class npc_unworthy_initiate_anchor : public CreatureScript
+{
+public:
+ npc_unworthy_initiate_anchor() : CreatureScript("npc_unworthy_initiate_anchor") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_unworthy_initiate_anchorAI(creature);
+ }
+
+ struct npc_unworthy_initiate_anchorAI : public PassiveAI
+ {
+ npc_unworthy_initiate_anchorAI(Creature* creature) : PassiveAI(creature), prisonerGUID(0) {}
+
+ uint64 prisonerGUID;
+
+ void SetGUID(uint64 guid, int32 /*id*/)
+ {
+ if (!prisonerGUID)
+ prisonerGUID = guid;
+ }
+
+ uint64 GetGUID(int32 /*id*/) const
+ {
+ return prisonerGUID;
+ }
+ };
+};
+
+class go_acherus_soul_prison : public GameObjectScript
+{
+public:
+ go_acherus_soul_prison() : GameObjectScript("go_acherus_soul_prison") { }
+
+ bool OnGossipHello(Player* player, GameObject* go)
+ {
+ if (Creature* anchor = go->FindNearestCreature(29521, 15))
+ if (uint64 prisonerGUID = anchor->AI()->GetGUID())
+ if (Creature* prisoner = ObjectAccessor::GetCreature(*player, prisonerGUID))
+ CAST_AI(npc_unworthy_initiate::npc_unworthy_initiateAI, prisoner->AI())->EventStart(anchor, player);
+
+ return false;
+ }
+
+};
+
+/*####
+## npc_scarlet_miner_cart
+####*/
+
+enum Spells_SM
+{
+ SPELL_CART_CHECK = 54173,
+ SPELL_CART_DRAG = 52465
+};
+
+class npc_scarlet_miner_cart : public CreatureScript
+{
+public:
+ npc_scarlet_miner_cart() : CreatureScript("npc_scarlet_miner_cart") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_scarlet_miner_cartAI(creature);
+ }
+
+ struct npc_scarlet_miner_cartAI : public PassiveAI
+ {
+ npc_scarlet_miner_cartAI(Creature* creature) : PassiveAI(creature), minerGUID(0)
+ {
+ me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ me->setFaction(35);
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); // Modelid2 is a horse.
+ }
+
+ uint64 minerGUID;
+
+ void SetGUID(uint64 guid, int32 /*id*/)
+ {
+ minerGUID = guid;
+ }
+
+ void DoAction(int32 /*param*/)
+ {
+ if (Creature* miner = ObjectAccessor::GetCreature(*me, minerGUID))
+ {
+ me->SetWalk(false);
+
+ //Not 100% correct, but movement is smooth. Sometimes miner walks faster
+ //than normal, this speed is fast enough to keep up at those times.
+ me->SetSpeed(MOVE_RUN, 1.25f);
+
+ me->GetMotionMaster()->MoveFollow(miner, 1.0f, 0);
+ me->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ me->setFaction(35);
+ }
+ }
+
+ void PassengerBoarded(Unit* who, int8 /*seatId*/, bool apply)
+ {
+ who->SetVisible(!apply);
+ if (!apply)
+ if (Creature* miner = ObjectAccessor::GetCreature(*me, minerGUID))
+ miner->DisappearAndDie();
+ }
+ };
+
+};
+
+/*####
+## npc_scarlet_miner
+####*/
+
+enum Says_SM
+{
+ SAY_SCARLET_MINER_0 = 0,
+ SAY_SCARLET_MINER_1 = 1
+};
+
+class npc_scarlet_miner : public CreatureScript
+{
+public:
+ npc_scarlet_miner() : CreatureScript("npc_scarlet_miner") { }
+
+ CreatureAI* GetAI(Creature* creature) const
+ {
+ return new npc_scarlet_minerAI(creature);
+ }
+
+ struct npc_scarlet_minerAI : public npc_escortAI
+ {
+ npc_scarlet_minerAI(Creature* creature) : npc_escortAI(creature)
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ uint32 IntroTimer;
+ uint32 IntroPhase;
+ uint64 carGUID;
+
+ void Reset()
+ {
+ carGUID = 0;
+ IntroTimer = 0;
+ IntroPhase = 0;
+ }
+
+ void InitWaypoint()
+ {
+ AddWaypoint(1, 2389.03f, -5902.74f, 109.014f, 5000);
+ AddWaypoint(2, 2341.812012f, -5900.484863f, 102.619743f);
+ AddWaypoint(3, 2306.561279f, -5901.738281f, 91.792419f);
+ AddWaypoint(4, 2300.098389f, -5912.618652f, 86.014885f);
+ AddWaypoint(5, 2294.142090f, -5927.274414f, 75.316849f);
+ AddWaypoint(6, 2286.984375f, -5944.955566f, 63.714966f);
+ AddWaypoint(7, 2280.001709f, -5961.186035f, 54.228283f);
+ AddWaypoint(8, 2259.389648f, -5974.197754f, 42.359348f);
+ AddWaypoint(9, 2242.882812f, -5984.642578f, 32.827850f);
+ AddWaypoint(10, 2217.265625f, -6028.959473f, 7.675705f);
+ AddWaypoint(11, 2202.595947f, -6061.325684f, 5.882018f);
+ AddWaypoint(12, 2188.974609f, -6080.866699f, 3.370027f);
+
+ if (urand(0, 1))
+ {
+ AddWaypoint(13, 2176.483887f, -6110.407227f, 1.855181f);
+ AddWaypoint(14, 2172.516602f, -6146.752441f, 1.074235f);
+ AddWaypoint(15, 2138.918457f, -6158.920898f, 1.342926f);
+ AddWaypoint(16, 2129.866699f, -6174.107910f, 4.380779f);
+ AddWaypoint(17, 2117.709473f, -6193.830078f, 13.3542f, 10000);
+ }
+ else
+ {
+ AddWaypoint(13, 2184.190186f, -6166.447266f, 0.968877f);
+ AddWaypoint(14, 2234.265625f, -6163.741211f, 0.916021f);
+ AddWaypoint(15, 2268.071777f, -6158.750977f, 1.822252f);
+ AddWaypoint(16, 2270.028320f, -6176.505859f, 6.340538f);
+ AddWaypoint(17, 2271.739014f, -6195.401855f, 13.3542f, 10000);
+ }
+ }
+
+ void InitCartQuest(Player* who)
+ {
+ carGUID = who->GetVehicleBase()->GetGUID();
+ InitWaypoint();
+ Start(false, false, who->GetGUID());
+ SetDespawnAtFar(false);
+ }
+
+ void WaypointReached(uint32 waypointId)
+ {
+ switch (waypointId)
+ {
+ case 1:
+ if (Unit* car = ObjectAccessor::GetCreature(*me, carGUID))
+ {
+ me->SetFacingToObject(car);
+ // xinef: add some flags
+ car->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE|UNIT_FLAG_IMMUNE_TO_PC|UNIT_FLAG_IMMUNE_TO_NPC);
+ car->setFaction(35);
+ }
+ Talk(SAY_SCARLET_MINER_0);
+ SetRun(true);
+ IntroTimer = 4000;
+ IntroPhase = 1;
+ break;
+ case 17:
+ if (Creature* car = ObjectAccessor::GetCreature(*me, carGUID))
+ {
+ car->SetPosition(car->GetPositionX(), car->GetPositionY(), me->GetPositionZ() + 1, car->GetOrientation());
+ car->StopMovingOnCurrentPos();
+ me->SetFacingToObject(car);
+ car->RemoveAura(SPELL_CART_DRAG);
+ }
+ Talk(SAY_SCARLET_MINER_1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff)
+ {
+ if (IntroPhase)
+ {
+ if (IntroTimer <= diff)
+ {
+ if (IntroPhase == 1)
+ {
+ if (Creature* car = ObjectAccessor::GetCreature(*me, carGUID))
+ DoCast(car, SPELL_CART_DRAG);
+ IntroTimer = 800;
+ IntroPhase = 2;
+ }
+ else
+ {
+ if (Creature* car = ObjectAccessor::GetCreature(*me, carGUID))
+ car->AI()->DoAction(0);
+ IntroPhase = 0;
+ }
+ } else IntroTimer-=diff;
+ }
+ npc_escortAI::UpdateAI(diff);
+ }
+ };
+
+};
+
+/*######
+## go_inconspicuous_mine_car
+######*/
+
+enum Spells_Cart
+{
+ SPELL_CART_SUMM = 52463
+};
+
+class go_inconspicuous_mine_car : public GameObjectScript
+{
+public:
+ go_inconspicuous_mine_car() : GameObjectScript("go_inconspicuous_mine_car") { }
+
+ bool OnGossipHello(Player* player, GameObject* /*go*/)
+ {
+ if (player->GetQuestStatus(12701) == QUEST_STATUS_INCOMPLETE)
+ {
+ // Hack Why Trinity Dont Support Custom Summon Location
+ if (Creature* miner = player->SummonCreature(28841, 2383.869629f, -5900.312500f, 107.996086f, player->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 1))
+ {
+ player->CastSpell(player, SPELL_CART_SUMM, true);
+ if (Creature* car = player->GetVehicleCreatureBase())
+ {
+ if (car->GetEntry() == 28817)
+ {
+ car->AI()->SetGUID(miner->GetGUID());
+ CAST_AI(npc_scarlet_miner::npc_scarlet_minerAI, miner->AI())->InitCartQuest(player);
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+};
+
+void AddSC_the_scarlet_enclave_c1()
+{
+ // Ours
+ new npc_eye_of_acherus();
+ new spell_q12641_death_comes_from_on_high_summon_ghouls();
+ new npc_death_knight_initiate();
+ new spell_item_gift_of_the_harvester();
+ new spell_q12698_the_gift_that_keeps_on_giving();
+ new npc_scarlet_ghoul();
+ new npc_dkc1_gothik();
+ new npc_scarlet_cannon();
+
+ // Theirs
+ new npc_unworthy_initiate();
+ new npc_unworthy_initiate_anchor();
+ new go_acherus_soul_prison();
+
+ new npc_scarlet_miner();
+ new npc_scarlet_miner_cart();
+ new go_inconspicuous_mine_car();
+}