void removeAdds()
    {
        for (std::vector<uint64>::iterator itr = adds.begin(); itr != adds.end(); ++itr)
        {
            Unit* temp = Unit::GetUnit((*me),*itr);
            if (temp && temp->isAlive())
            {
                (*temp).GetMotionMaster()->Clear(true);
                me->DealDamage(temp, temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                CAST_CRE(temp)->RemoveCorpse();
            }
        }
        adds.clear();

        for (std::vector<uint64>::iterator itr = assassins.begin(); itr != assassins.end(); ++itr)
        {
            Unit* temp = Unit::GetUnit((*me),*itr);
            if (temp && temp->isAlive())
            {
                (*temp).GetMotionMaster()->Clear(true);
                me->DealDamage(temp, temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                CAST_CRE(temp)->RemoveCorpse();
            }
        }
        assassins.clear();
    }
Example #2
0
        void Absorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
        {
            Unit* victim = GetTarget();
            int32 remainingHealth = victim->GetHealth() - dmgInfo.GetDamage();
            uint32 allowedHealth = victim->CountPctFromMaxHealth(35);
            // If damage kills us
            if (remainingHealth <= 0 && !victim->ToPlayer()->HasSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL))
            {
                // Cast healing spell, completely avoid damage
                absorbAmount = dmgInfo.GetDamage();

                uint32 defenseSkillValue = victim->GetDefenseSkillValue();
                // Max heal when defense skill denies critical hits from raid bosses
                // Formula: max defense at level + 140 (raiting from gear)
                uint32 reqDefForMaxHeal  = victim->getLevel() * 5 + 140;
                float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal)
                    ? 1.0f
                    : float(defenseSkillValue) / float(reqDefForMaxHeal);

                int32 healAmount = int32(victim->CountPctFromMaxHealth(uint32(healPct * pctFromDefense)));
                victim->CastCustomSpell(victim, PAL_SPELL_ARDENT_DEFENDER_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff);
                victim->ToPlayer()->AddSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 0, time(NULL) + 120);
            }
            else if (remainingHealth < int32(allowedHealth))
            {
                // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
                uint32 damageToReduce = (victim->GetHealth() < allowedHealth)
                    ? dmgInfo.GetDamage()
                    : allowedHealth - remainingHealth;
                absorbAmount = CalculatePctN(damageToReduce, absorbPct);
            }
        }
Example #3
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_HATEFUL:
                    {
                        //Cast Hateful strike on the player with the highest
                        //amount of HP within melee distance
                        uint32 MostHP = 0;
                        Unit* pMostHPTarget = NULL;

                        std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
                        int targetCounter = RAID_MODE(2, 3); // Picks 2 (3) highest threat targets as Hateful Strike candidates
                        for (; i != me->getThreatManager().getThreatList().end() && targetCounter > 0; ++i, --targetCounter)
                        {
                            Unit *pTarget = (*i)->getTarget();
                            if (pTarget->isAlive() && pTarget != me->getVictim() && pTarget->GetHealth() > MostHP && me->IsWithinMeleeRange(pTarget))
                            {
                                MostHP = pTarget->GetHealth();
                                pMostHPTarget = pTarget;
                            }
                        }

                        if (!pMostHPTarget)
                            pMostHPTarget = me->getVictim();

                        DoCast(pMostHPTarget, RAID_MODE(SPELL_HATEFUL_STRIKE, H_SPELL_HATEFUL_STRIKE), true);

                        events.ScheduleEvent(EVENT_HATEFUL, 1200);
                        break;
                    }
                    case EVENT_BERSERK:
                        DoCast(me, SPELL_BERSERK, true);
                        DoScriptText(EMOTE_BERSERK, me);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                    case EVENT_SLIME:
                        DoCast(me->getVictim(), SPELL_SLIME_BOLT);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                }
            }

            if (!Enraged && HealthBelowPct(5))
            {
                DoCast(me, SPELL_FRENZY, true);
                DoScriptText(EMOTE_ENRAGE, me);
                Enraged = true;
            }

            DoMeleeAttackIfReady();
        }
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                    case EVENT_HATEFUL:
                    {
                        //Cast Hateful strike on the player with the highest
                        //amount of HP within melee distance
                        uint32 MostHP = 0;
                        Unit* pMostHPTarget = NULL;
                        std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
                        for (; i != me->getThreatManager().getThreatList().end(); ++i)
                        {
                            Unit* target = (*i)->getTarget();
                            if (target->IsAlive() && target != me->GetVictim() && target->GetHealth() > MostHP && me->IsWithinMeleeRange(target))
                            {
                                MostHP = target->GetHealth();
                                pMostHPTarget = target;
                            }
                        }

                        if (!pMostHPTarget)
                            pMostHPTarget = me->GetVictim();

                        DoCast(pMostHPTarget, SPELL_HATEFUL_STRIKE, true);

                        events.ScheduleEvent(EVENT_HATEFUL, 1000);
                        break;
                    }
                    case EVENT_BERSERK:
                        DoCast(me, SPELL_BERSERK, true);
                        Talk(EMOTE_BERSERK);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                    case EVENT_SLIME:
                        DoCastVictim(SPELL_SLIME_BOLT, true);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                }
            }

            if (!Enraged && HealthBelowPct(5))
            {
                DoCast(me, SPELL_FRENZY, true);
                Talk(EMOTE_ENRAGE);
                Enraged = true;
            }

            DoMeleeAttackIfReady();
        }
Example #5
0
        void SetPhaseOne()
        {
            DoScriptText(SAY_HEART_CLOSED, me);

            DoCast(SPELL_STAND);
            me->SetReactState(REACT_AGGRESSIVE);

            _phase = 1;

            events.RescheduleEvent(EVENT_SEARING_LIGHT, TIMER_SEARING_LIGHT / 2);
            events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
            events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));

            Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT) : NULL;
            if (!heart)
                return;

            heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE);
            heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);

            if (!_hardMode)
            {
                if (!_transferHealth)
                    _transferHealth = (heart->GetMaxHealth() - heart->GetHealth());

                me->ModifyHealth(-((int32)_transferHealth));
            }
        }
