/* * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information * * 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 . */ /* ContentData go_ethereum_prison go_ethereum_stasis go_southfury_moonstone go_resonite_cask go_tablet_of_the_seven go_tele_to_dalaran_crystal go_tele_to_violet_stand go_soulwell go_amberpine_outhouse go_veil_skith_cage go_bells EndContentData */ #include "ScriptMgr.h" #include "DB2Structure.h" #include "GameEventMgr.h" #include "GameObject.h" #include "GameObjectAI.h" #include "GameTime.h" #include "Log.h" #include "MotionMaster.h" #include "Player.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "TemporarySummon.h" #include "WorldSession.h" /*###### ## go_gilded_brazier (Paladin First Trail quest (9678)) ######*/ enum GildedBrazier { NPC_STILLBLADE = 17716, QUEST_THE_FIRST_TRIAL = 9678 }; class go_gilded_brazier : public GameObjectScript { public: go_gilded_brazier() : GameObjectScript("go_gilded_brazier") { } struct go_gilded_brazierAI : public GameObjectAI { go_gilded_brazierAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { if (me->GetGoType() == GAMEOBJECT_TYPE_GOOBER) { if (player->GetQuestStatus(QUEST_THE_FIRST_TRIAL) == QUEST_STATUS_INCOMPLETE) { if (Creature* Stillblade = player->SummonCreature(NPC_STILLBLADE, 8106.11f, -7542.06f, 151.775f, 3.02598f, TEMPSUMMON_DEAD_DESPAWN, 1min)) Stillblade->AI()->AttackStart(player); } } return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_gilded_brazierAI(go); } }; /*###### ## go_tablet_of_the_seven ######*/ class go_tablet_of_the_seven : public GameObjectScript { public: go_tablet_of_the_seven() : GameObjectScript("go_tablet_of_the_seven") { } struct go_tablet_of_the_sevenAI : public GameObjectAI { go_tablet_of_the_sevenAI(GameObject* go) : GameObjectAI(go) { } /// @todo use gossip option ("Transcript the Tablet") instead, if Trinity adds support. bool OnGossipHello(Player* player) override { if (me->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) return true; if (player->GetQuestStatus(4296) == QUEST_STATUS_INCOMPLETE) player->CastSpell(player, 15065, false); return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_tablet_of_the_sevenAI(go); } }; /*###### ## go_ethereum_prison ######*/ enum EthereumPrison { SPELL_REP_LC = 39456, SPELL_REP_SHAT = 39457, SPELL_REP_CE = 39460, SPELL_REP_CON = 39474, SPELL_REP_KT = 39475, SPELL_REP_SPOR = 39476 }; const uint32 NpcPrisonEntry[] = { 22810, 22811, 22812, 22813, 22814, 22815, //good guys 20783, 20784, 20785, 20786, 20788, 20789, 20790 //bad guys }; class go_ethereum_prison : public GameObjectScript { public: go_ethereum_prison() : GameObjectScript("go_ethereum_prison") { } struct go_ethereum_prisonAI : public GameObjectAI { go_ethereum_prisonAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { me->UseDoorOrButton(); int Random = rand32() % (sizeof(NpcPrisonEntry) / sizeof(uint32)); if (Creature* creature = player->SummonCreature(NpcPrisonEntry[Random], me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetAbsoluteAngle(player), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s)) { if (!creature->IsHostileTo(player)) { if (FactionTemplateEntry const* pFaction = creature->GetFactionTemplateEntry()) { uint32 Spell = 0; switch (pFaction->Faction) { case 1011: Spell = SPELL_REP_LC; break; case 935: Spell = SPELL_REP_SHAT; break; case 942: Spell = SPELL_REP_CE; break; case 933: Spell = SPELL_REP_CON; break; case 989: Spell = SPELL_REP_KT; break; case 970: Spell = SPELL_REP_SPOR; break; } if (Spell) creature->CastSpell(player, Spell, false); else TC_LOG_ERROR("scripts", "go_ethereum_prison summoned Creature (entry {}) but faction ({}) are not expected by script.", creature->GetEntry(), creature->GetFaction()); } } } return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_ethereum_prisonAI(go); } }; /*###### ## go_ethereum_stasis ######*/ const uint32 NpcStasisEntry[] = { 22825, 20888, 22827, 22826, 22828 }; class go_ethereum_stasis : public GameObjectScript { public: go_ethereum_stasis() : GameObjectScript("go_ethereum_stasis") { } struct go_ethereum_stasisAI : public GameObjectAI { go_ethereum_stasisAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { me->UseDoorOrButton(); int Random = rand32() % (sizeof(NpcStasisEntry) / sizeof(uint32)); player->SummonCreature(NpcStasisEntry[Random], me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), me->GetAbsoluteAngle(player), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s); return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_ethereum_stasisAI(go); } }; /*###### ## go_resonite_cask ######*/ enum ResoniteCask { NPC_GOGGEROC = 11920 }; class go_resonite_cask : public GameObjectScript { public: go_resonite_cask() : GameObjectScript("go_resonite_cask") { } struct go_resonite_caskAI : public GameObjectAI { go_resonite_caskAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* /*player*/) override { if (me->GetGoType() == GAMEOBJECT_TYPE_GOOBER) me->SummonCreature(NPC_GOGGEROC, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5min); return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_resonite_caskAI(go); } }; /*###### ## go_southfury_moonstone ######*/ enum Southfury { NPC_RIZZLE = 23002, SPELL_BLACKJACK = 39865, //stuns player SPELL_SUMMON_RIZZLE = 39866 }; class go_southfury_moonstone : public GameObjectScript { public: go_southfury_moonstone() : GameObjectScript("go_southfury_moonstone") { } struct go_southfury_moonstoneAI : public GameObjectAI { go_southfury_moonstoneAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { //implicitTarget=48 not implemented as of writing this code, and manual summon may be just ok for our purpose //player->CastSpell(player, SPELL_SUMMON_RIZZLE, false); if (Creature* creature = player->SummonCreature(NPC_RIZZLE, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_DEAD_DESPAWN)) creature->CastSpell(player, SPELL_BLACKJACK, false); return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_southfury_moonstoneAI(go); } }; /*###### ## go_tele_to_dalaran_crystal ######*/ enum DalaranCrystal { QUEST_LEARN_LEAVE_RETURN = 12790, QUEST_TELE_CRYSTAL_FLAG = 12845 }; #define GO_TELE_TO_DALARAN_CRYSTAL_FAILED "This teleport crystal cannot be used until the teleport crystal in Dalaran has been used at least once." class go_tele_to_dalaran_crystal : public GameObjectScript { public: go_tele_to_dalaran_crystal() : GameObjectScript("go_tele_to_dalaran_crystal") { } struct go_tele_to_dalaran_crystalAI : public GameObjectAI { go_tele_to_dalaran_crystalAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { if (player->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG)) return false; player->GetSession()->SendNotification(GO_TELE_TO_DALARAN_CRYSTAL_FAILED); return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_tele_to_dalaran_crystalAI(go); } }; /*###### ## go_tele_to_violet_stand ######*/ class go_tele_to_violet_stand : public GameObjectScript { public: go_tele_to_violet_stand() : GameObjectScript("go_tele_to_violet_stand") { } struct go_tele_to_violet_standAI : public GameObjectAI { go_tele_to_violet_standAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { if (player->GetQuestRewardStatus(QUEST_LEARN_LEAVE_RETURN) || player->GetQuestStatus(QUEST_LEARN_LEAVE_RETURN) == QUEST_STATUS_INCOMPLETE) return false; return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_tele_to_violet_standAI(go); } }; /*###### ## go_blood_filled_orb ######*/ enum BloodFilledOrb { NPC_ZELEMAR = 17830 }; class go_blood_filled_orb : public GameObjectScript { public: go_blood_filled_orb() : GameObjectScript("go_blood_filled_orb") { } struct go_blood_filled_orbAI : public GameObjectAI { go_blood_filled_orbAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { if (me->GetGoType() == GAMEOBJECT_TYPE_GOOBER) player->SummonCreature(NPC_ZELEMAR, -369.746f, 166.759f, -21.50f, 5.235f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30s); return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_blood_filled_orbAI(go); } }; /*###### ## go_soulwell ######*/ class go_soulwell : public GameObjectScript { public: go_soulwell() : GameObjectScript("go_soulwell") { } struct go_soulwellAI : public GameObjectAI { go_soulwellAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { Unit* owner = me->GetOwner(); if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer())) return true; return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_soulwellAI(go); } }; /*###### ## go_amberpine_outhouse ######*/ #define GOSSIP_USE_OUTHOUSE "Use the outhouse." #define GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND "Quest item Anderhol's Slider Cider not found." enum AmberpineOuthouse { ITEM_ANDERHOLS_SLIDER_CIDER = 37247, NPC_OUTHOUSE_BUNNY = 27326, QUEST_DOING_YOUR_DUTY = 12227, SPELL_INDISPOSED = 53017, SPELL_INDISPOSED_III = 48341, SPELL_CREATE_AMBERSEEDS = 48330, GOSSIP_OUTHOUSE_INUSE = 12775, GOSSIP_OUTHOUSE_VACANT = 12779 }; class go_amberpine_outhouse : public GameObjectScript { public: go_amberpine_outhouse() : GameObjectScript("go_amberpine_outhouse") { } struct go_amberpine_outhouseAI : public GameObjectAI { go_amberpine_outhouseAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { QuestStatus status = player->GetQuestStatus(QUEST_DOING_YOUR_DUTY); if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED) { AddGossipItemFor(player, GossipOptionNpc::None, GOSSIP_USE_OUTHOUSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_OUTHOUSE_VACANT, me->GetGUID()); } else SendGossipMenuFor(player, GOSSIP_OUTHOUSE_INUSE, me->GetGUID()); return true; } bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 gossipListId) override { uint32 const action = player->PlayerTalkClass->GetGossipOptionAction(gossipListId); ClearGossipMenuFor(player); if (action == GOSSIP_ACTION_INFO_DEF + 1) { CloseGossipMenuFor(player); Creature* target = GetClosestCreatureWithEntry(player, NPC_OUTHOUSE_BUNNY, 3.0f); if (target) { target->AI()->SetData(1, player->GetNativeGender()); me->CastSpell(target, SPELL_INDISPOSED_III); } me->CastSpell(player, SPELL_INDISPOSED); if (player->HasItemCount(ITEM_ANDERHOLS_SLIDER_CIDER)) me->CastSpell(player, SPELL_CREATE_AMBERSEEDS); return true; } else { CloseGossipMenuFor(player); player->GetSession()->SendNotification(GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND); return false; } } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_amberpine_outhouseAI(go); } }; class go_massive_seaforium_charge : public GameObjectScript { public: go_massive_seaforium_charge() : GameObjectScript("go_massive_seaforium_charge") { } struct go_massive_seaforium_chargeAI : public GameObjectAI { go_massive_seaforium_chargeAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* /*player*/) override { me->SetLootState(GO_JUST_DEACTIVATED); return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_massive_seaforium_chargeAI(go); } }; /*######## #### go_veil_skith_cage #####*/ enum MissingFriends { QUEST_MISSING_FRIENDS = 10852, NPC_CAPTIVE_CHILD = 22314, SAY_FREE_0 = 0, }; class go_veil_skith_cage : public GameObjectScript { public: go_veil_skith_cage() : GameObjectScript("go_veil_skith_cage") { } struct go_veil_skith_cageAI : public GameObjectAI { go_veil_skith_cageAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { me->UseDoorOrButton(); if (player->GetQuestStatus(QUEST_MISSING_FRIENDS) == QUEST_STATUS_INCOMPLETE) { std::vector childrenList; GetCreatureListWithEntryInGrid(childrenList, me, NPC_CAPTIVE_CHILD, INTERACTION_DISTANCE); for (Creature* creature : childrenList) { player->KilledMonsterCredit(NPC_CAPTIVE_CHILD, creature->GetGUID()); creature->DespawnOrUnsummon(5s); creature->GetMotionMaster()->MovePoint(1, me->GetPositionX() + 5, me->GetPositionY(), me->GetPositionZ()); creature->AI()->Talk(SAY_FREE_0); creature->GetMotionMaster()->Clear(); } } return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_veil_skith_cageAI(go); } }; /*###### ## go_midsummer_bonfire ######*/ enum MidsummerBonfire { STAMP_OUT_BONFIRE_QUEST_COMPLETE = 45458, }; class go_midsummer_bonfire : public GameObjectScript { public: go_midsummer_bonfire() : GameObjectScript("go_midsummer_bonfire") { } struct go_midsummer_bonfireAI : public GameObjectAI { go_midsummer_bonfireAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override { player->CastSpell(player, STAMP_OUT_BONFIRE_QUEST_COMPLETE, true); CloseGossipMenuFor(player); return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_midsummer_bonfireAI(go); } }; enum MidsummerPoleRibbon { SPELL_TEST_RIBBON_POLE_1 = 29705, SPELL_TEST_RIBBON_POLE_2 = 29726, SPELL_TEST_RIBBON_POLE_3 = 29727, NPC_POLE_RIBBON_BUNNY = 17066, ACTION_COSMETIC_FIRES = 0 }; uint32 const RibbonPoleSpells[3] = { SPELL_TEST_RIBBON_POLE_1, SPELL_TEST_RIBBON_POLE_2, SPELL_TEST_RIBBON_POLE_3 }; class go_midsummer_ribbon_pole : public GameObjectScript { public: go_midsummer_ribbon_pole() : GameObjectScript("go_midsummer_ribbon_pole") { } struct go_midsummer_ribbon_poleAI : public GameObjectAI { go_midsummer_ribbon_poleAI(GameObject* go) : GameObjectAI(go) { } bool OnGossipHello(Player* player) override { if (Creature* creature = me->FindNearestCreature(NPC_POLE_RIBBON_BUNNY, 10.0f)) { creature->GetAI()->DoAction(ACTION_COSMETIC_FIRES); player->CastSpell(player, RibbonPoleSpells[urand(0, 2)], true); } return true; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_midsummer_ribbon_poleAI(go); } }; /*#### ## go_brewfest_music ####*/ enum BrewfestMusic { EVENT_BREWFESTDWARF01 = 11810, // 1.35 min EVENT_BREWFESTDWARF02 = 11812, // 1.55 min EVENT_BREWFESTDWARF03 = 11813, // 0.23 min EVENT_BREWFESTGOBLIN01 = 11811, // 1.08 min EVENT_BREWFESTGOBLIN02 = 11814, // 1.33 min EVENT_BREWFESTGOBLIN03 = 11815 // 0.28 min }; constexpr Seconds EVENT_BREWFESTDWARF01_TIME = 95s; constexpr Seconds EVENT_BREWFESTDWARF02_TIME = 155s; constexpr Seconds EVENT_BREWFESTDWARF03_TIME = 23s; constexpr Seconds EVENT_BREWFESTGOBLIN01_TIME = 68s; constexpr Seconds EVENT_BREWFESTGOBLIN02_TIME = 93s; constexpr Seconds EVENT_BREWFESTGOBLIN03_TIME = 28s; enum BrewfestMusicAreas { SILVERMOON = 3430, // Horde UNDERCITY = 1497, ORGRIMMAR_1 = 1296, ORGRIMMAR_2 = 14, THUNDERBLUFF = 1638, IRONFORGE_1 = 809, // Alliance IRONFORGE_2 = 1, STORMWIND = 12, EXODAR = 3557, DARNASSUS = 1657, SHATTRATH = 3703 // General }; enum BrewfestMusicEvents { EVENT_BM_SELECT_MUSIC = 1, EVENT_BM_START_MUSIC = 2 }; class go_brewfest_music : public GameObjectScript { public: go_brewfest_music() : GameObjectScript("go_brewfest_music") { } struct go_brewfest_musicAI : public GameObjectAI { uint32 rnd = 0; Milliseconds musicTime = 1s; go_brewfest_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_BM_SELECT_MUSIC, 1s); _events.ScheduleEvent(EVENT_BM_START_MUSIC, 2s); } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_BM_SELECT_MUSIC: if (!IsHolidayActive(HOLIDAY_BREWFEST)) // Check if Brewfest is active break; rnd = urand(0, 2); // Select random music sample _events.ScheduleEvent(EVENT_BM_SELECT_MUSIC, musicTime); // Select new song music after play time is over break; case EVENT_BM_START_MUSIC: if (!IsHolidayActive(HOLIDAY_BREWFEST)) // Check if Brewfest is active break; switch (me->GetAreaId()) { // Horde case SILVERMOON: case UNDERCITY: case ORGRIMMAR_1: case ORGRIMMAR_2: case THUNDERBLUFF: if (rnd == 0) { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN01); musicTime = EVENT_BREWFESTGOBLIN01_TIME; } else if (rnd == 1) { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN02); musicTime = EVENT_BREWFESTGOBLIN02_TIME; } else { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN03); musicTime = EVENT_BREWFESTGOBLIN03_TIME; } break; // Alliance case IRONFORGE_1: case IRONFORGE_2: case STORMWIND: case EXODAR: case DARNASSUS: if (rnd == 0) { me->PlayDirectMusic(EVENT_BREWFESTDWARF01); musicTime = EVENT_BREWFESTDWARF01_TIME; } else if (rnd == 1) { me->PlayDirectMusic(EVENT_BREWFESTDWARF02); musicTime = EVENT_BREWFESTDWARF02_TIME; } else { me->PlayDirectMusic(EVENT_BREWFESTDWARF03); musicTime = EVENT_BREWFESTDWARF03_TIME; } break; // Neurtal case SHATTRATH: std::vector playersNearby; me->GetPlayerListInGrid(playersNearby, me->GetVisibilityRange()); for (Player* player : playersNearby) { if (player->GetTeamId() == TEAM_HORDE) { if (rnd == 0) { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN01); musicTime = EVENT_BREWFESTGOBLIN01_TIME; } else if (rnd == 1) { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN02); musicTime = EVENT_BREWFESTGOBLIN02_TIME; } else { me->PlayDirectMusic(EVENT_BREWFESTGOBLIN03); musicTime = EVENT_BREWFESTGOBLIN03_TIME; } } else { if (rnd == 0) { me->PlayDirectMusic(EVENT_BREWFESTDWARF01); musicTime = EVENT_BREWFESTDWARF01_TIME; } else if (rnd == 1) { me->PlayDirectMusic(EVENT_BREWFESTDWARF02); musicTime = EVENT_BREWFESTDWARF02_TIME; } else { me->PlayDirectMusic(EVENT_BREWFESTDWARF03); musicTime = EVENT_BREWFESTDWARF03_TIME; } } } break; } _events.ScheduleEvent(EVENT_BM_START_MUSIC, 5s); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client break; default: break; } } } private: EventMap _events; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_brewfest_musicAI(go); } }; /*#### ## go_midsummer_music ####*/ enum MidsummerMusic { EVENTMIDSUMMERFIREFESTIVAL_A = 12319, // 1.08 min EVENTMIDSUMMERFIREFESTIVAL_H = 12325, // 1.12 min }; enum MidsummerMusicEvents { EVENT_MM_START_MUSIC = 1 }; class go_midsummer_music : public GameObjectScript { public: go_midsummer_music() : GameObjectScript("go_midsummer_music") { } struct go_midsummer_musicAI : public GameObjectAI { go_midsummer_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_MM_START_MUSIC, 1s); } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_MM_START_MUSIC: { if (!IsHolidayActive(HOLIDAY_MIDSUMMER_FIRE_FESTIVAL)) break; std::vector playersNearby; me->GetPlayerListInGrid(playersNearby, me->GetVisibilityRange()); for (Player* player : playersNearby) { if (player->GetTeamId() == TEAM_HORDE) me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_H, player); else me->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_A, player); } _events.ScheduleEvent(EVENT_MM_START_MUSIC, 5s); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value) break; } default: break; } } } private: EventMap _events; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_midsummer_musicAI(go); } }; /*#### ## go_darkmoon_faire_music ####*/ enum DarkmoonFaireMusic { MUSIC_DARKMOON_FAIRE_MUSIC = 8440 }; enum DarkmoonFaireMusicEvents { EVENT_DFM_START_MUSIC = 1 }; class go_darkmoon_faire_music : public GameObjectScript { public: go_darkmoon_faire_music() : GameObjectScript("go_darkmoon_faire_music") { } struct go_darkmoon_faire_musicAI : public GameObjectAI { go_darkmoon_faire_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_DFM_START_MUSIC, 1s); } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_DFM_START_MUSIC: if (!IsHolidayActive(HOLIDAY_DARKMOON_FAIRE)) break; me->PlayDirectMusic(MUSIC_DARKMOON_FAIRE_MUSIC); _events.ScheduleEvent(EVENT_DFM_START_MUSIC, 5s); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value) break; default: break; } } } private: EventMap _events; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_darkmoon_faire_musicAI(go); } }; /*#### ## go_pirate_day_music ####*/ enum PirateDayMusic { MUSIC_PIRATE_DAY_MUSIC = 12845 }; enum PirateDayMusicEvents { EVENT_PDM_START_MUSIC = 1 }; class go_pirate_day_music : public GameObjectScript { public: go_pirate_day_music() : GameObjectScript("go_pirate_day_music") { } struct go_pirate_day_musicAI : public GameObjectAI { go_pirate_day_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_PDM_START_MUSIC, 1s); } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_PDM_START_MUSIC: if (!IsHolidayActive(HOLIDAY_PIRATES_DAY)) break; me->PlayDirectMusic(MUSIC_PIRATE_DAY_MUSIC); _events.ScheduleEvent(EVENT_PDM_START_MUSIC, 5s); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client (sniffed value) break; default: break; } } } private: EventMap _events; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_pirate_day_musicAI(go); } }; /*#### ## go_bells ####*/ enum BellHourlySoundFX { BELLTOLLHORDE = 6595, // Undercity BELLTOLLTRIBAL = 6675, // Orgrimma/Thunderbluff BELLTOLLALLIANCE = 6594, // Stormwind BELLTOLLNIGHTELF = 6674, // Darnassus BELLTOLLDWARFGNOME = 7234, // Ironforge BELLTOLLKHARAZHAN = 9154 // Kharazhan }; enum BellHourlySoundZones { TIRISFAL_ZONE = 85, UNDERCITY_ZONE = 1497, DUN_MOROGH_ZONE = 1, IRONFORGE_ZONE = 1537, TELDRASSIL_ZONE = 141, DARNASSUS_ZONE = 1657, ASHENVALE_ZONE = 331, HILLSBRAD_FOOTHILLS_ZONE = 267, DUSKWOOD_ZONE = 10 }; enum BellHourlyObjects { GO_HORDE_BELL = 175885, GO_ALLIANCE_BELL = 176573, GO_KHARAZHAN_BELL = 182064 }; enum BellHourlyMisc { GAME_EVENT_HOURLY_BELLS = 73, EVENT_RING_BELL = 1 }; class go_bells : public GameObjectScript { public: go_bells() : GameObjectScript("go_bells") { } struct go_bellsAI : public GameObjectAI { go_bellsAI(GameObject* go) : GameObjectAI(go), _soundId(0) { } void InitializeAI() override { uint32 zoneId = me->GetZoneId(); switch (me->GetEntry()) { case GO_HORDE_BELL: { switch (zoneId) { case TIRISFAL_ZONE: case UNDERCITY_ZONE: case HILLSBRAD_FOOTHILLS_ZONE: case DUSKWOOD_ZONE: _soundId = BELLTOLLHORDE; // undead bell sound break; default: _soundId = BELLTOLLTRIBAL; // orc drum sound break; } break; } case GO_ALLIANCE_BELL: { switch (zoneId) { case IRONFORGE_ZONE: case DUN_MOROGH_ZONE: _soundId = BELLTOLLDWARFGNOME; // horn sound break; case DARNASSUS_ZONE: case TELDRASSIL_ZONE: case ASHENVALE_ZONE: _soundId = BELLTOLLNIGHTELF; // nightelf bell sound break; default: _soundId = BELLTOLLALLIANCE; // human bell sound } break; } case GO_KHARAZHAN_BELL: { _soundId = BELLTOLLKHARAZHAN; break; } } } void OnGameEvent(bool start, uint16 eventId) override { if (eventId == GAME_EVENT_HOURLY_BELLS && start) { time_t time = GameTime::GetGameTime(); tm localTm; localtime_r(&time, &localTm); uint8 _rings = (localTm.tm_hour) % 12; if (_rings == 0) // 00:00 and 12:00 { _rings = 12; } // Dwarf hourly horn should only play a single time, each time the next hour begins. if (_soundId == BELLTOLLDWARFGNOME) { _rings = 1; } for (auto i = 0; i < _rings; ++i) _events.ScheduleEvent(EVENT_RING_BELL, Seconds(i * 4 + 1)); } } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_RING_BELL: me->PlayDirectSound(_soundId); break; default: break; } } } private: EventMap _events; uint32 _soundId; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_bellsAI(go); } }; void AddSC_go_scripts() { new go_gilded_brazier(); new go_southfury_moonstone(); new go_tablet_of_the_seven(); new go_ethereum_prison(); new go_ethereum_stasis(); new go_resonite_cask(); new go_tele_to_dalaran_crystal(); new go_tele_to_violet_stand(); new go_blood_filled_orb(); new go_soulwell(); new go_amberpine_outhouse(); new go_massive_seaforium_charge(); new go_veil_skith_cage(); new go_midsummer_bonfire(); new go_midsummer_ribbon_pole(); new go_brewfest_music(); new go_midsummer_music(); new go_darkmoon_faire_music(); new go_pirate_day_music(); new go_bells(); }