void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_bHasImpaled)
        {
            if (m_creature->IsTemporarySummon())
            {
                TemporarySummon* pTemporary = (TemporarySummon*)m_creature;

                // Impale player
                if (Player* pSummoner = m_creature->GetMap()->GetPlayer(pTemporary->GetSummonerGuid()))
                    DoCastSpellIfCan(pSummoner, SPELL_IMPALED);
            }

            m_bHasImpaled = true;
        }

        // achievement check
        if (m_bBonedFailed)
            return;

        if (m_uiImpaledTimer > 8000)
        {
            m_bBonedFailed = true;

            if (m_pInstance)
                m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_BONED, false);
        }

        m_uiImpaledTimer += uiDiff;
    }
 void JustReachedHome() override
 {
     if (m_pInstance)
     {
         m_pInstance->SetData(TYPE_LADY_DEATHWHISPER, FAIL);
         m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);
     }
 }
 void JustReachedHome() override
 {
     if (m_pInstance)
     {
         m_pInstance->SetData(TYPE_MARROWGAR, FAIL);
         m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_BONED, false);
     }
 }
    void JustDied(Unit* /*Killer*/) override
    {
        if (Unit* pCreator = m_creature->GetCreator())
        {
            pCreator->RemoveAurasDueToSpell(SPELL_IMPALED);
            m_creature->ForcedDespawn();
        }

        if (m_pInstance && m_uiEmpaledTime > 8000)
            m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_BONED, false);
    }
    void Aggro(Unit* /*pWho*/) override
    {
        if (m_pInstance)
        {
            m_pInstance->SetData(TYPE_LADY_DEATHWHISPER, IN_PROGRESS);
            m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, true);
        }

        // make sure that the event will not continue in the fight
        m_bIsEventFinished = true;

        DoScriptText(SAY_AGGRO, m_creature);
        DoCastSpellIfCan(m_creature, SPELL_MANA_BARRIER, CAST_TRIGGERED);
    }
    void JustDied(Unit* /*pKiller*/) override
    {
        if (m_pInstance)
        {
            m_pInstance->SetData(TYPE_LADY_DEATHWHISPER, DONE);

            // Find required NPC as achievement criteria
            SummonsEntryList.clear();
            GetCreatureListWithEntryInGrid(SummonsEntryList, m_creature, NPC_CULT_ADHERENT, 250.0f);
            if (SummonsEntryList.empty())
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);

            SummonsEntryList.clear();
            GetCreatureListWithEntryInGrid(SummonsEntryList, m_creature, NPC_CULT_FANATIC, 250.0f);
            if (SummonsEntryList.empty())
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);
            SummonsEntryList.clear();
            GetCreatureListWithEntryInGrid(SummonsEntryList, m_creature, NPC_REANIMATED_FANATIC, 250.0f);
            if (SummonsEntryList.empty())
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);

            SummonsEntryList.clear();
            GetCreatureListWithEntryInGrid(SummonsEntryList, m_creature, NPC_REANIMATED_ADHERENT, 250.0f);
            if (SummonsEntryList.empty())
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);

            SummonsEntryList.clear();
            GetCreatureListWithEntryInGrid(SummonsEntryList, m_creature, NPC_DEFORMED_FANATIC, 250.0f);
            if (SummonsEntryList.empty())
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_FULL_HOUSE, false);

            m_pInstance->DoUpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, SPELL_ACHIEVEMENT_CREDIT);
        }

        DoScriptText(SAY_DEATH, m_creature);
    }
    void Aggro(Unit* /*pWho*/) override
    {
        if (m_pInstance)
        {
            m_pInstance->SetData(TYPE_DEATHBRINGER_SAURFANG, IN_PROGRESS);
            m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_IVE_GONE_AND_MADE_A_MESS, true);
            m_iMarkOfFallenCount = 0;
        }

        DoScriptText(SAY_AGGRO, m_creature);

        SetEquipmentSlots(false, EQUIP_MAIN, EQUIP_OFFHAND, EQUIP_RANGED);

        DoCastSpellIfCan(m_creature, SPELL_BLOOD_POWER, CAST_TRIGGERED);
        DoCastSpellIfCan(m_creature, SPELL_RUNE_OF_BLOOD, CAST_TRIGGERED);
        DoCastSpellIfCan(m_creature, SPELL_MARK_OF_FALLEN_CHAMPION, CAST_TRIGGERED);
    }
    void ReceiveAIEvent(AIEventType eventType, Creature* pSender, Unit* pInvoker, uint32 uiMiscValue) override
    {
        if (eventType == AI_EVENT_CUSTOM_A)
        {
            // prepare explosion; Rotface yells and achiev is failed
            if (DoCastSpellIfCan(m_creature, SPELL_UNSTABLE_EXPLOSION) == CAST_OK)
            {
                if (m_pInstance)
                {
                    if (Creature* pRotface = m_pInstance->GetSingleCreatureFromStorage(NPC_ROTFACE))
                        DoScriptText(SAY_OOZE_EXPLODE, pRotface);

                    m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_DANCES_OOZES, false);
                }

                m_uiUnstableExplosionTimer = 5000;
            }
        }
    }
    void JustDied(Unit* /*pKiller*/) override
    {
        if (m_pInstance)
        {
            m_pInstance->SetData(TYPE_DEATHBRINGER_SAURFANG, DONE);
            if (m_iMarkOfFallenCount > (m_bIs25Man ? 5: 3))
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_IVE_GONE_AND_MADE_A_MESS, false);
        }

        m_creature->CastSpell(m_creature, SPELL_ACHIEVEMENT_CREDIT, false);

        DoScriptText(SAY_DEATH, m_creature);
        DoCastSpellIfCan(m_creature, SPELL_REMOVE_MARKS, CAST_TRIGGERED);

        if (Creature* pTmp = m_creature->GetMap()->GetCreature(m_guidEventNpcGuid))
        {
            if (npc_highlord_saurfang_iccAI* pTmpAI = dynamic_cast<npc_highlord_saurfang_iccAI*>(pTmp->AI()))
                pTmpAI->DoContinueEvent();
        }
    }
    void Reset() override
    {
        SetCombatMovement(true);

        m_uiPhase = PHASE_NORMAL;

        m_uiBerserkTimer = 10 * MINUTE * IN_MILLISECONDS;
        m_uiBoneSliceTimer = 10000;
        m_uiColdflameTimer = 5000;
        m_uiBoneSpikeTimer = 12000;
        m_uiBoneStormTimer = 45000;
        m_uiBoneStormChargeTimer = 3000;
        m_uiBoneStormColdflameTimer = 1000;

        m_uiChargesCount = 0;

        m_creature->SetSpeedRate(MOVE_RUN, 1.0f);
        if (m_pInstance)
            m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_BONED, true);
    }
    void MovementInform(uint32 uiMoveType, uint32 uiPointId) override
    {
        if (uiMoveType != POINT_MOTION_TYPE)
            return;

        // "JustReachedHome()"
        if (uiPointId == POINT_ID_EVADE)
        {
            m_creature->SetFacingTo(M_PI_F);

            if (m_pInstance)
            {
                m_pInstance->SetData(TYPE_DEATHBRINGER_SAURFANG, FAIL);
                m_pInstance->SetSpecialAchievementCriteria(ACHIEVE_IVE_GONE_AND_MADE_A_MESS, false);
            }

            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
            m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PASSIVE);
        }
    }