Example #6
0
void CRetreatTask::Update()
{
	CCircuitAI* circuit = manager->GetCircuit();
	int frame = circuit->GetLastFrame();
	bool isExecute = (++updCount % 4 == 0);
	auto assignees = units;
	for (CCircuitUnit* unit : assignees) {
		Unit* u = unit->GetUnit();
		const float healthPerc = u->GetHealth() / u->GetMaxHealth();
		bool isRepaired;
		// FIXME: Wait until 101.0 engine
//		if (ass->GetShield() != nullptr) {
//			isRepaired = (healthPerc > 0.98f) && unit->IsShieldCharged(0.9f));
//		} else {
			isRepaired = healthPerc > 0.98f;
//		}

		if (isRepaired && !unit->IsDisarmed(frame)) {
			RemoveAssignee(unit);
		} else if (unit->IsForceExecute() || isExecute) {
			Execute(unit);
		} else {
			unit->Update(circuit);
		}
	}
}
 void UpdateAI(const uint32 diff)
 {
     if (!Vorpil)
     {
         me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
         return;
     }
     if (move <= diff)
     {
         if (sacrificed)
         {
             SpellEntry *spell = (SpellEntry *)GetSpellStore()->LookupEntry(HeroicMode?H_SPELL_EMPOWERING_SHADOWS:SPELL_EMPOWERING_SHADOWS);
             if (spell)
                 Vorpil->AddAura(new EmpoweringShadowsAura(spell, 0, NULL, Vorpil, me));
             Vorpil->SetHealth(Vorpil->GetHealth()+Vorpil->GetMaxHealth()/25);
             DoCast(me, SPELL_SHADOW_NOVA, true);
             me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
             return;
         }
         me->GetMotionMaster()->MoveFollow(Vorpil,0,0);
         if (me->GetDistance(Vorpil) < 3)
         {
             DoCast(me, SPELL_SACRIFICE, false);
             sacrificed = true;
             move = 500;
             return;
         }
         if (!Vorpil->isInCombat() || Vorpil->isDead())
         {
             me->DealDamage(me, me->GetMaxHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
             return;
         }
         move = 1000;
     } else move -= diff;
 }
Example #8
0
    void Reset()
    {
        FrostBolt_Timer = (rand()%60)*1000;                 //It won't be more than a minute without cast it
        FrostBoltNova_Timer = 15000;                        //Cast every 15 seconds
        ChainsOfKelthuzad_Timer = (rand()%30+30)*1000;      //Cast no sooner than once every 30 seconds
        ManaDetonation_Timer = 20000;                       //Seems to cast about every 20 seconds
        ShadowFisure_Timer = 25000;                         //25 seconds
        FrostBlast_Timer = (rand()%30+30)*1000;             //Random time between 30-60 seconds
        GuardiansOfIcecrown_Timer = 5000;                   //5 seconds for summoning each Guardian of Icecrown in phase 3

        for (int i=0; i<5; i++)
        {
            if (GuardiansOfIcecrown[i])
        {
            //delete creature
            Unit* pUnit = Unit::GetUnit((*me), GuardiansOfIcecrown[i]);
            if (pUnit && pUnit->isAlive())
                pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            GuardiansOfIcecrown[i] = 0;
        }
        }

        Phase1_Timer = 310000;                              //Phase 1 lasts 5 minutes and 10 seconds
        Phase2 = false;
        Phase3 = false;
    }
 void JustDied(Unit *killer)
 {
     std::vector<uint64>::iterator itr;
     for(itr=addsGuid.begin(); itr!=addsGuid.end(); itr++)
     {
         Unit* zombie = Unit::GetUnit((*m_creature), (*itr));
         if(zombie && zombie->isAlive())
             zombie->DealDamage(zombie, zombie->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
     }
     addsGuid.clear();
     if(pInstance) pInstance->SetData(TYPE_GLUTH, DONE);
 }
Example #10
0
        void Absorb(AuraEffect * /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
        {
            Unit * target = GetTarget();
            if (dmgInfo.GetDamage() < target->GetHealth())
                return;

            int32 healAmount = int32(target->CountPctFromMaxHealth(healPct));
            // remove the aura now, we don't want 40% healing bonus
            Remove(AURA_REMOVE_BY_ENEMY_SPELL);
            target->CastCustomSpell(target, PRI_SPELL_GUARDIAN_SPIRIT_HEAL, &healAmount, NULL, NULL, true);
            absorbAmount = dmgInfo.GetDamage();
        }
Example #11
0
        Unit* GetHatefullStrikeTarget()
        {
            // Get all Targets in Meleerange
            const std::list<HostileReference *> &threatlist = me->getThreatManager().getThreatList();
            std::list<Unit*> targetList;

            for (std::list<HostileReference*>::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
            {
                HostileReference* ref = (*itr);
                if (ref->getTarget() && me->IsWithinMeleeRange(ref->getTarget()))
                    targetList.push_back(ref->getTarget());
            }

            // Get Target with most HP and not getVictim()
            uint32 MostHP = 0;
            Unit* pMostHPTarget = NULL;
            uint32 counter = 0;

            for(std::list<Unit*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr)
            {
                counter++;

                //Only first 3 Targets in Threadlist
                if(counter > 3)
                    break;

                Unit *pTarget = (*itr);
                if (pTarget->isAlive() && pTarget->GetHealth() > MostHP)
                {
                    MostHP = pTarget->GetHealth();
                    pMostHPTarget = pTarget;
                }
            }

            if(pMostHPTarget)
                return pMostHPTarget;
            else
                return me->getVictim();
        }
Example #12
0
    Unit* CalculateHatefulStrikeTarget()
    {
        uint32 health = 0;
        Unit *pTarget = NULL;

        std::list<HostileReference*>& m_threatlist = m_creature->getThreatManager().getThreatList();
        std::list<HostileReference*>::const_iterator i = m_threatlist.begin();
        for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i)
        {
            Unit* pUnit = Unit::GetUnit((*m_creature), (*i)->getUnitGuid());
            if (pUnit && m_creature->IsWithinMeleeRange(pUnit))
            {
                if (pUnit->GetHealth() > health)
                {
                    health = pUnit->GetHealth();
                    pTarget = pUnit;
                }
            }
        }

        return pTarget;
    }
Example #13
0
        void Absorb(AuraEffect* /*aurEff*/, DamageInfo & dmgInfo, uint32 & absorbAmount)
        {
            Unit* target = GetTarget();
            if (dmgInfo.GetDamage() < target->GetHealth())
                return;
            if (target->ToPlayer()->HasSpellCooldown(ROG_SPELL_CHEAT_DEATH_COOLDOWN))
                return;
            if (!roll_chance_i(absorbChance))
                return;

            target->CastSpell(target, ROG_SPELL_CHEAT_DEATH_COOLDOWN, true);
            target->ToPlayer()->AddSpellCooldown(ROG_SPELL_CHEAT_DEATH_COOLDOWN, 0, time(NULL) + 60);

            uint32 health10 = target->CountPctFromMaxHealth(10);

            // hp > 10% - absorb hp till 10%
            if (target->GetHealth() > health10)
                absorbAmount = dmgInfo.GetDamage() - target->GetHealth() + health10;
            // hp lower than 10% - absorb everything
            else
                absorbAmount = dmgInfo.GetDamage();
        }
Example #14
0
        Unit* CalculateHatefulStrikeTarget()
        {
            uint32 health = 0;
            Unit* target = NULL;

            ThreatContainer::StorageType const &threatlist = me->getThreatManager().getThreatList();
            ThreatContainer::StorageType::const_iterator i = threatlist.begin();
            for (i = threatlist.begin(); i != threatlist.end(); ++i)
            {
                Unit* unit = Unit::GetUnit(*me, (*i)->getUnitGuid());
                if (unit && me->IsWithinMeleeRange(unit))
                {
                    if (unit->GetHealth() > health)
                    {
                        health = unit->GetHealth();
                        target = unit;
                    }
                }
            }

            return target;
        }
Example #15
0
            void OnPeriodic(constAuraEffectPtr aurEff)
            {
                Unit* xt002 = GetCaster();
                if (!xt002)
                    return;

                Unit* owner = GetOwner()->ToUnit();
                if (!owner)
                    return;

                if (aurEff->GetAmount() >= int32(owner->GetHealth()))
                    if (xt002->GetAI())
                        xt002->GetAI()->SetData(DATA_GRAVITY_BOMB_CASUALTY, 1);
            }
 void destroyPortals()
 {
     if (sumportals)
     {
         for (uint8 i = 0; i < 5; ++i)
         {
             Unit* Portal = Unit::GetUnit((*me), PortalsGuid[i]);
             if (Portal && Portal->isAlive())
                 Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
             PortalsGuid[i] = 0;
         }
         sumportals = false;
     }
 }
Example #17
0
            void JustDied(Unit* /*victim*/)
            {
                if (instance)
                    instance->SetData(DATA_HEXLORDEVENT, DONE);

                me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, 0);
                DoPlaySoundToSet(me, SOUND_YELL_DEATH);

                for (uint8 i = 0; i < 4 ; ++i)
                {
                    Unit* Temp = Unit::GetUnit((*me), AddGUID[i]);
                    if (Temp && Temp->isAlive())
                        Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                }
            }
 void DamageTaken(Unit* /*done_by*/, uint32 &damage) override
 {
     Unit* pOtherBoss = GetOtherBoss();
     if (pOtherBoss)
     {
         float dPercent = ((float)damage) / ((float)me->GetMaxHealth());
         int odmg = (int)(dPercent * ((float)pOtherBoss->GetMaxHealth()));
         int ohealth = pOtherBoss->GetHealth()-odmg;
         pOtherBoss->SetHealth(ohealth > 0 ? ohealth : 0);
         if (ohealth <= 0)
         {
             pOtherBoss->SetDeathState(JUST_DIED);
             pOtherBoss->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
         }
     }
 }
        void HandleOnHit()
        {
            if (!GetCaster())
                return;

            Unit* caster = GetCaster();

            if (!GetHitUnit())
                return;
            if (!GetSpellInfo())
                return;

            Unit* target = GetHitUnit();

            int bp = target->GetHealth() * 0.5;

            caster->CastCustomSpell(target, GetSpellInfo()->Id, &bp, NULL, NULL, true);
        }
Example #20
0
    void UpdateAI(const uint32 diff)
    {
        if (!ArchimondeGUID)
        {
            if (pInstance)
                ArchimondeGUID = pInstance->GetData64(DATA_ARCHIMONDE);
        }

        if (CheckTimer <= diff)
        {
            if (ArchimondeGUID)
            {
                Unit* Archimonde = Unit::GetUnit((*me), ArchimondeGUID);
                if (Archimonde)
                {
                    if ((((Archimonde->GetHealth()*100) / Archimonde->GetMaxHealth()) < 2) || !Archimonde->isAlive())
                        DoCast(me, SPELL_DENOUEMENT_WISP);
                    else
                        DoCast(Archimonde, SPELL_ANCIENT_SPARK);
                }
            }
            CheckTimer = 1000;
        } else CheckTimer -= diff;
    }
Example #21
0
            void SetPhaseOne()
            {
                Talk(SAY_HEART_CLOSED);
                Talk(EMOTE_HEART_CLOSED);

                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);
                DoCastSelf(SPELL_STAND);

                _phase = 1;

                events.RescheduleEvent(EVENT_SEARING_LIGHT, TIMER_SEARING_LIGHT / 2);
                events.RescheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB);
                events.RescheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX));

                Unit* heart = me->GetVehicleKit() ? me->GetVehicleKit()->GetPassenger(HEART_VEHICLE_SEAT_EXPOSED) : nullptr;
                if (!heart)
                    return;

                heart->CastSpell(me, SPELL_HEART_RIDE_VEHICLE, true);
                heart->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                heart->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
                heart->RemoveAurasDueToSpell(SPELL_EXPOSED_HEART);

                if (!_hardMode)
                {
                    if (!_transferHealth)
                        _transferHealth = (heart->GetMaxHealth() - heart->GetHealth());

                    if (_transferHealth >= me->GetHealth())
                        _transferHealth = me->GetHealth() - 1;

                    me->ModifyHealth(-((int32)_transferHealth));
                    me->LowerPlayerDamageReq(_transferHealth);
                }
            }
