// Function to search for new tubber in range
    void DoFindNewTubber()
    {
        GameObjectList 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 (GameObjectList::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;
    }
Exemple #3
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 instance_gnomeregan::SetData(uint32 uiType, uint32 uiData)
{
    switch (uiType)
    {
        case TYPE_GRUBBIS:
            m_auiEncounter[0] = uiData;
            if (uiData == IN_PROGRESS)
            {
                // Sort the explosive charges if needed
                if (!m_luiExplosiveChargeGUIDs.empty())
                {
                    GameObjectList lExplosiveCharges;
                    for (GuidList::const_iterator itr = m_luiExplosiveChargeGUIDs.begin(); itr != m_luiExplosiveChargeGUIDs.end(); ++itr)
                    {
                        if (GameObject* pCharge = instance->GetGameObject(*itr))
                            lExplosiveCharges.push_back(pCharge);
                    }
                    m_luiExplosiveChargeGUIDs.clear();

                    // Sort from east to west
                    lExplosiveCharges.sort(sortFromEastToWest);

                    // Sort to south and north
                    uint8 uiCounterSouth = 0;
                    uint8 uiCounterNorth = 0;
                    GameObject* pCaveInSouth = GetSingleGameObjectFromStorage(GO_CAVE_IN_SOUTH);
                    GameObject* pCaveInNorth = GetSingleGameObjectFromStorage(GO_CAVE_IN_NORTH);
                    if (pCaveInSouth && pCaveInNorth)
                    {
                        for (auto& lExplosiveCharge : lExplosiveCharges)
                        {
                            if (lExplosiveCharge->GetDistanceOrder(pCaveInSouth, pCaveInNorth) && uiCounterSouth < MAX_EXPLOSIVES_PER_SIDE)
                            {
                                m_aExplosiveSortedGuids[0][uiCounterSouth] = lExplosiveCharge->GetObjectGuid();
                                ++uiCounterSouth;
                            }
                            else if (uiCounterNorth < MAX_EXPLOSIVES_PER_SIDE)
                            {
                                m_aExplosiveSortedGuids[1][uiCounterNorth] = lExplosiveCharge->GetObjectGuid();
                                ++uiCounterNorth;
                            }
                        }
                    }
                }
            }
            if (uiData == FAIL)
            {
                // Despawn possible spawned explosive charges
                SetData(TYPE_EXPLOSIVE_CHARGE, DATA_EXPLOSIVE_CHARGE_USE);
            }
            if (uiData == DONE)
            {
                for (GuidList::const_iterator itr = m_lRedRocketGUIDs.begin(); itr != m_lRedRocketGUIDs.end(); ++itr)
                    DoRespawnGameObject(*itr, HOUR);
            }
            break;
        case TYPE_EXPLOSIVE_CHARGE:
            switch (uiData)
            {
                case DATA_EXPLOSIVE_CHARGE_1:
                    DoRespawnGameObject(m_aExplosiveSortedGuids[0][0], HOUR);
                    m_luiSpawnedExplosiveChargeGUIDs.push_back(m_aExplosiveSortedGuids[0][0]);
                    break;
                case DATA_EXPLOSIVE_CHARGE_2:
                    DoRespawnGameObject(m_aExplosiveSortedGuids[0][1], HOUR);
                    m_luiSpawnedExplosiveChargeGUIDs.push_back(m_aExplosiveSortedGuids[0][1]);
                    break;
                case DATA_EXPLOSIVE_CHARGE_3:
                    DoRespawnGameObject(m_aExplosiveSortedGuids[1][0], HOUR);
                    m_luiSpawnedExplosiveChargeGUIDs.push_back(m_aExplosiveSortedGuids[1][0]);
                    break;
                case DATA_EXPLOSIVE_CHARGE_4:
                    DoRespawnGameObject(m_aExplosiveSortedGuids[1][1], HOUR);
                    m_luiSpawnedExplosiveChargeGUIDs.push_back(m_aExplosiveSortedGuids[1][1]);
                    break;
                case DATA_EXPLOSIVE_CHARGE_USE:
                    Creature* pBlastmaster = GetSingleCreatureFromStorage(NPC_BLASTMASTER_SHORTFUSE);
                    if (!pBlastmaster)
                        break;
                    for (GuidList::const_iterator itr = m_luiSpawnedExplosiveChargeGUIDs.begin(); itr != m_luiSpawnedExplosiveChargeGUIDs.end(); ++itr)
                    {
                        if (GameObject* pExplosive = instance->GetGameObject(*itr))
                            pExplosive->Use(pBlastmaster);
                    }
                    m_luiSpawnedExplosiveChargeGUIDs.clear();
                    break;
            }
            return;
        case TYPE_THERMAPLUGG:
            m_auiEncounter[1] = uiData;
            if (uiData == IN_PROGRESS)
            {
                // Make Door locked
                if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_THE_FINAL_CHAMBER))
                {
                    pDoor->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
                    if (pDoor->GetLootState() == GO_ACTIVATED)
                        pDoor->ResetDoorOrButton();
                }

                // Always directly activates this bomb-face
                DoActivateBombFace(2);
            }
            else if (uiData == DONE || uiData == FAIL)
            {
                // Make Door unlocked again
                if (GameObject* pDoor = GetSingleGameObjectFromStorage(GO_THE_FINAL_CHAMBER))
                {
                    pDoor->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
                    if (pDoor->GetLootState() == GO_READY)
                        pDoor->UseDoorOrButton();
                }

                // Deactivate all remaining BombFaces
                for (uint8 i = 0; i < MAX_GNOME_FACES; ++i)
                    DoDeactivateBombFace(i);
            }
            break;
    }

    if (uiData == DONE)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;
        saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1];

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}