diff options
Diffstat (limited to 'src/server/scripts')
24 files changed, 1167 insertions, 224 deletions
diff --git a/src/server/scripts/Commands/cs_lfg.cpp b/src/server/scripts/Commands/cs_lfg.cpp index 747d84de9c5..d1662f3a97c 100644 --- a/src/server/scripts/Commands/cs_lfg.cpp +++ b/src/server/scripts/Commands/cs_lfg.cpp @@ -19,7 +19,9 @@ #include "Chat.h" #include "Language.h" #include "LFGMgr.h" +#include "ObjectMgr.h" #include "Group.h" +#include "GroupMgr.h" #include "Player.h" void GetPlayerInfo(ChatHandler* handler, Player* player) @@ -74,25 +76,55 @@ public: static bool HandleLfgGroupInfoCommand(ChatHandler* handler, char const* args) { - Player* target = NULL; - std::string playerName; - if (!handler->extractPlayerTarget((char*)args, &target, NULL, &playerName)) + Player* playerTarget; + ObjectGuid guidTarget; + std::string nameTarget; + + ObjectGuid parseGUID(HIGHGUID_PLAYER, uint32(atoul(args))); + + if (sObjectMgr->GetPlayerNameByGUID(parseGUID, nameTarget)) + { + playerTarget = ObjectAccessor::FindPlayer(parseGUID); + guidTarget = parseGUID; + } + else if (!handler->extractPlayerTarget((char*)args, &playerTarget, &guidTarget, &nameTarget)) return false; - Group* grp = target->GetGroup(); - if (!grp) + Group* groupTarget = NULL; + + if (playerTarget) + groupTarget = playerTarget->GetGroup(); + else + { + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_GROUP_MEMBER); + stmt->setUInt32(0, guidTarget.GetCounter()); + PreparedQueryResult resultGroup = CharacterDatabase.Query(stmt); + if (resultGroup) + groupTarget = sGroupMgr->GetGroupByDbStoreId((*resultGroup)[0].GetUInt32()); + } + if (!groupTarget) { - handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, playerName.c_str()); - return true; + handler->PSendSysMessage(LANG_LFG_NOT_IN_GROUP, nameTarget.c_str()); + handler->SetSentErrorMessage(true); + return false; } - ObjectGuid guid = grp->GetGUID(); + ObjectGuid guid = groupTarget->GetGUID(); std::string const& state = lfg::GetStateString(sLFGMgr->GetState(guid)); - handler->PSendSysMessage(LANG_LFG_GROUP_INFO, grp->isLFGGroup(), + handler->PSendSysMessage(LANG_LFG_GROUP_INFO, groupTarget->isLFGGroup(), state.c_str(), sLFGMgr->GetDungeon(guid)); - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) - GetPlayerInfo(handler, itr->GetSource()); + Group::MemberSlotList const& members = groupTarget->GetMemberSlots(); + + for (Group::MemberSlotList::const_iterator itr = members.begin(); itr != members.end(); ++itr) + { + Group::MemberSlot const& slot = *itr; + Player* p = ObjectAccessor::FindPlayer((*itr).guid); + if (p) + GetPlayerInfo(handler, p); + else + handler->PSendSysMessage("%s is offline.", slot.name.c_str()); + } return true; } diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index 4667b7c2767..54d1f314140 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -136,7 +136,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -164,17 +164,6 @@ public: if (!*args) return false; - // char* pmana = strtok((char*)args, " "); - // if (!pmana) - // return false; - - // char* pmanaMax = strtok(NULL, " "); - // if (!pmanaMax) - // return false; - - // int32 manam = atoi(pmanaMax); - // int32 mana = atoi(pmana); - int32 energy = atoi((char*)args)*10; int32 energym = atoi((char*)args)*10; @@ -185,7 +174,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -215,17 +204,6 @@ public: if (!*args) return false; - // char* pmana = strtok((char*)args, " "); - // if (!pmana) - // return false; - - // char* pmanaMax = strtok(NULL, " "); - // if (!pmanaMax) - // return false; - - // int32 manam = atoi(pmanaMax); - // int32 mana = atoi(pmana); - int32 rage = atoi((char*)args)*10; int32 ragem = atoi((char*)args)*10; @@ -236,7 +214,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -274,7 +252,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -390,7 +368,7 @@ public: else mark = atoi(pmark); - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (target == NULL) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -945,7 +923,7 @@ public: return false; } - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -986,7 +964,7 @@ public: if (!*args) return false; - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_NO_CHAR_SELECTED); @@ -1107,7 +1085,7 @@ public: if (!*args) return false; - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -1137,7 +1115,7 @@ public: if (drunklevel > 100) drunklevel = 100; - if (Player* target = handler->getSelectedPlayer()) + if (Player* target = handler->getSelectedPlayerOrSelf()) target->SetDrunkValue(drunklevel); return true; @@ -1148,7 +1126,7 @@ public: if (!*args) return false; - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -1302,7 +1280,7 @@ public: if (!*args) return false; - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { handler->SendSysMessage(LANG_PLAYER_NOT_FOUND); @@ -1324,7 +1302,7 @@ public: if (!*args) return false; - Player* target = handler->getSelectedPlayer(); + Player* target = handler->getSelectedPlayerOrSelf(); if (!target) { diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp index ec2f41cc625..cae26735568 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_archaedas.cpp @@ -41,14 +41,17 @@ enum Says enum Spells { - SPELL_GROUND_TREMOR = 6524, - SPELL_ARCHAEDAS_AWAKEN = 10347, - SPELL_BOSS_OBJECT_VISUAL = 11206, - SPELL_BOSS_AGGRO = 10340, - SPELL_SUB_BOSS_AGGRO = 11568, - SPELL_AWAKEN_VAULT_WALKER = 10258, - SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252, - SPELL_SELF_DESTRUCT = 9874 + SPELL_GROUND_TREMOR = 6524, + SPELL_ARCHAEDAS_AWAKEN = 10347, + SPELL_BOSS_OBJECT_VISUAL = 11206, + SPELL_BOSS_AGGRO = 10340, + SPELL_SUB_BOSS_AGGRO = 11568, + SPELL_AWAKEN_VAULT_WALKER = 10258, + SPELL_AWAKEN_EARTHEN_GUARDIAN = 10252, + SPELL_SELF_DESTRUCT = 9874, + SPELL_FREEZE_ANIM = 16245, + SPELL_MINION_FREEZE_ANIM = 10255 + }; class boss_archaedas : public CreatureScript @@ -96,6 +99,7 @@ class boss_archaedas : public CreatureScript me->setFaction(35); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + me->AddAura(SPELL_FREEZE_ANIM, me); } void ActivateMinion(ObjectGuid uiGuid, bool flag) @@ -109,6 +113,7 @@ class boss_archaedas : public CreatureScript minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); minion->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); minion->setFaction(14); + minion->RemoveAura(SPELL_MINION_FREEZE_ANIM); } } @@ -258,6 +263,7 @@ class npc_archaedas_minions : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); me->RemoveAllAuras(); + me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } void EnterCombat(Unit* /*who*/) override @@ -297,7 +303,7 @@ class npc_archaedas_minions : public CreatureScript { bWakingUp = false; bAmIAwake = true; - // AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID + AttackStart(ObjectAccessor::GetUnit(*me, instance->GetGuidData(0))); // whoWokeArchaedasGUID return; // dont want to continue until we finish the AttackStart method } @@ -346,6 +352,7 @@ class npc_stonekeepers : public CreatureScript me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); me->RemoveAllAuras(); + me->AddAura(SPELL_MINION_FREEZE_ANIM, me); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp b/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp index de899c04e1a..7f0faa138ec 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/boss_ironaya.cpp @@ -28,10 +28,9 @@ EndScriptData */ enum Ironaya { - SAY_AGGRO = 0, SPELL_ARCINGSMASH = 8374, SPELL_KNOCKAWAY = 10101, - SPELL_WSTOMP = 11876, + SPELL_WSTOMP = 11876 }; class boss_ironaya : public CreatureScript @@ -66,10 +65,7 @@ class boss_ironaya : public CreatureScript Initialize(); } - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); - } + void EnterCombat(Unit* /*who*/) override { } void UpdateAI(uint32 uiDiff) override { diff --git a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp index 9d33d41af62..11699d4ec43 100644 --- a/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp +++ b/src/server/scripts/EasternKingdoms/Uldaman/instance_uldaman.cpp @@ -18,12 +18,13 @@ /* ScriptData SDName: instance_uldaman -SD%Complete: 99 +SD%Complete: 80% SDComment: Need some cosmetics updates when archeadas door are closing (Guardians Waypoints). SDCategory: Uldaman EndScriptData */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" #include "InstanceScript.h" #include "uldaman.h" @@ -31,6 +32,8 @@ enum Spells { SPELL_ARCHAEDAS_AWAKEN = 10347, SPELL_AWAKEN_VAULT_WALKER = 10258, + SPELL_FREEZE_ANIM = 16245, + SPELL_MINION_FREEZE_ANIM = 10255 }; enum Events @@ -38,6 +41,13 @@ enum Events EVENT_SUB_BOSS_AGGRO = 2228 }; +enum IronayaTalk +{ + SAY_AGGRO = 0 +}; + +const Position IronayaPoint = { -231.228f, 246.6135f, -49.01617f, 0.0f }; + class instance_uldaman : public InstanceMapScript { public: @@ -136,9 +146,9 @@ class instance_uldaman : public InstanceMapScript { creature->setFaction(35); creature->RemoveAllAuras(); - //creature->RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_ANIMATION_FROZEN); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + creature->AddAura(SPELL_MINION_FREEZE_ANIM, creature); } void SetDoor(ObjectGuid guid, bool open) @@ -171,6 +181,8 @@ class instance_uldaman : public InstanceMapScript target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); target->setFaction(14); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + target->RemoveAura(SPELL_MINION_FREEZE_ANIM); + return; // only want the first one we find } // if we get this far than all four are dead so open the door @@ -190,11 +202,13 @@ class instance_uldaman : public InstanceMapScript Creature* target = instance->GetCreature(*i); if (!target || !target->IsAlive() || target->getFaction() == 14) continue; - archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true); - target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); target->setFaction(14); + target->RemoveAura(SPELL_MINION_FREEZE_ANIM); + archaedas->CastSpell(target, SPELL_AWAKEN_VAULT_WALKER, true); + target->CastSpell(target, SPELL_ARCHAEDAS_AWAKEN, true); + return; // only want the first one we find } } @@ -241,6 +255,7 @@ class instance_uldaman : public InstanceMapScript if (ObjectAccessor::GetUnit(*archaedas, target)) { + archaedas->RemoveAura(SPELL_FREEZE_ANIM); archaedas->CastSpell(archaedas, SPELL_ARCHAEDAS_AWAKEN, false); whoWokeuiArchaedasGUID = target; } @@ -255,6 +270,12 @@ class instance_uldaman : public InstanceMapScript ironaya->setFaction(415); ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); ironaya->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + + ironaya->GetMotionMaster()->Clear(); + ironaya->GetMotionMaster()->MovePoint(0, IronayaPoint); + ironaya->SetHomePosition(IronayaPoint); + + ironaya->AI()->Talk(SAY_AGGRO); } void RespawnMinions() diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp index 0311ed61c6a..ecda065fda9 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/boss_chrono_lord_epoch.cpp @@ -32,8 +32,7 @@ enum Spells SPELL_CURSE_OF_EXERTION = 52772, SPELL_TIME_WARP = 52766, //Time slows down, reducing attack, casting and movement speed by 70% for 6 sec. SPELL_TIME_STOP = 58848, //Stops time in a 50 yard sphere for 2 sec. - SPELL_WOUNDING_STRIKE = 52771, //Used only on the tank - H_SPELL_WOUNDING_STRIKE = 58830 + SPELL_WOUNDING_STRIKE = 52771 //Used only on the tank }; enum Yells @@ -45,109 +44,78 @@ enum Yells SAY_DEATH = 4 }; -class boss_epoch : public CreatureScript +enum Events { -public: - boss_epoch() : CreatureScript("boss_epoch") { } - - CreatureAI* GetAI(Creature* creature) const override - { - return GetInstanceAI<boss_epochAI>(creature); - } - - struct boss_epochAI : public ScriptedAI - { - boss_epochAI(Creature* creature) : ScriptedAI(creature) - { - Initialize(); - instance = creature->GetInstanceScript(); - } - - void Initialize() - { - uiStep = 1; - uiStepTimer = 26000; - uiCurseOfExertionTimer = 9300; - uiTimeWarpTimer = 25300; - uiTimeStopTimer = 21300; - uiWoundingStrikeTimer = 5300; - } - - uint8 uiStep; - - uint32 uiStepTimer; - uint32 uiWoundingStrikeTimer; - uint32 uiTimeWarpTimer; - uint32 uiTimeStopTimer; - uint32 uiCurseOfExertionTimer; - - InstanceScript* instance; - - void Reset() override - { - Initialize(); - - instance->SetBossState(DATA_EPOCH, NOT_STARTED); - } - - void EnterCombat(Unit* /*who*/) override - { - Talk(SAY_AGGRO); + EVENT_CURSE_OF_EXERTION = 1, + EVENT_TIME_WARP, + EVENT_TIME_STOP, + EVENT_WOUNDING_STRIKE +}; - instance->SetBossState(DATA_EPOCH, IN_PROGRESS); - } +class boss_epoch : public CreatureScript +{ + public: + boss_epoch() : CreatureScript("boss_epoch") { } - void UpdateAI(uint32 diff) override + struct boss_epochAI : public BossAI { - //Return since we have no target - if (!UpdateVictim()) - return; + boss_epochAI(Creature* creature) : BossAI(creature, DATA_EPOCH) { } - if (uiCurseOfExertionTimer < diff) + void EnterCombat(Unit* /*who*/) override { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_CURSE_OF_EXERTION); - uiCurseOfExertionTimer = 9300; - } else uiCurseOfExertionTimer -= diff; + Talk(SAY_AGGRO); + _EnterCombat(); - if (uiWoundingStrikeTimer < diff) - { - DoCastVictim(SPELL_WOUNDING_STRIKE); - uiWoundingStrikeTimer = 5300; - } else uiWoundingStrikeTimer -= diff; + events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300); + events.ScheduleEvent(EVENT_TIME_WARP, 25300); + events.ScheduleEvent(EVENT_TIME_STOP, 21300); + events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300); + } - if (uiTimeStopTimer < diff) + void ExecuteEvent(uint32 eventId) override { - DoCastAOE(SPELL_TIME_STOP); - uiTimeStopTimer = 21300; - } else uiTimeStopTimer -= diff; - - if (uiTimeWarpTimer < diff) + switch (eventId) + { + case EVENT_CURSE_OF_EXERTION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true)) + DoCast(target, SPELL_CURSE_OF_EXERTION); + events.ScheduleEvent(EVENT_CURSE_OF_EXERTION, 9300); + break; + case EVENT_TIME_WARP: + Talk(SAY_TIME_WARP); + DoCastAOE(SPELL_TIME_WARP); + events.ScheduleEvent(EVENT_TIME_WARP, 25300); + break; + case EVENT_TIME_STOP: + DoCastAOE(SPELL_TIME_STOP); + events.ScheduleEvent(EVENT_TIME_STOP, 21300); + break; + case EVENT_WOUNDING_STRIKE: + DoCastVictim(SPELL_WOUNDING_STRIKE); + events.ScheduleEvent(EVENT_WOUNDING_STRIKE, 5300); + break; + default: + break; + } + } + + void JustDied(Unit* /*killer*/) override { - Talk(SAY_TIME_WARP); - DoCastAOE(SPELL_TIME_WARP); - uiTimeWarpTimer = 25300; - } else uiTimeWarpTimer -= diff; + Talk(SAY_DEATH); + _JustDied(); + } - DoMeleeAttackIfReady(); - } - - void JustDied(Unit* /*killer*/) override - { - Talk(SAY_DEATH); - - instance->SetBossState(DATA_EPOCH, DONE); - } + void KilledUnit(Unit* victim) override + { + if (victim->GetTypeId() == TYPEID_PLAYER) + Talk(SAY_SLAY); + } + }; - void KilledUnit(Unit* victim) override + CreatureAI* GetAI(Creature* creature) const override { - if (victim->GetTypeId() != TYPEID_PLAYER) - return; - - Talk(SAY_SLAY); + return GetInstanceAI<boss_epochAI>(creature); } - }; - }; void AddSC_boss_epoch() diff --git a/src/server/scripts/Kalimdor/zone_desolace.cpp b/src/server/scripts/Kalimdor/zone_desolace.cpp index d5ff4c45d09..bb17de4fd6a 100644 --- a/src/server/scripts/Kalimdor/zone_desolace.cpp +++ b/src/server/scripts/Kalimdor/zone_desolace.cpp @@ -88,12 +88,20 @@ public: DoCast(me, SPELL_KODO_KOMBO_DESPAWN_BUFF, true); me->UpdateEntry(NPC_TAMED_KODO); + me->CombatStop(); + me->DeleteThreatList(); + me->SetSpeed(MOVE_RUN, 0.6f, true); me->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, me->GetFollowAngle()); + me->setActive(true); } } else if (spell->Id == SPELL_KODO_KOMBO_GOSSIP) { me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + me->SetHomePosition(me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetOrientation()); + me->GetMotionMaster()->Clear(); + me->GetMotionMaster()->MoveIdle(); + me->setActive(false); me->DespawnOrUnsummon(60000); } } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index 39c9fbe37a6..c56a49cb92c 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -741,7 +741,7 @@ class boss_dreadscale : public CreatureScript switch (pointId) { case 0: - instance->DoUseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); + instance->DoCloseDoorOrButton(instance->GetGuidData(GO_MAIN_GATE_DOOR)); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_AGGRESSIVE); me->SetInCombatWithZone(); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp index 6c3b2187325..9c339e596a4 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/boss_malygos.cpp @@ -128,7 +128,6 @@ enum Spells SPELL_ARCANE_BARRAGE_DAMAGE = 63934, // the actual damage - cast by affected player by script spell // Transition /II-III/ - SPELL_SUMMOM_RED_DRAGON_BUDYY = 56070, SPELL_RIDE_RED_DRAGON_BUDDY = 56071, SPELL_SUMMON_RED_DRAGON_BUDDY_F_CAST = 58846, // After implicitly hit player targets they will force cast 56070 on self SPELL_DESTROY_PLATFORM_CHANNEL = 58842, diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h index b6a0d3f9b62..d9b921b38a1 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/eye_of_eternity.h @@ -80,7 +80,8 @@ enum InstanceSpells SPELL_VORTEX_5 = 56263, // damage | used to enter to the vehicle SPELL_PORTAL_OPENED = 61236, SPELL_RIDE_RED_DRAGON_TRIGGERED = 56072, - SPELL_IRIS_OPENED = 61012 // visual when starting encounter + SPELL_IRIS_OPENED = 61012, // visual when starting encounter + SPELL_SUMMOM_RED_DRAGON_BUDDY = 56070 }; #endif diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index fffdbbc3d1b..7b884f39a41 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -39,6 +39,12 @@ public: SetBossNumber(MAX_ENCOUNTER); } + void OnPlayerEnter(Player* player) override + { + if (GetBossState(DATA_MALYGOS_EVENT) == DONE) + player->CastSpell(player, SPELL_SUMMOM_RED_DRAGON_BUDDY, true); + } + bool SetBossState(uint32 type, EncounterState state) override { if (!InstanceScript::SetBossState(type, state)) diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp index 1e2ca666378..6233c7e8953 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.cpp @@ -330,7 +330,7 @@ public: DespawnDwarf(); - instance->SetBossState(DATA_BRANN_EVENT, NOT_STARTED); + instance->SetBossState(DATA_TRIBUNAL_OF_AGES, NOT_STARTED); } } @@ -362,8 +362,10 @@ public: break; case 13: Talk(SAY_EVENT_INTRO_1); + instance->SetBossState(DATA_TRIBUNAL_OF_AGES, IN_PROGRESS); SetEscortPaused(true); JumpToNextStep(20000); + // @todo: There should be a pause here and a gossip should start the next step. break; case 17: Talk(SAY_EVENT_INTRO_2); @@ -421,9 +423,9 @@ public: Start(); } - void DamageTaken(Unit* /*done_by*/, uint32 & /*damage*/) override + void DamageTaken(Unit* /*done_by*/, uint32& /*damage*/) override { - if (brannSparklinNews) + if (instance->GetBossState(DATA_TRIBUNAL_OF_AGES) == IN_PROGRESS) brannSparklinNews = false; } @@ -442,9 +444,8 @@ public: switch (uiStep) { case 1: - if (instance->GetBossState(DATA_BRANN_EVENT) != NOT_STARTED) + if (instance->GetBossState(DATA_TRIBUNAL_OF_AGES) != NOT_STARTED) return; - instance->SetBossState(DATA_BRANN_EVENT, IN_PROGRESS); bIsBattle = false; Talk(SAY_ESCORT_START); SetRun(true); @@ -582,7 +583,7 @@ public: break; case 29: Talk(SAY_EVENT_END_02); - instance->SetBossState(DATA_BRANN_EVENT, DONE); + instance->SetBossState(DATA_TRIBUNAL_OF_AGES, DONE); me->CastSpell(me, SPELL_REWARD_ACHIEVEMENT, true); JumpToNextStep(5500); break; @@ -715,9 +716,7 @@ public: class achievement_brann_spankin_new : public AchievementCriteriaScript { public: - achievement_brann_spankin_new() : AchievementCriteriaScript("achievement_brann_spankin_new") - { - } + achievement_brann_spankin_new() : AchievementCriteriaScript("achievement_brann_spankin_new") { } bool OnCheck(Player* /*player*/, Unit* target) override { diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h index 2ed47b42bbc..df56aadfe22 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/halls_of_stone.h @@ -28,7 +28,7 @@ enum DataTypes // Encounter States/Boss GUIDs DATA_KRYSTALLUS = 0, DATA_MAIDEN_OF_GRIEF = 1, - DATA_BRANN_EVENT = 2, + DATA_TRIBUNAL_OF_AGES = 2, DATA_SJONNIR = 3, // Additional data diff --git a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp index a70d1ff3a0d..c67e31c4cc0 100644 --- a/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp +++ b/src/server/scripts/Northrend/Ulduar/HallsOfStone/instance_halls_of_stone.cpp @@ -23,8 +23,8 @@ DoorData const doorData[] = { - { GO_SJONNIR_DOOR, DATA_BRANN_EVENT, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END + { GO_SJONNIR_DOOR, DATA_TRIBUNAL_OF_AGES, DOOR_TYPE_PASSAGE, BOUNDARY_NONE }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END }; class instance_halls_of_stone : public InstanceMapScript @@ -90,7 +90,7 @@ class instance_halls_of_stone : public InstanceMapScript case GO_TRIBUNAL_CHEST: case GO_TRIBUNAL_CHEST_HERO: TribunalChestGUID = go->GetGUID(); - if (GetBossState(DATA_BRANN_EVENT) == DONE) + if (GetBossState(DATA_TRIBUNAL_OF_AGES) == DONE) go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); break; case GO_TRIBUNAL_SKY_FLOOR: @@ -156,7 +156,7 @@ class instance_halls_of_stone : public InstanceMapScript switch (type) { - case DATA_BRANN_EVENT: + case DATA_TRIBUNAL_OF_AGES: if (state == DONE) { if (GameObject* go = instance->GetGameObject(TribunalChestGUID)) @@ -178,7 +178,7 @@ class instance_halls_of_stone : public InstanceMapScript switch (bossId) { case DATA_SJONNIR: - if (GetBossState(DATA_BRANN_EVENT) != DONE) + if (GetBossState(DATA_TRIBUNAL_OF_AGES) != DONE) return false; break; default: diff --git a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp index 23b86737f4c..a04c809f893 100644 --- a/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp +++ b/src/server/scripts/Northrend/Ulduar/Ulduar/boss_flame_leviathan.cpp @@ -482,40 +482,47 @@ class boss_flame_leviathan : public CreatureScript if (action && action <= 4) // Tower destruction, debuff leviathan loot and reduce active tower count { if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2 | LOOT_MODE_HARD_MODE_3 | LOOT_MODE_HARD_MODE_4) && ActiveTowersCount == 4) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_4); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2 | LOOT_MODE_HARD_MODE_3) && ActiveTowersCount == 3) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_3); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1 | LOOT_MODE_HARD_MODE_2) && ActiveTowersCount == 2) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_2); - --ActiveTowersCount; - } + if (me->HasLootMode(LOOT_MODE_DEFAULT | LOOT_MODE_HARD_MODE_1) && ActiveTowersCount == 1) - { me->RemoveLootMode(LOOT_MODE_HARD_MODE_1); - --ActiveTowersCount; - } } switch (action) { case ACTION_TOWER_OF_STORM_DESTROYED: - towerOfStorms = false; + if (towerOfStorms) + { + towerOfStorms = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_FROST_DESTROYED: - towerOfFrost = false; + if (towerOfFrost) + { + towerOfFrost = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_FLAMES_DESTROYED: - towerOfFlames = false; + if (towerOfFlames) + { + towerOfFlames = false; + --ActiveTowersCount; + } break; case ACTION_TOWER_OF_LIFE_DESTROYED: - towerOfLife = false; + if (towerOfLife) + { + towerOfLife = false; + --ActiveTowersCount; + } break; case ACTION_START_HARD_MODE: // Activate hard-mode enable all towers, apply buffs on leviathan ActiveTowers = true; diff --git a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp index ea50969ecb8..ef9ad806c89 100644 --- a/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp +++ b/src/server/scripts/Northrend/VioletHold/instance_violet_hold.cpp @@ -794,9 +794,11 @@ public: trigger->CastSpell(trigger, spellInfoLightning, true, 0, 0, trigger->GetGUID()); // Kill all mobs registered with SetGuidData(ADD_TRASH_MOB) - for (GuidSet::const_iterator itr = trashMobs.begin(); itr != trashMobs.end(); ++itr) + for (GuidSet::const_iterator itr = trashMobs.begin(); itr != trashMobs.end();) { Creature* creature = instance->GetCreature(*itr); + // Increment the iterator before killing the creature because the kill will remove itr from trashMobs + ++itr; if (creature && creature->IsAlive()) trigger->Kill(creature); } diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 4aea36e3fe7..280a94aa21f 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1706,7 +1706,7 @@ public: break; } creature->SetStandState(UNIT_STAND_STATE_STAND); - creature->AI()->Talk(SAY_1); + creature->AI()->Talk(SAY_1, player); ENSURE_AI(npc_escortAI, (creature->AI()))->Start(true, false, player->GetGUID()); } return true; diff --git a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp index 1657b178327..d7ba0a34939 100644 --- a/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp +++ b/src/server/scripts/Outland/CoilfangReservoir/SerpentShrine/instance_serpent_shrine.cpp @@ -275,8 +275,8 @@ class instance_serpent_shrine : public InstanceMapScript if (data == DONE) { HandleGameObject(BridgePart[0], true); - HandleGameObject(BridgePart[0], true); - HandleGameObject(BridgePart[0], true); + HandleGameObject(BridgePart[1], true); + HandleGameObject(BridgePart[2], true); } break; case DATA_TRASH: diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp index fb44a403d86..dfc5f5992a6 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_nethekurse.cpp @@ -108,6 +108,7 @@ class boss_grand_warlock_nethekurse : public CreatureScript void Reset() override { + _Reset(); me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Initialize(); @@ -115,9 +116,8 @@ class boss_grand_warlock_nethekurse : public CreatureScript void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DIE); - - instance->SetBossState(DATA_NETHEKURSE, DONE); } void SetData(uint32 data, uint32 value) override diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp index 7d00cd97126..a950882eddd 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warbringer_omrogg.cpp @@ -160,6 +160,7 @@ class boss_warbringer_omrogg : public CreatureScript void Reset() override { + _Reset(); if (Unit* LeftHead = ObjectAccessor::GetUnit(*me, LeftHeadGUID)) { LeftHead->setDeathState(JUST_DIED); @@ -257,14 +258,14 @@ class boss_warbringer_omrogg : public CreatureScript Creature* LeftHead = ObjectAccessor::GetCreature(*me, LeftHeadGUID); Creature* RightHead = ObjectAccessor::GetCreature(*me, RightHeadGUID); + _JustDied(); + if (!LeftHead || !RightHead) return; LeftHead->AI()->Talk(YELL_DIE_L); RightHead->AI()->SetData(SETDATA_DATA, SETDATA_YELL); - - instance->SetBossState(DATA_OMROGG, DONE); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp index b44ae46c78c..21ed710f4d8 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/boss_warchief_kargath_bladefist.cpp @@ -35,7 +35,10 @@ enum Says { SAY_AGGRO = 0, SAY_SLAY = 1, - SAY_DEATH = 2 + SAY_DEATH = 2, + + SAY_CALL_EXECUTIONER_A = 3, + SAY_CALL_EXECUTIONER_H = 4 }; enum Spells @@ -84,10 +87,28 @@ class boss_warchief_kargath_bladefist : public CreatureScript resetcheck_timer = 5000; } + void SetData(uint32 type, uint32 data) override + { + if (type == 1) + { + switch (data) + { + case ALLIANCE: + Talk(SAY_CALL_EXECUTIONER_A); + break; + case HORDE: + Talk(SAY_CALL_EXECUTIONER_H); + break; + default: + break; + } + } + } + void Reset() override { removeAdds(); - + _Reset(); me->SetSpeed(MOVE_RUN, 2); me->SetWalk(false); @@ -96,10 +117,9 @@ class boss_warchief_kargath_bladefist : public CreatureScript void JustDied(Unit* /*killer*/) override { + _JustDied(); Talk(SAY_DEATH); removeAdds(); - - instance->SetBossState(DATA_KARGATH, DONE); } void EnterCombat(Unit* /*who*/) override diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp index c6b08bdada1..6939b15585a 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/instance_shattered_halls.cpp @@ -24,9 +24,30 @@ SDCategory: Hellfire Citadel, Shattered Halls EndScriptData */ #include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "SpellScript.h" +#include "SpellAuraEffects.h" #include "InstanceScript.h" +#include "Player.h" +#include "SpellAuras.h" #include "shattered_halls.h" +enum Spells +{ + SPELL_CLEAVE = 15284, + + SPELL_EXECUTE_1 = 39288, + SPELL_EXECUTE_2, + SPELL_EXECUTE_3 +}; + +DoorData const doorData[] = +{ + {GO_GRAND_WARLOCK_CHAMBER_DOOR_1, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_S }, + {GO_GRAND_WARLOCK_CHAMBER_DOOR_2, DATA_NETHEKURSE, DOOR_TYPE_PASSAGE, BOUNDARY_N }, + {0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE} +}; + class instance_shattered_halls : public InstanceMapScript { public: @@ -43,6 +64,43 @@ class instance_shattered_halls : public InstanceMapScript { SetHeaders(DataHeader); SetBossNumber(EncounterCount); + LoadDoorData(doorData); + executionTimer = 0; + executed = 0; + _team = 0; + } + + void OnPlayerEnter(Player* player) override + { + Aura* ex = nullptr; + + if (!_team) + _team = player->GetTeam(); + + player->RemoveAurasDueToSpell(SPELL_EXECUTE_1); + player->RemoveAurasDueToSpell(SPELL_EXECUTE_2); + player->RemoveAurasDueToSpell(SPELL_EXECUTE_3); + + if (!executionTimer || executionerGUID.IsEmpty()) + return; + + switch (executed) + { + case 0: + ex = player->AddAura(SPELL_EXECUTE_1, player); + break; + case 1: + ex = player->AddAura(SPELL_EXECUTE_2, player); + break; + case 2: + ex = player->AddAura(SPELL_EXECUTE_3, player); + break; + default: + break; + } + + if (ex) + ex->SetDuration(executionTimer); } void OnGameObjectCreate(GameObject* go) override @@ -50,21 +108,53 @@ class instance_shattered_halls : public InstanceMapScript switch (go->GetEntry()) { case GO_GRAND_WARLOCK_CHAMBER_DOOR_1: - nethekurseDoor1GUID = go->GetGUID(); + case GO_GRAND_WARLOCK_CHAMBER_DOOR_2: + AddDoor(go, true); + default: break; + } + } + + void OnGameObjectRemove(GameObject* go) override + { + switch (go->GetEntry()) + { + case GO_GRAND_WARLOCK_CHAMBER_DOOR_1: case GO_GRAND_WARLOCK_CHAMBER_DOOR_2: - nethekurseDoor2GUID = go->GetGUID(); + AddDoor(go, false); + default: break; } } void OnCreatureCreate(Creature* creature) override { + if (!_team) + { + Map::PlayerList const &players = instance->GetPlayers(); + if (!players.isEmpty()) + if (Player* player = players.begin()->GetSource()) + _team = player->GetTeam(); + } + switch (creature->GetEntry()) { case NPC_GRAND_WARLOCK_NETHEKURSE: nethekurseGUID = creature->GetGUID(); break; + case NPC_KARGATH_BLADEFIST: + kargathGUID = creature->GetGUID(); + break; + case NPC_RANDY_WHIZZLESPROCKET: + if (_team == HORDE) + creature->UpdateEntry(NPC_DRISELLA); + break; + case NPC_SHATTERED_EXECUTIONER: + executionTimer = 55 * MINUTE * IN_MILLISECONDS; + DoCastSpellOnPlayers(SPELL_EXECUTE_1); + executionerGUID = creature->GetGUID(); + SaveToDB(); + break; } } @@ -75,18 +165,20 @@ class instance_shattered_halls : public InstanceMapScript switch (type) { - case DATA_NETHEKURSE: - if (state == IN_PROGRESS) + case DATA_SHATTERED_EXECUTIONER: + if (state == DONE) { - HandleGameObject(nethekurseDoor1GUID, false); - HandleGameObject(nethekurseDoor2GUID, false); - } - else - { - HandleGameObject(nethekurseDoor1GUID, true); - HandleGameObject(nethekurseDoor2GUID, true); + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1); + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2); + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_3); + executionTimer = 0; + SaveToDB(); } break; + case DATA_KARGATH: + if (Creature* executioner = instance->GetCreature(executionerGUID)) + executioner->AI()->Reset(); + break; case DATA_OMROGG: break; } @@ -100,24 +192,305 @@ class instance_shattered_halls : public InstanceMapScript case NPC_GRAND_WARLOCK_NETHEKURSE: return nethekurseGUID; break; - case GO_GRAND_WARLOCK_CHAMBER_DOOR_1: - return nethekurseDoor1GUID; + case NPC_KARGATH_BLADEFIST: + return kargathGUID; break; - case GO_GRAND_WARLOCK_CHAMBER_DOOR_2: - return nethekurseDoor2GUID; + case NPC_SHATTERED_EXECUTIONER: + return executionerGUID; + break; + default: + return ObjectGuid::Empty; + break; + } + } + + void WriteSaveDataMore(std::ostringstream& data) override + { + if (!instance->IsHeroic()) + return; + + data << uint32(executed) << ' ' + << executionTimer << ' '; + } + + void ReadSaveDataMore(std::istringstream& data) override + { + if (!instance->IsHeroic()) + return; + + uint32 readbuff; + data >> readbuff; + executed = uint8(readbuff); + data >> readbuff; + + if (executed > VictimCount) + { + executed = VictimCount; + executionTimer = 0; + return; + } + + if (!readbuff) + return; + + Creature* executioner = nullptr; + + instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY()); + if (Creature* kargath = instance->GetCreature(kargathGUID)) + if (executionerGUID.IsEmpty()) + executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner); + + if (executioner) + for (uint8 i = executed; i < VictimCount; ++i) + executioner->SummonCreature(executionerVictims[i](GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos()); + + executionTimer = readbuff; + } + + uint32 GetData(uint32 type) const override + { + switch (type) + { + case DATA_PRISONERS_EXECUTED: + return executed; + break; + case DATA_TEAM_IN_INSTANCE: + return _team; + break; + default: + return 0; break; } - return ObjectGuid::Empty; + } + + void Update(uint32 diff) override + { + if (!executionTimer) + return; + + if (executionTimer <= diff) + { + switch (++executed) + { + case 1: + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_1); + DoCastSpellOnPlayers(SPELL_EXECUTE_2); + executionTimer = 10 * MINUTE * IN_MILLISECONDS; + break; + case 2: + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_2); + DoCastSpellOnPlayers(SPELL_EXECUTE_3); + executionTimer = 15 * MINUTE * IN_MILLISECONDS; + break; + default: + DoRemoveAurasDueToSpellOnPlayers(SPELL_EXECUTE_3); + executionTimer = 0; + break; + } + + if (Creature* executioner = instance->GetCreature(executionerGUID)) + executioner->AI()->SetData(1, executed); + + SaveToDB(); + } + else + executionTimer -= diff; } protected: ObjectGuid nethekurseGUID; - ObjectGuid nethekurseDoor1GUID; - ObjectGuid nethekurseDoor2GUID; + ObjectGuid kargathGUID; + ObjectGuid executionerGUID; + + uint8 executed; + uint32 executionTimer; + uint32 _team; + }; +}; + +class at_nethekurse_exit : public AreaTriggerScript +{ + public: + at_nethekurse_exit() : AreaTriggerScript("at_nethekurse_exit") { }; + + bool OnTrigger(Player* player, AreaTriggerEntry const*) override + { + if (InstanceScript* is = player->GetInstanceScript()) + { + if (is->instance->IsHeroic()) + { + Creature* executioner = nullptr; + + is->instance->LoadGrid(Executioner.GetPositionX(), Executioner.GetPositionY()); + if (Creature* kargath = ObjectAccessor::GetCreature(*player, is->GetGuidData(NPC_KARGATH_BLADEFIST))) + { + if (is->GetGuidData(NPC_SHATTERED_EXECUTIONER).IsEmpty()) + { + executioner = kargath->SummonCreature(NPC_SHATTERED_EXECUTIONER, Executioner); + kargath->AI()->SetData(1, is->GetData(DATA_TEAM_IN_INSTANCE)); + } + } + + if (executioner) + for (uint8 i = 0; i < VictimCount; ++i) + executioner->SummonCreature(executionerVictims[i](is->GetData(DATA_TEAM_IN_INSTANCE)), executionerVictims[i].GetPos()); + } + } + + return false; + } +}; + +class boss_shattered_executioner : public CreatureScript +{ + public: + boss_shattered_executioner() : CreatureScript("boss_shattered_executioner") { } + + struct boss_shattered_executionerAI : public BossAI + { + boss_shattered_executionerAI(Creature* creature) : BossAI(creature, DATA_SHATTERED_EXECUTIONER) + { + Initialize(); + }; + + void Initialize() + { + cleaveTimer = 500; + me->ResetLootMode(); + switch (instance->GetData(DATA_PRISONERS_EXECUTED)) + { + case 0: + me->AddLootMode(LOOT_MODE_HARD_MODE_3); + case 1: + me->AddLootMode(LOOT_MODE_HARD_MODE_2); + case 2: + me->AddLootMode(LOOT_MODE_HARD_MODE_1); + } + } + + void Reset() override + { + _Reset(); + if (instance->GetBossState(DATA_KARGATH) == DONE) + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + else + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); + + Initialize(); + } + + void JustSummoned(Creature*) override { } + + void JustDied(Unit*) override + { + _JustDied(); + Map::PlayerList const &players = instance->instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + Player* pl = itr->GetSource(); + uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; + if (pl->GetQuestStatus(qId) != QUEST_STATUS_NONE && pl->GetQuestStatus(qId) != QUEST_STATUS_FAILED) + pl->CompleteQuest(qId); + } + } + + void SetData(uint32 type, uint32 data) override + { + if (type == 1) + { + uint32 entry = executionerVictims[data - 1](instance->GetData(DATA_TEAM_IN_INSTANCE)); + if (Creature* victim = me->FindNearestCreature(entry, 30.0f, true)) + me->Kill(victim); + + if (data == 1) + { + Map::PlayerList const &players = instance->instance->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { + Player* pl = itr->GetSource(); + uint32 qId = pl->GetTeam() == ALLIANCE ? QUEST_IMPRISONED_A : QUEST_IMPRISONED_H; + if (pl->GetQuestStatus(qId) == QUEST_STATUS_INCOMPLETE) + pl->FailQuest(qId); + } + } + + switch (data) + { + case 3: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_1); + case 2: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_2); + case 1: + me->RemoveLootMode(LOOT_MODE_HARD_MODE_3); + default: + break; + } + } + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + if (cleaveTimer <= diff) + { + DoCast(SPELL_CLEAVE); + cleaveTimer = urand(5000, 7000); + } + else + cleaveTimer -= diff; + + DoMeleeAttackIfReady(); + } + private: + uint32 cleaveTimer; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return GetInstanceAI<boss_shattered_executionerAI>(creature); + } +}; + +class spell_kargath_executioner : public SpellScriptLoader +{ + public: + spell_kargath_executioner() : SpellScriptLoader("spell_kargath_executioner") { } + + class spell_kargath_executioner_AuraScript : public AuraScript + { + PrepareAuraScript(spell_kargath_executioner_AuraScript); + + bool AreaCheck(Unit* target) + { + if (target->GetMap()->GetId() != 540) + return false; + + return true; + } + + bool Load() override + { + return GetCaster()->GetTypeId() == TYPEID_PLAYER; + } + + void Register() override + { + DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_kargath_executioner_AuraScript::AreaCheck); + } }; + + AuraScript* GetAuraScript() const override + { + return new spell_kargath_executioner_AuraScript(); + } }; void AddSC_instance_shattered_halls() { new instance_shattered_halls(); + new at_nethekurse_exit(); + new boss_shattered_executioner(); + new spell_kargath_executioner(); } diff --git a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h index 90cbbe2a438..adc07bec2ff 100644 --- a/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h +++ b/src/server/scripts/Outland/HellfireCitadel/ShatteredHalls/shattered_halls.h @@ -21,18 +21,41 @@ #define DataHeader "SH" -uint32 const EncounterCount = 3; +uint32 const EncounterCount = 4; +uint32 const VictimCount = 3; enum DataTypes { - DATA_NETHEKURSE = 1, - DATA_OMROGG = 2, - DATA_KARGATH = 3 + DATA_NETHEKURSE = 0, + DATA_OMROGG = 1, + DATA_KARGATH = 2, + + DATA_SHATTERED_EXECUTIONER = 3, + DATA_PRISONERS_EXECUTED = 4, + + DATA_TEAM_IN_INSTANCE = 5 }; enum CreatureIds { - NPC_GRAND_WARLOCK_NETHEKURSE = 16807 + NPC_GRAND_WARLOCK_NETHEKURSE = 16807, + NPC_KARGATH_BLADEFIST = 16808, + + NPC_SHATTERED_EXECUTIONER = 17301, + + // Alliance Ids + NPC_RANDY_WHIZZLESPROCKET = 17288, + + NPC_CAPTAIN_ALINA = 17290, + NPC_ALLIANCE_VICTIM_1 = 17289, + NPC_ALLIANCE_VICTIM_2 = 17292, + + // Horde Ids + NPC_DRISELLA = 17294, + + NPC_CAPTAIN_BONESHATTER = 17296, + NPC_HORDE_VICTIM_1 = 17295, + NPC_HORDE_VICTIM_2 = 17297 }; enum GameobjectIds @@ -41,4 +64,33 @@ enum GameobjectIds GO_GRAND_WARLOCK_CHAMBER_DOOR_2 = 182540 }; +enum QuestIds +{ + QUEST_IMPRISONED_A = 9524, + QUEST_IMPRISONED_H = 9525 +}; + +const Position Executioner = { 152.8524f, -83.63912f, 2.021005f, 0.06981317f }; + +struct FactionSpawnerHelper +{ + FactionSpawnerHelper(uint32 allianceEntry, uint32 hordeEntry, const Position& pos) : _allianceNPC(allianceEntry), _hordeNPC(hordeEntry), _spawnPos(pos) { } + + inline uint32 operator()(uint32 teamID) const { return teamID == ALLIANCE ? _allianceNPC : _hordeNPC; } + inline const Position GetPos() const { return _spawnPos; } + +private: + const uint32 _allianceNPC; + const uint32 _hordeNPC; + const Position _spawnPos; +}; + +const FactionSpawnerHelper executionerVictims[VictimCount] = +{ + { NPC_CAPTAIN_ALINA, NPC_CAPTAIN_BONESHATTER, { 138.8807f, -84.22707f, 1.992269f, 0.06981317f } }, + { NPC_ALLIANCE_VICTIM_1, NPC_HORDE_VICTIM_1, { 151.2411f, -91.02930f, 2.019741f, 1.57079600f } }, + { NPC_ALLIANCE_VICTIM_2, NPC_HORDE_VICTIM_2, { 151.0459f, -77.51981f, 2.021008f, 4.74729500f } } +}; + + #endif diff --git a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp index 2a568a84a7c..471c776d54b 100644 --- a/src/server/scripts/Outland/zone_hellfire_peninsula.cpp +++ b/src/server/scripts/Outland/zone_hellfire_peninsula.cpp @@ -420,10 +420,483 @@ public: } }; +enum ExorcismSpells +{ + SPELL_JULES_GOES_PRONE = 39283, + SPELL_JULES_THREATENS_AURA = 39284, + SPELL_JULES_GOES_UPRIGHT = 39294, + SPELL_JULES_VOMITS_AURA = 39295, + + SPELL_BARADAS_COMMAND = 39277, + SPELL_BARADA_FALTERS = 39278, +}; + +enum ExorcismTexts +{ + SAY_BARADA_1 = 0, + SAY_BARADA_2 = 1, + SAY_BARADA_3 = 2, + SAY_BARADA_4 = 3, + SAY_BARADA_5 = 4, + SAY_BARADA_6 = 5, + SAY_BARADA_7 = 6, + SAY_BARADA_8 = 7, + + SAY_JULES_1 = 0, + SAY_JULES_2 = 1, + SAY_JULES_3 = 2, + SAY_JULES_4 = 3, + SAY_JULES_5 = 4, +}; + +Position const exorcismPos[11] = +{ + { -707.123f, 2751.686f, 101.592f, 4.577416f }, //Barada Waypoint-1 0 + { -710.731f, 2749.075f, 101.592f, 1.513286f }, //Barada Cast position 1 + { -710.332f, 2754.394f, 102.948f, 3.207566f }, //Jules 2 + { -714.261f, 2747.754f, 103.391f, 0.0f }, //Jules Waypoint-1 3 + { -713.113f, 2750.194f, 103.391f, 0.0f }, //Jules Waypoint-2 4 + { -710.385f, 2750.896f, 103.391f, 0.0f }, //Jules Waypoint-3 5 + { -708.309f, 2750.062f, 103.391f, 0.0f }, //Jules Waypoint-4 6 + { -707.401f, 2747.696f, 103.391f, 0.0f }, //Jules Waypoint-5 7 + { -708.591f, 2745.266f, 103.391f, 0.0f }, //Jules Waypoint-6 8 + { -710.597f, 2744.035f, 103.391f, 0.0f }, //Jules Waypoint-7 9 + { -713.089f, 2745.302f, 103.391f, 0.0f }, //Jules Waypoint-8 10 +}; + +enum ExorcismMisc +{ + NPC_DARKNESS_RELEASED = 22507, + NPC_FOUL_PURGE = 22506, + NPC_COLONEL_JULES = 22432, + + BARADAS_GOSSIP_MESSAGE = 10683, + + QUEST_THE_EXORCISM_OF_COLONEL_JULES = 10935, + + ACTION_START_EVENT = 1, + ACTION_JULES_HOVER = 2, + ACTION_JULES_FLIGHT = 3, + ACTION_JULES_MOVE_HOME = 4, +}; + +enum ExorcismEvents +{ + EVENT_BARADAS_TALK = 1, + + //Colonel Jules + EVENT_SUMMON_SKULL = 1, +}; + +/*###### +## npc_barada +######*/ + +class npc_barada : public CreatureScript +{ +public: + npc_barada() : CreatureScript("npc_barada") { } + + struct npc_baradaAI : public ScriptedAI + { + npc_baradaAI(Creature* creature) : ScriptedAI(creature) + { + Initialize(); + } + + void Initialize() + { + step = 0; + } + + void Reset() override + { + events.Reset(); + Initialize(); + + playerGUID.Clear(); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + } + + void sGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override + { + player->PlayerTalkClass->ClearMenus(); + switch (gossipListId) + { + case 1: + player->PlayerTalkClass->SendCloseGossip(); + me->AI()->Talk(SAY_BARADA_1); + me->AI()->DoAction(ACTION_START_EVENT); + break; + default: + break; + } + } + + void DoAction(int32 action) override + { + if (action == ACTION_START_EVENT) + { + if (Creature* jules = me->FindNearestCreature(NPC_COLONEL_JULES, 20.0f, true)) + { + julesGUID = jules->GetGUID(); + jules->AI()->Talk(SAY_JULES_1); + } + + me->GetMotionMaster()->MovePoint(0, exorcismPos[1]); + Talk(SAY_BARADA_2); + + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + } + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; + + if (id == 0) + me->GetMotionMaster()->MovePoint(1, exorcismPos[1]); + + if (id == 1) + events.ScheduleEvent(EVENT_BARADAS_TALK, 2000); + } + + void JustDied(Unit* /*killer*/) override + { + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + { + jules->AI()->DoAction(ACTION_JULES_MOVE_HOME); + jules->RemoveAllAuras(); + } + } + + void UpdateAI(uint32 diff) override + { + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_BARADAS_TALK: + switch (step) + { + case 0: + me->SetFacingTo(1.513286f); + + me->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL); + events.ScheduleEvent(EVENT_BARADAS_TALK, 3000); + step++; + break; + case 1: + DoCast(SPELL_BARADAS_COMMAND); + events.ScheduleEvent(EVENT_BARADAS_TALK, 5000); + step++; + break; + case 2: + Talk(SAY_BARADA_3); + events.ScheduleEvent(EVENT_BARADAS_TALK, 7000); + step++; + break; + case 3: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_2); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 18000); + step++; + break; + case 4: + DoCast(SPELL_BARADA_FALTERS); + me->HandleEmoteCommand(EMOTE_STAND_STATE_NONE); + + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->DoAction(ACTION_JULES_HOVER); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 11000); + step++; + break; + case 5: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 13000); + step++; + break; + case 6: + Talk(SAY_BARADA_4); + events.ScheduleEvent(EVENT_BARADAS_TALK, 5000); + step++; + break; + case 7: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 13000); + step++; + break; + case 8: + Talk(SAY_BARADA_4); + events.ScheduleEvent(EVENT_BARADAS_TALK, 12000); + step++; + break; + case 9: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 12000); + step++; + break; + case 10: + Talk(SAY_BARADA_4); + events.ScheduleEvent(EVENT_BARADAS_TALK, 5000); + step++; + break; + case 11: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->DoAction(ACTION_JULES_FLIGHT); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 12: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 8000); + step++; + break; + case 13: + Talk(SAY_BARADA_5); + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 14: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_4); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 15: + Talk(SAY_BARADA_6); + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 16: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_5); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 17: + Talk(SAY_BARADA_7); + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 18: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->AI()->Talk(SAY_JULES_3); + + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 19: + Talk(SAY_BARADA_7); + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 20: + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + { + jules->AI()->DoAction(ACTION_JULES_MOVE_HOME); + jules->RemoveAura(SPELL_JULES_VOMITS_AURA); + } + + events.ScheduleEvent(EVENT_BARADAS_TALK, 10000); + step++; + break; + case 21: + //End + if (Player* player = ObjectAccessor::FindPlayer(playerGUID)) + player->KilledMonsterCredit(NPC_COLONEL_JULES, ObjectGuid::Empty); + + if (Creature* jules = ObjectAccessor::GetCreature(*me, julesGUID)) + jules->RemoveAllAuras(); + + me->RemoveAura(SPELL_BARADAS_COMMAND); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED); + + Talk(SAY_BARADA_8); + me->GetMotionMaster()->MoveTargetedHome(); + EnterEvadeMode(); + break; + } + break; + } + } + } + + private: + EventMap events; + uint8 step; + ObjectGuid julesGUID; + ObjectGuid playerGUID; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_baradaAI(creature); + } +}; + +/*###### +## npc_colonel_jules +######*/ + +class npc_colonel_jules : public CreatureScript +{ +public: + npc_colonel_jules() : CreatureScript("npc_colonel_jules") { } + + struct npc_colonel_julesAI : public ScriptedAI + { + npc_colonel_julesAI(Creature* creature) : ScriptedAI(creature), summons(me) + { + Initialize(); + } + + void Initialize() + { + circleRounds = 0; + point = 0; + } + + void Reset() override + { + events.Reset(); + + summons.DespawnAll(); + circleRounds = 0; + point = 3; + wpreached = false; + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_JULES_HOVER: + me->AddAura(SPELL_JULES_GOES_PRONE, me); + me->AddAura(SPELL_JULES_THREATENS_AURA, me); + + me->SetCanFly(true); + me->SetSpeed(MOVE_RUN, 0.2f); + + me->SetFacingTo(3.207566f); + me->GetMotionMaster()->MoveJump(exorcismPos[2], 2.0f, 2.0f); + + events.ScheduleEvent(EVENT_SUMMON_SKULL, 10000); + break; + case ACTION_JULES_FLIGHT: + circleRounds++; + + me->RemoveAura(SPELL_JULES_GOES_PRONE); + + me->AddAura(SPELL_JULES_GOES_UPRIGHT, me); + me->AddAura(SPELL_JULES_VOMITS_AURA, me); + + wpreached = true; + me->GetMotionMaster()->MovePoint(point, exorcismPos[point]); + break; + case ACTION_JULES_MOVE_HOME: + wpreached = false; + me->SetSpeed(MOVE_RUN, 1.0f); + me->GetMotionMaster()->MovePoint(11, exorcismPos[2]); + + events.CancelEvent(EVENT_SUMMON_SKULL); + break; + } + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + summon->GetMotionMaster()->MoveRandom(10.0f); + } + + void MovementInform(uint32 type, uint32 id) override + { + if (type != POINT_MOTION_TYPE) + return; + + if (id < 10) + wpreached = true; + + if (id == 8) + { + for (uint8 i = 0; i < circleRounds; i++) + DoSummon(NPC_FOUL_PURGE, exorcismPos[8]); + } + + if (id == 10) + { + wpreached = true; + point = 3; + circleRounds++; + } + } + + void UpdateAI(uint32 diff) override + { + if (wpreached) + { + me->GetMotionMaster()->MovePoint(point, exorcismPos[point]); + point++; + wpreached = false; + } + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_SUMMON_SKULL: + uint8 summonCount = urand(1,3); + + for (uint8 i = 0; i < summonCount; i++) + me->SummonCreature(NPC_DARKNESS_RELEASED, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + 1.5f, 0, TEMPSUMMON_MANUAL_DESPAWN); + + events.ScheduleEvent(EVENT_SUMMON_SKULL, urand(10000, 15000)); + break; + } + } + } + + private: + EventMap events; + SummonList summons; + + uint8 circleRounds; + uint8 point; + + bool wpreached; + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_colonel_julesAI(creature); + } +}; + void AddSC_hellfire_peninsula() { new npc_aeranas(); new npc_ancestral_wolf(); new npc_wounded_blood_elf(); new npc_fel_guard_hound(); + new npc_barada(); + new npc_colonel_jules(); } |
