/* * Copyright (C) 2016+ AzerothCore , released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2 * Copyright (C) 2008-2016 TrinityCore * Copyright (C) 2005-2009 MaNGOS */ /* ContentData go_cat_figurine (the "trap" version of GO, two different exist) go_barov_journal go_ethereum_prison go_ethereum_stasis go_sacred_fire_of_life go_shrine_of_the_birds go_southfury_moonstone go_resonite_cask go_tablet_of_madness go_tablet_of_the_seven go_tele_to_dalaran_crystal go_tele_to_violet_stand go_scourge_cage go_jotunheim_cage go_table_theka go_soulwell go_bashir_crystalforge go_soulwell go_dragonflayer_cage go_tadpole_cage go_amberpine_outhouse go_hive_pod go_veil_skith_cage EndContentData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "GameObjectAI.h" #include "Spell.h" #include "Player.h" #include "WorldSession.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" // Ours /*###### ## go_noblegarden_colored_egg ######*/ class go_noblegarden_colored_egg : public GameObjectScript { public: go_noblegarden_colored_egg() : GameObjectScript("go_noblegarden_colored_egg") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (roll_chance_i(5)) player->CastSpell(player, 61734, true); // SPELL NOBLEGARDEN BUNNY return false; } }; class go_seer_of_zebhalak : public GameObjectScript { public: go_seer_of_zebhalak() : GameObjectScript("go_seer_of_zebhalak") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->GetQuestStatus(12007) == QUEST_STATUS_INCOMPLETE) player->CastSpell(player, 47293, true); return true; } }; class go_mistwhisper_treasure : public GameObjectScript { public: go_mistwhisper_treasure() : GameObjectScript("go_mistwhisper_treasure") { } bool OnGossipHello(Player* pPlayer, GameObject* go) override { if (!go->FindNearestCreature(28105, 30.0f)) // Tartek { if (Creature* cr = go->SummonCreature(28105, 6708.7f, 5115.45f, -18.3f, 0.7f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) { cr->MonsterYell("My treasure! You no steal from Tartek, dumb big-tongue traitor thing. Tartek and nasty dragon going to kill you! You so dumb.", LANG_UNIVERSAL, 0); cr->AI()->AttackStart(pPlayer); } } return false; } }; class go_witherbark_totem_bundle : public GameObjectScript { public: go_witherbark_totem_bundle() : GameObjectScript("go_witherbark_totem_bundle") { } struct go_witherbark_totem_bundleAI : public GameObjectAI { go_witherbark_totem_bundleAI(GameObject* gameObject) : GameObjectAI(gameObject) { _timer = 1; } void UpdateAI(uint32 diff) override { if (_timer) { _timer += diff; if (_timer > 5000) { go->CastSpell(nullptr, 9056); go->DestroyForNearbyPlayers(); _timer = 0; } } } uint32 _timer; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_witherbark_totem_bundleAI(go); } }; class go_arena_ready_marker : public GameObjectScript { public: go_arena_ready_marker() : GameObjectScript("go_arena_ready_marker") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (Battleground* bg = player->GetBattleground()) bg->ReadyMarkerClicked(player); return false; } }; /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* go) override { int Random = rand() % (sizeof(NpcPrisonEntry) / sizeof(uint32)); if (Creature* creature = player->SummonCreature(NpcPrisonEntry[Random], go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), go->GetAngle(player), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000)) { if (!creature->IsHostileTo(player)) { uint32 Spell = 0; switch (creature->GetEntry()) { case 22811: Spell = SPELL_REP_LC; break; case 22812: Spell = SPELL_REP_SHAT; break; case 22810: Spell = SPELL_REP_CE; break; case 22813: Spell = SPELL_REP_CON; break; case 22815: Spell = SPELL_REP_KT; break; case 22814: Spell = SPELL_REP_SPOR; break; } if (Spell) creature->CastSpell(player, Spell, false); } } return false; } }; /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* go) override { int Random = rand() % (sizeof(NpcStasisEntry) / sizeof(uint32)); player->SummonCreature(NpcStasisEntry[Random], go->GetPositionX(), go->GetPositionY(), go->GetPositionZ(), go->GetAngle(player), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); return false; } }; /*###### ## go_resonite_cask ######*/ enum ResoniteCask { NPC_GOGGEROC = 11920 }; class go_resonite_cask : public GameObjectScript { public: go_resonite_cask() : GameObjectScript("go_resonite_cask") { } bool OnGossipHello(Player* /*player*/, GameObject* go) override { // xinef: prevent spawning hundreds of them if (go->GetGoType() == GAMEOBJECT_TYPE_GOOBER && !go->FindNearestCreature(NPC_GOGGEROC, 20.0f)) go->SummonCreature(NPC_GOGGEROC, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 300000); return false; } }; /*###### ## Quest 11560: Oh Noes, the Tadpoles! ## go_tadpole_cage ######*/ enum Tadpoles { QUEST_OH_NOES_THE_TADPOLES = 11560, NPC_WINTERFIN_TADPOLE = 25201 }; class go_tadpole_cage : public GameObjectScript { public: go_tadpole_cage() : GameObjectScript("go_tadpole_cage") { } struct go_tadpole_cageAI : public GameObjectAI { go_tadpole_cageAI(GameObject* gameObject) : GameObjectAI(gameObject) { requireSummon = 2; } uint8 requireSummon; void SummonTadpoles() { requireSummon = 0; int8 count = urand(1, 3); for (int8 i = 0; i < count; ++i) go->SummonCreature(NPC_WINTERFIN_TADPOLE, go->GetPositionX() + cos(2 * M_PI * i / 3.0f) * 0.60f, go->GetPositionY() + sin(2 * M_PI * i / 3.0f) * 0.60f, go->GetPositionZ(), go->GetOrientation(), TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000); } void OnStateChanged(uint32 state, Unit* /*unit*/) override { if (requireSummon == 1 && state == GO_READY) requireSummon = 2; } void UpdateAI(uint32 /*diff*/) override { if (go->isSpawned() && requireSummon == 2) SummonTadpoles(); } bool GossipHello(Player* player, bool /*reportUse*/) override { if (requireSummon) return false; requireSummon = 1; if (player->GetQuestStatus(QUEST_OH_NOES_THE_TADPOLES) == QUEST_STATUS_INCOMPLETE) { std::list cList; GetCreatureListWithEntryInGrid(cList, go, NPC_WINTERFIN_TADPOLE, 5.0f); for (std::list::const_iterator itr = cList.begin(); itr != cList.end(); ++itr) { player->KilledMonsterCredit(NPC_WINTERFIN_TADPOLE, 0); (*itr)->DespawnOrUnsummon(urand(45000, 60000)); (*itr)->GetMotionMaster()->MoveFollow(player, 1.0f, frand(0.0f, 2 * M_PI), MOTION_SLOT_CONTROLLED); } } return false; } }; GameObjectAI* GetAI(GameObject* go) const override { return new go_tadpole_cageAI(go); } }; enum Flames { SPELL_FLAMES = 7897 }; class go_flames : public GameObjectScript { public: go_flames() : GameObjectScript("go_flames") { } struct go_flamesAI : public GameObjectAI { go_flamesAI(GameObject* gameObject) : GameObjectAI(gameObject), timer { 0 } { } void UpdateAI(uint32 diff) override { timer += diff; if (timer > 3000) { timer = 0; std::list players; acore::AnyPlayerExactPositionInGameObjectRangeCheck checker(go, 0.3f); acore::PlayerListSearcher searcher(go, players, checker); go->VisitNearbyWorldObject(0.3f, searcher); if (players.size() > 0) { std::list::iterator itr = players.begin(); std::advance(itr, urand(0, players.size() - 1)); if (Creature* trigger = go->SummonTrigger((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), 0, 2000, true)) trigger->CastSpell(trigger, SPELL_FLAMES); } } } private: uint32 timer; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_flamesAI(go); } }; enum Heat { SPELL_HEAT = 7902 }; class go_heat : public GameObjectScript { public: go_heat() : GameObjectScript("go_heat") { } struct go_heatAI : public GameObjectAI { go_heatAI(GameObject* gameObject) : GameObjectAI(gameObject), timer { 0 } { } void UpdateAI(uint32 diff) override { timer += diff; if (timer > 3000) { timer = 0; std::list players; acore::AnyPlayerExactPositionInGameObjectRangeCheck checker(go, 0.3f); acore::PlayerListSearcher searcher(go, players, checker); go->VisitNearbyWorldObject(0.3f, searcher); if (players.size() > 0) { std::list::iterator itr = players.begin(); std::advance(itr, urand(0, players.size() - 1)); if (Creature* trigger = go->SummonTrigger((*itr)->GetPositionX(), (*itr)->GetPositionY(), (*itr)->GetPositionZ(), 0, 2000, true)) trigger->CastSpell(trigger, SPELL_HEAT); } } } private: uint32 timer; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_heatAI(go); } }; // Theirs /*#### ## 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 }; // These are in seconds enum BrewfestMusicTime { EVENT_BREWFESTDWARF01_TIME = 95000, EVENT_BREWFESTDWARF02_TIME = 155000, EVENT_BREWFESTDWARF03_TIME = 23000, EVENT_BREWFESTGOBLIN01_TIME = 68000, EVENT_BREWFESTGOBLIN02_TIME = 93000, EVENT_BREWFESTGOBLIN03_TIME = 28000 }; 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 { go_brewfest_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_BM_SELECT_MUSIC, 1000); _events.ScheduleEvent(EVENT_BM_START_MUSIC, 1500); _currentMusicEvent = EVENT_BREWFESTGOBLIN01; } 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; // Select random music sample uint32 rnd = urand(0, 2); uint32 musicTime = 1000; //Restart the current selected music _currentMusicEvent = 0; //Check zone to play correct music if (go->GetAreaId() == SILVERMOON || go->GetAreaId() == UNDERCITY || go->GetAreaId() == ORGRIMMAR_1 || go->GetAreaId() == ORGRIMMAR_2 || go->GetAreaId() == THUNDERBLUFF) { switch (rnd) { case 0: _currentMusicEvent = EVENT_BREWFESTGOBLIN01; musicTime = EVENT_BREWFESTGOBLIN01_TIME; break; case 1: _currentMusicEvent = EVENT_BREWFESTGOBLIN02; musicTime = EVENT_BREWFESTGOBLIN02_TIME; break; case 2: _currentMusicEvent = EVENT_BREWFESTGOBLIN03; musicTime = EVENT_BREWFESTGOBLIN03_TIME; break; default: break; } } else if (go->GetAreaId() == IRONFORGE_1 || go->GetAreaId() == IRONFORGE_2 || go->GetAreaId() == STORMWIND || go->GetAreaId() == EXODAR || go->GetAreaId() == DARNASSUS) { switch (rnd) { case 0: _currentMusicEvent = EVENT_BREWFESTDWARF01; musicTime = EVENT_BREWFESTDWARF01_TIME; break; case 1: _currentMusicEvent = EVENT_BREWFESTDWARF02; musicTime = EVENT_BREWFESTDWARF02_TIME; break; case 2: _currentMusicEvent = EVENT_BREWFESTDWARF03; musicTime = EVENT_BREWFESTDWARF03_TIME; break; default: break; } } else if (go->GetAreaId() == SHATTRATH) { rnd = urand(0, 5); switch (rnd) { case 0: _currentMusicEvent = EVENT_BREWFESTGOBLIN01; musicTime = EVENT_BREWFESTGOBLIN01_TIME; break; case 1: _currentMusicEvent = EVENT_BREWFESTGOBLIN02; musicTime = EVENT_BREWFESTGOBLIN02_TIME; break; case 2: _currentMusicEvent = EVENT_BREWFESTGOBLIN03; musicTime = EVENT_BREWFESTGOBLIN03_TIME; break; case 3: _currentMusicEvent = EVENT_BREWFESTDWARF01; musicTime = EVENT_BREWFESTDWARF01_TIME; break; case 4: _currentMusicEvent = EVENT_BREWFESTDWARF02; musicTime = EVENT_BREWFESTDWARF02_TIME; break; case 5: _currentMusicEvent = EVENT_BREWFESTDWARF03; musicTime = EVENT_BREWFESTDWARF03_TIME; break; default: break; } } _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; // Play selected music if (_currentMusicEvent != 0) { go->PlayDirectMusic(_currentMusicEvent); } _events.ScheduleEvent(EVENT_BM_START_MUSIC, 5000); // Every 5 second's SMSG_PLAY_MUSIC packet (PlayDirectMusic) is pushed to the client break; default: break; } } } private: EventMap _events; uint32 _currentMusicEvent; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_brewfest_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 { uint32 rnd; go_pirate_day_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_PDM_START_MUSIC, 1000); } 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; go->PlayDirectMusic(MUSIC_PIRATE_DAY_MUSIC); _events.ScheduleEvent(EVENT_PDM_START_MUSIC, 5000); // 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_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 { uint32 rnd; go_darkmoon_faire_musicAI(GameObject* go) : GameObjectAI(go) { _events.ScheduleEvent(EVENT_DFM_START_MUSIC, 1000); } 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_ELWYNN) || !IsHolidayActive(HOLIDAY_DARKMOON_FAIRE_THUNDER) || !IsHolidayActive(HOLIDAY_DARKMOON_FAIRE_SHATTRATH)) break; go->PlayDirectMusic(MUSIC_DARKMOON_FAIRE_MUSIC); _events.ScheduleEvent(EVENT_DFM_START_MUSIC, 5000); // 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_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, 1000); } void UpdateAI(uint32 diff) override { _events.Update(diff); while (uint32 eventId = _events.ExecuteEvent()) { switch (eventId) { case EVENT_MM_START_MUSIC: { if (!IsHolidayActive(HOLIDAY_FIRE_FESTIVAL)) break; Map::PlayerList const& players = go->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) { if (Player* player = itr->GetSource()) { if (player->GetTeamId() == TEAM_HORDE) { go->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_H, player); } else { go->PlayDirectMusic(EVENTMIDSUMMERFIREFESTIVAL_A, player); } } } _events.ScheduleEvent(EVENT_MM_START_MUSIC, 5000); // 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_cat_figurine ######*/ enum CatFigurine { SPELL_SUMMON_GHOST_SABER = 5968, }; class go_cat_figurine : public GameObjectScript { public: go_cat_figurine() : GameObjectScript("go_cat_figurine") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { player->CastSpell(player, SPELL_SUMMON_GHOST_SABER, true); return false; } }; /*###### ## go_gilded_brazier (Paladin First Trail quest (9678)) ######*/ enum GildedBrazier { NPC_STILLBLADE = 17716, }; class go_gilded_brazier : public GameObjectScript { public: go_gilded_brazier() : GameObjectScript("go_gilded_brazier") { } bool OnGossipHello(Player* player, GameObject* go) override { if (go->GetGoType() == GAMEOBJECT_TYPE_GOOBER) { if (player->GetQuestStatus(9678) == QUEST_STATUS_INCOMPLETE) { if (Creature* Stillblade = player->SummonCreature(NPC_STILLBLADE, 8106.11f, -7542.06f, 151.775f, 3.02598f, TEMPSUMMON_DEAD_DESPAWN, 60000)) Stillblade->AI()->AttackStart(player); } } return true; } }; /*###### ## go_tablet_of_madness ######*/ class go_tablet_of_madness : public GameObjectScript { public: go_tablet_of_madness() : GameObjectScript("go_tablet_of_madness") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->HasSkill(SKILL_ALCHEMY) && player->GetSkillValue(SKILL_ALCHEMY) >= 300 && !player->HasSpell(24266)) player->CastSpell(player, 24267, false); return true; } }; /*###### ## 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") { } //TODO: use gossip option ("Transcript the Tablet") instead, if Trinity adds support. bool OnGossipHello(Player* player, GameObject* go) override { if (go->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER) return true; if (player->GetQuestStatus(4296) == QUEST_STATUS_INCOMPLETE) player->CastSpell(player, 15065, false); return true; } }; /*##### ## go_jump_a_tron ######*/ class go_jump_a_tron : public GameObjectScript { public: go_jump_a_tron() : GameObjectScript("go_jump_a_tron") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->GetQuestStatus(10111) == QUEST_STATUS_INCOMPLETE) player->CastSpell(player, 33382, true); return true; } }; /*###### ## go_sacred_fire_of_life ######*/ enum SacredFireOfLife { NPC_ARIKARA = 10882 }; class go_sacred_fire_of_life : public GameObjectScript { public: go_sacred_fire_of_life() : GameObjectScript("go_sacred_fire_of_life") { } bool OnGossipHello(Player* player, GameObject* go) override { if (go->GetGoType() == GAMEOBJECT_TYPE_GOOBER) player->SummonCreature(NPC_ARIKARA, -5008.338f, -2118.894f, 83.657f, 0.874f, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 30000); return true; } }; /*###### ## go_shrine_of_the_birds ######*/ /* enum ShrineOfTheBirds { NPC_HAWK_GUARD = 22992, NPC_EAGLE_GUARD = 22993, NPC_FALCON_GUARD = 22994, GO_SHRINE_HAWK = 185551, GO_SHRINE_EAGLE = 185547, GO_SHRINE_FALCON = 185553 }; class go_shrine_of_the_birds : public GameObjectScript { public: go_shrine_of_the_birds() : GameObjectScript("go_shrine_of_the_birds") { } bool OnGossipHello(Player* player, GameObject* go) override { uint32 BirdEntry = 0; float fX, fY, fZ; go->GetClosePoint(fX, fY, fZ, go->GetObjectSize(), INTERACTION_DISTANCE); switch (go->GetEntry()) { case GO_SHRINE_HAWK: BirdEntry = NPC_HAWK_GUARD; break; case GO_SHRINE_EAGLE: BirdEntry = NPC_EAGLE_GUARD; break; case GO_SHRINE_FALCON: BirdEntry = NPC_FALCON_GUARD; break; } if (BirdEntry) player->SummonCreature(BirdEntry, fX, fY, fZ, go->GetOrientation(), TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 60000); return false; } }; */ /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* /*go*/) 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, 0)) creature->CastSpell(player, SPELL_BLACKJACK, false); return false; } }; /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->GetQuestRewardStatus(QUEST_TELE_CRYSTAL_FLAG)) return false; player->GetSession()->SendNotification(GO_TELE_TO_DALARAN_CRYSTAL_FAILED); return true; } }; /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->GetQuestRewardStatus(QUEST_LEARN_LEAVE_RETURN) || player->GetQuestStatus(QUEST_LEARN_LEAVE_RETURN) == QUEST_STATUS_INCOMPLETE) return false; return true; } }; /*###### ## go_fel_crystalforge ######*/ #define GOSSIP_FEL_CRYSTALFORGE_TEXT 31000 #define GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN 31001 #define GOSSIP_FEL_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Beast for the cost of 10 Apexis Shards" #define GOSSIP_FEL_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Beast for the cost of 50 Apexis Shards" #define GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN "Use the fel crystalforge to make another purchase." enum FelCrystalforge { SPELL_CREATE_1_FLASK_OF_BEAST = 40964, SPELL_CREATE_5_FLASK_OF_BEAST = 40965, }; class go_fel_crystalforge : public GameObjectScript { public: go_fel_crystalforge() : GameObjectScript("go_fel_crystalforge") { } bool OnGossipHello(Player* player, GameObject* go) override { if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */ player->PrepareQuestMenu(go->GetGUID()); /* return true*/ AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_FEL_CRYSTALFORGE_TEXT, go->GetGUID()); return true; } bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) override { ClearGossipMenuFor(player); switch (action) { case GOSSIP_ACTION_INFO_DEF: player->CastSpell(player, SPELL_CREATE_1_FLASK_OF_BEAST, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); SendGossipMenuFor(player, GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, go->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF + 1: player->CastSpell(player, SPELL_CREATE_5_FLASK_OF_BEAST, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); SendGossipMenuFor(player, GOSSIP_FEL_CRYSTALFORGE_ITEM_TEXT_RETURN, go->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF + 2: AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_FEL_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_FEL_CRYSTALFORGE_TEXT, go->GetGUID()); break; } return true; } }; /*###### ## go_bashir_crystalforge ######*/ #define GOSSIP_BASHIR_CRYSTALFORGE_TEXT 31100 #define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN 31101 #define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1 "Purchase 1 Unstable Flask of the Sorcerer for the cost of 10 Apexis Shards" #define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5 "Purchase 5 Unstable Flask of the Sorcerer for the cost of 50 Apexis Shards" #define GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN "Use the bashir crystalforge to make another purchase." enum BashirCrystalforge { SPELL_CREATE_1_FLASK_OF_SORCERER = 40968, SPELL_CREATE_5_FLASK_OF_SORCERER = 40970, }; class go_bashir_crystalforge : public GameObjectScript { public: go_bashir_crystalforge() : GameObjectScript("go_bashir_crystalforge") { } bool OnGossipHello(Player* player, GameObject* go) override { if (go->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER) /* != GAMEOBJECT_TYPE_QUESTGIVER) */ player->PrepareQuestMenu(go->GetGUID()); /* return true*/ AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_BASHIR_CRYSTALFORGE_TEXT, go->GetGUID()); return true; } bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) override { ClearGossipMenuFor(player); switch (action) { case GOSSIP_ACTION_INFO_DEF: player->CastSpell(player, SPELL_CREATE_1_FLASK_OF_SORCERER, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); SendGossipMenuFor(player, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, go->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF + 1: player->CastSpell(player, SPELL_CREATE_5_FLASK_OF_SORCERER, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_RETURN, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2); SendGossipMenuFor(player, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_TEXT_RETURN, go->GetGUID()); break; case GOSSIP_ACTION_INFO_DEF + 2: AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF); AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_BASHIR_CRYSTALFORGE_ITEM_5, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_BASHIR_CRYSTALFORGE_TEXT, go->GetGUID()); break; } return true; } }; /*###### ## go_scourge_cage ######*/ enum ScourgeCage { NPC_SCOURGE_PRISONER = 25610 }; class go_scourge_cage : public GameObjectScript { public: go_scourge_cage() : GameObjectScript("go_scourge_cage") { } bool OnGossipHello(Player* player, GameObject* go) override { go->UseDoorOrButton(); if (Creature* pNearestPrisoner = go->FindNearestCreature(NPC_SCOURGE_PRISONER, 5.0f, true)) { player->KilledMonsterCredit(NPC_SCOURGE_PRISONER, pNearestPrisoner->GetGUID()); pNearestPrisoner->DisappearAndDie(); } return true; } }; /*###### ## go_arcane_prison ######*/ enum ArcanePrison { QUEST_PRISON_BREAK = 11587, SPELL_ARCANE_PRISONER_KILL_CREDIT = 45456 }; class go_arcane_prison : public GameObjectScript { public: go_arcane_prison() : GameObjectScript("go_arcane_prison") { } bool OnGossipHello(Player* player, GameObject* go) override { // xinef: prevent spawning hundreds of them if (player->GetQuestStatus(QUEST_PRISON_BREAK) == QUEST_STATUS_INCOMPLETE && !go->FindNearestCreature(25318, 20.0f)) { go->SummonCreature(25318, 3485.089844f, 6115.7422188f, 70.966812f, 0, TEMPSUMMON_TIMED_DESPAWN, 60000); player->CastSpell(player, SPELL_ARCANE_PRISONER_KILL_CREDIT, true); return true; } return false; } }; /*###### ## go_jotunheim_cage ######*/ enum JotunheimCage { NPC_EBON_BLADE_PRISONER_HUMAN = 30186, NPC_EBON_BLADE_PRISONER_NE = 30194, NPC_EBON_BLADE_PRISONER_TROLL = 30196, NPC_EBON_BLADE_PRISONER_ORC = 30195, SPELL_SUMMON_BLADE_KNIGHT_H = 56207, SPELL_SUMMON_BLADE_KNIGHT_NE = 56209, SPELL_SUMMON_BLADE_KNIGHT_ORC = 56212, SPELL_SUMMON_BLADE_KNIGHT_TROLL = 56214 }; class go_jotunheim_cage : public GameObjectScript { public: go_jotunheim_cage() : GameObjectScript("go_jotunheim_cage") { } bool OnGossipHello(Player* player, GameObject* go) override { go->UseDoorOrButton(); Creature* pPrisoner = go->FindNearestCreature(NPC_EBON_BLADE_PRISONER_HUMAN, 5.0f, true); if (!pPrisoner) { pPrisoner = go->FindNearestCreature(NPC_EBON_BLADE_PRISONER_TROLL, 5.0f, true); if (!pPrisoner) { pPrisoner = go->FindNearestCreature(NPC_EBON_BLADE_PRISONER_ORC, 5.0f, true); if (!pPrisoner) pPrisoner = go->FindNearestCreature(NPC_EBON_BLADE_PRISONER_NE, 5.0f, true); } } if (!pPrisoner || !pPrisoner->IsAlive()) return false; pPrisoner->DespawnOrUnsummon(); player->KilledMonsterCredit(NPC_EBON_BLADE_PRISONER_HUMAN, 0); switch (pPrisoner->GetEntry()) { case NPC_EBON_BLADE_PRISONER_HUMAN: player->CastSpell(player, SPELL_SUMMON_BLADE_KNIGHT_H, true); break; case NPC_EBON_BLADE_PRISONER_NE: player->CastSpell(player, SPELL_SUMMON_BLADE_KNIGHT_NE, true); break; case NPC_EBON_BLADE_PRISONER_TROLL: player->CastSpell(player, SPELL_SUMMON_BLADE_KNIGHT_TROLL, true); break; case NPC_EBON_BLADE_PRISONER_ORC: player->CastSpell(player, SPELL_SUMMON_BLADE_KNIGHT_ORC, true); break; } return true; } }; enum TableTheka { GOSSIP_TABLE_THEKA = 1653, QUEST_SPIDER_GOLD = 2936 }; class go_table_theka : public GameObjectScript { public: go_table_theka() : GameObjectScript("go_table_theka") { } bool OnGossipHello(Player* player, GameObject* go) override { if (player->GetQuestStatus(QUEST_SPIDER_GOLD) == QUEST_STATUS_INCOMPLETE) player->AreaExploredOrEventHappens(QUEST_SPIDER_GOLD); SendGossipMenuFor(player, GOSSIP_TABLE_THEKA, go->GetGUID()); return true; } }; /*###### ## go_inconspicuous_landmark ######*/ enum InconspicuousLandmark { SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB = 11462, ITEM_CUERGOS_KEY = 9275, }; class go_inconspicuous_landmark : public GameObjectScript { public: go_inconspicuous_landmark() : GameObjectScript("go_inconspicuous_landmark") { _lastUsedTime = time(nullptr); } bool OnGossipHello(Player* player, GameObject* /*go*/) override { if (player->HasItemCount(ITEM_CUERGOS_KEY)) return true; if (_lastUsedTime > time(nullptr)) return true; _lastUsedTime = time(nullptr) + MINUTE; player->CastSpell(player, SPELL_SUMMON_PIRATES_TREASURE_AND_TRIGGER_MOB, true); return true; } private: uint32 _lastUsedTime; }; /*###### ## go_soulwell ######*/ enum SoulWellData { GO_SOUL_WELL_R1 = 181621, GO_SOUL_WELL_R2 = 193169, SPELL_IMPROVED_HEALTH_STONE_R1 = 18692, SPELL_IMPROVED_HEALTH_STONE_R2 = 18693, SPELL_CREATE_MASTER_HEALTH_STONE_R0 = 34130, SPELL_CREATE_MASTER_HEALTH_STONE_R1 = 34149, SPELL_CREATE_MASTER_HEALTH_STONE_R2 = 34150, SPELL_CREATE_FEL_HEALTH_STONE_R0 = 58890, SPELL_CREATE_FEL_HEALTH_STONE_R1 = 58896, SPELL_CREATE_FEL_HEALTH_STONE_R2 = 58898, }; class go_soulwell : public GameObjectScript { public: go_soulwell() : GameObjectScript("go_soulwell") { } struct go_soulwellAI : public GameObjectAI { go_soulwellAI(GameObject* go) : GameObjectAI(go) { _stoneSpell = 0; _stoneId = 0; switch (go->GetEntry()) { case GO_SOUL_WELL_R1: _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R0; if (Unit* owner = go->GetOwner()) { if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1)) _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R1; else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2)) _stoneSpell = SPELL_CREATE_MASTER_HEALTH_STONE_R2; } break; case GO_SOUL_WELL_R2: _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R0; if (Unit* owner = go->GetOwner()) { if (owner->HasAura(SPELL_IMPROVED_HEALTH_STONE_R1)) _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R1; else if (owner->HasAura(SPELL_CREATE_MASTER_HEALTH_STONE_R2)) _stoneSpell = SPELL_CREATE_FEL_HEALTH_STONE_R2; } break; } if (_stoneSpell == 0) // Should never happen return; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_stoneSpell); if (!spellInfo) return; _stoneId = spellInfo->Effects[EFFECT_0].ItemType; } /// Due to the fact that this GameObject triggers CMSG_GAMEOBJECT_USE /// _and_ CMSG_GAMEOBJECT_REPORT_USE, this GossipHello hook is called /// twice. The script's handling is fine as it won't remove two charges /// on the well. We have to find how to segregate REPORT_USE and USE. bool GossipHello(Player* player, bool reportUse) override { if (reportUse) return false; Unit* owner = go->GetOwner(); if (_stoneSpell == 0 || _stoneId == 0) { if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell)) Spell::SendCastResult(player, spell, 0, SPELL_FAILED_ERROR); return true; } if (!owner || owner->GetTypeId() != TYPEID_PLAYER || !player->IsInSameRaidWith(owner->ToPlayer())) { if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell)) Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TARGET_NOT_IN_RAID); return true; } // Don't try to add a stone if we already have one. if (player->HasItemCount(_stoneId)) { if (SpellInfo const* spell = sSpellMgr->GetSpellInfo(_stoneSpell)) Spell::SendCastResult(player, spell, 0, SPELL_FAILED_TOO_MANY_OF_ITEM); return true; } player->CastSpell(player, _stoneSpell, false); // Item has to actually be created to remove a charge on the well. if (player->HasItemCount(_stoneId)) go->AddUse(); return true; } private: uint32 _stoneSpell; uint32 _stoneId; }; GameObjectAI* GetAI(GameObject* go) const override { return new go_soulwellAI(go); } }; /*###### ## Quest 11255: Prisoners of Wyrmskull ## go_dragonflayer_cage ######*/ enum PrisonersOfWyrmskull { QUEST_PRISONERS_OF_WYRMSKULL = 11255, NPC_PRISONER_PRIEST = 24086, NPC_PRISONER_MAGE = 24088, NPC_PRISONER_WARRIOR = 24089, NPC_PRISONER_PALADIN = 24090 }; class go_dragonflayer_cage : public GameObjectScript { public: go_dragonflayer_cage() : GameObjectScript("go_dragonflayer_cage") { } bool OnGossipHello(Player* player, GameObject* go) override { go->UseDoorOrButton(); if (player->GetQuestStatus(QUEST_PRISONERS_OF_WYRMSKULL) != QUEST_STATUS_INCOMPLETE) return true; Creature* pPrisoner = go->FindNearestCreature(NPC_PRISONER_PRIEST, 2.0f); if (!pPrisoner) { pPrisoner = go->FindNearestCreature(NPC_PRISONER_MAGE, 2.0f); if (!pPrisoner) { pPrisoner = go->FindNearestCreature(NPC_PRISONER_WARRIOR, 2.0f); if (!pPrisoner) pPrisoner = go->FindNearestCreature(NPC_PRISONER_PALADIN, 2.0f); } } if (!pPrisoner || !pPrisoner->IsAlive()) return true; Quest const* qInfo = sObjectMgr->GetQuestTemplate(QUEST_PRISONERS_OF_WYRMSKULL); if (qInfo) { /// @todo prisoner should help player for a short period of time player->KilledMonsterCredit(qInfo->RequiredNpcOrGo[0], 0); pPrisoner->DisappearAndDie(); } return true; } }; /*###### ## 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") { } bool OnGossipHello(Player* player, GameObject* go) override { QuestStatus status = player->GetQuestStatus(QUEST_DOING_YOUR_DUTY); if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE || status == QUEST_STATUS_REWARDED) { AddGossipItemFor(player, GOSSIP_ICON_CHAT, GOSSIP_USE_OUTHOUSE, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); SendGossipMenuFor(player, GOSSIP_OUTHOUSE_VACANT, go->GetGUID()); } else SendGossipMenuFor(player, GOSSIP_OUTHOUSE_INUSE, go->GetGUID()); return true; } bool OnGossipSelect(Player* player, GameObject* go, uint32 /*sender*/, uint32 action) override { 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->getGender()); go->CastSpell(target, SPELL_INDISPOSED_III); } go->CastSpell(player, SPELL_INDISPOSED); if (player->HasItemCount(ITEM_ANDERHOLS_SLIDER_CIDER)) player->CastSpell(player, SPELL_CREATE_AMBERSEEDS, true); return true; } else { CloseGossipMenuFor(player); player->GetSession()->SendNotification(GO_ANDERHOLS_SLIDER_CIDER_NOT_FOUND); return false; } } }; /*###### ## Quest 1126: Hive in the Tower ## go_hive_pod ######*/ enum Hives { QUEST_HIVE_IN_THE_TOWER = 9544, NPC_HIVE_AMBUSHER = 13301 }; class go_hive_pod : public GameObjectScript { public: go_hive_pod() : GameObjectScript("go_hive_pod") { } bool OnGossipHello(Player* player, GameObject* go) override { player->SendLoot(go->GetGUID(), LOOT_CORPSE); // xinef: prevent spawning hundreds of them if (go->FindNearestCreature(NPC_HIVE_AMBUSHER, 20.0f)) return true; go->SummonCreature(NPC_HIVE_AMBUSHER, go->GetPositionX() + 1, go->GetPositionY(), go->GetPositionZ(), go->GetAngle(player), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); go->SummonCreature(NPC_HIVE_AMBUSHER, go->GetPositionX(), go->GetPositionY() + 1, go->GetPositionZ(), go->GetAngle(player), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 60000); return true; } }; class go_massive_seaforium_charge : public GameObjectScript { public: go_massive_seaforium_charge() : GameObjectScript("go_massive_seaforium_charge") { } bool OnGossipHello(Player* /*player*/, GameObject* go) override { go->SetLootState(GO_JUST_DEACTIVATED); return true; } }; /*######## #### 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") { } bool OnGossipHello(Player* player, GameObject* go) override { go->UseDoorOrButton(); if (player->GetQuestStatus(QUEST_MISSING_FRIENDS) == QUEST_STATUS_INCOMPLETE) { std::list childrenList; GetCreatureListWithEntryInGrid(childrenList, go, NPC_CAPTIVE_CHILD, INTERACTION_DISTANCE); for (std::list::const_iterator itr = childrenList.begin(); itr != childrenList.end(); ++itr) { player->KilledMonsterCredit(NPC_CAPTIVE_CHILD, (*itr)->GetGUID()); (*itr)->DespawnOrUnsummon(5000); (*itr)->GetMotionMaster()->MovePoint(1, go->GetPositionX() + 5, go->GetPositionY(), go->GetPositionZ()); (*itr)->AI()->Talk(SAY_FREE_0); (*itr)->GetMotionMaster()->Clear(); } } return false; } }; void AddSC_go_scripts() { // Ours new go_noblegarden_colored_egg(); new go_seer_of_zebhalak(); new go_mistwhisper_treasure(); new go_witherbark_totem_bundle(); new go_arena_ready_marker(); new go_ethereum_prison(); new go_ethereum_stasis(); new go_resonite_cask(); new go_tadpole_cage(); new go_flames(); new go_heat(); // Theirs new go_brewfest_music(); new go_pirate_day_music(); new go_darkmoon_faire_music(); new go_midsummer_music(); new go_cat_figurine(); new go_gilded_brazier(); //new go_shrine_of_the_birds(); new go_southfury_moonstone(); new go_tablet_of_madness(); new go_tablet_of_the_seven(); new go_jump_a_tron(); new go_sacred_fire_of_life(); new go_tele_to_dalaran_crystal(); new go_tele_to_violet_stand(); new go_fel_crystalforge(); new go_bashir_crystalforge(); new go_scourge_cage(); new go_arcane_prison(); new go_jotunheim_cage(); new go_table_theka(); new go_inconspicuous_landmark(); new go_soulwell(); new go_dragonflayer_cage(); new go_amberpine_outhouse(); new go_hive_pod(); new go_massive_seaforium_charge(); new go_veil_skith_cage(); }