void UpdateAI(const uint32 diff)
{
      if (m_creature->GetHealthPercent() < 30.0f && Potioncd<diff && GCD<diff)
      {
         DoCastSpellIfCan (m_creature,HEALINGPOTION);
         Potioncd = POTIONCD;
         GCD = 1500;
      }
      if (m_creature->GetPower(POWER_MANA)<m_creature->GetMaxPower(POWER_MANA)*0.3 && Evocation_cd<diff && GCD<diff)
      {
         DoCastSpellIfCan (m_creature,EVOCATION);
         Evocation_cd = EVOCATION_CD;
         GCD = 1500;
      }
      if (m_creature->GetPower(POWER_MANA)<m_creature->GetMaxPower(POWER_MANA)*0.3 && Potioncd<diff && GCD<diff)
      {
         DoCastSpellIfCan (m_creature,MANAPOTION);
         Potioncd = POTIONCD;
         GCD = 1500;
      }

    //Always decrease our global cooldown first
    if (GlobalCooldown > diff)
        GlobalCooldown -= diff;
    else GlobalCooldown = 0;

    //Always decrease ZoneAttackMsgTimer
    if (ZoneAttackMsgTimer > diff)
        ZoneAttackMsgTimer -= diff;
    else ZoneAttackMsgTimer = 0;

    if (InnerTimer > diff)
        InnerTimer -= diff;
    else InnerTimer = 0;

      if(!(Potioncd < diff))
         Potioncd -= diff;
      if(!(Evocation_cd < diff))
         Evocation_cd -= diff;
      if(!(GCD < diff))
         GCD -= diff;

    if(!m_creature->isAlive())
        return;

    if(!m_creature->HasAura(48073,EFFECT_INDEX_0))
    {
     // Divine Spirit 6
     DoCastSpellIfCan(m_creature, 48073);
     return;
    }
    if(!m_creature->HasAura(48168,EFFECT_INDEX_0))
    {
    // Inner Fire 9
     DoCastSpellIfCan(m_creature, 48168);
     return;
    }
    //Return since we have no target
    if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
        return;

    Unit *target = m_creature->getVictim();

       if(target == m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,0) && !target->isAlive() && !m_creature->IsNonMeleeSpellCasted(false))
       {
          Unit* target2 = NULL;
          target2 = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,1);
          m_creature->getThreatManager().modifyThreatPercent(target,-100);
          if(target2 && target2->isAlive())
              {
                 m_creature->AddThreat(target2,1);
                 m_creature->Attack(target2,true);
                 AttackStart(target2);
                 return;
              }
          else
          {
              Reset();
              return;
          }
       }

    if(m_creature->IsHostileTo(target))
           enemy = target;

    if(enemy)
        if(!enemy->isAlive())
            enemy = NULL;


    //Always decrease Help when in combat
    if (Help > diff)
        Help -= diff;
    else Help = 0;

    //If we are within range melee the target
    if( m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
    {
        //Make sure our attack is ready and we arn't currently casting
        if( m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
        {
           int Change = 0;
           int info = 0;

                 if(enemy)
                  {
                   switch(urand(0, 8))
                   {
               case 0:
                  // Mass Dispel
                  info = 32375;
                  break;
               case 1:
                  // Pain Suppression
                    info = 33206;
                    Change = 1;
                    break;
               case 2:
                  // Power Infusion
                    info = 10060;
                    Change = 1;
                    break;
               case 3:
                  // Power Word: Shield
                    info = 41373;
                    Change = 1;
                    break;
               case 4:
                  // Circle of Healing
                    info = 48089;
                    Change = 1;
                    break;
               case 5:
                  // Holy Nova
                    info = 59701;
                    break;
               case 6:
                  // Renew
                    info = 37260;
                    Change = 1;
                    break;
               case 7:
                  // Empowered Smite
                    info = 41471;
                    break;
               case 8:
                  // Heal
                    info = 39013;
                    Change = 1;
                    break;
               }//switch
            }

            //65% chance to replace our white hit with a spell
            if (info && urand(0, 1) == 0 && !GlobalCooldown)
            {
                //Cast the spell
                if (Change == 1)DoCastSpellIfCan(m_creature, info);
                else DoCastSpellIfCan(enemy, info);

                //Set our global cooldown
                GlobalCooldown = CREATURE_COOLDOWN;
            }//end 50% change
            else m_creature->AttackerStateUpdate(m_creature->getVictim());

            m_creature->resetAttackTimer();
        }//end attack ready
    }// end attack distance
/*    else
    {
     if(!m_creature->IsNonMeleeSpellCasted(false))
     {
         if ((*m_creature).GetMotionMaster()->top()->GetMovementGeneratorType()!=TARGETED_MOTION_TYPE)
         {
            (*m_creature).GetMotionMaster()->Clear(false);
            (*m_creature).GetMotionMaster()->MoveChase(m_creature->getVictim());
         }
     }
    }//end else */
}
Пример #2
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;
            if (uiPhaseTimer <= diff)
            {
                switch (Phase)
                {
                    case CASTING_FLAME_SPHERES:
                    {
                        Creature* pSpheres[3];

                        //DoCast(me, SPELL_FLAME_SPHERE_SUMMON_1);
                        pSpheres[0] = DoSpawnCreature(CREATURE_FLAME_SPHERE, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS);
                        Unit* pSphereTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                        if (pSphereTarget && pSpheres[0])
                        {
                            float angle, x, y;
                            angle = pSpheres[0]->GetAngle(pSphereTarget);
                            x = pSpheres[0]->GetPositionX() + DATA_SPHERE_DISTANCE * std::cos(angle);
                            y = pSpheres[0]->GetPositionY() + DATA_SPHERE_DISTANCE * std::sin(angle);
                            pSpheres[0]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[0]->GetPositionZ());
                        }
                        if (IsHeroic())
                        {
                            //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_1);
                            pSpheres[1] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_1, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS);
                            //DoCast(me, H_SPELL_FLAME_SPHERE_SUMMON_2);
                            pSpheres[2] = DoSpawnCreature(H_CREATURE_FLAME_SPHERE_2, 0, 0, 5, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 10*IN_MILLISECONDS);
                            if (pSphereTarget && pSpheres[1] && pSpheres[2])
                            {
                                float angle, x, y;
                                angle = pSpheres[1]->GetAngle(pSphereTarget) + DATA_SPHERE_ANGLE_OFFSET;
                                x = pSpheres[1]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                y = pSpheres[1]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                pSpheres[1]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[1]->GetPositionZ());
                                angle = pSpheres[2]->GetAngle(pSphereTarget) - DATA_SPHERE_ANGLE_OFFSET;
                                x = pSpheres[2]->GetPositionX() + DATA_SPHERE_DISTANCE/2 * std::cos(angle);
                                y = pSpheres[2]->GetPositionY() + DATA_SPHERE_DISTANCE/2 * std::sin(angle);
                                pSpheres[2]->GetMotionMaster()->MovePoint(0, x, y, pSpheres[2]->GetPositionZ());
                            }
                        }

                        Phase = NORMAL;
                        uiPhaseTimer = 0;
                        break;
                    }
                    case JUST_VANISHED:
                        if (Unit* pEmbraceTarget = GetEmbraceTarget())
                        {
                            me->GetMotionMaster()->Clear();
                            me->SetSpeed(MOVE_WALK, 2.0f, true);
                            me->GetMotionMaster()->MoveChase(pEmbraceTarget);
                        }
                        Phase = VANISHED;
                        uiPhaseTimer = 1300;
                        break;
                    case VANISHED:
                        if (Unit* pEmbraceTarget = GetEmbraceTarget())
                            DoCast(pEmbraceTarget, DUNGEON_MODE(SPELL_EMBRACE_OF_THE_VAMPYR, H_SPELL_EMBRACE_OF_THE_VAMPYR));
                        Talk(SAY_FEED);
                        me->GetMotionMaster()->Clear();
                        me->SetSpeed(MOVE_WALK, 1.0f, true);
                        me->GetMotionMaster()->MoveChase(me->GetVictim());
                        Phase = FEEDING;
                        uiPhaseTimer = 20*IN_MILLISECONDS;
                        break;
                    case FEEDING:
                        Phase = NORMAL;
                        uiPhaseTimer = 0;
                        uiEmbraceTarget = 0;
                        break;
                    case NORMAL:
                        if (uiBloodthirstTimer <= diff)
                        {
                            DoCast(me, SPELL_BLOODTHIRST);
                            uiBloodthirstTimer = 10*IN_MILLISECONDS;
                        } else uiBloodthirstTimer -= diff;

                        if (uiFlamesphereTimer <= diff)
                        {
                            // because TARGET_UNIT_TARGET_ENEMY we need a target selected to cast
                            DoCastVictim(SPELL_CONJURE_FLAME_SPHERE);
                            Phase = CASTING_FLAME_SPHERES;
                            uiPhaseTimer = 3*IN_MILLISECONDS + diff;
                            uiFlamesphereTimer = 15*IN_MILLISECONDS;
                        } else uiFlamesphereTimer -= diff;

                        if (uiVanishTimer <= diff)
                        {
                            //Count alive players
                            Unit* target = NULL;
                            std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();
                            std::vector<Unit*> target_list;
                            for (std::list<HostileReference*>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                            {
                                target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
                                // exclude pets & totems
                                if (target && target->GetTypeId() == TYPEID_PLAYER && target->isAlive())
                                    target_list.push_back(target);
                                target = NULL;
                            }
                            //He only vanishes if there are 3 or more alive players
                            if (target_list.size() > 2)
                            {
                                Talk(SAY_VANISH);
                                DoCast(me, SPELL_VANISH);
                                Phase = JUST_VANISHED;
                                uiPhaseTimer = 500;
                                if (Unit* pEmbraceTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                                    uiEmbraceTarget = pEmbraceTarget->GetGUID();

                            }
                            uiVanishTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS);
                        } else uiVanishTimer -= diff;

                        DoMeleeAttackIfReady();
                    break;
                }
            } else uiPhaseTimer -= diff;
        }
    void UpdateAI(const uint32 uiDiff)
    {
        if (m_bIsEventInProgress)
        {
            if (m_uiTimeOutTimer && m_uiTimeOutTimer < uiDiff)
            {
                if (!m_uiPlayerGUID)
                {
                    //player are expected to use GO within a minute, if not, event will fail.
                    Reset();
                    return;
                }

                m_uiTimeOutTimer = 0;
            }
            else
                m_uiTimeOutTimer -= uiDiff;

            if (m_uiCheckAliveStateTimer < uiDiff)
            {
                if (Unit* pChallenger = Unit::GetUnit(*m_creature, uiChallengerGUID[m_uiChallengerCount]))
                {
                    if (!pChallenger->isAlive())
                    {
                        Player* pPlayer = (Player*)Unit::GetUnit(*m_creature, m_uiPlayerGUID);

                        if (pPlayer && !pPlayer->isAlive())
                        {
                            Reset();
                            return;
                        }

                        ++m_uiChallengerCount;

                        //count starts at 0
                        if (m_uiChallengerCount == MAX_CHALLENGER)
                        {
                            if (pPlayer && pPlayer->isAlive())
                                pPlayer->GroupEventHappens(QUEST_SECOND_TRIAL, m_creature);

                            Reset();
                            return;
                        }
                        else
                            m_uiEngageTimer = 15000;
                    }
                }
                m_uiCheckAliveStateTimer = 2500;
            }
            else
                m_uiCheckAliveStateTimer -= uiDiff;

            if (m_uiEngageTimer && m_uiEngageTimer < uiDiff)
            {
                Unit* pPlayer = Unit::GetUnit(*m_creature, m_uiPlayerGUID);

                if (pPlayer && pPlayer->isAlive())
                {
                    if (Creature* pCreature = (Creature*)Unit::GetUnit(*m_creature, uiChallengerGUID[m_uiChallengerCount]))
                    {
                        DoScriptText(uiSayId[m_uiChallengerCount], m_creature, pPlayer);
                        pCreature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                        pCreature->AI()->AttackStart(pPlayer);
                    }
                }

                m_uiEngageTimer = 0;
            }
            else
                m_uiEngageTimer -= uiDiff;
        }
    }
Пример #4
0
 void UpdateAI(const uint32 /*diff*/)
 {
     Unit* temp = Unit::GetUnit((*me), FrostTombGUID);
     if ((temp && temp->isAlive() && !temp->HasAura(SPELL_FROST_TOMB)) || !temp)
         me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
 }
