void instance_naxxramas::Update(uint32 uiDiff)
{
    // Down they fall together achiev
    if (BlaumeuxDead || RivendareDead || ZeliekDead || KorthazzDead)
    {
        if (DeadTimer < 15000 && UpdateCheck)
        {
            if (BlaumeuxDead && RivendareDead && ZeliekDead && KorthazzDead)
            {
                if(this)
                    DoCompleteAchievement(instance->IsRegularDifficulty() ? ACHIEVEMENT_TOGETHER : H_ACHIEVEMENT_TOGETHER);

                UpdateCheck = false;
            }
            else 
                DeadTimer += uiDiff;
        }
    }

    // Arachnofobia achiev
    if(m_bIsArachnofobia)
        m_uiArachnofobiaTimer += uiDiff;

    // Immortal check
    if (m_uiImmortaCheck < uiDiff)
    {
        IsRaidWiped();
        m_uiImmortaCheck = 1000;
    }else m_uiImmortaCheck -= uiDiff;
}
    void SetData(uint32 uiType, uint32 uiData)
    {
        switch(uiType)
        {
        case TYPE_STAGE:    m_auiEncounter[0] = uiData; break;
        case TYPE_BEASTS:   m_auiEncounter[1] = uiData; break;
        case TYPE_JARAXXUS: m_auiEncounter[2] = uiData; break;
        case TYPE_CRUSADERS:if (uiData == FAIL && (m_auiEncounter[3] == FAIL || m_auiEncounter[3] == NOT_STARTED))
                            m_auiEncounter[3] = NOT_STARTED;
                            else
                                m_auiEncounter[3] = uiData;
                            if (uiData == DONE) 
                            {
                               if (GameObject* pChest = GetSingleGameObjectFromStorage(m_uiCrusadersCache))
                                   if (pChest && !pChest->isSpawned())
                                         pChest->SetRespawnTime(7*DAY);
                            };
                            break;
        case TYPE_CRUSADERS_COUNT:  if (uiData == 0) --m_auiCrusadersCount;
                                         else m_auiCrusadersCount = uiData;
                                    break;
        case TYPE_VALKIRIES: if (m_auiEncounter[4] == SPECIAL && uiData == SPECIAL) uiData = DONE;
                             m_auiEncounter[4] = uiData; break;
        case TYPE_LICH_KING: m_auiEncounter[5] = uiData; break;
        case TYPE_ANUBARAK:  m_auiEncounter[6] = uiData; 
                            if (uiData == DONE) {
                            if (Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
                            {
                                if ( m_auiEncounter[7] >= 25) m_uiTributeChest1 = GO_TRIBUTE_CHEST_10H_25;
                                if ( m_auiEncounter[7] >= 45) m_uiTributeChest2 = GO_TRIBUTE_CHEST_10H_45;
                                if ( m_auiEncounter[7] >= 49) m_uiTributeChest3 = GO_TRIBUTE_CHEST_10H_50;
                                m_uiTributeChest4 = GO_TRIBUTE_CHEST_10H_99;
                            }
                            if (Difficulty == RAID_DIFFICULTY_25MAN_HEROIC){
                                if ( m_auiEncounter[7] >= 25) m_uiTributeChest1 = GO_TRIBUTE_CHEST_25H_25;
                                if ( m_auiEncounter[7] >= 45) m_uiTributeChest2 = GO_TRIBUTE_CHEST_25H_45;
                                if ( m_auiEncounter[7] >= 49) m_uiTributeChest3 = GO_TRIBUTE_CHEST_25H_50;
                                m_uiTributeChest4 = GO_TRIBUTE_CHEST_25H_99;
                            }
                            // Attention! It is (may be) not off-like, but  spawning all Tribute Chests is real
                            // reward for clearing TOC instance
                            if (m_uiTributeChest1)
                              if (GameObject* pChest1 = GetSingleGameObjectFromStorage(m_uiTributeChest1))
                                if (pChest1 && !pChest1->isSpawned()) pChest1->SetRespawnTime(7*DAY);
                            if (m_uiTributeChest2)
                              if (GameObject* pChest2 = GetSingleGameObjectFromStorage(m_uiTributeChest2))
                                if (pChest2 && !pChest2->isSpawned()) pChest2->SetRespawnTime(7*DAY);
                            if (m_uiTributeChest3)
                              if (GameObject* pChest3 = GetSingleGameObjectFromStorage(m_uiTributeChest3))
                                if (pChest3 && !pChest3->isSpawned()) pChest3->SetRespawnTime(7*DAY);
                            if (m_uiTributeChest4)
                              if (GameObject* pChest4 = GetSingleGameObjectFromStorage(m_uiTributeChest4))
                                if (pChest4 && !pChest4->isSpawned()) pChest4->SetRespawnTime(7*DAY);
                            };
        break;
        case TYPE_COUNTER:   m_auiEncounter[7] = uiData; uiData = DONE; break;
        case TYPE_EVENT:     m_auiEncounter[8] = uiData; uiData = NOT_STARTED; break;
        case TYPE_EVENT_TIMER:      m_auiEventTimer = uiData; uiData = NOT_STARTED; break;
        case TYPE_NORTHREND_BEASTS: m_auiNorthrendBeasts = uiData; break;
        case DATA_HEALTH_FJOLA:     m_uiDataDamageFjola = uiData; uiData = NOT_STARTED; break;
        case DATA_HEALTH_EYDIS:     m_uiDataDamageEydis = uiData; uiData = NOT_STARTED; break;
        case DATA_CASTING_VALKYRS:  m_uiValkyrsCasting = uiData; uiData = NOT_STARTED; break;
        }

        if (IsEncounterInProgress()) 
        {
            DoCloseDoor(GetData64(GO_WEST_PORTCULLIS));
            DoCloseDoor(GetData64(GO_NORTH_PORTCULLIS));
//            DoCloseDoor(GetData64(GO_SOUTH_PORTCULLIS));
        }
        else
        {
            DoOpenDoor(GetData64(GO_WEST_PORTCULLIS));
            DoOpenDoor(GetData64(GO_NORTH_PORTCULLIS));
//            DoOpenDoor(GetData64(GO_SOUTH_PORTCULLIS));
        };

        if (uiData == FAIL && uiType != TYPE_STAGE
                           && uiType != TYPE_EVENT
                           && uiType != TYPE_COUNTER
                           && uiType != TYPE_EVENT_TIMER)
        { if (IsRaidWiped()) { --m_auiEncounter[7];
                               needsave = true;
                             }
                               uiData = NOT_STARTED;
        }

        if ((uiData == DONE && uiType != TYPE_STAGE
                           && uiType != TYPE_EVENT
                           && uiType != TYPE_EVENT_TIMER)
                           || needsave == true)
        {
            OUT_SAVE_INST_DATA;

            std::ostringstream saveStream;

            for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
                saveStream << m_auiEncounter[i] << " ";

            m_strInstData = saveStream.str();

            SaveToDB();
            OUT_SAVE_INST_DATA_COMPLETE;
        needsave = false;
        }
    }
        void SetData(uint32 uiType, uint32 uiData)
        {
            switch(uiType)
            {
                case TYPE_JARAXXUS:
                    if (uiData == DONE) m_uiEvent = 2000;
                    break;
                case TYPE_CRUSADERS:
                    switch (uiData)
                    {
                        case IN_PROGRESS: m_uiResilienceWillFixItTimer = 0; break;
                        case SPECIAL: //Means the first blood
                            m_uiResilienceWillFixItTimer = 60*IN_MILLISECONDS;
                            uiData = IN_PROGRESS;
                            break;
                        case DONE:
                            DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_DEFEAT_FACTION_CHAMPIONS);
                            if (m_uiResilienceWillFixItTimer > 0)
                                DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_CHAMPIONS_KILLED_IN_MINUTE);
                            if (GameObject* pChest = instance->GetGameObject(m_uiCrusadersCacheGUID))
                                if (pChest && !pChest->isSpawned())
                                    pChest->SetRespawnTime(7*DAY);
                            m_uiEvent = 3100;
                            break;
                    }
                    break;
                case TYPE_VALKIRIES:
                    switch (uiData)
                    {
                        case FAIL:
                            if (m_auiEncounter[TYPE_VALKIRIES] == NOT_STARTED) uiData = NOT_STARTED;
                            break;
                        case SPECIAL:
                            if (m_auiEncounter[TYPE_VALKIRIES] == SPECIAL) uiData = DONE;
                            break;
                        case DONE:
                            if (instance->GetPlayers().getFirst()->getSource()->GetTeam() == ALLIANCE)
                                m_uiEvent = 4020;
                            else
                                m_uiEvent = 4030;
                            break;
                    }
                    break;
                case TYPE_ANUBARAK:
                    switch (uiData)
                    {
                        case DONE:
                            m_uiEvent = 6000;
                            break;
                        case SPECIAL:
                            uint32 tributeChest = 0;
                            if (instance->GetSpawnMode() == RAID_DIFFICULTY_10MAN_HEROIC)
                            {
                                if (m_uiTrialCounter >= 50)
                                    tributeChest = GO_TRIBUTE_CHEST_10H_99;
                                else
                                    if (m_uiTrialCounter >= 45)
                                        tributeChest = GO_TRIBUTE_CHEST_10H_50;
                                    else
                                        if (m_uiTrialCounter >= 25)
                                            tributeChest = GO_TRIBUTE_CHEST_10H_45;
                                        else
                                            tributeChest = GO_TRIBUTE_CHEST_10H_25;
                            }
                            else if (instance->GetSpawnMode() == RAID_DIFFICULTY_25MAN_HEROIC)
                            {
                                if (m_uiTrialCounter >= 50)
                                    tributeChest = GO_TRIBUTE_CHEST_25H_99;
                                else
                                    if (m_uiTrialCounter >= 45)
                                        tributeChest = GO_TRIBUTE_CHEST_25H_50;
                                    else
                                        if (m_uiTrialCounter >= 25)
                                            tributeChest = GO_TRIBUTE_CHEST_25H_45;
                                        else
                                            tributeChest = GO_TRIBUTE_CHEST_25H_25;
                            }
                            if (tributeChest)
                                if (Creature* pTirion =  instance->GetCreature(m_uiTirionGUID))
                                    if (GameObject* pChest = pTirion->SummonGameObject(tributeChest, 805.62f, 134.87f, 142.16f, 3.27f, 0, 0, 0, 0, 90000000))
                                        pChest->SetRespawnTime(pChest->GetRespawnDelay());
                            break;
                    }
                    break;
                case TYPE_COUNTER:   m_uiTrialCounter = uiData; uiData = DONE; break;
                case TYPE_EVENT:     m_uiEvent = uiData; uiData = NOT_STARTED; break;
                case TYPE_EVENT_TIMER:      m_uiEventTimer = uiData; uiData = NOT_STARTED; break;
                case TYPE_NORTHREND_BEASTS:
                    m_uiNorthrendBeasts = uiData;
                    switch (uiData)
                    {
                        case GORMOK_DONE:
                            m_uiEvent = 200;
                            SetData(TYPE_NORTHREND_BEASTS, IN_PROGRESS);
                            SetData(TYPE_BEASTS, IN_PROGRESS);
                            break;
                        case SNAKES_IN_PROGRESS: m_uiNotOneButTwoJormungarsTimer = 0; break;
                        case SNAKES_SPECIAL: m_uiNotOneButTwoJormungarsTimer = 10*IN_MILLISECONDS; break;
                        case SNAKES_DONE:
                            if (m_uiNotOneButTwoJormungarsTimer > 0)
                                DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_WORMS_KILLED_IN_10_SECONDS);
                            m_uiEvent = 300;
                            SetData(TYPE_NORTHREND_BEASTS, IN_PROGRESS);
                            SetData(TYPE_BEASTS, IN_PROGRESS);
                            break;
                        case ICEHOWL_DONE:
                            m_uiEvent = 400;
                            SetData(TYPE_NORTHREND_BEASTS, DONE);
                            SetData(TYPE_BEASTS, DONE);
                            break;
                        case FAIL:
                            SetData(TYPE_BEASTS, FAIL);
                            break;
                    }
                    break;
                case DATA_HEALTH_TWIN_SHARED:     m_uiDataDamageTwin = uiData; uiData = NOT_STARTED; break;

                //Achievements
                case DATA_SNOBOLD_COUNT:
                    if (uiData == INCREASE)
                        ++m_uiSnoboldCount;
                    else if (uiData == DECREASE)
                        --m_uiSnoboldCount;
                    break;
                case DATA_MISTRESS_OF_PAIN_COUNT:
                    if (uiData == INCREASE)
                        ++m_uiMistressOfPainCount;
                    else if (uiData == DECREASE)
                        --m_uiMistressOfPainCount;
                    break;
                case DATA_TRIBUTE_TO_IMMORTALITY_ELEGIBLE:
                    m_bTributeToImmortalityElegible = false;
                    break;
            }
            if (IsEncounterInProgress())
            {
                CloseDoor(GetData64(GO_EAST_PORTCULLIS));
                CloseDoor(GetData64(GO_WEB_DOOR));
            } else {
                OpenDoor(GetData64(GO_EAST_PORTCULLIS));
                OpenDoor(GetData64(GO_WEB_DOOR));
            }

            if (uiType < MAX_ENCOUNTERS)
            {
                sLog->outBasic("[ToCr] m_auiEncounter[uiType %u] %u = uiData %u;", uiType, m_auiEncounter[uiType], uiData);
                if (uiData == FAIL)
                {
                    if (IsRaidWiped())
                    {
                        --m_uiTrialCounter;
                        m_bNeedSave = true;
                        m_uiEvent = (uiType == TYPE_BEASTS? 666 : 0);
                    }
                    uiData = NOT_STARTED;
                }
                m_auiEncounter[uiType] = uiData;

                if (uiData == DONE || m_bNeedSave == true)
                {
                    if (Unit* pAnnouncer = instance->GetCreature(GetData64(NPC_BARRENT)))
                        pAnnouncer->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    Save();
                }
            }
        }