Example #22
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch(eventId)
                {
                    case EVENT_HATEFUL:
                    {
                        //Cast Hateful strike on the player with the highest
                        //amount of HP within melee distance
                        uint32 MostHP = 0;
                        uint32 maxCandidates = RAID_MODE(2,3);
                        Unit* pMostHPTarget = NULL;

                        std::list<HostileReference*> m_threatlist = me->getThreatManager().getThreatList();

                        if (m_threatlist.size()  > maxCandidates)
                            m_threatlist.resize(maxCandidates);  // Picks 2 (3) highest threat targets as Hateful Strike candidates

                        std::list<HostileReference*>::const_iterator i = m_threatlist.begin();

                        for (; i != m_threatlist.end(); ++i)
                        {
                            Unit* target = (*i)->getTarget();
                            if (target->isAlive() && target != me->getVictim() && target->GetHealth() > MostHP && me->IsWithinMeleeRange(target))
                            {
                                MostHP = target->GetHealth();
                                pMostHPTarget = target;
                            }
                        }

                        if (!pMostHPTarget)
                            pMostHPTarget = me->getVictim();

                        DoCast(pMostHPTarget, RAID_MODE(SPELL_HATEFUL_STRIKE, H_SPELL_HATEFUL_STRIKE), true);

                        /// wowhead article: "GREATLY boosts threat of the Hateful Strike candidates"
                        /// but i have no data (bonus threat percent, ect) for this "GREAT boost"...

                        events.ScheduleEvent(EVENT_HATEFUL, 1200);
                        break;
                    }
                    case EVENT_BERSERK:
                        DoCast(me, SPELL_BERSERK, true);
                        DoScriptText(EMOTE_BERSERK, me);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                    case EVENT_SLIME:
                        DoCast(me->getVictim(), SPELL_SLIME_BOLT);
                        events.ScheduleEvent(EVENT_SLIME, 2000);
                        break;
                }
            }

            if (!Enraged && HealthBelowPct(5))
            {
                DoCast(me, SPELL_FRENZY, true);
                DoScriptText(EMOTE_ENRAGE, me);
                Enraged = true;
            }

            DoMeleeAttackIfReady();
        }
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            events.Update(diff);

            while (uint32 eventId = events.ExecuteEvent())
            {
                switch (eventId)
                {
                    case EVENT_HATEFUL:
                    {
                        // Hateful Strike targets the highest non-MT threat in melee range on 10man
                        // and the higher HP target out of the two highest non-MT threats in melee range on 25man
                        float MostThreat = 0.0f;
                        Unit* secondThreatTarget = NULL;
                        Unit* thirdThreatTarget = NULL;

                        std::list<HostileReference*>::const_iterator i = me->getThreatManager().getThreatList().begin();
                        for (; i != me->getThreatManager().getThreatList().end(); ++i)
                        { // find second highest
                            Unit* target = (*i)->getTarget();
                            if (target->IsAlive() && target != me->GetVictim() && (*i)->getThreat() >= MostThreat && me->IsWithinMeleeRange(target))
                            {
                                MostThreat = (*i)->getThreat();
                                secondThreatTarget = target;
                            }
                        }

                        if (secondThreatTarget && Is25ManRaid())
                        { // find third highest
                            MostThreat = 0.0f;
                            i = me->getThreatManager().getThreatList().begin();
                            for (; i != me->getThreatManager().getThreatList().end(); ++i)
                            {
                                Unit* target = (*i)->getTarget();
                                if (target->IsAlive() && target != me->GetVictim() && target != secondThreatTarget && (*i)->getThreat() >= MostThreat && me->IsWithinMeleeRange(target))
                                {
                                    MostThreat = (*i)->getThreat();
                                    thirdThreatTarget = target;
                                }
                            }
                        }

                        Unit* pHatefulTarget = NULL;
                        if (!thirdThreatTarget)
                            pHatefulTarget = secondThreatTarget;
                        else if (secondThreatTarget)
                            pHatefulTarget = (secondThreatTarget->GetHealth() < thirdThreatTarget->GetHealth()) ? thirdThreatTarget : secondThreatTarget;

                        if (!pHatefulTarget)
                            pHatefulTarget = me->GetVictim();

                        DoCast(pHatefulTarget, SPELL_HATEFUL_STRIKE, true);

                        // add threat to highest threat targets
                        if (me->GetVictim() && me->IsWithinMeleeRange(me->GetVictim()))
                            me->getThreatManager().addThreat(me->GetVictim(), HATEFUL_THREAT_AMT);
                        if (secondThreatTarget)
                            me->getThreatManager().addThreat(secondThreatTarget, HATEFUL_THREAT_AMT);
                        if (thirdThreatTarget)
                            me->getThreatManager().addThreat(thirdThreatTarget, HATEFUL_THREAT_AMT); // this will only ever be used in 25m

                        events.Repeat(Seconds(1));
                        break;
                    }
                    case EVENT_BERSERK:
                        DoCast(me, SPELL_BERSERK, true);
                        Talk(EMOTE_BERSERK);
                        events.ScheduleEvent(EVENT_SLIME, Seconds(2));
                        break;
                    case EVENT_SLIME:
                        DoCastAOE(SPELL_SLIME_BOLT, true);
                        events.Repeat(Seconds(2));
                        break;
                }
            }

            if (!Enraged && HealthBelowPct(5))
            {
                DoCast(me, SPELL_FRENZY, true);
                Talk(EMOTE_FRENZY);
                Enraged = true;
            }

            DoMeleeAttackIfReady();
        }