Пример #5
0
bool AscentScriptCreatureAI::IsValidUnitTarget( Object* pObject, TargetFilter pFilter, float pMinRange, float pMaxRange )
{
	//Make sure its a valid unit
	if ( !pObject->IsUnit() )
		return false;
	if ( pObject->GetInstanceID() != _unit->GetInstanceID() )
		return false;

	Unit* UnitTarget = TO_UNIT( pObject );
	//Skip dead ( if required ), feign death or invisible targets
	if ( pFilter & TargetFilter_Corpse )
	{
		if ( UnitTarget->isAlive() || !UnitTarget->IsCreature() || TO_CREATURE( UnitTarget )->creature_info->Rank == ELITE_WORLDBOSS )
			return false;
	}
	else if ( !UnitTarget->isAlive() )
		return false;

	if ( UnitTarget->IsPlayer() && TO_PLAYER( UnitTarget )->m_isGmInvisible )
		return false;
	if ( UnitTarget->HasFlag( UNIT_FIELD_FLAGS, UNIT_FLAG_FEIGN_DEATH ) )
		return false;

	//Check if we apply target filtering
	if ( pFilter != TargetFilter_None )
	{
		//Skip units not on threat list
		if ( ( pFilter & TargetFilter_Aggroed ) && _unit->GetAIInterface()->getThreatByPtr( UnitTarget ) == 0 )
			return false;

		//Skip current attacking target if requested
		if ( ( pFilter & TargetFilter_NotCurrent ) && UnitTarget == _unit->GetAIInterface()->GetNextTarget() )
			return false;

		//Keep only wounded targets if requested
		if ( ( pFilter & TargetFilter_Wounded ) && UnitTarget->GetHealthPct() >= 99 )
			return false;

		//Skip targets not in melee range if requested
		if ( ( pFilter & TargetFilter_InMeleeRange ) && GetRangeToUnit( UnitTarget ) > _unit->GetAIInterface()->_CalcCombatRange( UnitTarget, false ) )
			return false;

		//Skip targets not in strict range if requested
		if ( ( pFilter & TargetFilter_InRangeOnly ) && ( pMinRange > 0 || pMaxRange > 0 ) )
		{
			float Range = GetRangeToUnit( UnitTarget );
			if ( pMinRange > 0 && Range < pMinRange )
				return false;
			if ( pMaxRange > 0 && Range > pMaxRange )
				return false;
		};

		//Skip targets not in Line Of Sight if requested
		if ( ( ~pFilter & TargetFilter_IgnoreLineOfSight ) && !_unit->IsInLineOfSight( UnitTarget ) )
			return false;

		//Handle hostile/friendly
		if ( ( ~pFilter & TargetFilter_Corpse ) && ( pFilter & TargetFilter_Friendly ) ) 
		{
			if ( !UnitTarget->CombatStatus.IsInCombat() )
				return false; //Skip not-in-combat targets if friendly
			if ( isHostile( _unit, UnitTarget ) || _unit->GetAIInterface()->getThreatByPtr( UnitTarget ) > 0 )
				return false;
		};
	};

	return true; //This is a valid unit target
};
Пример #6
0
    void UpdateAI(const uint32 diff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (ArcingSmashTimer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_ARCING_SMASH);
            ArcingSmashTimer = 10000;
        }else ArcingSmashTimer -= diff;

        if (FelAcidTimer < diff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_FEL_ACID);
            FelAcidTimer = 25000;
        }else FelAcidTimer -= diff;

        if (!m_creature->HasAura(SPELL_BERSERK, EFFECT_INDEX_0))
        {
            if (EnrageTimer < diff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK)
                    DoScriptText(urand(0, 1) ? SAY_ENRAGE1 : SAY_ENRAGE2, m_creature);
            }else EnrageTimer -= diff;
        }

        if (Phase1)
        {
            if (BewilderingStrikeTimer < diff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_BEWILDERING_STRIKE);
                float mt_threat = m_creature->getThreatManager().getThreat(m_creature->getVictim());

                if (Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1))
                    m_creature->AddThreat(target, mt_threat);

                BewilderingStrikeTimer = 20000;
            }else BewilderingStrikeTimer -= diff;

            if (EjectTimer < diff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_EJECT1);
                m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(), -40);
                EjectTimer = 15000;
            }else EjectTimer -= diff;

            if (AcidicWoundTimer < diff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_ACIDIC_WOUND);
                AcidicWoundTimer = 10000;
            }else AcidicWoundTimer -= diff;

            if (BloodboilTimer < diff)
            {
                if (BloodboilCount < 5)                     // Only cast it five times.
                {
                    //CastBloodboil(); // Causes issues on windows, so is commented out.
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_BLOODBOIL);
                    ++BloodboilCount;
                    BloodboilTimer = 10000*BloodboilCount;
                }
            }else BloodboilTimer -= diff;
        }

        if (!Phase1)
        {
            if (AcidGeyserTimer < diff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_ACID_GEYSER);
                AcidGeyserTimer = 30000;
            }else AcidGeyserTimer -= diff;

            if (EjectTimer < diff)
            {
                DoCastSpellIfCan(m_creature->getVictim(), SPELL_EJECT2);
                EjectTimer = 15000;
            }else EjectTimer -= diff;
        }

        if (PhaseChangeTimer < diff)
        {
            if (Phase1)
            {
                Unit* target = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
                if (target && target->isAlive())
                {
                    Phase1 = false;

                    TargetThreat = m_creature->getThreatManager().getThreat(target);
                    m_targetGuid = target->GetObjectGuid();
                    target->CastSpell(m_creature, SPELL_TAUNT_GURTOGG, true);

                    if (m_creature->getThreatManager().getThreat(target))
                        m_creature->getThreatManager().modifyThreatPercent(target, -100);

                    m_creature->AddThreat(target, 50000000.0f);

                    // If VMaps are disabled, this spell can call the whole instance
                    DoCastSpellIfCan(m_creature, SPELL_INSIGNIFIGANCE, CAST_TRIGGERED);
                    DoCastSpellIfCan(target, SPELL_FEL_RAGE_TARGET, CAST_TRIGGERED);
                    DoCastSpellIfCan(target, SPELL_FEL_RAGE_2, CAST_TRIGGERED);

                    /* These spells do not work, comment them out for now.
                    DoCastSpellIfCan(target, SPELL_FEL_RAGE_2, CAST_TRIGGERED);
                    DoCastSpellIfCan(target, SPELL_FEL_RAGE_3, CAST_TRIGGERED);*/

                    //Cast this without triggered so that it appears in combat logs and shows visual.
                    DoCastSpellIfCan(m_creature, SPELL_FEL_RAGE_SELF);

                    DoScriptText(urand(0, 1) ? SAY_SPECIAL1 : SAY_SPECIAL2, m_creature);

                    AcidGeyserTimer = 1000;
                    PhaseChangeTimer = 30000;
                }
            }else                                           // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage
            {
                if (m_targetGuid)
                    RevertThreatOnTarget(m_targetGuid);

                m_targetGuid.Clear();
                Phase1 = true;
                BloodboilTimer = 10000;
                BloodboilCount = 0;
                AcidicWoundTimer += 2000;
                ArcingSmashTimer += 2000;
                FelAcidTimer += 2000;
                EjectTimer += 2000;
                PhaseChangeTimer = 60000;
            }
        }else PhaseChangeTimer -= diff;

        //Enrage
        if (m_uiEnrageTimer < diff)
        {
            DoCast(m_creature, SPELL_ENRAGE);
            m_uiEnrageTimer = 60000;
        }else m_uiEnrageTimer -= diff;

        DoMeleeAttackIfReady();
    }
Пример #7
0
    void UpdateAI(const uint32 diff)
    {
        if(!m_creature->SelectHostilTarget() || !m_creature->getVictim() )
            return;

        if(pInstance && !pInstance->GetData(DATA_MOROES_EVENT))
            EnterEvadeMode();

        if(!Enrage && m_creature->GetHealth()*100 / m_creature->GetMaxHealth() < 30)
        {
            DoCast(m_creature, SPELL_FRENZY);
            Enrage = true;
        }

        if (CheckAdds_Timer < diff)
        {
            for (uint8 i = 0; i < 4; ++i)
            {
                Unit* Temp = NULL;
                if (AddGUID[i])
                {
                    Temp = Unit::GetUnit((*m_creature),AddGUID[i]);
                    if (Temp && Temp->isAlive())
                        if (!Temp->SelectHostilTarget() || !Temp->getVictim() )
                            ((Creature*)Temp)->AI()->AttackStart(m_creature->getVictim());
                }
            }
            CheckAdds_Timer = 5000;
        }else CheckAdds_Timer -= diff;

        if (!Enrage)
        {
            //Cast Vanish, then Garrote random victim
            if (Vanish_Timer < diff)
            {
                m_creature->setFaction(35);
                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                DoCast(m_creature, SPELL_VANISH);
                InVanish = true;
                Vanish_Timer = 30000;
                Wait_Timer = 5000;
            }else Vanish_Timer -= diff;

            if (InVanish)
            {
                if (Wait_Timer < diff)
                {
                    switch(rand()%2)
                    {
                        case 0:
                            DoYell(SAY_SPECIAL_1, LANG_UNIVERSAL, NULL);
                            DoPlaySoundToSet(m_creature, SOUND_SPECIAL_1);
                            break;
                        case 1:
                            DoYell(SAY_SPECIAL_2, LANG_UNIVERSAL, NULL);
                            DoPlaySoundToSet(m_creature, SOUND_SPECIAL_2);
                            break;
                    }

                    Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                    if (target)
                        target->CastSpell(target, SPELL_GARROTE,true);

                    m_creature->setFaction(16);
                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    m_creature->AI()->AttackStart(m_creature->getVictim());
                    InVanish = false;
                }else Wait_Timer -= diff;
            }

            //Blind highest aggro, and attack second highest
            if (Gouge_Timer < diff)
            {
                DoCast(m_creature->getVictim(), SPELL_GOUGE);
                if (m_creature->getThreatManager().getThreat(m_creature->getVictim()))
                    m_creature->getThreatManager().modifyThreatPercent(m_creature->getVictim(),-100);
                Gouge_Timer = 40000;
            }else Gouge_Timer -= diff;

            if (Blind_Timer < diff)
            {
                Unit* target = NULL;
                std::list<HostilReference*> t_list = m_creature->getThreatManager().getThreatList();

                if (t_list.empty())
                    return;

                std::vector<Unit*> target_list;
                for (std::list<HostilReference*>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                {
                    target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                    if (target && target->GetDistance2d(m_creature) < 5)
                        target_list.push_back(target);
                }
                if (target_list.size())
                    target = *(target_list.begin()+rand()%target_list.size());

                if (target)
                    DoCast(target, SPELL_BLIND);

                Blind_Timer = 40000;
            }else Blind_Timer -= diff;
        }

        if (!InVanish)
            DoMeleeAttackIfReady();
    }
Пример #8
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (m_bSummonKilrek)
        {
            if (m_uiSummonKilrekTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_SUMMON_IMP) == CAST_OK)
                {
                    m_uiSummonKilrekTimer = 45000;
                    m_bSummonKilrek = false;
                }
            }
            else
                m_uiSummonKilrekTimer -= uiDiff;
        }

        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiSacrifice_Timer < uiDiff)
        {
            Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);
            if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
            {
                DoCastSpellIfCan(pTarget, SPELL_SACRIFICE, CAST_TRIGGERED);

                if (Creature* pChains = m_creature->SummonCreature(NPC_DEMONCHAINS, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 21000))
                {
                    if (mob_demon_chainAI* pDemonAI = dynamic_cast<mob_demon_chainAI*>(pChains->AI()))
                        pDemonAI->m_uiSacrificeGUID = pTarget->GetGUID();

                    pChains->CastSpell(pChains, SPELL_DEMON_CHAINS, true);

                    DoScriptText(urand(0, 1) ? SAY_SACRIFICE1 : SAY_SACRIFICE2, m_creature);

                    m_uiSacrifice_Timer = 30000;
                }
            }
        }
        else
            m_uiSacrifice_Timer -= uiDiff;

        if (m_uiShadowbolt_Timer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHADOW_BOLT);
            m_uiShadowbolt_Timer = 10000;
        }
        else
            m_uiShadowbolt_Timer -= uiDiff;

        if (!m_bSummonedPortals)
        {
            if (m_uiSummon_Timer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_FIENDISH_PORTAL, CAST_INTERRUPT_PREVIOUS) == CAST_OK)
                {
                    DoScriptText(urand(0, 1) ? SAY_SUMMON1 : SAY_SUMMON2, m_creature);
                    m_bSummonedPortals = true;
                }
            }
            else
                m_uiSummon_Timer -= uiDiff;
        }

        if (!m_bBerserk)
        {
            if (m_uiBerserk_Timer < uiDiff)
            {
                DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_INTERRUPT_PREVIOUS);
                m_bBerserk = true;
            }
            else
                m_uiBerserk_Timer -= uiDiff;
        }

        DoMeleeAttackIfReady();
    }