void instance_trial_of_the_crusader::SetData(uint32 uiType, uint32 uiData)
{
    switch(uiType)
    {
    case TYPE_STAGE:
        m_auiEncounter[TYPE_STAGE] = uiData;
        break;
    case TYPE_BEASTS:
        m_auiEncounter[TYPE_BEASTS] = uiData;
        if (uiData == IN_PROGRESS)
            SetSpecialAchievementCriteria(TYPE_UPPER_BACK_PAIN, false);
        break;
    case TYPE_JARAXXUS:
        m_auiEncounter[TYPE_JARAXXUS] = uiData;
        if (uiData == IN_PROGRESS)
            SetSpecialAchievementCriteria(TYPE_THREE_SIXTY_PAIN_SPIKE, false);
        break;
    case TYPE_CRUSADERS:
        if (uiData == FAIL && (m_auiEncounter[TYPE_CRUSADERS] == FAIL || m_auiEncounter[TYPE_CRUSADERS] == NOT_STARTED))
            m_auiEncounter[TYPE_CRUSADERS] = NOT_STARTED;
        else
            m_auiEncounter[TYPE_CRUSADERS] = uiData;
        if (uiData == DONE)
        {
            if (Creature* pTirion = GetSingleCreatureFromStorage(NPC_TIRION))
                DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_ACHIEV_FACTION_CHAMPIONS_DEFEAT);

            uint32 uiCacheEntry = GO_CRUSADERS_CACHE_10;

            switch (instance->GetDifficulty())
            {
            case RAID_DIFFICULTY_10MAN_HEROIC:
                uiCacheEntry = GO_CRUSADERS_CACHE_10_H;
                break;
            case RAID_DIFFICULTY_25MAN_NORMAL:
                uiCacheEntry = GO_CRUSADERS_CACHE_25;
                break;
            case RAID_DIFFICULTY_25MAN_HEROIC:
                uiCacheEntry = GO_CRUSADERS_CACHE_25_H;
                break;
            }
            if (GameObject* pChest = GetSingleGameObjectFromStorage(uiCacheEntry))
                if (!pChest->isSpawned())
                    pChest->SetRespawnTime(7*DAY);
        };
        break;
    case TYPE_CRUSADERS_COUNT:
        if (uiData == 0)
            --m_auiCrusadersCount;
        else
            m_auiCrusadersCount = uiData;
        break;
    case TYPE_CRUSADERS_DEAD:
        m_auiCrusadersDead = uiData;
        break;
    case TYPE_CRUSADERS_ACHIEV_TIMER:
        if(m_auiCrusadersAchievFail)
            break;
        if (m_auiCrusadersAchievTimer <= uiData)
            m_auiCrusadersAchievFail = 1;
        else
            m_auiCrusadersAchievTimer -= uiData;
        break;
    case TYPE_CRUSADERS_ACHIEV_FAIL:
        m_auiCrusadersAchievFail = uiData;
        break;
    case TYPE_VALKIRIES:
        /*if (m_auiEncounter[4] == SPECIAL && uiData == SPECIAL)
            uiData = DONE;*/
        m_auiEncounter[TYPE_VALKIRIES] = uiData;
        break;
    case TYPE_LICH_KING:
        m_auiEncounter[TYPE_LICH_KING] = uiData;
        break;
    case TYPE_ANUBARAK:
        m_auiEncounter[TYPE_ANUBARAK] = uiData;

        if (uiData == IN_PROGRESS)
        {
            DoCloseDoor(GO_WEB_DOOR);
        }
        else
            DoOpenDoor(GO_WEB_DOOR);

        if (uiData == DONE)
        {
            if (Difficulty == RAID_DIFFICULTY_10MAN_HEROIC)
            {
                if (m_auiEncounter[TYPE_COUNTER] >= 25)
                    m_uiTributeChest1 = GO_TRIBUTE_CHEST_10H_25;
                if (m_auiEncounter[TYPE_COUNTER] >= 45)
                    m_uiTributeChest2 = GO_TRIBUTE_CHEST_10H_45;
                if (m_auiEncounter[TYPE_COUNTER] > 49)
                    m_uiTributeChest3 = GO_TRIBUTE_CHEST_10H_50;

                m_uiTributeChest4 = GO_TRIBUTE_CHEST_10H_99;
            }
            if (Difficulty == RAID_DIFFICULTY_25MAN_HEROIC)
            {
                if (m_auiEncounter[TYPE_COUNTER] >= 25)
                    m_uiTributeChest1 = GO_TRIBUTE_CHEST_25H_25;
                if (m_auiEncounter[TYPE_COUNTER] >= 45)
                    m_uiTributeChest2 = GO_TRIBUTE_CHEST_25H_45;
                if (m_auiEncounter[TYPE_COUNTER] > 49)
                    m_uiTributeChest3 = GO_TRIBUTE_CHEST_25H_50;

                m_uiTributeChest4 = GO_TRIBUTE_CHEST_25H_99;
            }
            // Attention! It is (may be) not off-like, but  spawning all Tribute Chests is real
            // reward for clearing TOC instance
            if (m_uiTributeChest1)
                if (GameObject* pChest1 = GetSingleGameObjectFromStorage(m_uiTributeChest1))
                    if (pChest1 && !pChest1->isSpawned())
                        pChest1->SetRespawnTime(7*DAY);

            if (m_uiTributeChest2)
                if (GameObject* pChest2 = GetSingleGameObjectFromStorage(m_uiTributeChest2))
                    if (pChest2 && !pChest2->isSpawned())
                        pChest2->SetRespawnTime(7*DAY);

            if (m_uiTributeChest3)
                if (GameObject* pChest3 = GetSingleGameObjectFromStorage(m_uiTributeChest3))
                    if (pChest3 && !pChest3->isSpawned())
                        pChest3->SetRespawnTime(7*DAY);

            if (m_uiTributeChest4)
                if (GameObject* pChest4 = GetSingleGameObjectFromStorage(m_uiTributeChest4))
                    if (pChest4 && !pChest4->isSpawned())
                        pChest4->SetRespawnTime(7*DAY);
        };
        break;
    case TYPE_COUNTER:
        m_auiEncounter[TYPE_COUNTER] = uiData;
        if (uiData < 25)
            SetSpecialAchievementCriteria(TYPE_SKILL, false);
        if (uiData < 45)
            SetSpecialAchievementCriteria(TYPE_MAD_SKILL, false);
        if (uiData < 50)
        {
            SetSpecialAchievementCriteria(TYPE_INSANITY, false);
            SetSpecialAchievementCriteria(TYPE_IMMORTALITY, false);
        }

        //uiData = DONE;
        break;
    case TYPE_DEATHS:
        m_auiEncounter[TYPE_DEATHS] += uiData;
        if (GetData(TYPE_DEATHS))
            SetSpecialAchievementCriteria(TYPE_IMMORTALITY, false);
        break;
    case TYPE_EVENT:
        m_auiEncounter[TYPE_EVENT] = uiData;
        uiData = NOT_STARTED;
        break;
    case TYPE_EVENT_TIMER:
        m_auiEventTimer = uiData;
        uiData = NOT_STARTED;
        break;
    case TYPE_NORTHREND_BEASTS:
        m_auiNorthrendBeasts = uiData;
        break;
    case DATA_HEALTH_FJOLA:
        m_uiDataDamageFjola = uiData; uiData = NOT_STARTED;
        break;
    case DATA_HEALTH_EYDIS:
        m_uiDataDamageEydis = uiData; uiData = NOT_STARTED;
        break;
    }

    if (IsEncounterInProgress()) 
    {
        DoCloseDoor(GO_WEST_PORTCULLIS);
        DoCloseDoor(GO_NORTH_PORTCULLIS);
        DoCloseDoor(GO_SOUTH_PORTCULLIS);

        if (Creature* pBarrent = GetSingleCreatureFromStorage(NPC_BARRENT)) 
            pBarrent->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
    }
    else
    {
        DoOpenDoor(GO_WEST_PORTCULLIS);
        DoCloseDoor(GO_NORTH_PORTCULLIS);
        DoCloseDoor(GO_SOUTH_PORTCULLIS);

        if (Creature* pBarrent = GetSingleCreatureFromStorage(NPC_BARRENT)) 
            pBarrent->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
    };

    if (uiData == FAIL && uiType != TYPE_STAGE && uiType != TYPE_EVENT && uiType != TYPE_COUNTER && uiType != TYPE_EVENT_TIMER)
    {
        if (IsRaidWiped())
        {
            //--m_auiEncounter[TYPE_COUNTER];
            SetData(TYPE_COUNTER, GetData(TYPE_COUNTER) - 1);
            needsave = true;
            UpdateWorldState();
        }
        uiData = NOT_STARTED;
    }

    if ((uiData == DONE && uiType != TYPE_STAGE && uiType != TYPE_EVENT && uiType != TYPE_EVENT_TIMER) || needsave == true)
    {
        OUT_SAVE_INST_DATA;

        std::ostringstream saveStream;

        for(uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
            saveStream << m_auiEncounter[i] << " ";

        m_strInstData = saveStream.str();

        SaveToDB();
        OUT_SAVE_INST_DATA_COMPLETE;
        needsave = false;
    }
}