Example #24
0
    void UpdateAI(const uint32 diff)
    {
        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim())
            return;

        if(!DrainingCrystal)
        {
            uint32 maxPowerMana = m_creature->GetMaxPower(POWER_MANA);
            if( maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10) )
            {
                if( DrainLifeTimer < diff )
                {
                    DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_LIFE);
                    DrainLifeTimer = 10000;
                } else DrainLifeTimer -= diff;

                // Heroic only
                if( Heroic )
                {
                    if( DrainManaTimer < diff )
                    {
                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DRAIN_MANA);
                        DrainManaTimer = 10000;
                    } else DrainManaTimer -= diff;
                }
            }

            if( FelExplosionTimer < diff )
            {
                if(!m_creature->IsNonMeleeSpellCasted(false))
                {
                    DoCast(m_creature, SPELL_FEL_EXPLOSION);
                    FelExplosionTimer = 2000;
                }
            } else FelExplosionTimer -= diff;

            // If below 10% mana, start recharging
            maxPowerMana = m_creature->GetMaxPower(POWER_MANA);
            if( maxPowerMana && ((m_creature->GetPower(POWER_MANA)*100 / maxPowerMana) < 10) )
            {
                if(DrainCrystalTimer < diff)
                {
                    SelectNearestCrystal();
                    if(Heroic)   DrainCrystalTimer = 10000 + rand()%5000;
                    else         DrainCrystalTimer = 20000 + rand()%5000;
                } else DrainCrystalTimer -= diff;
            }

        } else
        {
            if( IsDraining )
            {
                if( EmpowerTimer < diff )
                {
                    IsDraining = false;
                    DrainingCrystal = false;

                    DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL);
                    DoPlaySoundToSet(m_creature, SOUND_EMPOWERED);

                    Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID);
                    if( CrystalChosen && CrystalChosen->isAlive() )
                        // Use Deal Damage to kill it, not setDeathState.
                        CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);

                    CrystalGUID = 0;

                    m_creature->GetMotionMaster()->Clear();
                    m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
                } else EmpowerTimer -= diff;
            }
        }

        DoMeleeAttackIfReady();                             // No need to check if we are draining crystal here, as the spell has a stun.
    }
