void instance_sunken_temple::SetData(uint32 uiType, uint32 uiData)
{
    switch(uiType)
    {
        case TYPE_ATALARION:
            if (uiData == SPECIAL)
                DoSpawnAtalarionIfCan();
            m_auiEncounter[0] = uiData;
            break;
        case TYPE_PROTECTORS:
            if (uiData == DONE)
            {
                --m_uiProtectorsRemaining;
                if (!m_uiProtectorsRemaining)
                {
                    m_auiEncounter[1] = uiData;
                    DoUseDoorOrButton(m_uiJammalanBarrierGUID);
                    // Intro yell
                    if (Creature* pJammalan = instance->GetCreature(m_uiJammalanGUID))
                        DoScriptText(SAY_JAMMALAN_INTRO, pJammalan);
                }
            }
            break;
        case TYPE_JAMMALAN:
            m_auiEncounter[2] = uiData;
            break;
        case TYPE_MALFURION:
            m_auiEncounter[3] = uiData;
            break;
    }

    if (uiData == DONE)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;

        saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
        strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}
void instance_sunken_temple::SetData(uint32 uiType, uint32 uiData)
{
    switch (uiType)
    {
        case TYPE_ATALARION:
            if (uiData == SPECIAL)
                DoSpawnAtalarionIfCan();
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_PROTECTORS:
            if (uiData == DONE)
            {
                --m_uiProtectorsRemaining;
                if (!m_uiProtectorsRemaining)
                {
                    m_auiEncounter[uiType] = uiData;
                    DoUseDoorOrButton(GO_JAMMALAN_BARRIER);
                    // Intro yell
                    DoOrSimulateScriptTextForThisInstance(SAY_JAMMALAN_INTRO, NPC_JAMMALAN);
                }
            }
            break;
        case TYPE_JAMMALAN:
            if (uiData == DONE)
            {
                if (Creature* pEranikus = GetSingleCreatureFromStorage(NPC_SHADE_OF_ERANIKUS))
                    pEranikus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PLAYER);
            }
            m_auiEncounter[uiType] = uiData;
            break;
        case TYPE_AVATAR:
            if (uiData == SPECIAL)
            {
                ++m_uiFlameCounter;

                Creature* pShade = GetSingleCreatureFromStorage(NPC_SHADE_OF_HAKKAR);
                if (!pShade)
                    return;

                switch (m_uiFlameCounter)
                {
                        // Yells on each flame
                        // TODO It might be possible that these yells should be ordered randomly, however this is the seen state
                    case 1: DoScriptText(SAY_AVATAR_BRAZIER_1, pShade); break;
                    case 2: DoScriptText(SAY_AVATAR_BRAZIER_2, pShade); break;
                    case 3: DoScriptText(SAY_AVATAR_BRAZIER_3, pShade); break;
                        // Summon the avatar of all flames are used
                    case MAX_FLAMES:
                        DoScriptText(SAY_AVATAR_BRAZIER_4, pShade);
                        pShade->CastSpell(pShade, SPELL_SUMMON_AVATAR, TRIGGERED_OLD_TRIGGERED);
                        m_uiAvatarSummonTimer = 0;
                        m_uiSupressorTimer = 0;
                        break;
                }

                // Summon the suppressors only after the flames are doused
                // Summon timer is confusing random; timers were: 13, 39 and 52 secs;
                if (m_uiFlameCounter != MAX_FLAMES)
                    m_uiSupressorTimer = urand(15000, 45000);

                return;
            }

            // Prevent double processing
            if (m_auiEncounter[uiType] == uiData)
                return;

            if (uiData == IN_PROGRESS)
            {
                m_uiSupressorTimer = 0;
                DoUpdateFlamesFlags(false);

                // Summon timer; use a small delay
                m_uiAvatarSummonTimer = 3000;
                m_bIsFirstHakkarWave = true;

                // Summon the shade
                Player* pPlayer = GetPlayerInMap();
                if (!pPlayer)
                    return;

                if (Creature* pShade = pPlayer->SummonCreature(NPC_SHADE_OF_HAKKAR, aSunkenTempleLocation[1].m_fX, aSunkenTempleLocation[1].m_fY, aSunkenTempleLocation[1].m_fZ, aSunkenTempleLocation[1].m_fO, TEMPSPAWN_MANUAL_DESPAWN, 0))
                {
                    m_npcEntryGuidStore[NPC_SHADE_OF_HAKKAR] = pShade->GetObjectGuid();
                    pShade->SetRespawnDelay(DAY);
                }

                // Respawn circles
                for (GuidVector::const_iterator itr = m_vuiCircleGUIDs.begin(); itr != m_vuiCircleGUIDs.end(); ++itr)
                    DoRespawnGameObject(*itr, 30 * MINUTE);
            }
            else if (uiData == FAIL)
            {
                // In case of wipe during the summoning ritual the shade is despawned
                // The trash mobs stay in place, they are not despawned; the avatar is not sure if it's despawned or not but most likely he'll stay in place

                // Despawn the shade and the avatar if needed -- TODO, avatar really?
                if (Creature* pShade = GetSingleCreatureFromStorage(NPC_SHADE_OF_HAKKAR))
                    pShade->ForcedDespawn();

                // Reset flames
                DoUpdateFlamesFlags(true);
            }

            // Use combat doors
            DoUseDoorOrButton(GO_HAKKAR_DOOR_1);
            DoUseDoorOrButton(GO_HAKKAR_DOOR_2);

            m_auiEncounter[uiType] = uiData;

            break;
    }

    if (uiData == DONE)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;

        saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " "
                   << m_auiEncounter[3] << " " << m_auiEncounter[4];

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
    }
}