void JustDied(Unit* /*victim*/)
            {
                if (pInstance)
                    pInstance->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);
                }
            }
Example #2
0
 void DamageTaken(Unit* /*done_by*/, uint32 &damage)
 {
     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);
         }
     }
 }
Example #3
0
bool PlayerbotClassAI::DoSupportRaid(Player *gPlayer, float radius, bool dResurrect, bool dGroupHeal, bool dHeal, bool dCure, bool dBuff)
{
    bool needHeal = false;
    if (dGroupHeal || dHeal)
    {
        uint8 cntNeedHeal = 0;
        uint8 raidHPPercent = GetHealthPercentRaid(gPlayer, cntNeedHeal);
        if (dGroupHeal && raidHPPercent <=90 && cntNeedHeal > 1)
        {
            if (HealGroup(gPlayer, raidHPPercent, cntNeedHeal)) return true;
        }
        if (raidHPPercent < 60 ) needHeal = true;
    }
    //std::list<Unit*> unitList;
    //gPlayer->GetRaidMember(unitList,30);
    Group *pGroup = gPlayer->GetGroup();
    if (!pGroup) return false;
    for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
    {
        Unit* tPlayer = itr->getSource();
        if(!tPlayer || gPlayer->IsHostileTo(tPlayer)) continue;
        if(GetPlayerBot()->GetAreaId() != tPlayer->GetAreaId()) continue;
        if(!m_bot->IsWithinDistInMap(tPlayer, radius)) {
            continue;
        }
        if(tPlayer->isDead()) // May be we can rez
        {
            if(!dResurrect) continue;
            if(needHeal) continue; //First heal others needing heal
            if(tPlayer->GetGUID() == GetPlayerBot()->GetGUID()) continue;
            if(tPlayer->IsNonMeleeSpellCasted(true)) continue; //Already rez
            if(RezTarget(tPlayer)) {
                return true;
            }
            else continue;
        }
        if (dHeal)
        {
            uint8 tarHPPercent = tPlayer->GetHealth()*100 / tPlayer->GetMaxHealth();
            if (tarHPPercent < 100 && HealTarget(tPlayer, tarHPPercent)) return true;
        }
        if (needHeal && dHeal) continue; //First heal others needing heal
        if (dCure && CureTarget(tPlayer)) return true;
        if (dBuff && BuffPlayer(tPlayer)) return true;
    }
    return false;
}
Example #4
0
    void JustDied(Unit *victim)
    {
        DoYell(SAY_DEATH, LANG_UNIVERSAL, NULL);
        DoPlaySoundToSet(m_creature, SOUND_DEATH);

        //despawn copy
        if(Demon)
        {
            Unit *pUnit = NULL;
            pUnit = Unit::GetUnit((*m_creature), Demon);

            if(pUnit)
                pUnit->DealDamage(pUnit, pUnit->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
        }

        if(pInstance)
            pInstance->SetData(DATA_LEOTHERASTHEBLINDEVENT, 0);
    }
        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 #6
0
void IFighterTask::OnUnitDamaged(CCircuitUnit* unit, CEnemyUnit* attacker)
{
	CCircuitAI* circuit = manager->GetCircuit();
	int frame = circuit->GetLastFrame();
	CCircuitDef* cdef = unit->GetCircuitDef();
	Unit* u = unit->GetUnit();
	const float healthPerc = u->GetHealth() / u->GetMaxHealth();
	if (unit->GetShield() != nullptr) {
		const float minShield = circuit->GetSetupManager()->GetEmptyShield();
		if ((healthPerc > cdef->GetRetreat()) && unit->IsShieldCharged(minShield)) {
			if (cdef->IsRoleHeavy() && (healthPerc < 0.9f)) {
				circuit->GetBuilderManager()->EnqueueRepair(IBuilderTask::Priority::NOW, unit);
			}
			return;
		}
	} else if ((healthPerc > cdef->GetRetreat()) && !unit->IsDisarmed(frame)) {
		if (cdef->IsRoleHeavy() && (healthPerc < 0.9f)) {
			circuit->GetBuilderManager()->EnqueueRepair(IBuilderTask::Priority::NOW, unit);
		}
		return;
	} else if (healthPerc < 0.2f) {  // stuck units workaround: they don't shoot and don't see distant threat
		CRetreatTask* task = manager->GetCircuit()->GetMilitaryManager()->EnqueueRetreat();
		manager->AssignTask(unit, task);
		return;
	}

	CThreatMap* threatMap = circuit->GetThreatMap();
	const float range = cdef->GetMaxRange();
	if ((target == nullptr) || !target->IsInLOS()) {
		CRetreatTask* task = circuit->GetMilitaryManager()->EnqueueRetreat();
		manager->AssignTask(unit, task);
		return;
	}
	const AIFloat3& pos = unit->GetPos(frame);
	if ((target->GetPos().SqDistance2D(pos) > SQUARE(range)) ||
		(threatMap->GetThreatAt(unit, pos) * 2 > threatMap->GetUnitThreat(unit)))
	{
		CRetreatTask* task = circuit->GetMilitaryManager()->EnqueueRetreat();
		manager->AssignTask(unit, task);
		return;
	}
	cowards.insert(unit);
}
    void JustDied(Unit *killer)
    {
        for(uint8 i = 0; i < 2; ++i)
        {
            if(PortalGUID[i])
            {
                Unit* Portal = Unit::GetUnit((*me), PortalGUID[i]);
                if(Portal)
                    Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);

                PortalGUID[i] = 0;
            }
        }

        DoScriptText(SAY_DEATH, me);

        if(pInstance)
            pInstance->SetData(DATA_TERESTIAN, DONE);
    }
    void EnfeebleHealthEffect()
    {
        const SpellEntry *info = GetSpellStore()->LookupEntry(SPELL_ENFEEBLE_EFFECT);
        if (!info)
            return;

        ThreatList const& tList = m_creature->getThreatManager().getThreatList();
        std::vector<Unit *> targets;

        if (tList.empty())
            return;

        //begin + 1 , so we don't target the one with the highest threat
        ThreatList::const_iterator itr = tList.begin();
        std::advance(itr, 1);
        for(; itr!= tList.end(); ++itr)                    //store the threat list in a different container
        {
            Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                                                            //only on alive players
            if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
                targets.push_back(target);
        }

        //cut down to size if we have more than 5 targets
        while(targets.size() > 5)
            targets.erase(targets.begin()+rand()%targets.size());

        int i = 0;
        for(std::vector<Unit *>::iterator iter = targets.begin(); iter!= targets.end(); ++iter, ++i)
        {
            Unit *target = *iter;
            if (target)
            {
                enfeeble_targets[i] = target->GetGUID();
                enfeeble_health[i] = target->GetHealth();

                target->CastSpell(target, SPELL_ENFEEBLE, true, 0, 0, m_creature->GetGUID());
                target->SetHealth(1);
            }
        }

    }
