void instance_blood_furnace::OnCreatureDeath(Creature* pCreature)
{
    if (m_auiEncounter[TYPE_BROGGOK_EVENT] != IN_PROGRESS)
        return;

    if (pCreature->GetEntry() == NPC_NASCENT_FEL_ORC)
    {
        uint8 uiClearedCells = 0;
        for (uint8 i = 0; i < std::min<uint32>(m_uiBroggokEventPhase, MAX_ORC_WAVES); ++i)
        {
            if (m_aBroggokEvent[i].m_sSortedOrcGuids.size() == m_aBroggokEvent[i].m_uiKilledOrcCount)
            {
                ++uiClearedCells;
                continue;
            }

            // Increase kill counter, if we found a mob of this cell
            if (m_aBroggokEvent[i].m_sSortedOrcGuids.find(pCreature->GetObjectGuid()) != m_aBroggokEvent[i].m_sSortedOrcGuids.end())
                m_aBroggokEvent[i].m_uiKilledOrcCount++;

            if (m_aBroggokEvent[i].m_sSortedOrcGuids.size() == m_aBroggokEvent[i].m_uiKilledOrcCount)
                ++uiClearedCells;
        }

        // Increase phase when all opened cells are cleared
        if (uiClearedCells == m_uiBroggokEventPhase)
            DoNextBroggokEventPhase();
    }
}
    void Update(uint32 diff)
    {
        if (BroggokEventTimer && BroggokEventPhase < MAX_ORC_WAVES && instance->IsHeroic())
        {
            if (BroggokEventTimer <= diff)
                DoNextBroggokEventPhase();
            else BroggokEventTimer -= diff;
        }

        if (DoorTimer)
        {
            if (DoorTimer <= diff)
            {
                if (GameObject* Brog2 = instance->GetGameObject(Brog2GUID))
                {
                    if (Brog2)
                        Brog2->ResetDoorOrButton();

                }
                if (Creature* pBroggok = instance->GetCreature(BroggokGUID))
                {
                    pBroggok->SetReactState(REACT_AGGRESSIVE);
                    pBroggok->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_IMMUNE_TO_NPC);
                    pBroggok->SetInCombatWithZone();
                }
            }
            else DoorTimer -= diff;
        }
    }
void instance_blood_furnace::Update(uint32 uiDiff)
{
    // Broggok Event: For the last wave we don't check the timer; the boss is released only when all mobs die, also the timer is only active on heroic
    if (m_auiEncounter[TYPE_BROGGOK_EVENT] == IN_PROGRESS && m_uiBroggokEventPhase < MAX_ORC_WAVES && !instance->IsRegularDifficulty())
    {
        if (m_uiBroggokEventTimer < uiDiff)
            DoNextBroggokEventPhase();
        else
            m_uiBroggokEventTimer -= uiDiff;
    }
}
void instance_blood_furnace::Update(uint32 uiDiff)
{
    // Broggok Event: For the last wave we don't check the timer; the boss is released only when all mobs die, also the timer is only active on heroic
    if (m_auiEncounter[TYPE_BROGGOK_EVENT] == IN_PROGRESS && m_uiBroggokEventPhase < MAX_ORC_WAVES && !instance->IsRegularDifficulty())
    {
        if (m_uiBroggokEventTimer < uiDiff)
            DoNextBroggokEventPhase();
        else
            m_uiBroggokEventTimer -= uiDiff;
    }

    if (m_uiRandYellTimer < uiDiff)
    {
        if (Creature* pMagtheridon = GetSingleCreatureFromStorage(NPC_MAGTHERIDON))
        {
            DoScriptText(aRandomTaunt[urand(0, 5)], pMagtheridon);
            m_uiRandYellTimer = 90000;
        }
    }
    else
        m_uiRandYellTimer -= uiDiff;
}
    void OnCreatureDeath(Creature* pCreature)
    {
        if (pCreature->GetEntry() == NPC_NASCENT_FEL_ORC)
        {
            uint8 uiClearedCells = 0;
            for (uint8 i = 0; i < std::min<uint32>(BroggokEventPhase, MAX_ORC_WAVES); ++i)
            {
                if (BroggokEvent[i].SortedOrcGuids.size() == BroggokEvent[i].KilledOrcCount)
                {
                    ++uiClearedCells;
                    continue;
                }

               if (BroggokEvent[i].SortedOrcGuids.find(pCreature->GetGUID()) != BroggokEvent[i].SortedOrcGuids.end())
                   BroggokEvent[i].KilledOrcCount++;

               if (BroggokEvent[i].SortedOrcGuids.size() == BroggokEvent[i].KilledOrcCount)
                   ++uiClearedCells;
            }

            if (uiClearedCells == BroggokEventPhase)
                DoNextBroggokEventPhase();
        }
    }
    void Update(uint32 diff)
    {
        if (BroggokEventTimer && BroggokEventPhase < MAX_ORC_WAVES && instance->IsHeroic())
        {
            if (BroggokEventTimer <= diff)
            {
                DoNextBroggokEventPhase();
            }
            else BroggokEventTimer -= diff;
        }

        if (DoorTimer)
        {
            if (DoorTimer <= diff)
            {
                if (GameObject* Brog2 = instance->GetGameObject(Brog2GUID))
                {
                    if (Brog2)
                        Brog2->ResetDoorOrButton();
                }
            }
            else DoorTimer -= diff;
        }
    }