Example #25
0
/*this procedure handles clients CMSG_REQUEST_PARTY_MEMBER_STATS request*/
void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
{
    DEBUG_LOG("WORLD: Received CMSG_REQUEST_PARTY_MEMBER_STATS");
    uint64 Guid;
    recv_data >> Guid;

    Player *player = sObjectMgr.GetPlayer(Guid);
    if(!player)
    {
        WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2);
        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
        data.appendPackGUID(Guid);
        data << uint32(GROUP_UPDATE_FLAG_STATUS);
        data << uint16(MEMBER_STATUS_OFFLINE);
        SendPacket(&data);
        return;
    }

    Unit *pet = player->GetCharmOrPet();

    WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8);
    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related
    data << player->GetPackGUID();

    uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF
    if(pet)
        mask1 = 0xFFFFFFFF;                                 // for hunters and other classes with pets

    Powers powerType = player->getPowerType();
    data << uint32(mask1);                                  // group update mask
    data << uint16(MEMBER_STATUS_ONLINE);                   // member's online status
    data << uint32(player->GetHealth());                    // GROUP_UPDATE_FLAG_CUR_HP
    data << uint32(player->GetMaxHealth());                 // GROUP_UPDATE_FLAG_MAX_HP
    data << uint8(powerType);                               // GROUP_UPDATE_FLAG_POWER_TYPE
    data << uint16(player->GetPower(powerType));            // GROUP_UPDATE_FLAG_CUR_POWER
    data << uint16(player->GetMaxPower(powerType));         // GROUP_UPDATE_FLAG_MAX_POWER
    data << uint16(player->getLevel());                     // GROUP_UPDATE_FLAG_LEVEL
    data << uint16(player->GetZoneId());                    // GROUP_UPDATE_FLAG_ZONE
    data << uint16(player->GetPositionX());                 // GROUP_UPDATE_FLAG_POSITION
    data << uint16(player->GetPositionY());                 // GROUP_UPDATE_FLAG_POSITION

    uint64 auramask = 0;
    size_t maskPos = data.wpos();
    data << uint64(auramask);                               // placeholder
    for(uint8 i = 0; i < MAX_AURAS; ++i)
    {
        if(uint32 aura = player->GetVisibleAura(i))
        {
            auramask |= (uint64(1) << i);
            data << uint32(aura);
            data << uint8(1);
        }
    }
    data.put<uint64>(maskPos, auramask);                    // GROUP_UPDATE_FLAG_AURAS

    if(pet)
    {
        Powers petpowertype = pet->getPowerType();
        data << pet->GetObjectGuid();                       // GROUP_UPDATE_FLAG_PET_GUID
        data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME
        data << uint16(pet->GetDisplayId());                // GROUP_UPDATE_FLAG_PET_MODEL_ID
        data << uint32(pet->GetHealth());                   // GROUP_UPDATE_FLAG_PET_CUR_HP
        data << uint32(pet->GetMaxHealth());                // GROUP_UPDATE_FLAG_PET_MAX_HP
        data << uint8(petpowertype);                        // GROUP_UPDATE_FLAG_PET_POWER_TYPE
        data << uint16(pet->GetPower(petpowertype));        // GROUP_UPDATE_FLAG_PET_CUR_POWER
        data << uint16(pet->GetMaxPower(petpowertype));     // GROUP_UPDATE_FLAG_PET_MAX_POWER

        uint64 petauramask = 0;
        size_t petMaskPos = data.wpos();
        data << uint64(petauramask);                        // placeholder
        for(uint8 i = 0; i < MAX_AURAS; ++i)
        {
            if(uint32 petaura = pet->GetVisibleAura(i))
            {
                petauramask |= (uint64(1) << i);
                data << uint32(petaura);
                data << uint8(1);
            }
        }
        data.put<uint64>(petMaskPos, petauramask);          // GROUP_UPDATE_FLAG_PET_AURAS
        data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
    else
    {
        data << uint8(0);                                   // GROUP_UPDATE_FLAG_PET_NAME
        data << uint64(0);                                  // GROUP_UPDATE_FLAG_PET_AURAS
    }

    SendPacket(&data);
}
Example #26
0
void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacket *data)
{
    uint32 mask = player->GetGroupUpdateFlag();

    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)                // if update power type, update current/max power also
        mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER);

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)            // same for pets
        mask |= (GROUP_UPDATE_FLAG_PET_CUR_POWER | GROUP_UPDATE_FLAG_PET_MAX_POWER);

    uint32 byteCount = 0;
    for (int i = 1; i < GROUP_UPDATE_FLAGS_COUNT; ++i)
        if (mask & (1 << i))
            byteCount += GroupUpdateLength[i];

    data->Initialize(SMSG_PARTY_MEMBER_STATS, 8 + 4 + byteCount);
    *data << player->GetPackGUID();
    *data << uint32(mask);

    if (mask & GROUP_UPDATE_FLAG_STATUS)
    {
        if (player)
        {
            if (player->IsPvP())
                *data << uint16(MEMBER_STATUS_ONLINE | MEMBER_STATUS_PVP);
            else
                *data << uint16(MEMBER_STATUS_ONLINE);
        }
        else
            *data << uint16(MEMBER_STATUS_OFFLINE);
    }

    if (mask & GROUP_UPDATE_FLAG_CUR_HP)
        *data << uint32(player->GetHealth());

    if (mask & GROUP_UPDATE_FLAG_MAX_HP)
        *data << uint32(player->GetMaxHealth());

    Powers powerType = player->getPowerType();
    if (mask & GROUP_UPDATE_FLAG_POWER_TYPE)
        *data << uint8(powerType);

    if (mask & GROUP_UPDATE_FLAG_CUR_POWER)
        *data << uint16(player->GetPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_MAX_POWER)
        *data << uint16(player->GetMaxPower(powerType));

    if (mask & GROUP_UPDATE_FLAG_LEVEL)
        *data << uint16(player->getLevel());

    if (mask & GROUP_UPDATE_FLAG_ZONE)
        *data << uint16(player->GetZoneId());

    if (mask & GROUP_UPDATE_FLAG_POSITION)
        *data << uint16(player->GetPositionX()) << uint16(player->GetPositionY());

    if (mask & GROUP_UPDATE_FLAG_AURAS)
    {
        const uint64& auramask = player->GetAuraUpdateMask();
        *data << uint64(auramask);
        for(uint32 i = 0; i < MAX_AURAS; ++i)
        {
            if(auramask & (uint64(1) << i))
            {
                *data << uint32(player->GetVisibleAura(i));
                *data << uint8(1);
            }
        }
    }

    Unit *pet = player->GetCharmOrPet();
    if (mask & GROUP_UPDATE_FLAG_PET_GUID)
        *data << (pet ? pet->GetObjectGuid() : ObjectGuid());

    if (mask & GROUP_UPDATE_FLAG_PET_NAME)
    {
        if(pet)
            *data << pet->GetName();
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MODEL_ID)
    {
        if(pet)
            *data << uint16(pet->GetDisplayId());
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)
    {
        if(pet)
            *data << uint32(pet->GetHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)
    {
        if(pet)
            *data << uint32(pet->GetMaxHealth());
        else
            *data << uint32(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE)
    {
        if(pet)
            *data << uint8(pet->getPowerType());
        else
            *data << uint8(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_CUR_POWER)
    {
        if(pet)
            *data << uint16(pet->GetPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_MAX_POWER)
    {
        if(pet)
            *data << uint16(pet->GetMaxPower(pet->getPowerType()));
        else
            *data << uint16(0);
    }

    if (mask & GROUP_UPDATE_FLAG_PET_AURAS)
    {
        if(pet)
        {
            const uint64& auramask = pet->GetAuraUpdateMask();
            *data << uint64(auramask);
            for(uint32 i = 0; i < MAX_AURAS; ++i)
            {
                if(auramask & (uint64(1) << i))
                {
                    *data << uint32(pet->GetVisibleAura(i));
                    *data << uint8(1);
                }
            }
        }
        else
            *data << uint64(0);
    }

    if (mask & GROUP_UPDATE_FLAG_VEHICLE_SEAT)
    {
        *data << (uint32) player->m_movementInfo.GetTransportDBCSeat();
    }
}
Example #27
0
        uint32 NextStep(uint32 Step)
        {
            Unit* arca = Unit::GetUnit((*me), ArcanagosGUID);
            Map* pMap = me->GetMap();
            switch(Step)
            {
            case 0: return 9999999;
            case 1:
                me->MonsterYell(SAY_DIALOG_MEDIVH_1, LANG_UNIVERSAL, 0);
                return 10000;
            case 2:
                if (arca)
                    CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_2, LANG_UNIVERSAL, 0);
                return 20000;
            case 3:
                me->MonsterYell(SAY_DIALOG_MEDIVH_3, LANG_UNIVERSAL, 0);
                return 10000;
            case 4:
                if (arca)
                    CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_4, LANG_UNIVERSAL, 0);
                return 20000;
            case 5:
                me->MonsterYell(SAY_DIALOG_MEDIVH_5, LANG_UNIVERSAL, 0);
                return 20000;
            case 6:
                if (arca)
                    CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_6, LANG_UNIVERSAL, 0);
                return 10000;
            case 7:
                FireArcanagosTimer = 500;
                return 5000;
            case 8:
                FireMedivhTimer = 500;
                DoCast(me, SPELL_MANA_SHIELD);
                return 10000;
            case 9:
                me->MonsterTextEmote(EMOTE_DIALOG_MEDIVH_7, 0, false);
                return 10000;
            case 10:
                if (arca)
                    DoCast(arca, SPELL_CONFLAGRATION_BLAST, false);
                return 1000;
            case 11:
                if (arca)
                    CAST_CRE(arca)->MonsterYell(SAY_DIALOG_ARCANAGOS_8, LANG_UNIVERSAL, 0);
                return 5000;
            case 12:
                arca->GetMotionMaster()->MovePoint(0, -11010.82f, -1761.18f, 156.47f);
                arca->setActive(true);
                arca->InterruptNonMeleeSpells(true);
                arca->SetSpeed(MOVE_FLIGHT, 2.0f);
                return 10000;
            case 13:
                me->MonsterYell(SAY_DIALOG_MEDIVH_9, LANG_UNIVERSAL, 0);
                return 10000;
            case 14:
                me->SetVisible(false);
                me->ClearInCombat();

                if (pMap->IsDungeon())
                {
                    InstanceMap::PlayerList const &PlayerList = pMap->GetPlayers();
                    for (InstanceMap::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                    {
                        if (i->getSource()->isAlive())
                        {
                            if (i->getSource()->GetQuestStatus(9645) == QUEST_STATUS_INCOMPLETE)
                                i->getSource()->CompleteQuest(9645);
                        }
                    }
                }
                return 50000;
            case 15:
                arca->DealDamage(arca, arca->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
                return 5000;
            default : return 9999999;
            }

        }
Example #28
0
        void Absorb(AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & absorbAmount)
        {
            Unit* victim = GetTarget();
            int32 remainingHealth = victim->GetHealth() - dmgInfo.GetDamage();
            uint32 allowedHealth = victim->CountPctFromMaxHealth(35);

            //npcbot - calc for bots
            if (victim->GetTypeId() == TYPEID_UNIT/* && victim->ToCreature()->IsNPCBot()*/)
            {
                if (remainingHealth <= 0 && !victim->ToCreature()->GetSpellHistory()->HasCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL))
                {
                    // Cast healing spell, completely avoid damage
                    absorbAmount = dmgInfo.GetDamage();

                    uint32 defenseSkillValue = victim->GetDefenseSkillValue();
                    // Max heal when defense skill denies critical hits from raid bosses
                    // Formula: max defense at level + 140 (raiting from gear)
                    uint32 reqDefForMaxHeal  = victim->getLevel() * 5 + 140;
                    float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal)
                                           ? 1.0f
                                           : float(defenseSkillValue) / float(reqDefForMaxHeal);

                    int32 healAmount = int32(victim->CountPctFromMaxHealth(int32(healPct * pctFromDefense)));
                    victim->CastCustomSpell(victim, PAL_SPELL_ARDENT_DEFENDER_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff);
                    victim->ToCreature()->AddBotSpellCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 120 * IN_MILLISECONDS);
                }
                else if (remainingHealth < int32(allowedHealth))
                {
                    // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
                    uint32 damageToReduce = (victim->GetHealth() < allowedHealth)
                                            ? dmgInfo.GetDamage()
                                            : allowedHealth - remainingHealth;
                    absorbAmount = CalculatePct(damageToReduce, absorbPct);
                }

                return;
            }
            //end npcbot

            // If damage kills us
            if (remainingHealth <= 0 && !victim->GetSpellHistory()->HasCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL))
            {
                // Cast healing spell, completely avoid damage
                absorbAmount = dmgInfo.GetDamage();

                uint32 defenseSkillValue = victim->GetDefenseSkillValue();
                // Max heal when defense skill denies critical hits from raid bosses
                // Formula: max defense at level + 140 (raiting from gear)
                uint32 reqDefForMaxHeal  = victim->getLevel() * 5 + 140;
                float pctFromDefense = (defenseSkillValue >= reqDefForMaxHeal)
                                       ? 1.0f
                                       : float(defenseSkillValue) / float(reqDefForMaxHeal);

                int32 healAmount = int32(victim->CountPctFromMaxHealth(uint32(healPct * pctFromDefense)));
                victim->CastCustomSpell(victim, PAL_SPELL_ARDENT_DEFENDER_HEAL, &healAmount, NULL, NULL, true, NULL, aurEff);
                victim->GetSpellHistory()->AddCooldown(PAL_SPELL_ARDENT_DEFENDER_HEAL, 0, std::chrono::minutes(2));
            }
            else if (remainingHealth < int32(allowedHealth))
            {
                // Reduce damage that brings us under 35% (or full damage if we are already under 35%) by x%
                uint32 damageToReduce = (victim->GetHealth() < allowedHealth)
                                        ? dmgInfo.GetDamage()
                                        : allowedHealth - remainingHealth;
                absorbAmount = CalculatePct(damageToReduce, absorbPct);
            }
        }