Пример #9
0
void WorldSession::HandlePetAction(WorldPacket& recv_data)
{
    ObjectGuid petGuid;
    uint32 data;
    ObjectGuid targetGuid;
    recv_data >> petGuid;
    recv_data >> data;
    recv_data >> targetGuid;

    uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data);
    uint8 flag = UNIT_ACTION_BUTTON_TYPE(data);             // delete = 0x07 CastSpell = C1

    DETAIL_LOG("HandlePetAction: %s flag is %u, spellid is %u, target %s.", petGuid.GetString().c_str(), uint32(flag), spellid, targetGuid.GetString().c_str());

    // used also for charmed creature/player
    Unit* pet = _player->GetMap()->GetUnit(petGuid);
    if (!pet)
    {
        sLog.outError("HandlePetAction: %s not exist.", petGuid.GetString().c_str());
        return;
    }

    if (GetPlayer()->GetObjectGuid() != pet->GetCharmerOrOwnerGuid())
    {
        sLog.outError("HandlePetAction: %s isn't controlled by %s.", petGuid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
        return;
    }

    if (!pet->isAlive())
        return;

    if (pet->GetTypeId() == TYPEID_PLAYER)
    {
        // controller player can only do melee attack
        if (!(flag == ACT_COMMAND && spellid == COMMAND_ATTACK))
            return;
    }
    else if (((Creature*)pet)->IsPet())
    {
        // pet can have action bar disabled
        if (((Pet*)pet)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)
            return;
    }

    CharmInfo* charmInfo = pet->GetCharmInfo();
    if (!charmInfo)
    {
        sLog.outError("WorldSession::HandlePetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId());
        return;
    }

    switch (flag)
    {
        case ACT_COMMAND:                                   // 0x07
            switch (spellid)
            {
                case COMMAND_STAY:                          // flat=1792  // STAY
                    pet->StopMoving();
                    pet->GetMotionMaster()->Clear(false);
                    pet->GetMotionMaster()->MoveIdle();
                    charmInfo->SetCommandState(COMMAND_STAY);
                    break;
                case COMMAND_FOLLOW:                        // spellid=1792  // FOLLOW
                    pet->AttackStop();
                    pet->GetMotionMaster()->MoveFollow(_player, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
                    charmInfo->SetCommandState(COMMAND_FOLLOW);
                    break;
                case COMMAND_ATTACK:                        // spellid=1792  // ATTACK
                {
                    Unit* TargetUnit = _player->GetMap()->GetUnit(targetGuid);
                    if (!TargetUnit)
                        return;

                    // not let attack friendly units.
                    if (GetPlayer()->IsFriendlyTo(TargetUnit))
                        return;
                    // Not let attack through obstructions
                    if (!pet->IsWithinLOSInMap(TargetUnit))
                        return;

                    // This is true if pet has no target or has target but targets differs.
                    if (pet->getVictim() != TargetUnit)
                    {
                        if (pet->getVictim())
                            pet->AttackStop();

                        if (pet->hasUnitState(UNIT_STAT_CONTROLLED))
                        {
                            pet->Attack(TargetUnit, true);
                            pet->SendPetAIReaction();
                        }
                        else
                        {
                            pet->GetMotionMaster()->Clear();

                            if (((Creature*)pet)->AI())
                                ((Creature*)pet)->AI()->AttackStart(TargetUnit);

                            // 10% chance to play special pet attack talk, else growl
                            if (((Creature*)pet)->IsPet() && ((Pet*)pet)->getPetType() == SUMMON_PET && pet != TargetUnit && roll_chance_i(10))
                                pet->SendPetTalk((uint32)PET_TALK_ATTACK);
                            else
                            {
                                // 90% chance for pet and 100% chance for charmed creature
                                pet->SendPetAIReaction();
                            }
                        }
                    }
                    break;
                }
                case COMMAND_ABANDON:                       // abandon (hunter pet) or dismiss (summoned pet)
                    if (((Creature*)pet)->IsPet())
                    {
                        Pet* p = (Pet*)pet;
                        if (p->getPetType() == HUNTER_PET)
                            p->Unsummon(PET_SAVE_AS_DELETED, _player);
                        else
                            // dismissing a summoned pet is like killing them (this prevents returning a soulshard...)
                            p->SetDeathState(CORPSE);
                    }
                    else                                    // charmed
                        _player->Uncharm();
                    break;
                default:
                    sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
            }
            break;
        case ACT_REACTION:                                  // 0x6
            switch (spellid)
            {
                case REACT_PASSIVE:                         // passive
                case REACT_DEFENSIVE:                       // recovery
                case REACT_AGGRESSIVE:                      // activete
                    charmInfo->SetReactState(ReactStates(spellid));
                    break;
            }
            break;
        case ACT_DISABLED:                                  // 0x81    spell (disabled), ignore
        case ACT_PASSIVE:                                   // 0x01
        case ACT_ENABLED:                                   // 0xC1    spell
        {
            Unit* unit_target = NULL;
            if (targetGuid)
                unit_target = _player->GetMap()->GetUnit(targetGuid);

            // do not cast unknown spells
            SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
            if (!spellInfo)
            {
                sLog.outError("WORLD: unknown PET spell id %i", spellid);
                return;
            }

            if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
                return;

            for (int i = 0; i < MAX_EFFECT_INDEX; ++i)
            {
                if (spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_INSTANT || spellInfo->EffectImplicitTargetA[i] == TARGET_ALL_ENEMY_IN_AREA_CHANNELED)
                    return;
            }

            // do not cast not learned spells
            if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
                return;

            pet->clearUnitState(UNIT_STAT_MOVING);

            Spell* spell = new Spell(pet, spellInfo, false);

            SpellCastResult result = spell->CheckPetCast(unit_target);

            // auto turn to target unless possessed
            if (result == SPELL_FAILED_UNIT_NOT_INFRONT && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
            {
                if (unit_target)
                {
                    pet->SetInFront(unit_target);
                    if (unit_target->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)unit_target);
                }
                else if (Unit* unit_target2 = spell->m_targets.getUnitTarget())
                {
                    pet->SetInFront(unit_target2);
                    if (unit_target2->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)unit_target2);
                }
                if (Unit* powner = pet->GetCharmerOrOwner())
                    if (powner->GetTypeId() == TYPEID_PLAYER)
                        pet->SendCreateUpdateToPlayer((Player*)powner);
                result = SPELL_CAST_OK;
            }

            if (result == SPELL_CAST_OK)
            {
                ((Creature*)pet)->AddCreatureSpellCooldown(spellid);

                unit_target = spell->m_targets.getUnitTarget();

                // 10% chance to play special pet attack talk, else growl
                // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
                if (((Creature*)pet)->IsPet() && (((Pet*)pet)->getPetType() == SUMMON_PET) && (pet != unit_target) && (urand(0, 100) < 10))
                    pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
                else
                {
                    pet->SendPetAIReaction();
                }

                if (unit_target && !GetPlayer()->IsFriendlyTo(unit_target) && !pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
                {
                    // This is true if pet has no target or has target but targets differs.
                    if (pet->getVictim() != unit_target)
                    {
                        if (pet->getVictim())
                            pet->AttackStop();
                        pet->GetMotionMaster()->Clear();
                        if (((Creature*)pet)->AI())
                            ((Creature*)pet)->AI()->AttackStart(unit_target);
                    }
                }

                spell->prepare(&(spell->m_targets));
            }
            else
            {
                if (pet->HasAuraType(SPELL_AURA_MOD_POSSESS))
                    Spell::SendCastResult(GetPlayer(), spellInfo, 0, result);
                else
                {
                    Unit* owner = pet->GetCharmerOrOwner();
                    if (owner && owner->GetTypeId() == TYPEID_PLAYER)
                        Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true);
                }

                if (!((Creature*)pet)->HasSpellCooldown(spellid))
                    GetPlayer()->SendClearCooldown(spellid, pet);

                spell->finish(false);
                delete spell;
            }
            break;
        }
        default:
            sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid);
    }
}
Пример #10
0
		void UpdateAI(const uint32 diff) {
			if (Phase == NORMAL) {
				//Return since we have no target
				if (!UpdateVictim())
					return;

				if (uiSinsterStrikeTimer <= diff) {
					DoCast(me->getVictim(), SPELL_SINSTER_STRIKE);
					uiSinsterStrikeTimer = urand(5 * IN_MILLISECONDS,
							9 * IN_MILLISECONDS);
				} else
					uiSinsterStrikeTimer -= diff;

				if (uiCallFlamesTimer <= diff) {
					if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) {
						DoCast(pTarget, SPELL_CALL_FLAMES);
						uiCallFlamesTimer = urand(8 * IN_MILLISECONDS,
								12 * IN_MILLISECONDS);
					}
				} else
					uiCallFlamesTimer -= diff;

				if (!bSacrificed) {
					if (uiRitualOfSwordTimer <= diff) {
						if (Unit* pSacrificeTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) {
							DoScriptText(
									RAND(SAY_SACRIFICE_PLAYER_1,
											SAY_SACRIFICE_PLAYER_2,
											SAY_SACRIFICE_PLAYER_3,
											SAY_SACRIFICE_PLAYER_4,
											SAY_SACRIFICE_PLAYER_5), me);
							DoCast(pSacrificeTarget, SPELL_RITUAL_OF_THE_SWORD);
							//Spell doesn't teleport
							DoTeleportPlayer(pSacrificeTarget, 296.632f,
									-346.075f, 90.63f, 4.6f);
							me->SetUnitMovementFlags(MOVEMENTFLAG_CAN_FLY);
							DoTeleportTo(296.632f, -346.075f, 120.85f);
							Phase = SACRIFICING;
							if (pInstance) {
								pInstance->SetData64(DATA_SACRIFICED_PLAYER,
										pSacrificeTarget->GetGUID());

								for (uint8 i = 0; i < 3; ++i)
									if (Creature* pSummon = me->SummonCreature(CREATURE_RITUAL_CHANNELER, RitualChannelerPos[i], TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000))
										pSummon->AI()->DoAction(0);
							}

							bSacrificed = true;
						}
					} else
						uiRitualOfSwordTimer -= diff;
				}

				DoMeleeAttackIfReady();
			} else //SACRIFICING
			{
				if (uiSacrificeTimer <= diff) {
					Unit* pSacrificeTarget =
							pInstance ?
									Unit::GetUnit(
											*me,
											pInstance->GetData64(
													DATA_SACRIFICED_PLAYER)) :
									NULL;
					if (pInstance && !summons.empty() && pSacrificeTarget
							&& pSacrificeTarget->isAlive())
						me->Kill(pSacrificeTarget, false); // durability damage?

					//go down
					Phase = NORMAL;
					pSacrificeTarget = NULL;
					me->SetUnitMovementFlags(MOVEMENTFLAG_WALKING);
					if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
						me->GetMotionMaster()->MoveChase(pTarget);

					uiSacrificeTimer = 8 * IN_MILLISECONDS;
				} else
					uiSacrificeTimer -= diff;
			}
		}