void instance_blood_furnace::SetData(uint32 uiType, uint32 uiData)
{
    switch (uiType)
    {
        case TYPE_THE_MAKER_EVENT:
            if (uiData == IN_PROGRESS)
                DoUseDoorOrButton(GO_DOOR_MAKER_FRONT);
            if (uiData == FAIL)
                DoUseDoorOrButton(GO_DOOR_MAKER_FRONT);
            if (uiData == DONE)
            {
                DoUseDoorOrButton(GO_DOOR_MAKER_FRONT);
                DoUseDoorOrButton(GO_DOOR_MAKER_REAR);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_BROGGOK_EVENT:
            if (m_auiEncounter[uiType] == uiData)
                return;

            // Combat door; the exit door is opened in event
            DoUseDoorOrButton(GO_DOOR_BROGGOK_FRONT);
            if (uiData == IN_PROGRESS)
            {
                if (m_uiBroggokEventPhase <= MAX_ORC_WAVES)
                {
                    m_uiBroggokEventPhase = 0;
                    DoSortBroggokOrcs();
                    // open first cage
                    DoNextBroggokEventPhase();
                }
            }
            else if (uiData == FAIL)
            {
                // On wipe we reset only the orcs; if the party wipes at the boss itself then the orcs don't reset
                if (m_uiBroggokEventPhase <= MAX_ORC_WAVES)
                {
                    for (uint8 i = 0; i < MAX_ORC_WAVES; ++i)
                    {
                        // Reset Orcs
                        if (!m_aBroggokEvent[i].m_bIsCellOpened)
                            continue;

                        m_aBroggokEvent[i].m_uiKilledOrcCount = 0;
                        for (GuidSet::const_iterator itr = m_aBroggokEvent[i].m_sSortedOrcGuids.begin(); itr != m_aBroggokEvent[i].m_sSortedOrcGuids.end(); ++itr)
                        {
                            if (Creature* pOrc = instance->GetCreature(*itr))
                            {
                                if (!pOrc->isAlive())
                                    pOrc->Respawn();
                            }
                        }

                        // Close Door
                        DoUseDoorOrButton(m_aBroggokEvent[i].m_cellGuid);
                        m_aBroggokEvent[i].m_bIsCellOpened = false;
                    }
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_KELIDAN_EVENT:
            if (uiData == DONE)
            {
                DoUseDoorOrButton(GO_DOOR_KELIDAN_EXIT);
                DoUseDoorOrButton(GO_DOOR_FINAL_EXIT);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        default:
            script_error_log("Instance Blood Furnace SetData with Type %u Data %u, but this is not implemented.", uiType, uiData);
            return;
    }

    if (uiData == DONE)
    {
        OUT_SAVE_INST_DATA;

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

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}
    void SetData(uint32 type, uint32 data)
    {
        switch(type)
        {
            case DATA_MAKEREVENT:
                if (data == IN_PROGRESS)
                {
                    HandleGameObject(Maker1GUID, false);
                }
                else HandleGameObject(Maker1GUID, true);
                if (data == DONE)
                {
                    HandleGameObject(Maker2GUID, true);
                }
                if (Encounter[0] != DONE)
                    Encounter[0] = data;
                break;
            case DATA_BROGGOKEVENT:
                if (data == IN_PROGRESS)
                {
                    if (Creature* pBroggok = instance->GetCreature(BroggokGUID))
                        DoScriptText(SAY_BROGGOK_INTRO, pBroggok);

                    HandleGameObject(Brog1GUID, false);

                    if (BroggokEventPhase <= MAX_ORC_WAVES)
                    {
                        DoSortBroggokOrcs();
                        DoNextBroggokEventPhase();
                    }
                }
                else 
                {
                    HandleGameObject(Brog1GUID, true);
                }
                if (data == FAIL)
                {
                    if (BroggokEventPhase <= MAX_BROGGOK_WAVES)
                    {
                        for (uint8 i = 0; i < MAX_ORC_WAVES; ++i)
                        {
                            if (!BroggokEvent[i].IsCellOpened)
                                continue;

                            BroggokEvent[i].KilledOrcCount = 0;
                            for (std::set<uint64>::const_iterator itr = BroggokEvent[i].SortedOrcGuids.begin(); itr != BroggokEvent[i].SortedOrcGuids.end(); ++itr)
                            {
                                if (Creature* pOrc = instance->GetCreature(*itr))
                                {
                                    if (!pOrc->isAlive())
                                    {
                                        pOrc->Respawn();
                                        BroggokEventPhase = 0;
                                    }
                                }
                            }

                            DoUseDoorOrButton(BroggokEvent[i].CellGuid);
                            BroggokEvent[i].IsCellOpened = false;
                            if (GameObject* Lever = instance->GetGameObject(LeverGUID))
                            {
                                if (Lever)
                                    Lever->ResetDoorOrButton();
                            }
                        }
                    }
           
                }
                if (data == DONE)
                {
                    HandleGameObject(Brog2GUID, true);
                }
                if (Encounter[1] != DONE)
                    Encounter[1] = data;
                break;
            case DATA_KELIDANEVENT:
                if (data == DONE)
                {
                    HandleGameObject(Sewer1GUID, true);
                    HandleGameObject(Sewer2GUID, true);
                }
                if (Encounter[2] != DONE)
                    Encounter[2] = data;
                break;
        }

        if (data == DONE)
        {
            SaveToDB();
            OUT_SAVE_INST_DATA_COMPLETE;
        }
    }