Example #29
0
     void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (BerserkTimer < diff)
        {
            m_creature->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, NULL);
            DoPlaySoundToSet(m_creature, SOUND_BERSERK);
            DoCast(m_creature, SPELL_BERSERK, true);
            BerserkTimer = 60000;
        }else BerserkTimer -= diff;

        if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE)
        {
            if (SaberlashTimer < diff)
            {
                // A tank with more than 490 defense skills should receive no critical hit
                //m_creature->CastSpell(m_creature, 41296, true);
                m_creature->CastSpell(m_creature->getVictim(), SPELL_SABER_LASH, true);
                //m_creature->RemoveAurasDueToSpell(41296);
                SaberlashTimer = 30000;
            }else SaberlashTimer -= diff;

            if (FrenzyTimer < diff)
            {
                DoCast(m_creature, SPELL_FRENZY);
                FrenzyTimer = (10+rand()%5)*1000;
            }else FrenzyTimer -= diff;

            if (Phase == PHASE_LYNX)
                if (CheckTimer < diff)
                {
                    if (m_creature->GetHealth() * 4 < m_creature->GetMaxHealth() * (3 - TransformCount))
                        EnterPhase(PHASE_SPLIT);
                    CheckTimer = 1000;
                }else CheckTimer -= diff;
        }

        if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE)
        {
            if (TotemTimer < diff)
            {
                DoCast(m_creature, SPELL_SUMMON_TOTEM);
                TotemTimer = 20000;
            }else TotemTimer -= diff;

            if (ShockTimer < diff)
            {
                if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0))
                {
                    if (target->IsNonMeleeSpellCasted(false))
                        DoCast(target,SPELL_EARTHSHOCK);
                    else
                        DoCast(target,SPELL_FLAMESHOCK);
                    ShockTimer = 10000 + rand()%5000;
                }
            }else ShockTimer -= diff;

            if (Phase == PHASE_HUMAN)
                if (CheckTimer < diff)
                {
                    if (((m_creature->GetHealth()*100) / m_creature->GetMaxHealth() <= 20)/*m_creature->GetHealth() * 10 < m_creature->GetMaxHealth()*/)
                        EnterPhase(PHASE_MERGE);
                    else
                    {
                        Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID);
                        if (Lynx && ((Lynx->GetHealth()*100) / Lynx->GetMaxHealth() <= 20)/*Lynx->GetHealth() * 10 < Lynx->GetMaxHealth()*/)
                            EnterPhase(PHASE_MERGE);
                    }
                    CheckTimer = 1000;
                }else CheckTimer -= diff;
        }

        if (Phase == PHASE_MERGE)
        {
            if (CheckTimer < diff)
            {
                Unit *Lynx = Unit::GetUnit(*m_creature, LynxGUID);
                if (Lynx)
                {
                    Lynx->GetMotionMaster()->MoveFollow(m_creature, 0, 0);
                    m_creature->GetMotionMaster()->MoveFollow(Lynx, 0, 0);
                    if (m_creature->IsWithinDistInMap(Lynx, 6.0f))
                    {
                        if (TransformCount < 3)
                            EnterPhase(PHASE_LYNX);
                        else
                            EnterPhase(PHASE_ENRAGE);
                    }
                }
                CheckTimer = 1000;
            }else CheckTimer -= diff;
        }

        DoMeleeAttackIfReady();
    }