Пример #11
0
void guardAI::UpdateAI(const uint32 diff)
{
    //Always decrease our global cooldown first
    if (GlobalCooldown > diff)
        GlobalCooldown -= diff;
    else GlobalCooldown = 0;

    //Always decrease ZoneAttackMsgTimer
    if (ZoneAttackMsgTimer > diff)
        ZoneAttackMsgTimer -= diff;
    else ZoneAttackMsgTimer = 0;

    //Always decrease Bandage
    if (Bandage > diff)
        Bandage -= diff;
    else Bandage = 0;

    //Always decrease OffHand
    if (OffHand > diff)
        OffHand -= diff;
    else OffHand = 0;

    //Always decrease Potion
    if (Potion > diff)
        Potion -= diff;
    else Potion = 0;

    if(!m_creature->isAlive())
        return;

	if (!m_creature->isInCombat() && !(m_creature->GetEntry() == 2041 || m_creature->GetEntry() == 4423))
    {
       int temp1 = m_creature->GetPower(POWER_RAGE);
       int temp2 = temp1;
       temp1 = temp2 - 3;
       if(temp1 > 0)
          m_creature->SetPower(POWER_RAGE,temp1);
       else
          m_creature->SetPower(POWER_RAGE,0);
    }

    //Return since we have no target
    if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
        return;

    Unit *target = m_creature->getVictim();

       if(target == m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,0) && !target->isAlive() && !m_creature->IsNonMeleeSpellCasted(false))
       {
          Unit* target2 = NULL;
          target2 = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO,1);
          m_creature->getThreatManager().modifyThreatPercent(target,-100);
          if(target2 && target2->isAlive())
              {
                 m_creature->AddThreat(target2,1);
                 m_creature->Attack(target2,true);
                 AttackStart(target2);
                 return;
              }
          else
          {
              Reset();
              return;
          }
       }

    if(m_creature->IsHostileTo(target))
           enemy = target;

    if(enemy)
        if(!enemy->isAlive())
            enemy = NULL;


    //Always decrease Help when in combat
    if (Help > diff)
        Help -= diff;
    else Help = 0;

    if(!Help && !(m_creature->GetEntry() == 2041 || m_creature->GetEntry() == 4423))
    {
       int entry = m_creature->GetEntry();
       float x;
       float y;
       float z;
       float X;
       float Y;
       float Z;
       m_creature->GetPosition(x,y,z);
       m_creature->getVictim()->GetPosition(X,Y,Z);
       if(x > X)
           X = x + 20;
       else
           X = x - 20;
       if(y > Y)
           Y = y + 20;
       else
           Y = y - 20;
       m_creature->GetRespawnCoord(x,y,z); 

          if(entry != 12480 && entry != 12481)
           {
       Helper = DoSpawnCreature(entry, (float) (X - x), (float) (Y - y), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
    /*   Helper = DoSpawnCreature(entry, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000); */
       if(Helper && enemy)
          ((CreatureAI*)Helper->AI())->AttackStart(enemy); 
           }else
             {
       Helper = DoSpawnCreature(68, (float) (X - x + 3), (float) (Y - y - 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
           if(Helper && enemy)
           ((CreatureAI*)Helper->AI())->AttackStart(enemy); 
           Creature* Helper2 = NULL;
       Helper2 = DoSpawnCreature(68, (float) (X - x - 3), (float) (Y - y + 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
           if(Helper2 && enemy)
           ((CreatureAI*)Helper2->AI())->AttackStart(enemy); 
            Creature* Helper3 = NULL;
       Helper3 = DoSpawnCreature(68, (float) (X - x + 3), (float) (Y - y + 3), (float) (Z -z), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 5000);
           if(Helper3 && enemy)
           ((CreatureAI*)Helper3->AI())->AttackStart(enemy); 
             }

       Help = urand(45000, 75000);
    }

    // Make sure our attack is ready and we arn't currently casting
    if (m_creature->isAttackReady() && !m_creature->IsNonMeleeSpellCasted(false))
    {
            if(m_creature->getVictim() && m_creature->SelectHostileTarget() && m_creature->GetEntry() == 3084 && OffHand > 0 && OffHand < 500)
            {
                m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ATTACKOFF);
                m_creature->AttackerStateUpdate(m_creature->getVictim());
                m_creature->resetAttackTimer();
                OffHand = 0;
            }
        //If we are within range melee the target
        if (m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
        {

           if(_Aggro != 2 && m_creature->GetEntry() != 2041 && m_creature->GetEntry() != 5624)
           {
              _Aggro = 2;
              DoCastSpellIfCan(m_creature,2457);
              return;
           }

           if(m_creature->GetHealthPercent() > 39.0f && m_creature->HasAura(2458,EFFECT_INDEX_0) && m_creature->GetEntry() != 2041 && m_creature->GetEntry() != 5624)
           {
              DoCastSpellIfCan(m_creature,2457);
              return; 
           }

            bool Healing = false;
            int info = 0;
            int Change = 0;

            //Select a healing spell if less than 30% hp
            if (m_creature->GetHealthPercent() < 40.0f)
            {
               if(Potion == 0 && !Healing)
               {
                  Potion = 60000;
                  info = 17534;
                  Healing = true;
               }
               else
               {
                  if(Bandage == 0 && !Healing)
                  {
                     Bandage = 60000;
                     info = 38919;
                     Healing = true;
                  }
                  else
                      if(m_creature->HasAura(2457,EFFECT_INDEX_0))
                      {
                         info = 2458;
                         Change = 3;
                      }  
               }//if bandage
            }//if health <40%
            else
            {
                         if(!m_creature->HasAura(2048,EFFECT_INDEX_0) && m_creature->GetPower(POWER_RAGE) > 100)
                         {
                            info = 2048;
                            Change = 3;    
                         }
                         else
                         {
                            if(enemy && !enemy->HasAura(25203,EFFECT_INDEX_0) && m_creature->GetPower(POWER_RAGE) > 100)
                            {
                               info = 25203;
                               Change = 4;    
                            }
                            //select a hostile spell
                            else
                            {
                               if(enemy && m_creature->GetPower(POWER_RAGE) > 100)
                               {
                                  switch(urand(0, 7))
                                  {
                                     case 0:
                                        info = 29707;
                                        break;
                                     case 1:
                                        info = 11574;
                                        break;
                                     case 2:
                                        info = 30022;
                                        break;
                                     case 3:
                                        info = 11597;
                                        break;
                                     case 4:
                                        if(m_creature->HasAura(2457,EFFECT_INDEX_0))
                                           info = 25248;
                                        else info = 20569;
                                        break;
                                     case 5:
                                        if(m_creature->HasAura(2457,EFFECT_INDEX_0))
                                           info = 20560;
                                        else info = 6554;
                                        break;
                                     case 6:
                                        if(m_creature->HasAura(2457,EFFECT_INDEX_0))
                                           info = 11581;
                                        else info = 1680;
                                        break;
                                     case 7:
                                        info = 11597;
                                        break;
                                  }//switch
                               }//if rage
                            }//else hostile spell
                         }//if no demoralizing
                     }//if no battle shout

            if(m_creature->GetEntry() == 4423)
               info = 0;

            if(m_creature->GetEntry() == 5624)
            {
                info = 0;
                if(!m_creature->HasAura(41924,EFFECT_INDEX_0))
                    DoCastSpellIfCan(m_creature, 41924);
            }

            //50% chance to replace our white hit with a spell
            if (info && urand(0, 1) == 0 && !GlobalCooldown)
            {
                //Cast the spell
                if (Healing)DoCastSpellIfCan(m_creature, info);
                else
                {
                         if(Change == 3)
                         {
                            DoCastSpellIfCan(m_creature, info);                            
                         }
                         else
                         {
                            if(Change == 4)
                               DoCastSpellIfCan(enemy, info);
                            else
                                DoCastSpellIfCan(enemy, info);
                         }              
                }
                //Set our global cooldown
                GlobalCooldown = GENERIC_CREATURE_COOLDOWN;
            }
            else m_creature->AttackerStateUpdate(m_creature->getVictim());

            m_creature->resetAttackTimer();
            if(m_creature->GetEntry() == 3084)
                OffHand = 1000;
        }
    }
    else
    {
        //Only run this code if we arn't already casting
        if (!m_creature->IsNonMeleeSpellCasted(false))
        {
            bool Healing = false;
            SpellEntry const *info = NULL;

            //Select a healing spell if less than 30% hp ONLY 33% of the time
            if (m_creature->GetHealthPercent() < 30.0f && !urand(0, 2))
                info = SelectSpell(m_creature, -1, -1, SELECT_TARGET_ANY_FRIEND, 0, 0, 0, 0, SELECT_EFFECT_HEALING);

            //No healing spell available, See if we can cast a ranged spell (Range must be greater than ATTACK_DISTANCE)
            if (info) Healing = true;
            else info = SelectSpell(m_creature->getVictim(), -1, -1, SELECT_TARGET_ANY_ENEMY, 0, 0, ATTACK_DISTANCE, 0, SELECT_EFFECT_DONTCARE);

            //Found a spell, check if we arn't on cooldown
            if (info && !GlobalCooldown)
            {
                //If we are currently moving stop us and set the movement generator
                if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=IDLE_MOTION_TYPE)
                {
                    (*m_creature).GetMotionMaster()->Clear(false);
                    (*m_creature).GetMotionMaster()->MoveIdle();
                }

                //Cast spell
                if (Healing) DoCastSpell(m_creature,info);
                else DoCastSpell(m_creature->getVictim(),info);

                //Set our global cooldown
                GlobalCooldown = GENERIC_CREATURE_COOLDOWN;

            }                                               //If no spells available and we arn't moving run to target
			else if ((*m_creature).GetMotionMaster()->GetCurrentMovementGeneratorType()!=CHASE_MOTION_TYPE)
            {
                //Cancel our current spell and then mutate new movement generator
                m_creature->InterruptNonMeleeSpells(false);
                (*m_creature).GetMotionMaster()->Clear(false);
                (*m_creature).GetMotionMaster()->MoveChase(m_creature->getVictim());
            }
        }
    }
}
Пример #12
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;
		
		if(phase == 2 && boss_phase == 1)
		{
			events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000);
			events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000);
			events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000);
			boss_phase++;

		}
		
		if(phase == 3 && boss_phase == 2)
		{
			
			events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000);
			events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000);
			events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000);
			events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000));
			

		}

        events.Update(diff);


        while (uint32 eventId = events.ExecuteEvent())
        {
            switch(eventId)
            {
                case EVENT_ENRAGE:
                    DoScriptText(SAY_MOLGEIM_BERSERK, me);
                    DoCast(SPELL_BERSERK);
                    break;
                case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
                {
                    Unit *pTarget = DoSelectLowestHpFriendly(60);
                    if (!pTarget || (pTarget && !pTarget->isAlive()))
                        pTarget = me;
					me->SummonCreature(33705, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ() , 0 , TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 60000); // Fais pop la rune
				    events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000);
                    break;
                }
                case EVENT_SHIELD_OF_RUNES:
                    DoCast(me, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H));
                    events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, urand(27000,34000));
                    break;
                case EVENT_RUNE_OF_DEATH:
                    DoScriptText(SAY_MOLGEIM_RUNE_DEATH, me);
                    if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
                        DoCast(pTarget, SPELL_RUNE_OF_DEATH);
                    events.ScheduleEvent(EVENT_RUNE_OF_DEATH, urand(30000,40000));
                    break;
                case EVENT_RUNE_OF_SUMMONING:
                    DoScriptText(SAY_MOLGEIM_SUMMON, me);
                    if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM))
                      //  DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
                    events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, urand(20000,30000));
                    break;
            }
        }

        DoMeleeAttackIfReady();
    }