Example #9
0
		uint32 AbsorbDamage(uint32 School, uint32* dmg)
		{
			Unit* caster = GetUnitCaster();
			if(caster == NULL)
				return 0;

			int health_pct = caster->GetHealthPct();
			uint32 cur_health = caster->GetHealth();
			uint32 max_health = caster->GetMaxHealth();
			uint32 new_health_pct = (cur_health - *dmg) * 100 / max_health;

			// "Damage that would take you below $s1% health or taken while you are at $s1% health is reduced by $52284s1%."
			if((health_pct > 35 && new_health_pct < 35) || health_pct == 35)
			{
				uint32 dmg_absorbed = *dmg * (GetSpellProto()->EffectBasePoints[0] + 1) / 100;
				*dmg -= dmg_absorbed;

				return dmg_absorbed;
			}
			else
				return 0;
		}
    void UpdateAI(const uint32 uiDiff)
    {
        //Return since we have no target
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if(m_bCanShatter)
            if(m_uiShatterTimer < uiDiff)
            {
                ShatterGolem();
                m_bCanShatter = false;
            }else m_uiShatterTimer -= uiDiff;

        for(uint8 i=0; i<3; ++i)
        {
            Unit* pGolem = Unit::GetUnit(*m_creature, m_uiGolemsGUID[i][0]);
            if(pGolem && pGolem->isAlive())
                if(pGolem->GetHealth()*100 / pGolem->GetMaxHealth() < 1)
                    m_uiGolemsGUID[i][1] = 1; 
        }

        if(!m_bCanShatter && m_uiGolemsGUID[0][1] == 1 && m_uiGolemsGUID[1][1] == 1 && m_uiGolemsGUID[2][1] == 1) 
        {
            DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_SHATTERING_STOMP_N : SPELL_SHATTERING_STOMP_H);
            m_uiShatterTimer = 3000;
            m_bCanShatter = true;
        }

        // Health check
        if (m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < (100-(20*m_uiHealthAmountModifier)))
        {
            SummonGolems();
            ++m_uiHealthAmountModifier;

            DoScriptText(urand(0, 1) ? SAY_FORGE_1 : SAY_FORGE_2, m_creature);
        }

        DoMeleeAttackIfReady();
    }
Example #11
0
            void SetPhaseOne()
            {
                DoScriptText(SAY_HEART_CLOSED, me);
                if (me->HasAura(SPELL_SUBMERGE))
                    me->RemoveAurasDueToSpell(SPELL_SUBMERGE);
                DoCast(me, SPELL_STAND);
                // Just for the case this isn't done by the spell above.
                me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC | UNIT_FLAG_NOT_SELECTABLE);
                me->SetReactState(REACT_AGGRESSIVE);

                phase = PHASE_ONE;
                events.SetPhase(PHASE_ONE);

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

                Unit* heart = FindHeart();
                if (!heart)
                    return;

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

                if (!hardMode)
                {
                    if (!transferHealth) // Not settled == heart did not die
                        if ( uint32 healthDiff = (heart->GetMaxHealth() - heart->GetHealth()) )
                        {
                            me->DealDamage(me, healthDiff);
                            me->LowerPlayerDamageReq(healthDiff);
                        }

                    // Note: if the heart did not go down enough or the players sucked too much (heal through bots), we may have jumped back in heart-phase
                    // Otherwise, damage to the heart got mirrored to the XT002, thus one or more of the heart-phases can be excluded.  
                    RecalcHeartPhase();
                }
            }
    void Reset()
    {
        for(uint8 i = 0; i < 2; ++i)
        {
            if(PortalGUID[i])
            {
                Unit* Portal = Unit::GetUnit((*me), PortalGUID[i]);
                if(Portal)
                    Portal->DealDamage(Portal, Portal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);

                PortalGUID[i] = 0;
            }
        }

        CheckKilrekTimer    = 30000;
        SacrificeTimer      = 30000;
        ShadowboltTimer     =  5000;
        SummonTimer         = 10000;
        BerserkTimer        = 600000;

        SummonedPortals     = false;
        Berserk             = false;

        if (pInstance)
            pInstance->SetData(TYPE_TERESTIAN, NOT_STARTED);

        me->RemoveAurasDueToSpell(SPELL_BROKEN_PACT);

        if (Minion* Kilrek = me->GetFirstMinion())
        {
            if (!Kilrek->isAlive())
            {
                Kilrek->UnSummon();
                DoCast(me, SPELL_SUMMON_IMP, true);
            }
        }
        else DoCast(me, SPELL_SUMMON_IMP, true);
    }
