void instance_ruins_of_ahnqiraj::OnCreatureEnterCombat(Creature* pCreature)
{
    switch (pCreature->GetEntry())
    {
        case NPC_KURINNAXX: SetData(TYPE_KURINNAXX, IN_PROGRESS); break;
        //case NPC_RAJAXX:    SetData(TYPE_RAJAXX, IN_PROGRESS);    break;
        case NPC_MOAM:      SetData(TYPE_MOAM, IN_PROGRESS);      break;
        case NPC_BURU:      SetData(TYPE_BURU, IN_PROGRESS);      break;
        case NPC_AYAMISS:   SetData(TYPE_AYAMISS, IN_PROGRESS);   break;
        case NPC_OSSIRIAN:  SetData(TYPE_OSSIRIAN, IN_PROGRESS);  break;
        case NPC_COLONEL_ZERRAN:
        case NPC_MAJOR_PAKKON:
        case NPC_MAJOR_YEGGETH:
        case NPC_CAPTAIN_XURREM:
        case NPC_CAPTAIN_DRENN:
        case NPC_CAPTAIN_TUUBID:
        case NPC_CAPTAIN_QEEZ:
            if (GetData(TYPE_RAJAXX) == FAIL || GetData(TYPE_RAJAXX) == NOT_STARTED)
            {
                m_uiCurrentArmyWave = 0;
                DoSendNextArmyWave();
                SetData(TYPE_RAJAXX, IN_PROGRESS);
            }
    }
}
void instance_ruins_of_ahnqiraj::DoSortArmyWaves()
{
    CreatureList lCreatureList;

    // Sort the 7 army waves
    // We need to use gridsearcher for this, because coords search is too complicated here
    for (uint8 i = 0; i < MAX_ARMY_WAVES; ++i)
    {
        // Clear all the army waves
        m_sArmyWavesGuids[i].clear();
        lCreatureList.clear();

        if (Creature* pTemp = GetSingleCreatureFromStorage(aArmySortingParameters[i].m_uiEntry))
        {
            GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_QIRAJI_WARRIOR, aArmySortingParameters[i].m_fSearchDist);
            GetCreatureListWithEntryInGrid(lCreatureList, pTemp, NPC_SWARMGUARD_NEEDLER, aArmySortingParameters[i].m_fSearchDist);

            for (CreatureList::const_iterator itr = lCreatureList.begin(); itr != lCreatureList.end(); ++itr)
            {
                if ((*itr)->isAlive())
                    m_sArmyWavesGuids[i].insert((*itr)->GetObjectGuid());
            }

            if (pTemp->isAlive())
                m_sArmyWavesGuids[i].insert(pTemp->GetObjectGuid());
        }
    }

    // send the first wave
    m_uiCurrentArmyWave = 0;
    DoSendNextArmyWave();
}
void instance_ruins_of_ahnqiraj::OnCreatureDeath(Creature* pCreature)
{
    switch (pCreature->GetEntry())
    {
        case NPC_KURINNAXX:
            SetData(TYPE_KURINNAXX, DONE);
            break;
        case NPC_RAJAXX:
            SetData(TYPE_RAJAXX, DONE);
            break;
        case NPC_MOAM:
            SetData(TYPE_MOAM, DONE);
            break;
        case NPC_BURU:
            SetData(TYPE_BURU, DONE);
            break;
        case NPC_AYAMISS:
            SetData(TYPE_AYAMISS, DONE);
            break;
        case NPC_OSSIRIAN:
            SetData(TYPE_OSSIRIAN, DONE);
            break;
        case NPC_COLONEL_ZERRAN:
        case NPC_MAJOR_PAKKON:
        case NPC_MAJOR_YEGGETH:
        case NPC_CAPTAIN_XURREM:
        case NPC_CAPTAIN_DRENN:
        case NPC_CAPTAIN_TUUBID:
        case NPC_CAPTAIN_QEEZ:
        case NPC_QIRAJI_WARRIOR:
        case NPC_SWARMGUARD_NEEDLER:
        {
            // If event isn't started by Andorov, return
            if (GetData(TYPE_RAJAXX) != IN_PROGRESS)
            {
                return;
            }

            // Check if the dead creature belongs to the current wave
            if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].find(pCreature->GetObjectGuid()) != m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].end())
            {
                m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].erase(pCreature->GetObjectGuid());

                // If all the soldiers from the current wave are dead, then send the next one
                if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].empty())
                {
                    DoSendNextArmyWave();
                }
            }
            break;
        }
    }
}
void instance_ruins_of_ahnqiraj::Update(uint32 uiDiff)
{
    if (GetData(TYPE_RAJAXX) == IN_PROGRESS)
    {
        if (m_uiArmyDelayTimer)
        {
            if (m_uiArmyDelayTimer <= uiDiff)
            {
                DoSendNextArmyWave();
                m_uiArmyDelayTimer = 2 * MINUTE * IN_MILLISECONDS;
            }
            else
                m_uiArmyDelayTimer -= uiDiff;
        }
    }
}
void instance_ruins_of_ahnqiraj::Update(uint32 uiDiff)
{
    if (GetData(TYPE_RAJAXX) == IN_PROGRESS)
    {
        if (m_uiWipeCheckTimer <= uiDiff)
            CheckRajaxxWipe();
        else
            m_uiWipeCheckTimer -= uiDiff;
        if (m_uiArmyDelayTimer)
        {
            if (m_uiArmyDelayTimer <= uiDiff)
                DoSendNextArmyWave();
            else
                m_uiArmyDelayTimer -= uiDiff;
        }
    }
}
void instance_ruins_of_ahnqiraj::OnCreatureDeath(Creature* pCreature)
{
    switch (pCreature->GetEntry())
    {
        case NPC_KURINNAXX: SetData(TYPE_KURINNAXX, DONE); break;
        case NPC_RAJAXX:    SetData(TYPE_RAJAXX, DONE);    break;
        case NPC_MOAM:      SetData(TYPE_MOAM, DONE);      break;
        case NPC_BURU:      SetData(TYPE_BURU, DONE);      break;
        case NPC_AYAMISS:   SetData(TYPE_AYAMISS, DONE);   break;
        case NPC_OSSIRIAN:  SetData(TYPE_OSSIRIAN, DONE);  break;
        case NPC_GENERAL_ANDOROV: SetData(TYPE_ANDOROV, FAIL); break;
        case NPC_COLONEL_ZERRAN:
        case NPC_MAJOR_PAKKON:
        case NPC_MAJOR_YEGGETH:
        case NPC_CAPTAIN_XURREM:
        case NPC_CAPTAIN_DRENN:
        case NPC_CAPTAIN_TUUBID:
        case NPC_CAPTAIN_QEEZ:
        case NPC_QIRAJI_WARRIOR:
        case NPC_SWARMGUARD_NEEDLER:
        {
            // If event isn't started by Andorov, return
            if (GetData(TYPE_RAJAXX) != IN_PROGRESS)
                return;

            Map::PlayerList const &PlayerList = instance->GetPlayers();
            for (Map::PlayerList::const_iterator itr = PlayerList.begin(); itr != PlayerList.end(); ++itr)
            {
                if (itr->getSource() && itr->getSource()->IsInWorld())
                    itr->getSource()->SetCombatTimer(60 * IN_MILLISECONDS);
            }

            // Check if the dead creature belongs to the current wave
            if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].find(pCreature->GetObjectGuid()) != m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].end())
            {
                m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].erase(pCreature->GetObjectGuid());
                // If all the soldiers from the current wave are dead, then send the next one
                if (m_sArmyWavesGuids[m_uiCurrentArmyWave - 1].empty())
                    DoSendNextArmyWave();
            }
            break;
        }
    }
}
void instance_ruins_of_ahnqiraj::DoSendNextArmyWave()
{
    // The next army wave is sent into battle after 2 min or after the previous wave is finished
    if (GetData(TYPE_RAJAXX) != IN_PROGRESS)
        return;

    // The last wave is General Rajaxx itself
    if (m_uiCurrentArmyWave == MAX_ARMY_WAVES)
    {
        if (Creature* pRajaxx = GetSingleCreatureFromStorage(NPC_RAJAXX))
        {
            pRajaxx->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
            DoScriptText(SAY_INTRO, pRajaxx);
            pRajaxx->SetInCombatWithZone();
        }
    }
    else
    {
        // Increase the wave id if some are already dead
        while (m_sArmyWavesGuids[m_uiCurrentArmyWave].empty())
        {
            ++m_uiCurrentArmyWave;
            if (m_uiCurrentArmyWave == MAX_ARMY_WAVES)
                DoSendNextArmyWave();
        }
        if (m_uiCurrentArmyWave >= MAX_ARMY_WAVES)
            return;
        float fX, fY, fZ;

        for (ObjectGuidSet::const_iterator itr = m_sArmyWavesGuids[m_uiCurrentArmyWave].begin(); itr != m_sArmyWavesGuids[m_uiCurrentArmyWave].end(); ++itr)
        {
            if (Creature* pTemp = instance->GetCreature(*itr))
            {
                if (!pTemp->isAlive())
                {
                    m_sArmyWavesGuids[m_uiCurrentArmyWave].erase(itr);
                    itr = m_sArmyWavesGuids[m_uiCurrentArmyWave].begin();
                    continue;
                }
                switch (pTemp->GetEntry())
                {
                    case NPC_COLONEL_ZERRAN:
                    case NPC_MAJOR_PAKKON:
                    case NPC_MAJOR_YEGGETH:
                    case NPC_CAPTAIN_XURREM:
                    case NPC_CAPTAIN_DRENN:
                    case NPC_CAPTAIN_TUUBID:
                    case NPC_CAPTAIN_QEEZ:
                        pTemp->SetActiveObjectState(true);
                    break;
                }
                pTemp->SetWalk(false);
                pTemp->GetRandomPoint(aAndorovMoveLocs[4].m_fX, aAndorovMoveLocs[4].m_fY, aAndorovMoveLocs[4].m_fZ, 10.0f, fX, fY, fZ);
                pTemp->GetMotionMaster()->MovePoint(0, fX, fY, fZ);
            }
        }
        // Yell on each wave (except the first 2)
        if (aArmySortingParameters[m_uiCurrentArmyWave].m_uiYellEntry)
        {
            if (Creature* pRajaxx = GetSingleCreatureFromStorage(NPC_RAJAXX))
                DoScriptText(aArmySortingParameters[m_uiCurrentArmyWave].m_uiYellEntry, pRajaxx);
        }
    }
#if AQ_PATCH < 20
    m_uiArmyDelayTimer = 3 * MINUTE * IN_MILLISECONDS;
#else
    m_uiArmyDelayTimer = 2 * MINUTE * IN_MILLISECONDS;
#endif
    ++m_uiCurrentArmyWave;
    m_uiWipeCheckTimer = 30 * IN_MILLISECONDS;
}