void instance_zulaman::Update(uint32 uiDiff)
{
    if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
    {
        if (m_uiEventTimer <= uiDiff)
        {
            if (m_auiEncounter[TYPE_RUN_EVENT_TIME] == 5)   // TODO, verify 5min for warning texts
                DoTimeRunSay(RUN_FAIL_SOON);

            if (m_auiEncounter[TYPE_RUN_EVENT_TIME] == 0)
            {
                debug_log("SD2: Instance Zulaman: event time reach end, event failed.");
                SetData(TYPE_EVENT_RUN, FAIL);
                return;
            }

            --m_auiEncounter[TYPE_RUN_EVENT_TIME];
            SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
            debug_log("SD2: Instance Zulaman: minute decrease to %u.", m_auiEncounter[TYPE_RUN_EVENT_TIME]);

            m_uiEventTimer = MINUTE * IN_MILLISECONDS;
        }
        else
            m_uiEventTimer -= uiDiff;
    }
}
void instance_zulaman::DoChestEvent(BossToChestIndex uiIndex)
{
    // Store Order of this kill
    m_aEventNpcInfo[uiIndex].uiSavePosition = GetKilledPreBosses() + 1;

    // Do Yell
    DoTimeRunSay(RUN_PROGRESS);

    // related NPC:     m_aEventNpcInfo[uiIndex].npGuid
    // related Chest:   m_aEventNpcInfo[uiIndex]        // Not yet stored, because likely unneeded
}
void instance_zulaman::SetData(uint32 uiType, uint32 uiData)
{
    debug_log("SD2: Instance Zulaman: SetData received for type %u with data %u", uiType, uiData);

    switch (uiType)
    {
        case TYPE_EVENT_RUN:
            if (uiData == SPECIAL)
            {
                ++m_uiGongCount;
                if (m_uiGongCount == 5)
                    m_auiEncounter[TYPE_EVENT_RUN] = uiData;
                return;
            }
            if (uiData == IN_PROGRESS)
            {
                DoTimeRunSay(RUN_START);
                DoUseDoorOrButton(GO_MASSIVE_GATE);
                if (m_auiEncounter[TYPE_RUN_EVENT_TIME])
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                else
                    SetData(TYPE_RUN_EVENT_TIME, 20);   // 20 Minutes as default time
                DoUpdateWorldState(WORLD_STATE_ID, 1);
            }
            if (uiData == FAIL)
            {
                DoTimeRunSay(RUN_FAIL);
                DoUpdateWorldState(WORLD_STATE_ID, 0);
                // Kill remaining Event NPCs
                for (uint8 i = 0; i < MAX_CHESTS; ++i)
                {
                    // Not yet rescued, so too late
                    if (!m_aEventNpcInfo[i].uiSavePosition)
                    {
                        if (Creature* pCreature = instance->GetCreature(m_aEventNpcInfo[i].npGuid))
                            pCreature->ForcedDespawn();
                    }
                }
            }
            if (uiData == DONE)
            {
                DoTimeRunSay(RUN_DONE);
                DoUpdateWorldState(WORLD_STATE_ID, 0);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_AKILZON:
            DoUseDoorOrButton(GO_WIND_DOOR);
            if (uiData == DONE)
            {
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                {
                    m_auiEncounter[TYPE_RUN_EVENT_TIME] += 10; // Add 10 minutes
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                    DoChestEvent(INDEX_AKILZON);
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_NALORAKK:
            if (uiData == DONE)
            {
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                {
                    m_auiEncounter[TYPE_RUN_EVENT_TIME] += 15; // Add 15 minutes
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                    DoChestEvent(INDEX_NALORAKK);
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_JANALAI:
            if (uiData == DONE)
            {
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                    DoChestEvent(INDEX_JANALAI);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_HALAZZI:
            DoUseDoorOrButton(GO_LYNX_TEMPLE_ENTRANCE);
            if (uiData == DONE)
            {
                DoUseDoorOrButton(GO_LYNX_TEMPLE_EXIT);
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                    DoChestEvent(INDEX_HALAZZI);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_MALACRASS:
            DoUseDoorOrButton(GO_HEXLORD_ENTRANCE);
            if (uiData == DONE)
                DoUseDoorOrButton(GO_WOODEN_DOOR);
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_ZULJIN:
            DoUseDoorOrButton(GO_FIRE_DOOR);
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_RUN_EVENT_TIME:
            m_auiEncounter[uiType] = uiData;
            DoUpdateWorldState(WORLD_STATE_COUNTER, m_auiEncounter[uiType]);
            break;

        case TYPE_RAND_VENDOR_1:
            m_auiRandVendor[0] = uiData;
            break;
        case TYPE_RAND_VENDOR_2:
            m_auiRandVendor[1] = uiData;
            break;

        default:
            script_error_log("Instance Zulaman: ERROR SetData = %u for type %u does not exist/not implemented.", uiType, uiData);
            return;
    }

    if (uiData == DONE && GetKilledPreBosses() == 4 && (uiType == TYPE_AKILZON || uiType == TYPE_NALORAKK || uiType == TYPE_JANALAI || uiType == TYPE_HALAZZI))
    {
        DoUseDoorOrButton(GO_HEXLORD_ENTRANCE);
        if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
            SetData(TYPE_EVENT_RUN, DONE);
    }

    if (uiData == DONE || uiType == TYPE_RUN_EVENT_TIME || uiType == TYPE_EVENT_RUN)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;
        saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
                   << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " "
                   << m_auiEncounter[6] << " " << m_auiEncounter[7];

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}
void instance_zulaman::SetData(uint32 uiType, uint32 uiData)
{
    debug_log("SD2: Instance Zulaman: SetData received for type %u with data %u",uiType,uiData);

    switch (uiType)
    {
        case TYPE_EVENT_RUN:
            if (uiData == SPECIAL)
            {
                ++m_uiGongCount;
                if (m_uiGongCount == 5)
                    m_auiEncounter[TYPE_EVENT_RUN] = uiData;
                return;
            }
            if (uiData == IN_PROGRESS)
            {
                DoTimeRunSay(RUN_START);
                DoUseDoorOrButton(GO_MASSIVE_GATE);
                if (m_auiEncounter[TYPE_RUN_EVENT_TIME])
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                else
                    SetData(TYPE_RUN_EVENT_TIME, 20);   // 20 Minutes as default time
                DoUpdateWorldState(WORLD_STATE_ID, 1);
            }
            if (uiData == FAIL)
            {
                DoTimeRunSay(RUN_FAIL);
                DoUpdateWorldState(WORLD_STATE_ID, 0);
				m_auiEncounter[TYPE_EVENT_RUN] = uiData;
                // Kill remaining Event NPCs
                for (uint8 i = 0; i < MAX_CHESTS; ++i)
                {
                    // Not yet rescued, so too late
                    if (!m_aEventNpcInfo[i].uiSavePosition)
                    {
                        if (Creature* pCreature = instance->GetCreature(m_aEventNpcInfo[i].npGuid))
						{
                            //Summon corpse of creature
                            switch(pCreature->GetEntry())
                            {
                                case NPC_TANZAR:
                                    pCreature->SummonCreature(NPC_TANZARS_CORPSE, 0.0f, 0.0f, 0.0f, 0.0f,TEMPSUMMON_CORPSE_DESPAWN, 0);
                                    break;
                                case NPC_KRAZ:
                                    pCreature->SummonCreature(NPC_KRAZS_CORPSE, 0.0f, 0.0f, 0.0f, 0.0f,TEMPSUMMON_CORPSE_DESPAWN, 0);
                                    break;
                                case NPC_ASHLI:
                                    pCreature->SummonCreature(NPC_ASHLIS_CORPSE, 0.0f, 0.0f, 0.0f, 0.0f,TEMPSUMMON_CORPSE_DESPAWN, 0);
                                    break;
                                case NPC_HARKOR:
                                    pCreature->SummonCreature(NPC_HARKORS_CORPSE, 0.0f, 0.0f, 0.0f, 0.0f,TEMPSUMMON_CORPSE_DESPAWN, 0);
                                    break;
                            }
                            pCreature->ForcedDespawn();
						}
                    }
                }
            }
            if (uiData == DONE)
            {
                DoTimeRunSay(RUN_DONE);
                DoUpdateWorldState(WORLD_STATE_ID, 0);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_AKILZON:
            DoUseDoorOrButton(GO_WIND_DOOR);
            if (uiData == DONE)
            {
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                {
                    m_auiEncounter[TYPE_RUN_EVENT_TIME] += 10; // Add 10 minutes
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                    DoChestEvent(INDEX_AKILZON);
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_NALORAKK:
            if (uiData == DONE)
            {
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                {
                    m_auiEncounter[TYPE_RUN_EVENT_TIME] += 15; // Add 15 minutes
                    SetData(TYPE_RUN_EVENT_TIME, m_auiEncounter[TYPE_RUN_EVENT_TIME]);
                    DoChestEvent(INDEX_NALORAKK);
                }
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_JANALAI:
            if (uiData == FAIL)
            {
                m_uiEggsRemainingCount_Left = 20;
                m_uiEggsRemainingCount_Right = 20;

                for(GUIDList::const_iterator itr = m_lEggsGUIDList.begin(); itr != m_lEggsGUIDList.end(); ++itr)
                {
                    if (Creature* pEgg = instance->GetCreature(*itr))
                    {
                        if (!pEgg->isAlive())
                            pEgg->Respawn();
                    }
                }
            }
            if (uiData == DONE)
            {
                m_lEggsGUIDList.clear();

                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                    DoChestEvent(INDEX_JANALAI);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_HALAZZI:
            DoUseDoorOrButton(GO_LYNX_TEMPLE_ENTRANCE);
            if (uiData == DONE)
            {
                DoUseDoorOrButton(GO_LYNX_TEMPLE_EXIT);
                if (m_auiEncounter[TYPE_EVENT_RUN] == IN_PROGRESS)
                    DoChestEvent(INDEX_HALAZZI);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_MALACRASS:
            DoUseDoorOrButton(GO_HEXLORD_ENTRANCE);
            if (uiData == DONE)
                DoUseDoorOrButton(GO_WOODEN_DOOR);
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_ZULJIN:
            DoUseDoorOrButton(GO_FIRE_DOOR);
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_RUN_EVENT_TIME:
            m_auiEncounter[uiType] = uiData;
            DoUpdateWorldState(WORLD_STATE_COUNTER, m_auiEncounter[uiType]);
            break;

        case TYPE_J_EGGS_RIGHT:
            --m_uiEggsRemainingCount_Right;
            break;
        case TYPE_J_EGGS_LEFT:
            --m_uiEggsRemainingCount_Left;
            break;
        case TYPE_RAND_VENDOR_1:
            m_auiRandVendor[0] = uiData;
            break;
        case TYPE_RAND_VENDOR_2:
            m_auiRandVendor[1] = uiData;
            break;

        default:
            error_log("SD2: Instance Zulaman: ERROR SetData = %u for type %u does not exist/not implemented.", uiType, uiData);
            return;
    }

	if (m_auiEncounter[TYPE_AKILZON] == DONE && m_auiEncounter[TYPE_NALORAKK] == DONE && m_auiEncounter[TYPE_JANALAI] == DONE)
    {
        DoUseDoorOrButton(GO_LYNX_TEMPLE_ENTRANCE);
    }

    if (uiData == DONE && GetKilledPreBosses() == 4 && (uiType == TYPE_AKILZON || uiType == TYPE_NALORAKK || uiType == TYPE_JANALAI || uiType == TYPE_HALAZZI))
    {
        DoUseDoorOrButton(GO_HEXLORD_ENTRANCE);
    }

    if (uiData == DONE || uiType == TYPE_RUN_EVENT_TIME || uiType == TYPE_EVENT_RUN)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;
        saveStream << m_auiEncounter[TYPE_EVENT_RUN] << " " << m_auiEncounter[TYPE_AKILZON] << " " << m_auiEncounter[TYPE_NALORAKK] << " "
            << m_auiEncounter[TYPE_JANALAI] << " " << m_auiEncounter[TYPE_HALAZZI] << " " << m_auiEncounter[TYPE_MALACRASS] << " "
            << m_auiEncounter[TYPE_ZULJIN] << " " << m_auiEncounter[TYPE_RUN_EVENT_TIME];

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}