Пример #13
0
void hyjalAI::UpdateAI(const uint32 diff)
{
    if (IsDummy)
    {
        if (MassTeleportTimer < diff && DoMassTeleport)
        {
            DoCast(me, SPELL_MASS_TELEPORT, false);
            DoMassTeleport = false;
        } else MassTeleportTimer -= diff;
        return;
    }
    if (DoHide)
    {
        DoHide = false;
        switch (me->GetEntry())
        {
        case JAINA:
            if (instance && instance->GetData(DATA_ALLIANCE_RETREAT))
            {
                me->SetVisible(false);
                HideNearPos(me->GetPositionX(), me->GetPositionY());
                HideNearPos(5037.76f, -1889.71f);
                for (uint8 i = 0; i < 92; ++i)//summon fires
                    me->SummonGameObject(FLAMEOBJECT, AllianceFirePos[i][0], AllianceFirePos[i][1], AllianceFirePos[i][2], AllianceFirePos[i][3], AllianceFirePos[i][4], AllianceFirePos[i][5], AllianceFirePos[i][6], AllianceFirePos[i][7], 0);
            }
            else me->SetVisible(true);
            break;
        case THRALL: //thrall
            if (instance && instance->GetData(DATA_HORDE_RETREAT))
            {
                me->SetVisible(false);
                HideNearPos(me->GetPositionX(), me->GetPositionY());
                HideNearPos(5563, -2763.19f);
                HideNearPos(5542.2f, -2629.36f);
                for (uint8 i = 0; i < 65; ++i)//summon fires
                    me->SummonGameObject(FLAMEOBJECT, HordeFirePos[i][0], HordeFirePos[i][1], HordeFirePos[i][2], HordeFirePos[i][3], HordeFirePos[i][4], HordeFirePos[i][5], HordeFirePos[i][6], HordeFirePos[i][7], 0);
            }
            else me->SetVisible(true);
            break;
        }
    }
    if (DoRespawn)
    {
        if (RespawnTimer <= diff)
        {
            DoRespawn = false;
            RespawnNearPos(me->GetPositionX(), me->GetPositionY());
            if (Faction == 0)
            {
                RespawnNearPos(5037.76f, -1889.71f);
            } else if (Faction == 1)
            {
                RespawnNearPos(5563, -2763.19f);
                RespawnNearPos(5542.2f, -2629.36f);
            }
            me->SetVisible(true);
        } else {
            RespawnTimer -= diff;
            me->SetVisible(false);
        }
        return;
    }
    if (Overrun)
        DoOverrun(Faction, diff);
    if (bRetreat)
    {
        if (RetreatTimer <= diff)
        {
            IsDummy = true;
            bRetreat = false;
            HideNearPos(me->GetPositionX(), me->GetPositionY());
            switch (me->GetEntry())
            {
            case JAINA://jaina
                HideNearPos(5037.76f, -1889.71f);
                break;
            case THRALL://thrall
                HideNearPos(5563, -2763.19f);
                HideNearPos(5542.2f, -2629.36f);
                HideNearPos(5603.75f, -2853.12f);
                break;
            }
            me->SetVisible(false);
        } else RetreatTimer -= diff;
    }

    if (!EventBegun)
        return;

    if (Summon)
    {
        if (instance && EnemyCount)
        {
            EnemyCount = instance->GetData(DATA_TRASH);
            if (!EnemyCount)
                NextWaveTimer = 5000;
        }

        if (NextWaveTimer <= diff)
        {
            if (Faction == 0)
                SummonNextWave(AllianceWaves, WaveCount, AllianceBase);
            else if (Faction == 1)
                SummonNextWave(HordeWaves, WaveCount, HordeBase);
            ++WaveCount;
        } else NextWaveTimer -= diff;
    }

    if (CheckTimer <= diff)
    {
        for (uint8 i = 0; i < 2; ++i)
        {
            if (BossGUID[i])
            {
                Unit* unit = Unit::GetUnit((*me), BossGUID[i]);
                if (unit && (!unit->isAlive()))
                {
                    if (BossGUID[i] == BossGUID[0])
                    {
                        Talk(INCOMING);
                        FirstBossDead = true;
                    }
                    else if (BossGUID[i] == BossGUID[1])
                    {
                        Talk(SUCCESS);
                        SecondBossDead = true;
                    }
                    EventBegun = false;
                    CheckTimer = 0;
                    me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
                    BossGUID[i] = 0;
                    if (instance)
                        instance->DoUpdateWorldState(WORLD_STATE_ENEMY, 0); // Reset world state for enemies to disable it
                }
            }
        }
        CheckTimer = 5000;
    } else CheckTimer -= diff;

    if (!UpdateVictim())
        return;

    for (uint8 i = 0; i < HYJAL_AI_MAX_SPELLS; ++i)
    {
        if (Spells[i].SpellId)
        {
            if (SpellTimer[i] <= diff)
            {
                if (me->IsNonMeleeSpellCasted(false))
                    me->InterruptNonMeleeSpells(false);

                Unit* target = NULL;

                switch (Spells[i].TargetType)
                {
                case TARGETTYPE_SELF:
                    target = me;
                    break;
                case TARGETTYPE_RANDOM:
                    target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                    break;
                case TARGETTYPE_VICTIM:
                    target = me->getVictim();
                    break;
                }

                if (target && target->isAlive())
                {
                    DoCast(target, Spells[i].SpellId);
                    SpellTimer[i] = Spells[i].Cooldown;
                }
            } else SpellTimer[i] -= diff;
        }
    }

    DoMeleeAttackIfReady();
}
    void UpdateAI(const uint32 diff)
    {
        //Inhibitmagic_Timer
        if (Inhibitmagic_Timer <= diff)
        {
            float dist;
            Map *map = me->GetMap();
            Map::PlayerList const &PlayerList = map->GetPlayers();
            for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                if (Player* i_pl = i->getSource())
                    if (i_pl->isAlive() && (dist = i_pl->GetDistance(me)) < 45)
                    {
                        i_pl->RemoveAurasDueToSpell(SPELL_INHIBITMAGIC);
                        me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if (dist < 35)
                            me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if (dist < 25)
                            me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                        if (dist < 15)
                            me->AddAura(SPELL_INHIBITMAGIC, i_pl);
                    }
            Inhibitmagic_Timer = 3000+(rand()%1000);
        } else Inhibitmagic_Timer -= diff;

        //Return since we have no target
        if (!UpdateVictim())
            return;

        //Attractmagic_Timer
        if (Attractmagic_Timer <= diff)
        {
            DoCast(me, SPELL_ATTRACTMAGIC);
            Attractmagic_Timer = 30000;
            Carnivorousbite_Timer = 1500;
        } else Attractmagic_Timer -= diff;

        //Carnivorousbite_Timer
        if (Carnivorousbite_Timer <= diff)
        {
            DoCast(me, SPELL_CARNIVOROUSBITE);
            Carnivorousbite_Timer = 10000;
        } else Carnivorousbite_Timer -= diff;

        //FocusFire_Timer
        if (FocusFire_Timer <= diff)
        {
            // Summon Focus Fire & Emote
            Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
            if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive())
            {
                focusedTarget = pTarget;
                me->SummonCreature(ENTRY_FOCUS_FIRE, pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN, 5500);

                // Emote
                std::string *emote = new std::string(EMOTE_FOCUSES_ON);
                emote->append(pTarget->GetName());
                emote->append("!");
                const char* text = emote->c_str();
                me->MonsterTextEmote(text, 0, true);
                delete emote;
            }
            FocusFire_Timer = 15000+(rand()%5000);
        } else FocusFire_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Пример #15
0
void instance_blackwing_lair::Update(uint32 uiDiff)
{
	//IN_PROGRESS = Razorgore Phase 1
    if (GetData(TYPE_RAZORGORE) == IN_PROGRESS)
    {
        if (m_uiRazorgoreSummonTimer <= uiDiff)
        {
            if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE))
            {
                for (uint32 i = 0; i < 8; i++)
                {
                    /* SPAWNS BY VALUE
                     * ===========
                     * 0         = nothing
                     * 1 - 3     = orc
                     * 4         = dragon
                     */
                     
                    uint8 orcCount = 0;
                    if (m_uiOrcSummoned < MAX_BLACKWING_ORC)
                        orcCount = 3;

                    uint8 dragonCount = 0;
                    if (m_uiDragonkinSummoned < MAX_BLACKWING_DRAGONKIN)
                        dragonCount = 1;

                    if (orcCount || dragonCount)
                    {
                        uint32 spawnType = urand(1, orcCount + dragonCount);
                        if (!orcCount)
                            spawnType = 4;
                   
                         Creature* spawnedOrcs	 = 0;
						 Creature* spawnedDragon = 0;

						if (spawnType < 4)
                        {
                            ++m_uiOrcSummoned;
							spawnedOrcs = pRazorgore->SummonCreature(urand(0, 1) ? NPC_BLACKWING_LEGIONNAIRE : NPC_BLACKWING_MAGE, Corner[i].x,
                                    Corner[i].y, Corner[i].z, Corner[i].o, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);                 
                        }
						else
                        {
							++m_uiDragonkinSummoned;
							spawnedDragon = pRazorgore->SummonCreature(NPC_DEATH_TALON_DRAGONSPAWN, Corner[i].x, Corner[i].y, Corner[i].z, Corner[i].o,
								TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 10000);
                        }

                        //All adds have initial aggro on the Razorgore controller. The mage types will run to the center of the room and start to attack the controller with their ranged fireballs
                        Unit* pController = pRazorgore->GetCharmerOrOwner();
						if (spawnedOrcs)
                        {
							razorgoreAdds.push_back(spawnedOrcs);

                            if (pController && pController->isAlive())
								spawnedOrcs->AI()->AttackStart(pController);
							else
							{
								if (Unit* pTarget = spawnedOrcs->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
									spawnedOrcs->AI()->AttackStart(pTarget);
							}
                        }
						if (spawnedDragon)
						{
							razorgoreAdds.push_back(spawnedDragon);

							if (pRazorgore->isAlive())
							{
								spawnedDragon->AI()->AttackStart(pRazorgore);
								spawnedDragon->AddThreat(pRazorgore, 100.0f);
							}
							else
							{
								if (Unit* pTarget = spawnedDragon->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
									spawnedDragon->AI()->AttackStart(pTarget);
							}
						}
                    }
                }
            }

            m_uiRazorgoreSummonTimer = TIMER_NEXT_ADD_SPAWN;
        }
        else
            m_uiRazorgoreSummonTimer -= uiDiff;
    }

	/*if (GetData(TYPE_RAZORGORE) == DONE)
	{
		HandleGameObject(GO_PORTCULLIS_RAZORGORE, true);

		for(auto& creature : m_lBlackwingGuardsman)
		{
			if (Creature* guardsman = instance->GetCreature(creature))
				guardsman->ForcedDespawn();
		}

		if (Creature* grethok = GetSingleCreatureFromStorage(NPC_GRETHOK_THE_CONTROLLER))
			grethok->ForcedDespawn();	
	}*/

    if (m_uiChromaggusPullTimer)
    {
        if (m_uiChromaggusPullTimer <= uiDiff)
        {
            if (Creature* pChromaggus = GetSingleCreatureFromStorage(NPC_CHROMAGGUS))
            {
                pChromaggus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
				pChromaggus->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                pChromaggus->SetInCombatWithZone();
            }
            m_uiChromaggusPullTimer = 0;
        }
        else
            m_uiChromaggusPullTimer -= uiDiff;
    }

	if (m_uiGuardsmanManager && !m_uiGuardsmanManager)
	{
		if (m_uiGuardsmanManagerTimer <= uiDiff)
		{
			for (auto& creature : m_lBlackwingGuardsman)
			{
				if (Creature* pGuardsmans = instance->GetCreature(creature))
				{
					if (pGuardsmans->isDead() && GetData(TYPE_RAZORGORE) != DONE && GetData(TYPE_RAZORGORE) != SPECIAL && GetData(TYPE_RAZORGORE) != IN_PROGRESS && GetData(TYPE_RAZORGORE) != FAIL)
						pGuardsmans->Respawn();

					m_uiGuardsmanManager = false;
				}
			}
			m_uiGuardsmanManagerTimer = 30000;
		}
		else
			m_uiGuardsmanManagerTimer -= uiDiff;
	}

	if (m_uiGrethokManager && !m_uiGrethokManager)
	{
		if (m_uiGrethokManagerTimer <= uiDiff)
		{
			if (Creature* pGrethok = GetSingleCreatureFromStorage(NPC_GRETHOK_THE_CONTROLLER))
			{
				if (pGrethok->isDead() && GetData(TYPE_RAZORGORE) != DONE && GetData(TYPE_RAZORGORE) != SPECIAL && GetData(TYPE_RAZORGORE) != IN_PROGRESS && GetData(TYPE_RAZORGORE) != FAIL)
					pGrethok->Respawn();

				m_uiGrethokManager = false;
			}
			m_uiGrethokManagerTimer = 30000;
		}
		else
			m_uiGrethokManagerTimer -= uiDiff;
	}

	if (m_uiRazorgorManager)
	{
		if (m_uiRazorgorManagerTimer <= uiDiff)
		{
			if (Creature* pRazorgore = GetSingleCreatureFromStorage(NPC_RAZORGORE))
			{
				if (pRazorgore->isDead() && GetData(TYPE_RAZORGORE) != DONE)
					SetData(TYPE_RAZORGORE, DONE);

				m_uiRazorgorManager = false;
			}
			m_uiRazorgorManagerTimer = 30000;
		}
		else
			m_uiRazorgorManagerTimer -= uiDiff;
	}

	if (m_uiVealManager)
	{
		if (m_uiVealManagerTimer <= uiDiff)
		{
			if (Creature* pVeal = GetSingleCreatureFromStorage(NPC_VAELASTRASZ))
			{
				if (pVeal->isDead() && GetData(TYPE_VAELASTRASZ) != DONE)
					SetData(TYPE_VAELASTRASZ, DONE);

				m_uiVealManager = false;
			}
			m_uiVealManagerTimer = 30000;
		}
		else
			m_uiVealManagerTimer -= uiDiff;
	}

	/*if (m_uiLashLayerManager)
	{
		if (m_uiLashLayerManagerTimer <= uiDiff)
		{
			if (Creature* pLash = GetSingleCreatureFromStorage(NPC_LASHLAYER))
			{
				if (pLash->isDead() && GetData(TYPE_LASHLAYER) != DONE)
					SetData(TYPE_LASHLAYER, DONE);

				m_uiLashLayerManager = false;
			}
			m_uiLashLayerManagerTimer = 30000;
		}
		else
			m_uiLashLayerManagerTimer -= uiDiff;
	}*/

	if (m_uiChromaggusManager)
	{
		if (m_uiChromaggusManagerTimer <= uiDiff)
		{
			if (Creature* pChromaggus = GetSingleCreatureFromStorage(NPC_CHROMAGGUS))
			{
				if (pChromaggus->isDead() && GetData(TYPE_CHROMAGGUS) != DONE)
					SetData(TYPE_CHROMAGGUS, DONE);

				m_uiChromaggusManager = false;
			}
			m_uiChromaggusManagerTimer = 30000;
		}
		else
			m_uiChromaggusManagerTimer -= uiDiff;
	}
Пример #16
0
 void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
 {
     Unit* caster = GetCaster();
     if (caster && caster->isAlive() && GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH)
         caster->CastSpell(caster, SPELL_LEECH_POISON_PCT, true);
 }
Пример #17
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (StormCount)
            {
                Unit* target = Unit::GetUnit(*me, CloudGUID);
                if (!target || !target->isAlive())
                {
                    EnterEvadeMode();
                    return;
                }
                else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID))
                    Cyclone->CastSpell(target, 25160, true); // keep casting or...

                if (StormSequenceTimer <= diff)
                    HandleStormSequence(target);
                else
                    StormSequenceTimer -= diff;

                return;
            }

            if (Enrage_Timer <= diff)
            {
                me->MonsterYell(SAY_ONENRAGE, LANG_UNIVERSAL, 0);
                DoPlaySoundToSet(me, SOUND_ONENRAGE);
                DoCast(me, SPELL_BERSERK, true);
                Enrage_Timer = 600000;
            } else Enrage_Timer -= diff;

            if (StaticDisruption_Timer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (!target) target = me->getVictim();
                TargetGUID = target->GetGUID();
                DoCast(target, SPELL_STATIC_DISRUPTION, false);
                me->SetInFront(me->getVictim());
                StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s

                /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f;
                SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/
            } else StaticDisruption_Timer -= diff;

            if (GustOfWind_Timer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (!target) target = me->getVictim();
                DoCast(target, SPELL_GUST_OF_WIND);
                GustOfWind_Timer = urand(20, 30) * 1000; //20 to 30 seconds(bosskillers)
            } else GustOfWind_Timer -= diff;

            if (CallLighting_Timer <= diff)
            {
                DoCast(me->getVictim(), SPELL_CALL_LIGHTNING);
                CallLighting_Timer = urand(12, 17) * 1000; //totaly random timer. can't find any info on this
            } else CallLighting_Timer -= diff;

            if (!isRaining && ElectricalStorm_Timer < uint32(8000 + rand() % 5000))
            {
                SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f);
                isRaining = true;
            }

            if (ElectricalStorm_Timer <= diff) {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true);
                if (!target)
                {
                    EnterEvadeMode();
                    return;
                }
                target->CastSpell(target, 44007, true);//cloud visual
                DoCast(target, SPELL_ELECTRICAL_STORM, false);//storm cyclon + visual
                float x, y, z;
                target->GetPosition(x, y, z);
                if (target)
                {
                    target->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
                    target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0);
                }
                Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000);
                if (Cloud)
                {
                    CloudGUID = Cloud->GetGUID();
                    Cloud->SetUnitMovementFlags(MOVEMENTFLAG_LEVITATING);
                    Cloud->StopMoving();
                    Cloud->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
                    Cloud->setFaction(35);
                    Cloud->SetMaxHealth(9999999);
                    Cloud->SetHealth(9999999);
                    Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                }
                ElectricalStorm_Timer = 60000; //60 seconds(bosskillers)
                StormCount = 1;
                StormSequenceTimer = 0;
            } else ElectricalStorm_Timer -= diff;

            if (SummonEagles_Timer <= diff)
            {
                me->MonsterYell(SAY_ONSUMMON, LANG_UNIVERSAL, 0);
                DoPlaySoundToSet(me, SOUND_ONSUMMON);

                float x, y, z;
                me->GetPosition(x, y, z);

                for (uint8 i = 0; i < 8; ++i)
                {
                    Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]);
                    if (!bird) //they despawned on die
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                        {
                            x = target->GetPositionX() + irand(-10, 10);
                            y = target->GetPositionY() + irand(-10, 10);
                            z = target->GetPositionZ() + urand(16, 20);
                            if (z > 95)
                                z = 95.0f - urand(0, 5);
                        }
                        Creature* creature = me->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0);
                        if (creature)
                        {
                            creature->AddThreat(me->getVictim(), 1.0f);
                            creature->AI()->AttackStart(me->getVictim());
                            BirdGUIDs[i] = creature->GetGUID();
                        }
                    }
                }
                SummonEagles_Timer = 999999;
            } else SummonEagles_Timer -= diff;

            DoMeleeAttackIfReady();
        }
