// 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; }
// 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 boss_mr_smiteAI::PhaseEquipStart() { // Try to get scripted instance data ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); if (!pInstance) return; // Get chest object if available GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); if (!pChest) return; // Enter equipment phase (0: Walk to chest object) m_uiPhase = PHASE_EQUIP_NULL; // Get contact point of chest object float fX, fY, fZ; pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); // Erase all previous movements and walk towards the clostest point available near // that chest object m_creature->GetMotionMaster()->Clear(); m_creature->SetFacingToObject(pChest); m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); }
void PhaseEquipStart() { ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); if (!pInstance) { return; } GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); if (!pChest) { return; } m_uiPhase = PHASE_EQUIP_NULL; float fX, fY, fZ; pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); m_creature->GetMotionMaster()->Clear(); m_creature->SetFacingToObject(pChest); m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); }
void instance_blackrock_spire::DoSendNextFlamewreathWave() { GameObject* pSummoner = GetSingleGameObjectFromStorage(GO_FATHER_FLAME); if (!pSummoner) return; // TODO - The npcs would move nicer if they had DB waypoints, so i suggest to change their default movement to DB waypoints, and random movement when they reached their goal if (m_uiFlamewreathWaveCount < 6) // Send two adds (6 waves, then boss) { Creature* pSummoned = NULL; for (uint8 i = 0; i < 2; ++i) { float fX, fY, fZ; pSummoner->GetRandomPoint(rookeryEventSpawnPos[0], rookeryEventSpawnPos[1], rookeryEventSpawnPos[2], 2.5f, fX, fY, fZ); // Summon Rookery Hatchers in first wave, else random if (pSummoned = pSummoner->SummonCreature(urand(0, 1) && m_uiFlamewreathWaveCount ? NPC_ROOKERY_GUARDIAN : NPC_ROOKERY_HATCHER, fX, fY, fZ, 0.0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 300000)) { pSummoner->GetContactPoint(pSummoned, fX, fY, fZ); pSummoned->GetMotionMaster()->MovePoint(1, fX, fY, pSummoner->GetPositionZ()); } } if (pSummoned && m_uiFlamewreathWaveCount == 0) DoScriptText(SAY_ROOKERY_EVENT_START, pSummoned); if (m_uiFlamewreathWaveCount < 4) m_uiFlamewreathEventTimer = 30000; else if (m_uiFlamewreathWaveCount < 6) m_uiFlamewreathEventTimer = 40000; else m_uiFlamewreathEventTimer = 10000; ++m_uiFlamewreathWaveCount; } else // Send Flamewreath { if (Creature* pSolakar = pSummoner->SummonCreature(NPC_SOLAKAR_FLAMEWREATH, rookeryEventSpawnPos[0], rookeryEventSpawnPos[1], rookeryEventSpawnPos[2], 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, HOUR * IN_MILLISECONDS)) pSolakar->GetMotionMaster()->MovePoint(1, pSummoner->GetPositionX(), pSummoner->GetPositionY(), pSummoner->GetPositionZ()); SetData(TYPE_FLAMEWREATH, SPECIAL); m_uiFlamewreathEventTimer = 0; } }
// 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 UpdateAI(const uint32 diff) { if (bCanEat || bIsEating) { if (EatTimer < diff) { if (bCanEat && !bIsEating) { if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid)) { GameObject* pGo = pPlayer->GetGameObject(SPELL_PLACE_CARCASS); // Workaround for broken function GetGameObject if (!pGo) { if (SpellEntry const* pSpell = GetSpellStore()->LookupEntry(SPELL_PLACE_CARCASS)) { if (SpellEffectEntry const * effect = pSpell->GetSpellEffect(EFFECT_INDEX_0)) { uint32 uiGameobjectEntry = effect->EffectMiscValue; pGo = GetClosestGameObjectWithEntry(pPlayer, uiGameobjectEntry, 2*INTERACTION_DISTANCE); } } } if (pGo) { if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) m_creature->GetMotionMaster()->MovementExpired(); m_creature->GetMotionMaster()->MoveIdle(); m_creature->StopMoving(); float fX, fY, fZ; pGo->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); m_creature->GetMotionMaster()->MovePoint(POINT_ID, fX, fY, fZ); } } bCanEat = false; } else if (bIsEating) { DoCastSpellIfCan(m_creature, SPELL_JUST_EATEN); DoScriptText(SAY_JUST_EATEN, m_creature); if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid)) pPlayer->KilledMonsterCredit(NPC_EVENT_PINGER, m_creature->GetObjectGuid()); Reset(); m_creature->GetMotionMaster()->Clear(); } } else EatTimer -= diff; return; } if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) return; if (CastTimer < diff) { DoCastSpellIfCan(m_creature->getVictim(), SPELL_NETHER_BREATH); CastTimer = 5000; }else CastTimer -= diff; DoMeleeAttackIfReady(); }
void UpdateAI(const uint32 diff) { if (m_bEvent) { if (m_bIsMovingToLunch) return; if (m_uiEventTimer < diff) { m_uiEventTimer = 5000; ++m_uiEventPhase; switch (m_uiEventPhase) { case 1: if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid)) { GameObject* pGo = pPlayer->GetGameObject(SPELL_LUNCH); // Workaround for broken function GetGameObject if (!pGo) { const SpellEntry* pSpell = GetSpellStore()->LookupEntry(SPELL_LUNCH); uint32 uiGameobjectEntry = pSpell->EffectMiscValue[EFFECT_INDEX_1]; pGo = GetClosestGameObjectWithEntry(pPlayer, uiGameobjectEntry, 2 * INTERACTION_DISTANCE); } if (pGo) { m_bIsMovingToLunch = true; float fX, fY, fZ; pGo->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); m_creature->GetMotionMaster()->MovePoint(POINT_ID, fX, fY, fZ); } } break; case 2: DoScriptText(EMOTE_EAT_LUNCH, m_creature); m_creature->HandleEmote(EMOTE_STATE_USESTANDING); break; case 3: if (Player* pPlayer = m_creature->GetMap()->GetPlayer(m_playerGuid)) pPlayer->TalkedToCreature(m_creature->GetEntry(), m_creature->GetObjectGuid()); m_creature->UpdateEntry(NPC_KYLE_FRIENDLY); break; case 4: m_uiEventTimer = 30000; DoScriptText(EMOTE_DANCE, m_creature); m_creature->HandleEmote(EMOTE_STATE_DANCESPECIAL); break; case 5: m_creature->HandleEmote(EMOTE_STATE_NONE); Reset(); m_creature->GetMotionMaster()->Clear(); break; } } else m_uiEventTimer -= diff; } }