// Function to search for new rookery egg in range void DoFindNewEgg() { GameObjectList lEggsInRange; GetGameObjectListWithEntryInGrid(lEggsInRange, m_creature, GO_ROOKERY_EGG, 20.0f); if (lEggsInRange.empty()) // No GO found return; lEggsInRange.sort(ObjectDistanceOrder(m_creature)); GameObject* pNearestEgg = nullptr; // Always need to find new ones for (GameObjectList::const_iterator itr = lEggsInRange.begin(); itr != lEggsInRange.end(); ++itr) { if (!((*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE))) { pNearestEgg = *itr; break; } } if (!pNearestEgg) return; float fX, fY, fZ; pNearestEgg->GetContactPoint(m_creature, fX, fY, fZ, 1.0f); m_creature->SetWalk(false); m_creature->GetMotionMaster()->MovePoint(1, fX, fY, fZ); m_bIsMovementActive = true; }
void DoFindNewTubber() { std::list<GameObject*> tubbersInRange; GetGameObjectListWithEntryInGrid(tubbersInRange, me, GO_BLUELEAF_TUBBER, 40.0f); if (tubbersInRange.empty()) return; tubbersInRange.remove_if([](GameObject* go) { return go->isSpawned() || !go->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND); }); tubbersInRange.sort(Trinity::ObjectDistanceOrderPred(me)); GameObject* nearestTubber = tubbersInRange.front(); if (!nearestTubber) return; TargetTubberGUID = nearestTubber->GetGUID(); // XFurry was wrong... me->GetMotionMaster()->MovePoint(POINT_TUBBER, nearestTubber->GetPositionX(), nearestTubber->GetPositionY(), nearestTubber->GetPositionZ()); IsMovementActive = true; }
void Reset() { m_uiPoisonVolley_Timer = 15000; m_uiSpawnSpider_Timer = 20000; m_uiAspect_Timer = 12000; m_uiTransform_Timer = 60000; m_uiTransformBack_Timer = 60000; m_uiDrainLife_Timer = 30000; m_uiCorrosivePoison_Timer = 1000; m_uiWebs_Timer = 5000; m_uiTrash_Timer = 5000; m_bFirstSpidersAreSpawned = false; m_bIsInPhaseTwo = false; m_bHasWebbed = false; std::list<GameObject*> lSpiderEggs; GetGameObjectListWithEntryInGrid(lSpiderEggs, m_creature, GO_EGG, DEFAULT_VISIBILITY_INSTANCE); if (lSpiderEggs.empty()) debug_log("DS: boss_marli, no Eggs with the entry %u were found", GO_EGG); else { for(std::list<GameObject*>::iterator iter = lSpiderEggs.begin(); iter != lSpiderEggs.end(); ++iter) { if ((*iter)->GetGoState() == GO_STATE_ACTIVE) (*iter)->SetGoState(GO_STATE_READY); } } }
void DoFindNewTubber() { std::list<GameObject*> tubbersInRange; GetGameObjectListWithEntryInGrid(tubbersInRange, me, GO_BLUELEAF_TUBBER, 40.0f); if (tubbersInRange.empty()) return; tubbersInRange.sort(DistanceOrder(me)); GameObject* nearestTubber = NULL; for (std::list<GameObject*>::const_iterator itr = tubbersInRange.begin(); itr != tubbersInRange.end(); ++itr) { if (!(*itr)->isSpawned() && (*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND)) { nearestTubber = *itr; break; } } if (!nearestTubber) return; TargetTubberGUID = nearestTubber->GetGUID(); // XFurry was wrong... me->GetMotionMaster()->MovePoint(POINT_TUBBER, nearestTubber->GetPositionX(), nearestTubber->GetPositionY(), nearestTubber->GetPositionZ()); IsMovementActive = true; }
// Function to search for new tubber in range void DoFindNewTubber() { std::list<GameObject*> lTubbersInRange; GetGameObjectListWithEntryInGrid(lTubbersInRange, m_creature, GO_BLUELEAF_TUBBER, 40.0f); if (lTubbersInRange.empty()) return; lTubbersInRange.sort(ObjectDistanceOrder(m_creature)); GameObject* pNearestTubber = nullptr; // Always need to find new ones for (std::list<GameObject*>::const_iterator itr = lTubbersInRange.begin(); itr != lTubbersInRange.end(); ++itr) { if (!(*itr)->isSpawned() && (*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND) && (*itr)->IsWithinLOSInMap(m_creature)) { pNearestTubber = *itr; break; } } if (!pNearestTubber) return; m_targetTubberGuid = pNearestTubber->GetObjectGuid(); float fX, fY, fZ; pNearestTubber->GetContactPoint(m_creature, fX, fY, fZ); m_creature->GetMotionMaster()->MovePoint(1, fX, fY, fZ); m_bIsMovementActive = true; }
void SetPlatform(uint32 entry, bool ready) { std::list<GameObject*> gobjects; GetGameObjectListWithEntryInGrid(gobjects, me, entry, 80.0f); for (auto gobject : gobjects) gobject->SetGoState(ready ? GO_STATE_READY : GO_STATE_ACTIVE); }
void RemoveTraps() { // make sure there's no traps after a reset std::list<GameObject*> m_lTraps; GetGameObjectListWithEntryInGrid(m_lTraps, m_creature, GO_SAND_TRAP, 50.f); if (!m_lTraps.empty()) for(std::list<GameObject*>::iterator itr = m_lTraps.begin(); itr != m_lTraps.end(); ++itr) if ((*itr)) (*itr)->RemoveFromWorld(); }
void DespawnGameobjects(uint32 entry, float distance) { std::list<GameObject*> gameobjects; GetGameObjectListWithEntryInGrid(gameobjects, me, entry, distance); if (gameobjects.empty()) return; for (std::list<GameObject*>::iterator iter = gameobjects.begin(); iter != gameobjects.end(); ++iter) (*iter)->RemoveFromWorld(); }
// Function to respawn fire GOs void DoRespawnFires(bool bFirstEvent) { GameObjectList lFiresInRange; GetGameObjectListWithEntryInGrid(lFiresInRange, m_creature, GO_COIL_FIRE_L, 110.0f); GetGameObjectListWithEntryInGrid(lFiresInRange, m_creature, GO_COIL_FIRE_S, 110.0f); if (lFiresInRange.empty()) { script_error_log("Bloodmyst Isle: ERROR Failed to find any gameobjects of entry %u and %u in range.", GO_COIL_FIRE_L, GO_COIL_FIRE_S); return; } for (GameObjectList::const_iterator itr = lFiresInRange.begin(); itr != lFiresInRange.end(); ++itr) { if ((bFirstEvent && (*itr)->GetPositionZ() < 150.0f) || (!bFirstEvent && (*itr)->GetPositionZ() > 150.0f)) { (*itr)->SetRespawnTime(5 * MINUTE); (*itr)->Refresh(); } } }
void WaypointReached(uint32 uiPointId) override { switch (uiPointId) { case 3: DoScriptText(SAY_ENTER_OWL_THICKET, m_creature); break; case 10: // Cavern 1 case 15: // Cavern 2 case 20: // Cavern 3 case 25: // Cavern 4 case 36: // Cavern 5 m_uiCurrentWaypoint = uiPointId; DoChannelTorchSpell(); break; case 39: m_uiCurrentWaypoint = uiPointId; StartNextDialogueText(SAY_REACH_ALTAR_1); SetEscortPaused(true); break; case 41: { // Search for all nearest lights and respawn them std::list<GameObject*> m_lEluneLights; GetGameObjectListWithEntryInGrid(m_lEluneLights, m_creature, GO_ELUNE_LIGHT, 20.0f); for (std::list<GameObject*>::const_iterator itr = m_lEluneLights.begin(); itr != m_lEluneLights.end(); ++itr) { if ((*itr)->isSpawned()) continue; (*itr)->SetRespawnTime(115); (*itr)->Refresh(); } if (GameObject* pAltar = m_creature->GetMap()->GetGameObject(m_altarGuid)) m_creature->SetFacingToObject(pAltar); break; } case 42: // Summon the 2 priestess SetEscortPaused(true); DoSummonPriestess(); DoScriptText(SAY_RANSHALLA_ALTAR_2, m_creature); break; case 44: // Stop the escort and turn towards the altar SetEscortPaused(true); if (GameObject* pAltar = m_creature->GetMap()->GetGameObject(m_altarGuid)) m_creature->SetFacingToObject(pAltar); break; } }
void WaypointReached(uint32 pointId) { switch(pointId) { case 3: Talk(SAY_ENTER_OWL_THICKET); break; case 10: // Cavern 1 case 15: // Cavern 2 case 20: // Cavern 3 case 25: // Cavern 4 case 36: // Cavern 5 DoChannelTorchSpell(); break; case 39: StartNextDialogueText(SAY_REACH_ALTAR_1); SetEscortPaused(true); break; case 41: { // Search for all nearest lights and respawn them std::list<GameObject*> eluneLights; GetGameObjectListWithEntryInGrid(eluneLights, me, GO_ELUNE_LIGHT, 20.0f); for (std::list<GameObject*>::const_iterator itr = eluneLights.begin(); itr != eluneLights.end(); ++itr) { if ((*itr)->isSpawned()) continue; (*itr)->SetRespawnTime(115); (*itr)->Refresh(); } if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID)) me->SetFacingToObject(altar); break; } case 42: // Summon the 2 priestess SetEscortPaused(true); DoSummonPriestess(); Talk(SAY_RANSHALLA_ALTAR_2); events.ScheduleEvent(EVENT_RESUME,2000); break; case 44: // Stop the escort and turn towards the altar SetEscortPaused(true); if (GameObject* altar = me->GetMap()->GetGameObject(_altarGUID)) me->SetFacingToObject(altar); break; } }
GameObject* SelectNextEgg() { std::list<GameObject*> lEggs; GetGameObjectListWithEntryInGrid(lEggs, me, GO_EGG, DEFAULT_VISIBILITY_INSTANCE); if (lEggs.empty()) debug_log("SD2: boss_marli, no Eggs with the entry %i were found", GO_EGG); else { lEggs.sort(ObjectDistanceOrder(me)); for(std::list<GameObject*>::iterator iter = lEggs.begin(); iter != lEggs.end(); ++iter) { if ((*iter)->GetGoState() == (GO_STATE_READY)) return (*iter); } } return NULL; }
// function to cleanup the world states and GO flags void DoEncounterCleanup() { // remove world state if (Player* pSummoner = m_creature->GetMap()->GetPlayer(m_summonerGuid)) pSummoner->SendUpdateWorldState(WORLD_STATE_TETHYR_SHOW, 0); // reset all cannons std::list<GameObject*> lCannonsInRange; GetGameObjectListWithEntryInGrid(lCannonsInRange, m_creature, GO_COVE_CANNON, 100.0f); for (std::list<GameObject*>::const_iterator itr = lCannonsInRange.begin(); itr != lCannonsInRange.end(); ++itr) (*itr)->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); // despawn all marksmen std::list<Creature*> lMarksmenInRange; GetCreatureListWithEntryInGrid(lMarksmenInRange, m_creature, NPC_THERAMORE_MARKSMAN, 100.0f); for (std::list<Creature*>::const_iterator itr = lMarksmenInRange.begin(); itr != lMarksmenInRange.end(); ++itr) (*itr)->ForcedDespawn(30000); }
// Function to respawn GOs void DoRespawnObjects(uint32 uiEntry, float fRange) { GameObjectList lBarrelsInRange; m_lExplosivesGuidsList.clear(); GetGameObjectListWithEntryInGrid(lBarrelsInRange, m_creature, uiEntry, fRange); if (lBarrelsInRange.empty()) { script_error_log("Bloodmyst Isle: ERROR Failed to find any gameobjects of entry %u in range.", uiEntry); return; } // respawn explosives and store for future use for (GameObjectList::const_iterator itr = lBarrelsInRange.begin(); itr != lBarrelsInRange.end(); ++itr) { (*itr)->SetRespawnTime(5 * MINUTE); (*itr)->Refresh(); m_lExplosivesGuidsList.push_back((*itr)->GetObjectGuid()); } }
// Function to search for new tubber in range void DoFindNewCrystal(Player* pMaster) { GameObjectList lCrystalsInRange; for (unsigned int i : aGOList) { GetGameObjectListWithEntryInGrid(lCrystalsInRange, m_creature, i, 40.0f); // If a crystal was found in range, stop the search here, else try with another GO if (!lCrystalsInRange.empty()) break; } if (lCrystalsInRange.empty()) // Definely no GO found { m_creature->PlayDirectSound(SOUND_GROWL); return; } lCrystalsInRange.sort(ObjectDistanceOrder(m_creature)); GameObject* pNearestCrystal = nullptr; // Always need to find new ones for (GameObjectList::const_iterator itr = lCrystalsInRange.begin(); itr != lCrystalsInRange.end(); ++itr) { if ((*itr)->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_INTERACT_COND)) { pNearestCrystal = *itr; break; } } if (!pNearestCrystal) { m_creature->PlayDirectSound(SOUND_GROWL); return; } float fX, fY, fZ; pNearestCrystal->GetContactPoint(m_creature, fX, fY, fZ, 3.0f); m_creature->SetWalk(false); m_creature->GetMotionMaster()->MovePoint(1, fX, fY, fZ); m_bIsMovementActive = true; }
void MovementInform(uint32 uiMotionType, uint32 uiPointId) override { if (uiMotionType == WAYPOINT_MOTION_TYPE) { // start attacking if (uiPointId == 12) { // make cannons usable std::list<GameObject*> lCannonsInRange; GetGameObjectListWithEntryInGrid(lCannonsInRange, m_creature, GO_COVE_CANNON, 100.0f); for (std::list<GameObject*>::const_iterator itr = lCannonsInRange.begin(); itr != lCannonsInRange.end(); ++itr) (*itr)->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); // attack all marksmen std::list<Creature*> lMarksmenInRange; GetCreatureListWithEntryInGrid(lMarksmenInRange, m_creature, NPC_THERAMORE_MARKSMAN, 100.0f); for (std::list<Creature*>::const_iterator itr = lMarksmenInRange.begin(); itr != lMarksmenInRange.end(); ++itr) { (*itr)->AI()->AttackStart(m_creature); AttackStart(*itr); } } } else if (uiMotionType == POINT_MOTION_TYPE) { // Spout on cannon point reach if (uiPointId) { if (DoCastSpellIfCan(m_creature, urand(0, 1) ? SPELL_SPOUT_LEFT : SPELL_SPOUT_RIGHT, CAST_INTERRUPT_PREVIOUS) == CAST_OK) { // Remove the target focus m_creature->SetTargetGuid(ObjectGuid()); m_uiPhase = PHASE_SPOUT; } } } }
void MovementInform(uint32 uiMovementType, uint32 uiPointId) override { if (!uiPointId) return; DoCastSpellIfCan(m_creature, SPELL_QUEST_CREDIT, CAST_TRIGGERED); DoCastSpellIfCan(m_creature, SPELL_COSMETIC_EXPLOSION, CAST_TRIGGERED); DoScriptText(EMOTE_FLARE_BURST, m_creature); m_creature->ForcedDespawn(2000); // respawn all fires in range std::list<GameObject*> lFiresInRange; GetGameObjectListWithEntryInGrid(lFiresInRange, m_creature, GO_LARGE_FIRE, 50.0f); if (lFiresInRange.empty()) return; for (std::list<GameObject*>::const_iterator itr = lFiresInRange.begin(); itr != lFiresInRange.end(); ++itr) { (*itr)->SetRespawnTime(60); (*itr)->Refresh(); } }
void FilterTargets(std::list<WorldObject*>& unitList) { std::list<GameObject*> stalagmites; GetGameObjectListWithEntryInGrid(stalagmites, GetCaster(), GO_STALAGMITE, 100.0f); unitList.remove_if(crystal_storm_filter(GetCaster(), stalagmites)); }
void UpdateEscortAI(const uint32 uiDiff) override { if (HasEscortState(STATE_ESCORT_PAUSED)) { if (m_uiRitualTimer < uiDiff) { switch (m_uiRitualPhase) { case 0: DoCastSpellIfCan(m_creature, SPELL_IDOL_SHUTDOWN); m_uiRitualTimer = 1000; break; case 1: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 39000; break; case 2: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 3: DoScriptText(SAY_BELNISTRASZ_3_MIN, m_creature, m_creature); m_uiRitualTimer = 20000; break; case 4: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 40000; break; case 5: DoSummonSpawner(irand(1, 3)); DoScriptText(SAY_BELNISTRASZ_2_MIN, m_creature, m_creature); m_uiRitualTimer = 40000; break; case 6: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 7: DoScriptText(SAY_BELNISTRASZ_1_MIN, m_creature, m_creature); m_uiRitualTimer = 40000; break; case 8: DoSummonSpawner(irand(1, 3)); m_uiRitualTimer = 20000; break; case 9: DoScriptText(SAY_BELNISTRASZ_FINISH, m_creature, m_creature); m_uiRitualTimer = 3000; break; case 10: { if (Player* pPlayer = GetPlayerForEscort()) { pPlayer->RewardPlayerAndGroupAtEventExplored(QUEST_EXTINGUISHING_THE_IDOL, m_creature); if (GameObject* pGo = GetClosestGameObjectWithEntry(m_creature, GO_BELNISTRASZ_BRAZIER, 10.0f)) { if (!pGo->IsSpawned()) { pGo->SetRespawnTime(HOUR * IN_MILLISECONDS); pGo->Refresh(); } } } m_creature->RemoveAurasDueToSpell(SPELL_IDOL_SHUTDOWN); SetEscortPaused(false); // Desactivate the fires on the idol now it is extinguished DoCastSpellIfCan(m_creature, SPELL_IDOL_ROOM_SHAKE); GameObjectList lOvenFires; for (auto&& gameObjectEntry : aGOList) GetGameObjectListWithEntryInGrid(lOvenFires, m_creature, gameObjectEntry, 40.0f); for (auto&& gameObject : lOvenFires) gameObject->SetLootState(GO_JUST_DEACTIVATED); break; } } ++m_uiRitualPhase; } else m_uiRitualTimer -= uiDiff; return; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (m_uiFireballTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FIREBALL); m_uiFireballTimer = urand(2000, 3000); } else m_uiFireballTimer -= uiDiff; if (m_uiFrostNovaTimer < uiDiff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_FROST_NOVA); m_uiFrostNovaTimer = urand(10000, 15000); } else m_uiFrostNovaTimer -= uiDiff; DoMeleeAttackIfReady(); }
void Aggro(Unit* pWho) { for (uint8 i = 0; i < 4; ++i) m_PlagueFissureGUID[i].clear(); for (uint32 i = 10; i <= 52; ++i) if (GameObject* pPlagueFissure = GetClosestGameObjectWithEntry(m_creature, 181500+i, 100.0f)) { if (i != 10 && i != 17 && i != 18 && i != 19 && i != 20 && i != 21 && i != 22 && i != 23 && i != 24 && i != 26) m_PlagueFissureGUID[0].push_back(pPlagueFissure->GetGUID()); if (i != 11 && i != 12 && i != 13 && i != 14 && i != 15 && i != 16 && i != 25 && i != 27 && i != 28 && i != 29 && i != 30 && i != 31) m_PlagueFissureGUID[1].push_back(pPlagueFissure->GetGUID()); if (i != 32 && i != 33 && i != 34 && i != 35 && i != 36 && i != 40 && i != 41 && i != 42 && i != 43 && i != 44 && i != 45) m_PlagueFissureGUID[2].push_back(pPlagueFissure->GetGUID()); if (i != 37 && i != 48 && i != 39 && i != 46 && i != 47 && i != 48 && i != 49 && i != 50 && i != 51 && i != 52) m_PlagueFissureGUID[3].push_back(pPlagueFissure->GetGUID()); } std::list<GameObject*> lList; GetGameObjectListWithEntryInGrid(lList, m_creature, 181678, 100.0f); if (!lList.empty()) for (std::list<GameObject*>::iterator itr = lList.begin(); itr != lList.end(); ++itr) { m_PlagueFissureGUID[1].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[2].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[3].push_back((*itr)->GetGUID()); } lList.clear(); GetGameObjectListWithEntryInGrid(lList, m_creature, 181676, 100.0f); if (!lList.empty()) for (std::list<GameObject*>::iterator itr = lList.begin(); itr != lList.end(); ++itr) { m_PlagueFissureGUID[0].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[2].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[3].push_back((*itr)->GetGUID()); } lList.clear(); GetGameObjectListWithEntryInGrid(lList, m_creature, 181677, 100.0f); if (!lList.empty()) for (std::list<GameObject*>::iterator itr = lList.begin(); itr != lList.end(); ++itr) { m_PlagueFissureGUID[0].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[1].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[3].push_back((*itr)->GetGUID()); } lList.clear(); GetGameObjectListWithEntryInGrid(lList, m_creature, 181695, 100.0f); if (!lList.empty()) for (std::list<GameObject*>::iterator itr = lList.begin(); itr != lList.end(); ++itr) { m_PlagueFissureGUID[0].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[1].push_back((*itr)->GetGUID()); m_PlagueFissureGUID[2].push_back((*itr)->GetGUID()); } switch (rand()%3) { case 0: DoScriptText(SAY_AGGRO1, m_creature); break; case 1: DoScriptText(SAY_AGGRO2, m_creature); break; case 2: DoScriptText(SAY_AGGRO3, m_creature); break; } // Teleport "cheaters" to center of room Map* map = m_creature->GetMap(); if (map->IsDungeon()) { Map::PlayerList const &PlayerList = map->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) i->getSource()->TeleportTo(NAXXRAMAS, 2804.946f, -3678.315f, 273.666f, 4.385f); } if(m_pInstance) m_pInstance->SetData(TYPE_HEIGAN, IN_PROGRESS); }