Пример #18
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

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

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

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

                // If below 10% mana, start recharging
                maxPowerMana = me->GetMaxPower(POWER_MANA);
                if (maxPowerMana && ((me->GetPower(POWER_MANA)*100 / maxPowerMana) < 10))
                {
                    if (DrainCrystalTimer <= diff)
                    {
                        SelectNearestCrystal();
                        if (IsHeroic())
                            DrainCrystalTimer = urand(10000, 15000);
                        else
                            DrainCrystalTimer = urand(20000, 25000);
                    }
                    else DrainCrystalTimer -= diff;
                }
            }
            else
            {
                if (IsDraining)
                {
                    if (EmpowerTimer <= diff)
                    {
                        IsDraining = false;
                        DrainingCrystal = false;

                        DoScriptText(SAY_EMPOWERED, me);

                        Unit* CrystalChosen = Unit::GetUnit(*me, CrystalGUID);
                        if (CrystalChosen && CrystalChosen->isAlive())
                            // Use Deal Damage to kill it, not setDeathState.
                            CrystalChosen->Kill(CrystalChosen);

                        CrystalGUID = 0;

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

            DoMeleeAttackIfReady();                             // No need to check if we are draining crystal here, as the spell has a stun.
        }
Пример #19
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*> m_threatlist = me->getThreatManager().getThreatList();
                        m_threatlist.resize(RAID_MODE(2,3));  // Picks 2 (3) highest threat targets as Hateful Strike candidates
                        std::list<HostileReference*>::const_iterator i = m_threatlist.begin();

                        for (; i != me->getThreatManager().getThreatList().end(); ++i)
                        {
                            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);

                        /// 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();
        }
Пример #20
0
        void UpdateAI(const uint32 diff)
        {
            if (Intro && !Done)
            {
                if (AggroTimer <= diff)
                {
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    DoScriptText(SAY_AGGRO, me);
                    me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
                    Done = true;
                    if (AggroTargetGUID)
                    {
                        Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID);
                        if (pUnit)
                            AttackStart(pUnit);

                        DoZoneInCombat();
                    }
                    else
                    {
                        EnterEvadeMode();
                        return;
                    }
                } else AggroTimer -= diff;
            }

            if (!UpdateVictim() || !Done)
                return;

            if (SummonShadowsTimer <= diff)
            {
                //MindControlGhost();

                for (uint8 i = 0; i < 2; ++i)
                {
                    Creature* Shadow = NULL;
                    float X = CalculateRandomLocation(me->GetPositionX(), 10);
                    Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
                    if (Shadow)
                    {
                        Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                        if (!target)
                            target = me->getVictim();

                        if (target)
                            Shadow->AI()->AttackStart(target);
                    }
                }
                SummonShadowsTimer = 60000;
            } else SummonShadowsTimer -= diff;

            if (SummonDoomBlossomTimer <= diff)
            {
                if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
                {
                    float X = CalculateRandomLocation(target->GetPositionX(), 20);
                    float Y = CalculateRandomLocation(target->GetPositionY(), 20);
                    float Z = target->GetPositionZ();
                    Z = me->GetMap()->GetHeight(X, Y, Z);
                    Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
                    if (DoomBlossom)
                    {
                        DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                        DoomBlossom->setFaction(me->getFaction());
                        DoomBlossom->AddThreat(target, 1.0f);
                        CAST_AI(mob_doom_blossom::mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID());
                        target->CombatStart(DoomBlossom);
                        SetThreatList(DoomBlossom);
                        SummonDoomBlossomTimer = 35000;
                    }
                }
            } else SummonDoomBlossomTimer -= diff;

            if (IncinerateTimer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1);
                if (!target)
                    target = me->getVictim();

                if (target)
                {
                    DoScriptText(RAND(SAY_SPECIAL1, SAY_SPECIAL2), me);
                    DoCast(target, SPELL_INCINERATE);
                    IncinerateTimer = 20000 + rand()%31 * 1000;
                }
            } else IncinerateTimer -= diff;

            if (CrushingShadowsTimer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                if (target && target->isAlive())
                    DoCast(target, SPELL_CRUSHING_SHADOWS);
                CrushingShadowsTimer = 10000 + rand()%16 * 1000;
            } else CrushingShadowsTimer -= diff;

            /*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
            /*if (ShadowOfDeathTimer <= diff)
            {
                Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 1);

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

                if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER)
                {
                    DoCast(target, SPELL_SHADOW_OF_DEATH);
                    GhostGUID = target->GetGUID();
                    ShadowOfDeathTimer = 30000;
                    SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
                }
            } else ShadowOfDeathTimer -= diff;*/

            if (RandomYellTimer <= diff)
            {
                DoScriptText(RAND(SAY_SPELL1, SAY_SPELL2), me);
                RandomYellTimer = 50000 + rand()%51 * 1000;
            } else RandomYellTimer -= diff;

            if (!me->HasAura(SPELL_BERSERK))
            {
                if (EnrageTimer <= diff)
            {
                DoCast(me, SPELL_BERSERK);
                DoScriptText(SAY_ENRAGE, me);
            } else EnrageTimer -= diff;
            }

            DoMeleeAttackIfReady();
        }
    void UpdateAI(const uint32 diff)
    {
        //Only if not incombat check if the event is started
        if (!me->isInCombat() && pInstance && pInstance->GetData(DATA_KARATHRESSEVENT))
        {
            Unit* pTarget = Unit::GetUnit((*me), pInstance->GetData64(DATA_KARATHRESSEVENT_STARTER));

            if (pTarget)
            {
                AttackStart(pTarget);
            }
        }

        //Return since we have no target
        if (!UpdateVictim())
            return;

        //someone evaded!
        if (pInstance && !pInstance->GetData(DATA_KARATHRESSEVENT))
        {
            EnterEvadeMode();
            return;
        }

        //WaterBoltVolley_Timer
        if (WaterBoltVolley_Timer <= diff)
        {
            DoCast(me->getVictim(), SPELL_WATER_BOLT_VOLLEY);
            WaterBoltVolley_Timer = 30000;
        } else WaterBoltVolley_Timer -= diff;

        //TidalSurge_Timer
        if (TidalSurge_Timer <= diff)
        {
            DoCast(me->getVictim(), SPELL_TIDAL_SURGE);
            // Hacky way to do it - won't trigger elseways
            me->getVictim()->CastSpell(me->getVictim(), SPELL_TIDAL_SURGE_FREEZE, true);
            TidalSurge_Timer = 15000+rand()%5000;
        } else TidalSurge_Timer -= diff;

        //Cyclone_Timer
        if (Cyclone_Timer <= diff)
        {
            //DoCast(me, SPELL_SUMMON_CYCLONE); // Doesn't work
            Cyclone_Timer = 30000+rand()%10000;
            Creature* Cyclone = me->SummonCreature(CREATURE_CYCLONE, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), float(rand()%5), TEMPSUMMON_TIMED_DESPAWN, 15000);
            if (Cyclone)
            {
                CAST_CRE(Cyclone)->SetFloatValue(OBJECT_FIELD_SCALE_X, 3.0f);
                Cyclone->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                Cyclone->setFaction(me->getFaction());
                Cyclone->CastSpell(Cyclone, SPELL_CYCLONE_CYCLONE, true);
                Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
                if (pTarget)
                {
                    Cyclone->AI()->AttackStart(pTarget);
                }
            }
        } else Cyclone_Timer -= diff;

        //Heal_Timer
        if (Heal_Timer <= diff)
        {
            // It can be cast on any of the mobs
            Unit* pUnit = NULL;

            while (pUnit == NULL || !pUnit->isAlive())
            {
                pUnit = selectAdvisorUnit();
            }

            if (pUnit && pUnit->isAlive())
                DoCast(pUnit, SPELL_HEAL);
            Heal_Timer = 60000;
        } else Heal_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Пример #22