Example #13
0
    uint32 NextStep(uint32 Step)
    {
        Unit* Spark = Unit::GetUnit((*me), SparkGUID);

        switch(Step)
        {
        case 0: return 99999;
        case 1:
            //DespawnNagaFlag(true);
            DoScriptText(EMOTE_SPARK, Spark);
            return 1000;
        case 2:
            DoScriptText(GEEZLE_SAY_1, me, Spark);
            if (Spark)
            {
                Spark->SetInFront(me);
                me->SetInFront(Spark);
            }
            return 5000;
        case 3: DoScriptText(SPARK_SAY_2, Spark); return 7000;
        case 4: DoScriptText(SPARK_SAY_3, Spark); return 8000;
        case 5: DoScriptText(GEEZLE_SAY_4, me, Spark); return 8000;
        case 6: DoScriptText(SPARK_SAY_5, Spark); return 9000;
        case 7: DoScriptText(SPARK_SAY_6, Spark); return 8000;
        case 8: DoScriptText(GEEZLE_SAY_7, me, Spark); return 2000;
        case 9:
            me->GetMotionMaster()->MoveTargetedHome();
            if (Spark)
                Spark->GetMotionMaster()->MovePoint(0, -5030.95f, -11291.99f, 7.97f);
            return 20000;
        case 10:
            if (Spark)
                Spark->DealDamage(Spark,Spark->GetHealth(),NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            //DespawnNagaFlag(false);
            me->SetVisibility(VISIBILITY_OFF);
        default: return 99999999;
        }
    }
bool PlayerbotShamanAI::HealGroup (Unit *target, uint8 hp, uint8 &countNeedHeal)
{
    Player *m_bot = GetPlayerBot();
    if (countNeedHeal < 2) {
        return false;
    }
    Unit *rTarget = DoSelectLowestHpFriendly(30,500);
    if (!rTarget || rTarget->isDead() || rTarget->GetHealth() * 100 / rTarget->GetMaxHealth() > 80 ) {
        return false;
    }

    if (hp < 65 && RIPTIDE && rTarget->HasAura(RIPTIDE,m_bot->GetGUID()) && CastSpell(CHAIN_HEAL, rTarget)) {
        return true;
    }
    if (hp < 85 && CastSpell(RIPTIDE, rTarget)) {
        return true;
    }
    if (hp < 75 && CastSpell(CHAIN_HEAL, rTarget,true,true)) {
        return true;
    }

    return false;
}
Example #15
0
        void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount)
        {
            Unit* caster = GetCaster();

            if (!caster)
                return;

            int32 remainingHealth = caster->GetHealth() - dmgInfo.GetDamage();
            int32 cauterizeHeal = caster->CountPctFromMaxHealth(40);

            if (caster->ToPlayer()->HasSpellCooldown(SPELL_MAGE_CAUTERIZE_DAMAGE))
                return;

            if (!roll_chance_i(absorbChance))
                return;

            if (remainingHealth <= 0)
            {
                absorbAmount = dmgInfo.GetDamage();
                caster->CastCustomSpell(caster, SPELL_MAGE_CAUTERIZE_DAMAGE, NULL,&cauterizeHeal, NULL, true, NULL, aurEff);
                caster->ToPlayer()->AddSpellCooldown(SPELL_MAGE_CAUTERIZE_DAMAGE, 0, time(NULL) + 60);
            }
        }
void PlayerbotPaladinAI::DoNonCombatActions()
{
    PlayerbotAI *ai = GetAI();
    Player *m_bot = GetPlayerBot();
    if (!m_bot || !ai || m_bot->isDead()) { return; }

    //If Casting or Eating/Drinking return
    if (m_bot->HasUnitState(UNIT_STATE_CASTING)) { return; }
    if (m_bot->getStandState() == UNIT_STAND_STATE_SIT) { return; }

    //buff and heal raid
    if (DoSupportRaid(m_bot)) { return; }

    //heal pets and bots
    Unit *target = DoSelectLowestHpFriendly(40, 1000);
    if (target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth())) { return; }

    //mana/hp check
    //Don't bother with eating, if low on hp, just let it heal themself
    if (m_bot->getRace() == (uint8) RACE_UNDEAD_PLAYER && ai->GetHealthPercent() < 75 && CastSpell(R_CANNIBALIZE,m_bot)) { return; }
    if (m_bot->GetHealth() < m_bot->GetMaxHealth() && CastSpell(FLASH_OF_LIGHT,m_bot)) { return; }
    if (ai->GetManaPercent() < 70) { ai->Feast(); }
} //end DoNonCombatActions
Example #17
0
		void HandleDamage()
		{
			Unit* caster = GetCaster();
			if (caster->GetTypeId() != TYPEID_PLAYER)
				return;

			Unit* target = GetHitUnit();
			int32 damage = GetHitDamage();
			// Glyph cooldown reset when target was failed to kill
			if (AuraEffect* glyph = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 1980, EFFECT_0))
				if (target && target->GetHealthPct() <= glyph->GetAmount() && !caster->HasAura(95652))
					if (int32(target->GetHealth()) > damage)
					{
				caster->ToPlayer()->RemoveSpellCooldown(32379, true);
				caster->CastSpell(caster, 95652, true);
					}

			// Pain and Suffering reduces damage
			if (AuraEffect* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, PRIEST_ICON_ID_PAIN_AND_SUFFERING, EFFECT_1))
				AddPct(damage, aurEff->GetAmount());

			caster->CastCustomSpell(caster, SPELL_PRIEST_SHADOW_WORD_DEATH, &damage, 0, 0, true);
		}
