diff --git a/data/sql/updates/pending_db_world/rev_1666118683155607500.sql b/data/sql/updates/pending_db_world/rev_1666118683155607500.sql new file mode 100644 index 000000000..185e0659d --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1666118683155607500.sql @@ -0,0 +1,23 @@ +-- Headless Horseman +DELETE FROM `creature_text` WHERE `CreatureID`=23682; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23682, 0, 0, 'It is over, your search is done. Let fate choose now, the righteous one.', 14, 0, 100, 0, 0, 11961, 22261, 0, 'Headless Horseman - TALK_ENTRANCE'), +(23682, 1, 0, 'Here\'s my body, fit and pure! Now, your blackened souls I\'ll cure!', 14, 0, 100, 0, 0, 12567, 22271, 0, 'Headless Horseman - TALK_REJOINED'), +(23682, 2, 0, 'Harken, cur! Tis you I spurn! Now feel... the burn!', 12, 0, 100, 0, 0, 0, 22587, 0, 'Headless Horseman - TALK_CONFLAGRATION'), +(23682, 3, 0, 'Soldiers arise, stand and fight! Bring victory at last to this fallen knight!', 14, 0, 100, 0, 0, 11963, 23861, 0, 'Headless Horseman - TALK_SPROUTING_PUMPKINS'), +(23682, 4, 0, 'This end have I reached before. What new adventure lies in store?', 14, 0, 100, 0, 0, 11964, 23455, 0, 'Headless Horseman - TALK_DEATH'), +(23682, 5, 0, 'Your body lies beaten, battered and broken! Let my curse be your own, fate has spoken!', 14, 0, 100, 0, 0, 11962, 40546, 0, 'Headless Horseman - TALK_PLAYER_DEATH'); + +-- Head of the Horseman +DELETE FROM `creature_text` WHERE `CreatureID`=23775; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES +(23775, 0, 0, '% laughs.', 16, 0, 100, 0, 0, 11965, 37127, 0, 'Head of the Horseman - TALK_LAUGH'), +(23775, 0, 1, '% laughs.', 16, 0, 100, 0, 0, 11975, 37127, 0, 'Head of the Horseman - TALK_LAUGH'), +(23775, 0, 2, '% laughs.', 16, 0, 100, 0, 0, 11976, 37127, 0, 'Head of the Horseman - TALK_LAUGH'), +(23775, 1, 0, 'Get over here, you idiot!', 12, 0, 100, 0, 0, 0, 22415, 0, 'Head of the Horseman - TALK_LOST_HEAD'); + +-- Add ScriptName to Pumpkin Shrine +UPDATE `gameobject_template` SET `ScriptName`='go_pumpkin_shrine' WHERE `entry`=186267; + +-- Remove quest Call the Headless Horseman from Pumpkin Shrine +DELETE FROM `gameobject_queststarter` WHERE `id`=186267 AND `quest`=11405; diff --git a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp index 315eecb88..d0024de85 100644 --- a/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp +++ b/src/server/scripts/EasternKingdoms/ScarletMonastery/instance_scarlet_monastery.cpp @@ -155,6 +155,9 @@ public: if (data == SPECIAL) encounter = SPECIAL; break; + case DATA_HORSEMAN_EVENT: + encounter = data; + break; } } @@ -177,6 +180,8 @@ public: { if (type == TYPE_MOGRAINE_AND_WHITE_EVENT) return encounter; + else if (type == DATA_HORSEMAN_EVENT) + return encounter; return 0; } private: diff --git a/src/server/scripts/Events/hallows_end.cpp b/src/server/scripts/Events/hallows_end.cpp index 65b569c32..412d71231 100644 --- a/src/server/scripts/Events/hallows_end.cpp +++ b/src/server/scripts/Events/hallows_end.cpp @@ -24,6 +24,7 @@ #include "PassiveAI.h" #include "ScriptMgr.h" #include "ScriptedCreature.h" +#include "ScriptedGossip.h" #include "SpellAuraEffects.h" #include "SpellScript.h" #include "TaskScheduler.h" @@ -981,14 +982,29 @@ enum headlessHorseman EVENT_HORSEMAN_CONFLAGRATION = 5, EVENT_SUMMON_PUMPKIN = 6, EVENT_HORSEMAN_FOLLOW = 7, + + // Headless Horseman + TALK_ENTRANCE = 0, + TALK_REJOINED = 1, + TALK_CONFLAGRATION = 2, + TALK_SPROUTING_PUMPKINS = 3, + TALK_DEATH = 4, + TALK_PLAYER_DEATH = 5, + + // Head of the Horseman + TALK_LAUGH = 0, + TALK_LOST_HEAD = 1, + + // Player + TALK_PLAYER_RISE = 22695, + TALK_PLAYER_TIME_IS_NIGH = 22696, + TALK_PLAYER_FELT_DEATH = 22720, + TALK_PLAYER_KNOW_DEMISE = 22721, }; -enum hhSounds +enum hhMisc { - SOUND_AGGRO = 11961, - SOUND_SLAY = 11962, - SOUND_SPROUT = 11963, - SOUND_DEATH = 11964, + DATA_HORSEMAN_EVENT = 5, }; struct boss_headless_horseman : public ScriptedAI @@ -1006,8 +1022,7 @@ struct boss_headless_horseman : public ScriptedAI void JustDied(Unit* /*killer*/) override { summons.DespawnAll(); - me->Say("This end have I reached before. What new adventure lies in store?", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_DEATH); + Talk(TALK_DEATH); std::list unitList; me->GetCreaturesWithEntryInRange(unitList, 100.0f, NPC_PUMPKIN_FIEND); for (std::list::iterator itr = unitList.begin(); itr != unitList.end(); ++itr) @@ -1016,12 +1031,14 @@ struct boss_headless_horseman : public ScriptedAI Map::PlayerList const& players = me->GetMap()->GetPlayers(); if (!players.IsEmpty() && players.begin()->GetSource() && players.begin()->GetSource()->GetGroup()) sLFGMgr->FinishDungeon(players.begin()->GetSource()->GetGroup()->GetGUID(), lfg::LFG_DUNGEON_HEADLESS_HORSEMAN, me->FindMap()); + + if (InstanceScript* instance = me->GetInstanceScript()) + instance->SetData(DATA_HORSEMAN_EVENT, DONE); } void KilledUnit(Unit* /*who*/) override { - me->Yell("Your body lies beaten, battered and broken. Let my curse be your own, fate has spoken.", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SLAY); + Talk(TALK_PLAYER_DEATH); } void DoAction(int32 param) override @@ -1052,7 +1069,7 @@ struct boss_headless_horseman : public ScriptedAI events.CancelEvent(EVENT_HORSEMAN_WHIRLWIND); events.CancelEvent(EVENT_HORSEMAN_CONFLAGRATION); events.CancelEvent(EVENT_SUMMON_PUMPKIN); - me->Yell("Here's my body, fit and pure! Now, your blackened souls I'll cure!", LANG_UNIVERSAL); + Talk(TALK_REJOINED); if (phase == 1) events.ScheduleEvent(EVENT_HORSEMAN_CONFLAGRATION, 6s); @@ -1131,6 +1148,14 @@ struct boss_headless_horseman : public ScriptedAI me->SetSpeed(MOVE_WALK, 5.0f, true); } + void JustReachedHome() override + { + if (InstanceScript* instance = me->GetInstanceScript()) + instance->SetData(DATA_HORSEMAN_EVENT, FAIL); + + me->DespawnOrUnsummon(); + } + void UpdateAI(uint32 diff) override { events.Update(diff); @@ -1152,23 +1177,22 @@ struct boss_headless_horseman : public ScriptedAI switch (talkCount) { case 1: - player->Say("Horseman rise...", LANG_UNIVERSAL); + player->Say(TALK_PLAYER_RISE); break; case 2: - player->Say("Your time is nigh...", LANG_UNIVERSAL); + player->Say(TALK_PLAYER_TIME_IS_NIGH); if (Creature* trigger = me->SummonTrigger(1765.28f, 1347.46f, 17.5514f, 0.0f, 15 * IN_MILLISECONDS)) trigger->CastSpell(trigger, SPELL_EARTH_EXPLOSION, true); break; case 3: me->GetMotionMaster()->MovePath(236820, false); me->CastSpell(me, SPELL_SHAKE_CAMERA_SMALL, true); - player->Say("You felt death once...", LANG_UNIVERSAL); - me->Say("It is over, your search is done. Let fate choose now, the righteous one.", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_AGGRO); + player->Say(TALK_PLAYER_FELT_DEATH); + Talk(TALK_ENTRANCE); break; case 4: me->CastSpell(me, SPELL_SHAKE_CAMERA_MEDIUM, true); - player->Say("Now, know demise!", LANG_UNIVERSAL); + player->Say(TALK_PLAYER_KNOW_DEMISE); talkCount = 0; return; // pop and return, skip repeat } @@ -1220,7 +1244,7 @@ struct boss_headless_horseman : public ScriptedAI { me->CastSpell(target, SPELL_HORSEMAN_CONFLAGRATION, false); target->CastSpell(target, SPELL_HORSEMAN_CONFLAGRATION_SOUND, true); - me->Say("Harken, cur! Tis you I spurn! Now feel... the burn!", LANG_UNIVERSAL, target); + Talk(TALK_CONFLAGRATION); } events.RepeatEvent(12500); @@ -1236,8 +1260,7 @@ struct boss_headless_horseman : public ScriptedAI } else { - me->Say("Soldiers arise, stand and fight! Bring victory at last to this fallen knight!", LANG_UNIVERSAL); - me->PlayDirectSound(SOUND_SPROUT); + Talk(TALK_SPROUTING_PUMPKINS); events.RepeatEvent(15000); talkCount = 0; } @@ -1334,6 +1357,8 @@ struct boss_headless_horseman_head : public ScriptedAI me->CastSpell(me, SPELL_THROW_HEAD_BACK, true); if (Unit* owner = GetOwner()) owner->RemoveAura(SPELL_HORSEMAN_IMMUNITY); + + Talk(TALK_LOST_HEAD); } } @@ -1351,20 +1376,8 @@ struct boss_headless_horseman_head : public ScriptedAI if (timer >= 30000) { timer = urand(0, 15000); - uint32 sound = 11965; - switch (urand(0, 2)) - { - case 1: - sound = 11975; - break; - case 2: - sound = 11976; - break; - } - me->CastSpell(me, SPELL_HORSEMAN_SPEAKS, true); - me->TextEmote("Headless Horseman laughs"); - me->PlayDirectSound(sound); + Talk(TALK_LAUGH); } } }; @@ -1450,6 +1463,33 @@ public: } }; +class go_pumpkin_shrine : public GameObjectScript +{ +public: + go_pumpkin_shrine() : GameObjectScript("go_pumpkin_shrine") {} + + bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 /*action*/) override + { + CloseGossipMenuFor(player); + + if (InstanceScript* instance = go->GetInstanceScript()) + { + if (instance->GetData(DATA_HORSEMAN_EVENT) == IN_PROGRESS || instance->GetData(DATA_HORSEMAN_EVENT) == DONE) + return true; + + if (player->FindNearestCreature(NPC_HEADLESS_HORSEMAN_MOUNTED, 100.0f)) + return true; + + if (Creature* horseman = go->SummonCreature(NPC_HEADLESS_HORSEMAN_MOUNTED, 1754.00f, 1346.00f, 17.50f, 0.0f, TEMPSUMMON_MANUAL_DESPAWN, 0)) + horseman->CastSpell(player, SPELL_SUMMONING_RHYME_TARGET, true); + + instance->SetData(DATA_HORSEMAN_EVENT, IN_PROGRESS); + } + + return true; + } +}; + void AddSC_event_hallows_end_scripts() { // Spells @@ -1475,6 +1515,7 @@ void AddSC_event_hallows_end_scripts() // Headless Horseman new go_loosely_turned_soil(); + new go_pumpkin_shrine(); RegisterCreatureAI(boss_headless_horseman); RegisterCreatureAI(boss_headless_horseman_head); RegisterCreatureAI(boss_headless_horseman_pumpkin);