0
        void UpdateAI(const uint32 diff)
        {
            if (!UpdateVictim())
                return;

            if (HealthBelowPct(10) && !Enraged)
            {
                Enraged = true;
                DoCast(me, SPELL_ENRAGE, true);
                DoScriptText(SAY_ENRAGE, me);
            }

            //Randomly cast one beam.
            if (BeamTimer <= diff)
            {
                Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0);
                if (!target || !target->isAlive())
                    return;

                BeamTimer = 9000;

                switch (CurrentBeam)
                {
                    case 0:
                        DoCast(target, SPELL_BEAM_SINISTER);
                        break;
                    case 1:
                        DoCast(target, SPELL_BEAM_VILE);
                        break;
                    case 2:
                        DoCast(target, SPELL_BEAM_WICKED);
                        break;
                    case 3:
                        DoCast(target, SPELL_BEAM_SINFUL);
                        break;
                }
                ++BeamCount;
                uint32 Beam = CurrentBeam;
                if (BeamCount > 3)
                    while (CurrentBeam == Beam)
                        CurrentBeam = rand()%3;
            } else BeamTimer -= diff;

            // Random Prismatic Shield every 15 seconds.
            if (PrismaticShieldTimer <= diff)
            {
                uint32 random = rand()%6;
                if (PrismaticAuras[random])
                    DoCast(me, PrismaticAuras[random]);
                PrismaticShieldTimer = 15000;
            } else PrismaticShieldTimer -= diff;

            // Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other.
            if (FatalAttractionTimer <= diff)
            {
                ExplosionCount = 0;

                TeleportPlayers();

                DoScriptText(RAND(SAY_SPELL2, SAY_SPELL3), me);
                FatalAttractionExplodeTimer = 2000;
                FatalAttractionTimer = urand(40, 71) * 1000;
            } else FatalAttractionTimer -= diff;

            if (FatalAttractionExplodeTimer <= diff)
            {
                // Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later.
                if (ExplosionCount < 3)
                {
                    for (uint8 i = 0; i < 3; ++i)
                    {
                        Unit* unit = NULL;
                        if (TargetGUID[i])
                        {
                            unit = Unit::GetUnit((*me), TargetGUID[i]);
                            if (unit)
                                unit->CastSpell(unit, SPELL_ATTRACTION, true);
                            TargetGUID[i] = 0;
                        }
                    }

                    ++ExplosionCount;
                    FatalAttractionExplodeTimer = 1000;
                }
                else
                {
                    FatalAttractionExplodeTimer = FatalAttractionTimer + 2000;
                    ExplosionCount = 0;
                }
            } else FatalAttractionExplodeTimer -= diff;

            if (ShriekTimer <= diff)
            {
                DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK);
                ShriekTimer = 25000+rand()%10 * 1000;
            } else ShriekTimer -= diff;

            if (SaberTimer <= diff)
            {
                DoCast(me->getVictim(), SPELL_SABER_LASH);
                SaberTimer = 25000+rand()%10 * 1000;
            } else SaberTimer -= diff;

            //Enrage
            if (!me->HasAura(SPELL_BERSERK))
            {
                if (EnrageTimer <= diff)
                {
                    DoCast(me, SPELL_BERSERK);
                    DoScriptText(SAY_ENRAGE, me);
                } else EnrageTimer -= diff;
            }

            //Random taunts
            if (RandomYellTimer <= diff)
            {
                DoScriptText(RAND(SAY_TAUNT1, SAY_TAUNT2, SAY_TAUNT3), me);
                RandomYellTimer = urand(60, 151) * 1000;
            } else RandomYellTimer -= diff;

            DoMeleeAttackIfReady();
        }
Пример #23
0
    void UpdateAI(const uint32 diff)
    {
        if (!CanDoSomething())
            return;

        if (pInstance && !pInstance->GetData(TYPE_MOROES))
            EnterEvadeMode();

        if (!Enrage && me->GetHealth()*100 / me->GetMaxHealth() < 30)
        {
            DoCastMe( SPELL_FRENZY);
            Enrage = true;
        }

        if (CheckAdds_Timer < diff)
        {
            for (uint8 i = 0; i < 4; ++i)
            {
                Unit* Temp = NULL;
                if (AddGUID[i])
                {
                    Temp = Unit::GetUnit((*me),AddGUID[i]);
                    if (Temp && Temp->isAlive())
                        if (!Temp->SelectHostileTarget() || !Temp->getVictim())
                            ((Creature*)Temp)->AI()->AttackStart(me->getVictim());
                }
            }
            CheckAdds_Timer = 5000;
        } else CheckAdds_Timer -= diff;

        if (!Enrage)
        {
            //Cast Vanish, then Garrote random victim
            if (Vanish_Timer < diff)
            {
                me->setFaction(35);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                DoCastMe( SPELL_VANISH);
                InVanish = true;
                Vanish_Timer = 30000;
                Wait_Timer = 5000;
            } else Vanish_Timer -= diff;

            if (InVanish)
            {
                if (Wait_Timer < diff)
                {
                    DoScriptText(urand(0, 1) ? SAY_SPECIAL_1 : SAY_SPECIAL_2, me);

                    if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                        target->CastSpell(target, SPELL_GARROTE, true);

                    me->setFaction(16);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
                    me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                    me->AI()->AttackStart(me->getVictim());
                    InVanish = false;
                } else Wait_Timer -= diff;
            }

            //Gouge highest aggro, and attack second highest
            if (Gouge_Timer < diff)
            {
                DoCastVictim( SPELL_GOUGE);
                Gouge_Timer = 40000;
            } else Gouge_Timer -= diff;

            if (Blind_Timer < diff)
            {
                Unit* target = NULL;
                std::list<HostileReference*> t_list = me->getThreatManager().getThreatList();

                if (t_list.empty())
                    return;

                std::vector<Unit*> target_list;
                for (ThreatList::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                {
                    target = Unit::GetUnit(*me, (*itr)->getUnitGuid());
                    if (target && target->IsWithinDist(me, ATTACK_DISTANCE, false))
                        target_list.push_back(target);
                }
                if (target_list.size())
                    target = *(target_list.begin()+rand()%target_list.size());

                if (target)
                    DoCast(target, SPELL_BLIND);

                Blind_Timer = 40000;
            } else Blind_Timer -= diff;
        }

        if (!InVanish)
            DoMeleeAttackIfReady();
    }
Пример #24
0
    void UpdateAI(const uint32 diff)
    {
        if(Intro == INTRO_IN_PROGRESS)
        {
            if(AggroTimer < diff)
            {
                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                m_creature->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
                Intro = INTRO_DONE;
            }
            else
                AggroTimer -= diff;
        }

        if(!UpdateVictim() || Intro == INTRO_IN_PROGRESS)
            return;

        if (CheckTimer < diff)
        {
            if(!m_creature->IsWithinDistInMap(&wLoc, 90))
                EnterEvadeMode();
            else
                DoZoneInCombat();

            m_creature->SetSpeed(MOVE_RUN, 2.5);

            CheckTimer = 1500;
        }
        else
            CheckTimer -= diff;

        if(SummonDoomBlossomTimer < diff)
        {
            AddSpellToCast(m_creature, 40188);
            SummonDoomBlossomTimer = 25000+rand()%15000;
        }
        else
            SummonDoomBlossomTimer -= diff;

        if(IncinerateTimer < diff)
        {
            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 200, true, m_creature->getVictimGUID());
            if(!target)
                target = m_creature->getVictim();

            if(target)
            {
                AddSpellToCastWithScriptText(target, SPELL_INCINERATE, RAND(SAY_SPECIAL1, SAY_SPECIAL2));
                IncinerateTimer = urand(5000, 40000);
            }
        }
        else
            IncinerateTimer -= diff;

        if(CrushingShadowsTimer < diff)
        {
            AddSpellToCastWithScriptText(m_creature, SPELL_CRUSHING_SHADOWS, SAY_SPELL3);
            CrushingShadowsTimer = urand(17000, 42000);
        }
        else
            CrushingShadowsTimer -= diff;


        if(ShadowOfDeathTimer < diff)
        {
            Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, 100, true, m_creature->getVictimGUID());

            if(target && target->isAlive() && !target->HasAura(SPELL_SHADOW_OF_DEATH, 0) && !target->HasAura(40282, 0) )
            {
                AddSpellToCast(target, SPELL_SHADOW_OF_DEATH, false, true);
                ShadowOfDeathTimer = 30000;
            }
        }
        else
            ShadowOfDeathTimer -= diff;

        if(RandomYellTimer < diff)
        {
            DoScriptText(RAND(SAY_SPELL1, SAY_SPELL2), m_creature);
            RandomYellTimer = 50000 + rand()%51000;
        }
        else
            RandomYellTimer -= diff;

        if(!m_creature->HasAura(SPELL_BERSERK, 0))
        {
            if(EnrageTimer < diff)
            {
                AddSpellToCastWithScriptText(m_creature, SPELL_BERSERK, SAY_ENRAGE);
            }
            else
                EnrageTimer -= diff;
        }

        CastNextSpellIfAnyAndReady();
        DoMeleeAttackIfReady();
    }
Пример #25
0
    void UpdateFollowerAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
        {
            if (HasFollowState(STATE_FOLLOW_POSTEVENT))
            {
                if (m_uiEndEventTimer < uiDiff)
                {
                    if (!pSpraggle || !pSpraggle->isAlive())
                    {
                        SetFollowComplete();
                        return;
                    }

                    switch (m_uiEndEventProgress)
                    {
                        case 1:
                            DoScriptText(SAY_RIN_END_1, m_creature);
                            m_uiEndEventTimer = 3000;
                            break;
                        case 2:
                            DoScriptText(SAY_SPR_END_2, pSpraggle);
                            m_uiEndEventTimer = 5000;
                            break;
                        case 3:
                            DoScriptText(SAY_RIN_END_3, m_creature);
                            m_uiEndEventTimer = 1000;
                            break;
                        case 4:
                            DoScriptText(EMOTE_RIN_END_4, m_creature);
                            SetFaint();
                            m_uiEndEventTimer = 9000;
                            break;
                        case 5:
                            DoScriptText(EMOTE_RIN_END_5, m_creature);
                            ClearFaint();
                            m_uiEndEventTimer = 1000;
                            break;
                        case 6:
                            DoScriptText(SAY_RIN_END_6, m_creature);
                            m_uiEndEventTimer = 3000;
                            break;
                        case 7:
                            DoScriptText(SAY_SPR_END_7, pSpraggle);
                            m_uiEndEventTimer = 10000;
                            break;
                        case 8:
                            DoScriptText(EMOTE_RIN_END_8, m_creature);
                            m_uiEndEventTimer = 5000;
                            break;
                        case 9:
                            SetFollowComplete();
                            break;
                    }

                    ++m_uiEndEventProgress;
                }
                else
                    m_uiEndEventTimer -= uiDiff;
            }
            else if (HasFollowState(STATE_FOLLOW_INPROGRESS))
            {
                if (!HasFollowState(STATE_FOLLOW_PAUSED))
                {
                    if (m_uiFaintTimer < uiDiff)
                    {
                        SetFaint();
                        m_uiFaintTimer = urand(60000, 120000);
                    }
                    else
                        m_uiFaintTimer -= uiDiff;
                }
            }

            return;
        }

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

        //Only do this if we haven't spawned nef yet
        if (SpawnedAdds < 42)
        {
            //ShadowBoltTimer
            if (ShadowBoltTimer <= diff)
            {
                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    DoCast(pTarget, SPELL_SHADOWBOLT);

                ShadowBoltTimer = urand(3000,10000);
            } else ShadowBoltTimer -= diff;

            //FearTimer
            if (FearTimer <= diff)
            {
                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    DoCast(pTarget, SPELL_FEAR);

                FearTimer = 10000 + (rand()%10000);
            } else FearTimer -= diff;

            //Add spawning mechanism
            if (AddSpawnTimer <= diff)
            {
                //Spawn 2 random types of creatures at the 2 locations
                uint32 CreatureID;
                Creature* Spawned = NULL;
                Unit* pTarget = NULL;

                //1 in 3 chance it will be a chromatic
                if (urand(0,2) == 0)
                    CreatureID = CREATURE_CHROMATIC_DRAKANOID;
                else
                    CreatureID = DrakType1;

                ++SpawnedAdds;

                //Spawn Creature and force it to start attacking a random target
                Spawned = me->SummonCreature(CreatureID,ADD_X1,ADD_Y1,ADD_Z1,5.000f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
                pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                if (pTarget && Spawned)
                {
                    Spawned->AI()->AttackStart(pTarget);
                    Spawned->setFaction(103);
                }

                //1 in 3 chance it will be a chromatic
                if (urand(0,2) == 0)
                    CreatureID = CREATURE_CHROMATIC_DRAKANOID;
                else
                    CreatureID = DrakType2;

                ++SpawnedAdds;

                Spawned = me->SummonCreature(CreatureID,ADD_X2,ADD_Y2,ADD_Z2,5.000f,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,5000);
                pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                if (pTarget && Spawned)
                {
                    Spawned->AI()->AttackStart(pTarget);
                    Spawned->setFaction(103);
                }

                //Begin phase 2 by spawning Nefarian and what not
                if (SpawnedAdds >= 42)
                {
                    //Teleport Victor Nefarius way out of the map
                    //MapManager::Instance().GetMap(me->GetMapId(), me)->CreatureRelocation(me,0,0,-5000,0);

                    //Inturrupt any spell casting
                    me->InterruptNonMeleeSpells(false);

                    //Root self
                    DoCast(me, 33356);

                    //Make super invis
                    DoCast(me, 8149);

                    //Teleport self to a hiding spot (this causes errors in the blizzlike log but no real issues)
                    DoTeleportTo(HIDE_X,HIDE_Y,HIDE_Z);
                    me->addUnitState(UNIT_STAT_FLEEING);

                    //Spawn nef and have him attack a random target
                    Creature* Nefarian = me->SummonCreature(CREATURE_NEFARIAN,NEF_X,NEF_Y,NEF_Z,0,TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT,120000);
                    pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true);
                    if (pTarget && Nefarian)
                    {
                        Nefarian->AI()->AttackStart(pTarget);
                        Nefarian->setFaction(103);
                        NefarianGUID = Nefarian->GetGUID();
                    }
                    else error_log("BSCR: Blackwing Lair: Unable to spawn nefarian properly.");
                }

                AddSpawnTimer = 4000;
            } else AddSpawnTimer -= diff;
        }
        else if (NefarianGUID)
        {
            if (NefCheckTime <= diff)
            {
                Unit* Nefarian = Unit::GetCreature((*me),NefarianGUID);

                //If nef is dead then we die to so the players get out of combat
                //and cannot repeat the event
                if (!Nefarian || !Nefarian->isAlive())
                {
                    NefarianGUID = 0;
                    me->ForcedDespawn();
                }

                NefCheckTime = 2000;
            } else NefCheckTime -= diff;
        }
    }