Example #18
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);
                }
            }
 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 #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 DestroyPortals() {
        //we destroy portals during banish phase or when we die
        Unit* BeamerD = NULL;
        Unit* BeamerDhelp = NULL;
        BeamerD = Unit::GetUnit((*m_creature), BeamerGUID[0]);
        BeamerDhelp = Unit::GetUnit((*m_creature), BeamerhelpGUID[0]);
        if (BeamerD && BeamerD->isAlive()) {
            BeamerD->DealDamage(BeamerD, BeamerD->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerGUID[0] = 0;
        }
        if (BeamerDhelp && BeamerDhelp->isAlive()) {
            BeamerDhelp->DealDamage(BeamerDhelp, BeamerDhelp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerhelpGUID[0] = 0;
        }
 
        Unit* BeamerS = NULL;
        Unit* BeamerShelp = NULL;
        BeamerS = Unit::GetUnit((*m_creature), BeamerGUID[1]);
        BeamerShelp = Unit::GetUnit((*m_creature), BeamerhelpGUID[1]);
        if (BeamerS && BeamerS->isAlive()) {
            BeamerS->DealDamage(BeamerS, BeamerS->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerGUID[1] = 0;
        }
        if (BeamerShelp && BeamerShelp->isAlive()) {
            BeamerShelp->DealDamage(BeamerShelp, BeamerShelp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerhelpGUID[1] = 0;
        }
 
        Unit* BeamerP = NULL;
        Unit* BeamerPhelp = NULL;
        BeamerP = Unit::GetUnit((*m_creature), BeamerGUID[2]);
        BeamerPhelp = Unit::GetUnit((*m_creature), BeamerhelpGUID[2]);
        if (BeamerP && BeamerP->isAlive()) {
            BeamerP->DealDamage(BeamerP, BeamerP->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerGUID[2] = 0;
        }
        if (BeamerPhelp && BeamerPhelp->isAlive()) {
            BeamerPhelp->DealDamage(BeamerPhelp, BeamerPhelp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
            BeamerhelpGUID[2] = 0;
        }
    }
Example #22
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 #23
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 #24
0
    void UpdateAI(const uint32 diff)
    {
        if (!m_creature->SelectHostileTarget() || !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 (!m_bIsRegularMode)
                {
                    if (DrainManaTimer < diff)
                    {
                        DoCast(SelectUnit(SELECT_TARGET_RANDOM, 1), 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 (m_bIsRegularMode)
                        DrainCrystalTimer = urand(20000, 25000);
                    else
                        DrainCrystalTimer = urand(10000, 15000);

                }else DrainCrystalTimer -= diff;
            }

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

                    DoScriptText(SAY_EMPOWERED, m_creature);

                    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
void PetAI::UpdateAI(const uint32 diff)
{
    if (!m_creature->isAlive())
        return;

    Unit* owner = m_creature->GetCharmerOrOwner();

    m_updateAlliesTimer.Update(diff);
    if (m_updateAlliesTimer.Passed())
    {
        UpdateAllies();
        m_updateAlliesTimer.Reset();
    }

    if (!inCombat && !m_savedTargetGuid.IsEmpty())
    {
        if (Unit* saved_target = m_creature->GetMap()->GetUnit(m_savedTargetGuid))
        {
            if (!saved_target->isAlive())
                m_savedTargetGuid.Clear();
            else if (!saved_target->IsCrowdControlled())
                AttackStart(saved_target);
        }
        else
            m_savedTargetGuid.Clear();
    }

    if (inCombat &&
        (!m_creature->getVictim() ||
         !m_creature->getVictim()->isAlive() ||
        (m_creature->IsPet() && m_creature->GetCharmInfo()->HasState(CHARM_STATE_ACTION, ACTIONS_DISABLE))))
        _stopAttack();

    if (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT) || m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED))
    {
        UpdateAIType();
        return;
    }

    // i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
    if (m_creature->getVictim())
    {
        bool meleeReach = m_creature->CanReachWithMeleeAttack(m_creature->getVictim());

        if (_needToStop())
        {
            DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
            _stopAttack();
            return;
        }
        else if (!m_creature->getVictim()->isAlive())        // Stop attack if target dead
        {
            m_creature->InterruptNonMeleeSpells(false);
            _stopAttack();
            return;
        }
        else if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && IsInCombat() && m_creature->getVictim() && m_creature->getVictim()->IsCrowdControlled())  // Stop attack if target under CC effect
        {
            m_savedTargetGuid = m_creature->getVictim()->GetObjectGuid();
            m_creature->InterruptSpell(CURRENT_GENERIC_SPELL, true);
            if (!m_creature->IsNonMeleeSpellCasted(false, false, true))
                _stopAttack();
            return;
        }
        else if (m_creature->IsStopped() || meleeReach)
        {
            // required to be stopped cases
            if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
            {
                if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
                    m_creature->InterruptNonMeleeSpells(false);
                else
                    return;
            }
            // not required to be stopped case
            else if (DoMeleeAttackIfReady())
            {
                if (!m_creature->getVictim())
                    return;

                //if pet misses its target, it will also be the first in threat list
                m_creature->getVictim()->AddThreat(m_creature);

                if (_needToStop())
                    _stopAttack();
            }
        }

        if (!m_creature->IsNonMeleeSpellCasted(true))
        {
            m_attackDistanceRecheckTimer.Update(diff);
            if (m_attackDistanceRecheckTimer.Passed())
            {
                m_attackDistanceRecheckTimer.Reset();
                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType == PET_AI_RANGED)
                {
                    float dist = m_creature->GetDistance(m_creature->getVictim());
                    if ((m_creature->CanReachWithMeleeAttack(m_creature->getVictim()) &&
                        m_creature->IsWithinDist(m_creature->GetOwner(), m_creature->GetMap()->GetVisibilityDistance() / 2.0f)) ||
                        dist > (m_attackDistance + 2.0f))
                    {
                        MoveToVictim(m_creature->getVictim());
                        return;
                    }
                }

                if (sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI))
                {
                    // AOE check
                }
            }
        }
    }
    else if (Unit* target = GetPrimaryTarget())
    {
        AttackStart(target);
    }
    else if (owner && owner->IsInCombat())
    {
        switch (m_creature->GetCharmState(CHARM_STATE_REACT))
        {
            case REACT_DEFENSIVE:
            {
                if (!m_creature->getVictim()
                    || !m_creature->getVictim()->isAlive()
                    || (m_primaryTargetGuid.IsEmpty() && owner->getVictim() != m_creature->getVictim() && owner->getVictim()->isAlive()))
                    AttackStart(owner->getAttackerForHelper());
                break;
            }
            case REACT_AGGRESSIVE:
            {
                if (!m_creature->getVictim() || !m_creature->getVictim()->isAlive())
                    AttackStart(owner->getAttackerForHelper());
                break;
            }
            case REACT_PASSIVE:
            default:
                break;
        }
    }

    UpdateAIType();

    if (m_creature->IsNonMeleeSpellCasted(true))
        return;

    // Autocast (casted only in combat or persistent spells in any state)
    if (!sWorld.getConfig(CONFIG_BOOL_PET_ADVANCED_AI) && m_AIType != PET_AI_PASSIVE)
    {
        typedef std::vector<std::pair<ObjectGuid, uint32> > TargetSpellList;
        TargetSpellList targetSpellStore;

        for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
        {
            uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            if (m_creature->HasSpellCooldown(spellInfo))
                continue;

            // ignore some combinations of combat state and combat/noncombat spells
            if (!inCombat)
            {
                // ignore attacking spells, and allow only self/around spells
                if (!IsPositiveSpell(spellInfo->Id))
                    continue;

                // non combat spells allowed
                // only pet spells have IsNonCombatSpell and not fit this reqs:
                // Consume Shadows, Lesser Invisibility, so ignore checks for its
                if (!IsNonCombatSpell(spellInfo))
                {
                    // allow only spell without spell cost or with spell cost but not duration limit
                    int32 duration = GetSpellDuration(spellInfo);
                    if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
                        continue;

                    // allow only spell without cooldown > duration
                    int32 cooldown = GetSpellRecoveryTime(spellInfo);
                    if (cooldown >= 0 && duration >= 0 && cooldown > duration)
                        continue;
                }
            }
            else
            {
                // just ignore non-combat spells
                if (IsNonCombatSpell(spellInfo))
                    continue;
            }

            Unit* autoCastTarget = NULL;

            if (inCombat && m_creature->getVictim() && !m_creature->hasUnitState(UNIT_STAT_FOLLOW))
            {
                SpellCastResult result = CanAutoCast(m_creature->getVictim(), spellInfo);
                if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                    autoCastTarget = m_creature->getVictim();
            }

            if (!autoCastTarget)
            {
                for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
                {
                    Unit* target = m_creature->GetMap()->GetUnit(*tar);

                    // Only buff targets that are in combat, unless the spell can only be cast while out of combat
                    if (!target)
                        continue;

                    SpellCastResult result = CanAutoCast(target, spellInfo);
                    if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
                    {
                        autoCastTarget = target;
                        break;
                    }
                }
            }

            if (autoCastTarget)
                targetSpellStore.push_back(TargetSpellList::value_type(autoCastTarget->GetObjectGuid(), spellInfo->Id));
        }

        // found units to cast on to
        if (!targetSpellStore.empty())
        {
            uint32 index = urand(0, targetSpellStore.size() - 1);
            if (Unit* target = m_creature->GetMap()->GetUnit(targetSpellStore[index].first))
                m_creature->DoPetCastSpell(target, targetSpellStore[index].second);
        }
    }
    else
    {
        AutoSpellList currentSpells;
        switch (m_AIType)
        {
            case PET_AI_PASSIVE:
            {
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
            case PET_AI_SLACKER:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEFENCE));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                break;
            }
            case PET_AI_HEALER:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                if (m_creature->GetHealth() < m_creature->GetMaxHealth() ||
                    (owner && (owner->GetHealth() < owner->GetMaxHealth())))
                    currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                break;
            }
            case PET_AI_RANGED:
            {
                if (!IsInCombat())
                    break;

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
            case PET_AI_MELEE:
            case PET_AI_RANGED_NOAMMO:
            {
                if (!IsInCombat())
                    break;

                if (Unit* victim = m_creature->getVictim())
                {
                    if (!victim->getVictim() || (victim->getVictim()->GetObjectGuid() != m_creature->GetObjectGuid()))
                    {
                        currentSpells.push_back(GetSpellType(PET_SPELL_ATTACKSTART));
                        currentSpells.push_back(GetSpellType(PET_SPELL_THREAT));
                    }
                }

                if (m_creature->IsCrowdControlled() || (owner && owner->IsCrowdControlled()))
                    currentSpells.push_back(GetSpellType(PET_SPELL_FREEACTION));
            }
            /* no break here!*/
            default:
            {
                if (!IsInCombat())
                    break;

                currentSpells.push_back(GetSpellType(PET_SPELL_MELEE));
                currentSpells.push_back(GetSpellType(PET_SPELL_DEBUFF));
                currentSpells.push_back(GetSpellType(PET_SPELL_RANGED));
                currentSpells.push_back(GetSpellType(PET_SPELL_BUFF));
                break;
            }
        }

        if (!IsInCombat())
        {
            currentSpells.push_back(GetSpellType(PET_SPELL_NONCOMBAT));
            if (m_creature->GetHealthPercent() < 95.0f)
                currentSpells.push_back(GetSpellType(PET_SPELL_HEAL));
        }
        else
            currentSpells.push_back(GetSpellType(PET_SPELL_SPECIAL));

        for (AutoSpellList::const_iterator itr = currentSpells.begin(); itr != currentSpells.end(); ++itr)
        {
            uint32 spellID = *itr;
            if (!spellID)
                continue;

            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
            if (!spellInfo)
                continue;

            if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                continue;

            Unit* pTarget =  m_creature->IsPet() ? ((Pet*)m_creature)->SelectPreferredTargetForSpell(spellInfo) :
                                                   ((Creature*)m_creature)->SelectPreferredTargetForSpell(spellInfo);
            bool b_castOk = false;

            if (pTarget)
            {
                SpellCastResult result = CanAutoCast(pTarget, spellInfo);
                DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Update %s, AI %u try cast %u Target %s",
                            m_creature->GetGuidStr().c_str(),
                            m_AIType,
                            spellID,
                            pTarget ? pTarget->GetGuidStr().c_str() : "<none>");
                switch (result)
                {
                    case SPELL_FAILED_UNIT_NOT_INFRONT:
                    {
                        if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                        {
                            b_castOk = true;
                            m_creature->SetInFront(pTarget);
                            if (pTarget->GetTypeId() == TYPEID_PLAYER)
                                m_creature->SendCreateUpdateToPlayer((Player*)pTarget);
                        }
                        break;
                    }
                    case SPELL_CAST_OK:
                    {
                        if (DoCastSpellIfCan(pTarget, spellID) == CAST_OK)
                            b_castOk = true;
                        break;
                    }
                    default:
                    {
                        Player* owner = (Player*)m_creature->GetOwner();
                        if (owner)
                            Spell::SendCastResult(owner,spellInfo,0,result, true);

                        DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Update cast %s, AI %u Target %s spell %u result %u",
                            m_creature->GetGuidStr().c_str(),
                            m_AIType,
                            pTarget ? pTarget->GetGuidStr().c_str() : "<none>",
                            spellID,
                            result);
                        break;
                    }
                }
            }
            else
                continue;

            if (b_castOk)
            {
                m_creature->AddSpellAndCategoryCooldowns(spellInfo);
                if (m_creature->IsPet())
                {
                    if(((Pet*)m_creature)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
                        m_creature->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
                    else
                        m_creature->SendPetAIReaction();
                }
                break;
            }
        }
    }
}
Example #26
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 (instance)
            {
                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();
    }
void PlayerbotShamanAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    uint8 reqHeal = 0;
    uint8 OwnPartyHP = GetHealthPercentRaid(m_bot, reqHeal);

    switch(ai->GetScenarioType())
    {
        case SCENARIO_DUEL:
            ((ai->GetHealthPercent() < 80 && CastSpell(LESSER_HEAL)) ||
            CastSpell(LIGHTNING_BOLT, pTarget));
            return;
    }

    // Cast CC breakers if any match found (include any dispels first)  does not work yet
    //uint32 ccSpells[4] = { R_ESCAPE_ARTIST, R_EVERY_MAN_FOR_HIMSELF, R_WILL_OF_FORSAKEN, R_STONEFORM };
    //if (ai->GetManaPercent() < 35) { ccSpells[0] = 0; ccSpells[1] = 0; } //We dont have any mana to waste...
    //if (castSelfCCBreakers(ccSpells)) {  } // Most of them don't trigger gcd


    #pragma region Choose Actions
    // Choose actions accoring to talents
    if (m_tank->GetGUID() == m_bot->GetGUID()) { m_role=BOT_ROLE_TANK; } // Hey! I am Main Tank
    else if (TALENT_ENHANCEMENT) { m_role = BOT_ROLE_DPS_MELEE; }
    else if (TALENT_ELEMENTAL) { m_role = BOT_ROLE_DPS_RANGED; }
    else if (TALENT_RESTO) { m_role = BOT_ROLE_SUPPORT; }
    else { m_role = BOT_ROLE_DPS_MELEE; } //Unknown build or low level.. Mainly attack

    // if i am under attack and if i am not tank or offtank: change target if needed
    if (m_tank->GetGUID() != m_bot->GetGUID() && isUnderAttack()  )
    {
            if (pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist <= 2) {  } // My target is almost up to me, no need to search
            else //Have to select nearest target
            {
                Unit *curAtt = GetNearestAttackerOf(m_bot);
                if (curAtt && curAtt->GetGUID() != pTarget->GetGUID())
                {
                    m_bot->SetSelection(curAtt->GetGUID());
                    //ai->AddLootGUID(curAtt->GetGUID());
                    DoNextCombatManeuver(curAtt); //Restart new update to get variables fixed..
                    return;
                }
            }
            //my target is attacking me
    }
    #pragma endregion

    // Choose Weapon Enchant
    if (ChangeWeaponEnchants()) return;

	if (TALENT_ELEMENTAL){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }}
	if (TALENT_ENHANCEMENT){ if (!m_bot->HasAura(LIGHTNING_SHIELD) && CastSpell(LIGHTNING_SHIELD,m_bot)) { return; }}
	if (TALENT_RESTO){ if (!m_bot->HasAura(WATER_SHIELD) && CastSpell(WATER_SHIELD,m_bot)) { return; }}
    // Choose shield
	/*
    if (EARTH_SHIELD && ai->GetHealthPercent() < 80 && isUnderAttack()) { if (CastSpell(EARTH_SHIELD,m_bot)) { return; } }
    else if (WATER_SHIELD && ai->GetManaPercent() < 40) { if (CastSpell(WATER_SHIELD,m_bot)) { return; } }
    else if (LIGHTNING_SHIELD &&
        ( isUnderAttack() || m_tank->GetGUID() == m_bot->GetGUID() )  && !(m_bot->HasAura(WATER_SHIELD) && ai->GetManaPercent() < 80)
        ) { if (CastSpell(LIGHTNING_SHIELD,m_bot)) { return; } }
    else if (CastSpell(WATER_SHIELD,m_bot)) { return; }
	*/
    // If there's a cast stop
    if(m_bot->HasUnitState(UNIT_STAT_CASTING)) return;

    switch(m_role)
    {
        #pragma region BOT_ROLE_TANK / BOT_ROLE_OFFTANK
        case BOT_ROLE_TANK:
        case BOT_ROLE_OFFTANK:
             if (!TALENT_ELEMENTAL && !TALENT_RESTO) { TakePosition(pTarget); }
            else { TakePosition(pTarget,BOT_ROLE_DPS_RANGED); } // mob will come to you sooner or later no need to hurry

            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 70 && DoSupportRaid(m_bot)) { return; }

            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_MELEE
        case BOT_ROLE_DPS_MELEE:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_DPS_RANGED
        case BOT_ROLE_DPS_RANGED:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (ai->GetManaPercent() > 40 && DoSupportRaid(m_bot)) { return; }
            break;
        #pragma endregion

        #pragma region BOT_ROLE_SUPPORT
        case BOT_ROLE_SUPPORT:
            TakePosition(pTarget);
            // Do support stuff
            if (!m_bot->isMoving() && ChangeTotems(m_role)) { return; }
            if (DoSupportRaid(m_bot)) { return; }
            //heal pets and bots
            Unit *target = DoSelectLowestHpFriendly(40, 1000);
            if(target && target->isAlive() && HealTarget(target, target->GetHealth()*100 / target->GetMaxHealth()) ) { return; }

            break;
        #pragma endregion
    }
    #pragma region ShamanCommon


    //Defensive Stuff
    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        if (pDist > 5 && CastSpell(FROST_SHOCK, pTarget)) { return; }
        if ((pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_BEAST || pTarget->GetCreatureType() == (uint32) CREATURE_TYPE_HUMANOID) && CastSpell(HEX, pTarget)) { return; } // no gcd
        if (CastSpell(WIND_SHEAR, pTarget)) { } // no gcd
    }
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    if (pTarget->IsNonMeleeSpellCasted(true) && CastSpell(WIND_SHEAR, pTarget)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pVictim && pVictim->GetGUID() == m_bot->GetGUID() && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; }

    //Catch
    if (pTarget->HasUnitMovementFlag(UNIT_FLAG_FLEEING))
    {
        if (CastSpell(FROST_SHOCK,pTarget)) return;
    }


    //Buff and restores
    if ( ( (ai->GetHealthPercent() < 60 && isUnderAttack()) ||
        (ai->GetManaPercent() < 30) ) && CastSpell(SHAMANISTIC_RAGE, m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} // no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} // no GCD
    if (!m_bot->HasAura(HEROISM) && !m_bot->HasAura(EXHAUSTION) && !m_bot->HasAura(SATED) && CastSpell(HEROISM,m_bot)) { return; }
    if (m_role != BOT_ROLE_SUPPORT && CastSpell(NATURES_SWIFTNESS, m_bot)) { } //healers keep it for healing no gcd
    else if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd

    // If at threat limit, use WIND_SHEAR to reduce threat
    if (pThreat > threatThreshold && m_tank->GetGUID() != m_bot->GetGUID() && !isUnderAttack())
    {
        if (m_tank->getVictim() && m_tank->getVictim()->GetGUID() != pTarget->GetGUID()) // I am attacking wrong target!!
        {
            m_bot->SetSelection(m_tank->getVictim()->GetGUID());
            return;
        }
        else
        {
            if (CastSpell(WIND_SHEAR,pTarget)) { return; } //Lets see if we can manage
            else { return; } //use no spells and wait threat to be reduced
        }
    }


	if (TALENT_ELEMENTAL)
	{
		if (CastSpell(ELEMENTAL_MASTERY, m_bot)) { } //no gcd
		if (!pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(FLAME_SHOCK,pTarget)) { return; }
		if (CastSpell(LAVA_BURST,pTarget)) { return; }
		if (CastSpell(CHAIN_LIGHTNING,pTarget)) { return; }
		if (CastSpell(LIGHTNING_BOLT,pTarget)) { return; }
	}

    //dps
    if (MAELSTROM_WEAPON)
    {
        Aura *maelaura = m_bot->GetAura(MAELSTROM_WEAPON);
        if (maelaura && maelaura->GetStackAmount() == 5)
        {
            if ((isUnderAttack(m_tank,3) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(CHAIN_LIGHTNING,pTarget,true,true)) { return; }
            if (CastSpell(LIGHTNING_BOLT,pTarget,true,true)) { return; }
        }
    }
	if (CastSpell(FLAME_SHOCK,pTarget)) { return; }
    if (CastSpell(STORMSTRIKE,pTarget,true,true)) { return; }

    //if (!TALENT_ENHANCEMENT && CanCast(LAVA_BURST,pTarget,true) && pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) && CastSpell(LAVA_BURST,pTarget,false)) { return; }
	if (CastSpell(FERAL_SPIRIT,m_bot)) { return; }
    if (CanCast(EARTH_SHOCK,pTarget,true) && (pTarget->HasAura(STORMSTRIKE,m_bot->GetGUID()) || pTarget->HasAura(FLAME_SHOCK,m_bot->GetGUID()) ) && CastSpell(EARTH_SHOCK,pTarget)) { return; }
    //if (CanCast(FLAME_SHOCK,pTarget) && CastSpell(FLAME_SHOCK,pTarget)) { return; }
	if (CastSpell(LAVA_LASH,pTarget,true,true)) { return; }
	if (CastSpell(FIRE_NOVA,pTarget)) { return; }
    //if ((isUnderAttack(m_tank,4) || m_tank->GetGUID() == m_bot->GetGUID()) && CastSpell(FIRE_NOVA,pTarget)) { return; }
    if (ai->GetManaPercent() > 60 && castDispel(PURGE,pTarget)) { return; } //PURGE but dont overpurge

    #pragma endregion


    // drink potion if support / healer (Other builds simply overuse mana and waste mana pots)
    if(ai->GetManaPercent() < 5 && (m_role == BOT_ROLE_SUPPORT || m_role == BOT_ROLE_HEALER) )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }


} //end DoNextCombatManeuver
Example #28
0
        uint32 NextStep(uint32 Step)
        {
            Unit* arca = Unit::GetUnit(*me, ArcanagosGUID);
            Map* map = 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 (map->IsDungeon())
                {
                    InstanceMap::PlayerList const &PlayerList = map->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 #29
0
        void DoIntro()
        {
            if(!Madrigosa)
                return;

            switch(IntroPhase)
            {
                case 0:
                    DoScriptText(YELL_MADR_ICE_BARRIER, Madrigosa);
                    IntroPhaseTimer = 5000;
                    ++IntroPhase;
                    break;
                case 1:
                    me->SetInFront(Madrigosa);
                    Madrigosa->SetInFront(me);
                    DoScriptText(YELL_MADR_INTRO, Madrigosa, me);
                    IntroPhaseTimer = 9000;
                    ++IntroPhase;
                    break;
                case 2:
                    DoScriptText(YELL_INTRO, me, Madrigosa);
                    IntroPhaseTimer = 13000;
                    ++IntroPhase;
                    break;
                case 3:
                    DoCast(me, SPELL_INTRO_FROST_BLAST);
                    Madrigosa->SetLevitate(true);
                    me->AttackStop();
                    Madrigosa->AttackStop();
                    IntroFrostBoltTimer = 3000;
                    IntroPhaseTimer = 28000;
                    ++IntroPhase;
                    break;
                case 4:
                    DoScriptText(YELL_INTRO_BREAK_ICE, me);
                    IntroPhaseTimer = 6000;
                    ++IntroPhase;
                    break;
                case 5:
                    Madrigosa->CastSpell(me, SPELL_INTRO_ENCAPSULATE_CHANELLING, false);
                    DoScriptText(YELL_MADR_TRAP, Madrigosa);
                    DoCast(me, SPELL_INTRO_ENCAPSULATE);
                    IntroPhaseTimer = 11000;
                    ++IntroPhase;
                    break;
                case 6:
                    me->SetSpeed(MOVE_RUN, 4.0f, true);
                    DoScriptText(YELL_INTRO_CHARGE, me);
                    IntroPhaseTimer = 3000;
                    ++IntroPhase;
                    break;
                case 7:
                    me->DealDamage(Madrigosa, Madrigosa->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, true);
                    DoScriptText(YELL_MADR_DEATH, Madrigosa);
                    me->SetFullHealth();
                    me->AttackStop();
                    me->SetSpeed(MOVE_RUN, 1.0f, true);
                    IntroPhaseTimer = 3000;
                    ++IntroPhase;
                    break;
                case 8:
                    DoScriptText(YELL_INTRO_KILL_MADRIGOSA, me);
                    me->SetOrientation(0.14f);
                    Madrigosa->setDeathState(CORPSE);
                    IntroPhaseTimer = 5000;
                    ++IntroPhase;
                    break;
                case 9:
                    DoScriptText(YELL_INTRO_TAUNT, me);
                    IntroPhaseTimer = 5000;
                    ++IntroPhase;
                    break;
                case 10:
                    EndIntro();
                    break;
            }
        }
Example #30
0
    void UpdateAI(const uint32 diff)
    {
        if(!UpdateVictim())
            return;

        if(Cleanse_Timer < diff )
        {
            std::list<Creature*> pList = FindFriendlyCC(30);
            if (!pList.empty())
            {
                Unit* target = *(pList.begin());
                DoCast(target,SPELL_CLEANSE_BW_VINDICATOR);
            }
            Cleanse_Timer = 3000+rand()%1000;
        }
        else
            Cleanse_Timer -= diff;

        if(FlashofLight_Timer < diff)
        {
            Unit* target = SelectLowestHpFriendly(50, 1000);
            if(target)
            {
                DoCast(target,SPELL_FLASHOFLIGHT_BW_VINDICATOR);

                if(target->GetHealth() <= target->GetMaxHealth()*0.5)
                    FlashofLight_Timer = 2000;
                else
                    FlashofLight_Timer = 2000 +rand()%7000;
            }
        }
        else
            FlashofLight_Timer -= diff;

        if(HammerofJustice_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_HAMMEROFJUSTICE_BW_VINDICATOR);
            HammerofJustice_Timer = 18000;
        }
        else
            HammerofJustice_Timer -= diff;

        if(HammerofWrath_Timer < diff)
        {
            Map* pMap = m_creature->GetMap();
            Map::PlayerList const &PlayerList = pMap->GetPlayers();
            if (!PlayerList.isEmpty())
            {
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                {
                    Player *p = i->getSource();
                    if(p->isAlive() && p->GetHealth() <= p->GetMaxHealth()*0.2)
                    {
                        DoCast(p, SPELL_HAMMEROFWRATH_BW_VINDICATOR);
                        break;
                    }
                }
            }
            HammerofWrath_Timer = 3000+rand()%2000;
        }
        else
            HammerofWrath_Timer -= diff;

        DoMeleeAttackIfReady();
    }