Example #30
0
    void UpdateAI (const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (PhaseTwo)
        {
            me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
            me->setDeathState(JUST_DIED);
            me->SetHealth(0);
            me->GetMotionMaster()->Clear();
            me->clearUnitState(UNIT_STAT_ALL_STATE);
            me->LoadCreaturesAddon(true);
            return;
        }

        if (LorkhanDead)
            return;

        // Resurrect
        if (ThekalDead || ZathDead)
        {
            if (!IsResurrecting && (CheckDeath_Timer - 2000) <= diff)
            {
                if (ZathDead)
                    if (Unit* pZath = Unit::GetUnit(*me, ZathGUID))
                        pZath->CastSpell(pZath, SPELL_RESURRECT, false, 0, 0, pZath->GetGUID());
                if (ThekalDead)
                    if (Unit* pThekal = Unit::GetUnit(*me, ThekalGUID))
                        pThekal->CastSpell(pThekal, SPELL_RESURRECT, false, 0, 0, pThekal->GetGUID());
                IsResurrecting = true;
            }
            else if (ThekalDead)
                CheckDeath_Timer -= diff;
        }

        // Shield Timer
        if (Shield_Timer <= diff)
        {
            DoCast(me, SPELL_SHIELD);
            Shield_Timer = 61000;
        }
        else
            Shield_Timer -= diff;

        // BloodLust Timer
        if (BloodLust_Timer <= diff)
        {
            DoCast(me, SPELL_BLOODLUST);
            BloodLust_Timer = 20000 + rand()%8000;
        }
        else
            BloodLust_Timer -= diff;

        // Cast Greater heal on Thekal or Zath if they are in melee range.
        if (GreaterHeal_Timer <= diff)
        {
            if (pInstance)
            {
                Unit *pThekal = Unit::GetUnit((*me), ThekalGUID);
                Unit *pZath = Unit::GetUnit((*me), ZathGUID);

                if (!pThekal || !pZath)
                    return;

                // Might use a loop and a vector in the future
                // Target lowest ally in range
                if (me->IsWithinMeleeRange(pThekal) && me->IsWithinMeleeRange(pZath))
                    if ((pThekal->GetHealth() / pThekal->GetMaxHealth()) < (pZath->GetHealth() / pZath->GetMaxHealth()))
                        if ((pThekal->GetHealth() / pThekal->GetMaxHealth()) < (me->GetHealth() / me->GetMaxHealth()))
                            DoCast(pThekal, SPELL_GREATERHEAL);
                        else
                            DoCast(me, SPELL_GREATERHEAL);
                    else if ((pZath->GetHealth() / pZath->GetMaxHealth()) < (me->GetHealth() / me->GetMaxHealth()))
                        DoCast(pZath, SPELL_GREATERHEAL);
                    else
                        DoCast(me, SPELL_GREATERHEAL);
                else if (me->IsWithinMeleeRange(pThekal) && !me->IsWithinMeleeRange(pZath))
                    if ((pThekal->GetHealth() / pThekal->GetMaxHealth()) < (me->GetHealth() / me->GetMaxHealth()))
                        DoCast(pThekal, SPELL_GREATERHEAL);
                    else
                        DoCast(me, SPELL_GREATERHEAL);
                else if (!me->IsWithinMeleeRange(pThekal) && me->IsWithinMeleeRange(pZath))
                    if ((pZath->GetHealth() / pZath->GetMaxHealth()) < (me->GetHealth() / me->GetMaxHealth()))
                        DoCast(pZath, SPELL_GREATERHEAL);
                    else
                        DoCast(me, SPELL_GREATERHEAL);
                else if (!me->IsWithinMeleeRange(pThekal) && !me->IsWithinMeleeRange(pZath))
                    DoCast(me, SPELL_GREATERHEAL);
            }
            GreaterHeal_Timer = 15000 + rand()%5000;
        }
        else
            GreaterHeal_Timer -= diff;

        // Disarm Timer
        if (Disarm_Timer <= diff)
        {
            DoCast(me->getVictim(), SPELL_DISARM);
            Disarm_Timer = 15000 + rand()%10000;
        }
        else
            Disarm_Timer -= diff;

        DoMeleeAttackIfReady();
    }