Пример #27
0
        void UpdateFollowerAI(const uint32 diff)
        {
            if(!UpdateVictim())
            {
                //we are doing the post-event, or...
                if(HasFollowState(STATE_FOLLOW_POSTEVENT))
                {
                    if(m_uiPostEventTimer <= diff)
                    {
                        m_uiPostEventTimer = 5000;

                        Unit* pTorta = Unit::GetUnit(*me, TortaGUID);
                        if(!pTorta || !pTorta->isAlive())
                        {
                            //something happened, so just complete
                            SetFollowComplete();
                            return;
                        }

                        switch(m_uiPhasePostEvent)
                        {
                            case 1:
                                DoScriptText(SAY_TOOG_POST_1, me);
                                break;
                            case 2:
                                DoScriptText(SAY_TORT_POST_2, pTorta);
                                break;
                            case 3:
                                DoScriptText(SAY_TOOG_POST_3, me);
                                break;
                            case 4:
                                DoScriptText(SAY_TORT_POST_4, pTorta);
                                break;
                            case 5:
                                DoScriptText(SAY_TOOG_POST_5, me);
                                break;
                            case 6:
                                DoScriptText(SAY_TORT_POST_6, pTorta);
                                me->GetMotionMaster()->MovePoint(POINT_ID_TO_WATER, m_afToWaterLoc[0], m_afToWaterLoc[1], m_afToWaterLoc[2]);
                                break;
                        }

                        ++m_uiPhasePostEvent;
                    }
                    else
                        m_uiPostEventTimer -= diff;
                }
                //...we are doing regular speech check
                else if(HasFollowState(STATE_FOLLOW_INPROGRESS))
                {
                    if(m_uiCheckSpeechTimer <= diff)
                    {
                        m_uiCheckSpeechTimer = 5000;

                        if(urand(0, 9) > 8)
                            DoScriptText(RAND(SAY_TOOG_THIRST, SAY_TOOG_WORRIED), me);
                    }
                    else
                        m_uiCheckSpeechTimer -= diff;
                }

                return;
            }

            DoMeleeAttackIfReady();
        }
Пример #28
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        // Pounding
        if (Pounding_Timer <= diff)
        {
            DoCast(m_creature->getVictim(), SPELL_POUNDING);

            DoScriptText(RAND(SAY_POUNDING1,SAY_POUNDING2), m_creature);
             Pounding_Timer = 15000;                         //cast time(3000) + cooldown time(12000)
        } else Pounding_Timer -= diff;

        // Arcane Orb
        if (ArcaneOrb_Timer <= diff)
        {
            Unit *pTarget = NULL;
            std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
            std::vector<Unit *> target_list;
            for (std::list<HostilReference *>::iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
            {
                pTarget = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                if (!pTarget)
                    continue;

                // exclude pets & totems
                if (pTarget->GetTypeId() != TYPEID_PLAYER)
                    continue;

                //18 yard radius minimum
                if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER && pTarget->isAlive() && !pTarget->IsWithinDist(m_creature, 18, false))
                    target_list.push_back(pTarget);
                pTarget = NULL;
            }

            if (target_list.size())
                pTarget = *(target_list.begin()+rand()%target_list.size());
            else
                pTarget = m_creature->getVictim();

            if (pTarget)
                m_creature->CastSpell(pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(), SPELL_ARCANE_ORB, false, NULL, NULL, NULL, pTarget);

            ArcaneOrb_Timer = 3000;
        } else ArcaneOrb_Timer -= diff;

        // Single Target knock back, reduces aggro
        if (KnockAway_Timer <= diff)
        {
            DoCast(m_creature->getVictim(), SPELL_KNOCK_AWAY);

            //Drop 25% aggro
            if (DoGetThreat(m_creature->getVictim()))
                DoModifyThreatPercent(m_creature->getVictim(),-25);

            KnockAway_Timer = 30000;
        } else KnockAway_Timer -= diff;

        //Berserk
        if (Berserk_Timer < diff && !Enraged)
        {
            DoCast(m_creature, SPELL_BERSERK);
            Enraged = true;
        } else Berserk_Timer -= diff;

        DoMeleeAttackIfReady();

        EnterEvadeIfOutOfCombatArea(diff);
    }
Пример #29
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Mortal Wound
        if (m_uiMortalWoundTimer < uiDiff)
        {
            DoCast(m_creature->getVictim(), SPELL_MORTALWOUND);
            m_uiMortalWoundTimer = 10000;
        }
        else
            m_uiMortalWoundTimer -= uiDiff;

         //Decimate_Timer
        if (m_uiDecimateTimer < uiDiff)
        {
            DoCast(m_creature->getVictim(),SPELL_DECIMATE); // need core support

            // workaround below
            std::list<HostileReference*> t_list = m_creature->getThreatManager().getThreatList();
            if (t_list.size())
            {
                //begin + 1 , so we don't target the one with the highest threat
                std::list<HostileReference*>::iterator itr = t_list.begin();
                std::advance(itr, 1);
                for(; itr!= t_list.end(); ++itr)
                {
                    Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                    if (target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER &&
                        (target->GetHealth() > target->GetMaxHealth() * 0.05))
                        target->SetHealth(target->GetMaxHealth() * 0.05);
                }
            }
            // Move Zombies
            if (!m_lZombieGUIDList.empty())
            {
                for(std::list<uint64>::iterator itr = m_lZombieGUIDList.begin(); itr != m_lZombieGUIDList.end(); ++itr)
                    if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
                        if (pTemp->isAlive())
                        {
                            ((mob_zombie_chowsAI*)pTemp->AI())->bIsForceMove = true;
                            if (m_creature->GetHealth() > m_creature->GetMaxHealth() * 0.05) // remove when SPELL_DECIMATE is working
                                pTemp->SetHealth(pTemp->GetMaxHealth() * 0.02);
                            pTemp->AddThreat(m_creature, 1000000000.0f); // force move toward to Gluth
                        }
            }
            m_uiDecimateTimer = (m_bIsRegularMode ? 100000 : 120000);
        }else m_uiDecimateTimer -= uiDiff;

        // Enrage
        if (m_uiEnrageTimer < uiDiff)
        {
            DoCast(m_creature, m_bIsRegularMode ? SPELL_ENRAGE : SPELL_ENRAGE_H);
            m_uiEnrageTimer = 60000;
        }
        else m_uiEnrageTimer -= uiDiff;

        if (RangeCheck_Timer < uiDiff)
        {
            if (!m_lZombieGUIDList.empty())
            {
                for(std::list<uint64>::iterator itr = m_lZombieGUIDList.begin(); itr != m_lZombieGUIDList.end(); ++itr)
                    if (Creature* pTemp = (Creature*)Unit::GetUnit(*m_creature, *itr))
                        if (pTemp->isAlive() && m_creature->IsWithinDistInMap(pTemp, ATTACK_DISTANCE))
                        {
                            DoScriptText(EMOTE_ZOMBIE, m_creature);
                            m_creature->SetHealth(m_creature->GetHealth() + m_creature->GetMaxHealth() * 0.05);
                            pTemp->ForcedDespawn();
                        }
            }
            RangeCheck_Timer = 1000;
        }else RangeCheck_Timer -= uiDiff;

        //Summon_Timer
        if (Summon_Timer < uiDiff)
        {
            for(uint8 i = 0; i < (m_bIsRegularMode ? 1 : 2); i++)
            {
                if (Creature* pZombie = m_creature->SummonCreature(NPC_ZOMBIE_CHOW,ADD_1X,ADD_1Y,ADD_1Z,0,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,80000))
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        pZombie->AddThreat(pTarget);
                        m_lZombieGUIDList.push_back(pZombie->GetGUID());
                    }
                }
            }
            Summon_Timer = 10000;
        } else Summon_Timer -= uiDiff;

        // Berserk
        if (m_uiBerserkTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature, SPELL_BERSERK, CAST_TRIGGERED);
            m_uiBerserkTimer = MINUTE*5*IN_MILLISECONDS;
        }
        else
            m_uiBerserkTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Пример #30
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        switch(m_uiPhase)
        {
            case PHASE_ATTACKING:
                if (m_uiCheckoutMana_Timer <= uiDiff)
                {
                    m_uiCheckoutMana_Timer = 1500;
                    if (m_creature->GetPower(POWER_MANA) * 100 / m_creature->GetMaxPower(POWER_MANA) > 75.0f)
                    {
                        DoCastSpellIfCan(m_creature, SPELL_ENERGIZE);
                        DoScriptText(EMOTE_ENERGIZING, m_creature);
                        m_uiPhase = PHASE_ENERGIZING;
                        return;
                    }
                } 
                else
                    m_uiCheckoutMana_Timer -= uiDiff;

                if (m_uiSummonManaFiends_Timer <= uiDiff)
                {
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_1, CAST_TRIGGERED);
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_2, CAST_TRIGGERED);
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_SUMMON_MANAFIEND_3, CAST_TRIGGERED);
                    m_uiSummonManaFiends_Timer = 90000;
                }
                else
                    m_uiSummonManaFiends_Timer -= uiDiff;

                if (m_uiManaDrain_Timer <= uiDiff)
                {
                    m_uiManaDrain_Timer = urand(2000, 6000);
                    // choose random target with mana
                    std::list<Unit*> lTargets;
                    ThreatList const& threatlist = m_creature->getThreatManager().getThreatList();
                    if (threatlist.empty())
                        return;

                    for (ThreatList::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr)
                    {
                        Unit* pUnit = m_creature->GetMap()->GetUnit((*itr)->getUnitGuid());
                        if (pUnit && pUnit->isAlive() && pUnit->GetPower(POWER_MANA))
                            lTargets.push_back(pUnit);
                    }

                    if (lTargets.empty())
                        return;

                    std::list<Unit*>::iterator itr = lTargets.begin();
                    std::advance(itr, urand(0, lTargets.size()-1));

                    DoCastSpellIfCan(*itr, SPELL_DRAIN_MANA);
                } 
                else
                    m_uiManaDrain_Timer -= uiDiff;

                if (m_uiTrample_Timer <= uiDiff)
                {
                    DoCastSpellIfCan(m_creature->getVictim(), SPELL_TRAMPLE);
                    m_uiTrample_Timer = 15000;
                } 
                else
                    m_uiTrample_Timer -= uiDiff;

                DoMeleeAttackIfReady();
                break;
            case PHASE_ENERGIZING:
                if (m_uiCheckoutMana_Timer <= uiDiff)
                {
                    m_uiCheckoutMana_Timer = 1500;
                    if (m_creature->GetPower(POWER_MANA) == m_creature->GetMaxPower(POWER_MANA))
                    {
                        m_creature->RemoveAurasDueToSpell(SPELL_ENERGIZE);
                        DoCastSpellIfCan(m_creature, SPELL_ARCANE_ERUPTION);
                        DoScriptText(EMOTE_MANA_FULL, m_creature);
                        m_uiPhase = PHASE_ATTACKING;
                        return;
                    }
                } 
                else
                    m_uiCheckoutMana_Timer -= uiDiff;
                break;
        }
    }