Beispiel #1
0
void OPvPWintergrasp::PromotePlayer(Player *killer) const
{
    Aura *aur;
    if (aur = killer->GetAura(SPELL_RECRUIT))
    {
        if (aur->GetStackAmount() >= 5)
        {
            killer->RemoveAura(SPELL_RECRUIT);
            killer->CastSpell(killer, SPELL_CORPORAL, true);
        }
        else
            killer->CastSpell(killer, SPELL_RECRUIT, true);
    }
    else if (aur = killer->GetAura(SPELL_CORPORAL))
    {
        if (aur->GetStackAmount() >= 5)
        {
            killer->RemoveAura(SPELL_CORPORAL);
            killer->CastSpell(killer, SPELL_LIEUTENANT, true);
        }
        else
            killer->CastSpell(killer, SPELL_CORPORAL, true);
    }
    else if (killer->HasAura(SPELL_LIEUTENANT))
        killer->CastSpell(killer, SPELL_LIEUTENANT, true);
}
Beispiel #2
0
void OPvPWintergrasp::HandleKill(Player *killer, Unit *victim)
{
    if(victim->GetTypeId() == TYPEID_PLAYER)
    {
        // We handle promotion here because player should not get promotion if he has buff but do the kill outside the zone
        if(victim->getLevel() >= 70)
        {
            Aura *aur;
            if(aur = killer->GetAura(SPELL_RECRUIT))
            {
                if(aur->GetStackAmount() >= 5)
                {
                    killer->RemoveAura(SPELL_RECRUIT);
                    killer->CastSpell(killer, SPELL_CORPORAL, true);
                }
                else
                    killer->CastSpell(killer, SPELL_RECRUIT, true);
            }
            else if(aur = killer->GetAura(SPELL_CORPORAL))
            {
                if(aur->GetStackAmount() >= 5)
                {
                    killer->RemoveAura(SPELL_CORPORAL);
                    killer->CastSpell(killer, SPELL_LIEUTENANT, true);
                }
                else
                    killer->CastSpell(killer, SPELL_CORPORAL, true);
            }
            else if(killer->HasAura(SPELL_LIEUTENANT))
                killer->CastSpell(killer, SPELL_LIEUTENANT, true);
        }
    }
}
Beispiel #3
0
            void HandleScript(SpellEffIndex /*effIndex*/)
            {
                if (!(GetHitCreature() && GetHitCreature()->IsAlive()))
                    return;

                Aura *unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE);
                if (unstable != NULL)
                {
                    uint8 newStack = uint8(unstable->GetStackAmount()+1);
                    unstable->SetStackAmount(newStack);

                    // explode!
                    if (newStack >= 5)
                    {
                        GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
                        GetCaster()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
                        if (InstanceScript* instance = GetCaster()->GetInstanceScript())
                            if (Creature* rotface = Unit::GetCreature(*GetCaster(), instance->GetData64(DATA_ROTFACE)))
                                if (rotface->IsAlive())
                                {
                                    rotface->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
                                    rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
                                }

                        if (Creature* cre = GetCaster()->ToCreature())
                            cre->AI()->DoAction(EVENT_STICKY_OOZE);
                        GetCaster()->CastSpell(GetCaster(), SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, GetCaster()->GetGUID());
                        if (InstanceScript* instance = GetCaster()->GetInstanceScript())
                            instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false));
                    }
                }

                GetHitCreature()->DespawnOrUnsummon();
            }
        void UpdateAI(uint32 diff) override
        {
            if (!UpdateVictim())
                return;

            if (uiGripOfSladRanTimer <= diff)
            {
                Unit* target = me->GetVictim();

                DoCast(target, SPELL_GRIP_OF_SLAD_RAN);
                uiGripOfSladRanTimer = urand(3, 6)*IN_MILLISECONDS;

                Aura* grip = target->GetAura(SPELL_GRIP_OF_SLAD_RAN, me->GetGUID());
                if (grip && grip->GetStackAmount() == 5)
                {
                    target->RemoveAurasDueToSpell(SPELL_GRIP_OF_SLAD_RAN, me->GetGUID());
                    target->CastSpell(target, SPELL_SNAKE_WRAP, true);

                    if (TempSummon* _me = me->ToTempSummon())
                        if (Unit* summoner = _me->GetSummoner())
                            if (Creature* sladran = summoner->ToCreature())
                                sladran->AI()->SetGUID(target->GetGUID(), DATA_SNAKES_WHYD_IT_HAVE_TO_BE_SNAKES);

                    me->DespawnOrUnsummon();
                }
            } else uiGripOfSladRanTimer -= diff;
        }
Beispiel #5
0
 void HandleRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode)
 {
     PreventDefaultAction();
     Aura* aura = aurEff->GetBase();
     if (aura->GetStackAmount() == 1)
         aura->Remove(AURA_REMOVE_BY_DEFAULT);
     else
         aura->SetStackAmount(GetStackAmount() - 1);
 }
    void UpdateAI(const uint32 diff) 
    {
        if (!UpdateVictim())
            return;

        if (CheckIntenseColdTimer < diff && !MoreThanTwoIntenseCold)
        {
            std::list<HostilReference*> ThreatList = m_creature->getThreatManager().getThreatList();
            for(std::list<HostilReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); itr++)
            {
                Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
                if (!target || target->GetTypeId() != TYPEID_PLAYER)
                    continue;

                Aura *AuraIntenseCold = target->GetAura(SPELL_INTENSE_COLD_TRIGGERED);
                if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2)
                {
                    MoreThanTwoIntenseCold = true;
                    break;
                }
            }
            CheckIntenseColdTimer = 2000;
        }else CheckIntenseColdTimer -= diff;

        if (!Enrage && (m_creature->GetHealth() < m_creature->GetMaxHealth() * 0.25))
        {
            DoScriptText(SAY_ENRAGE , m_creature);
            DoCast(m_creature, SPELL_ENRAGE);
            Enrage = true;
        }

        if (CRYSTALFIRE_BREATH_Timer < diff)
        {
            DoCast(m_creature->getVictim(), HeroicMode ? SPELL_CRYSTALFIRE_BREATH_H : SPELL_CRYSTALFIRE_BREATH_N);
            CRYSTALFIRE_BREATH_Timer = 14000;
        }else CRYSTALFIRE_BREATH_Timer -=diff;

        if (TAIL_SWEEP_Timer < diff)
        {
            DoCast(m_creature, SPELL_TAIL_SWEEP);
            TAIL_SWEEP_Timer = 5000;
        }else TAIL_SWEEP_Timer -=diff;

        if (CRYSTAL_CHAINS_CRYSTALIZE_Timer < diff)
        {
            DoScriptText(SAY_CRYSTAL_NOVA , m_creature);
            if (HeroicMode)
                DoCast(m_creature, SPELL_CRYSTALIZE);
            else
                if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    DoCast(target, SPELL_CRYSTAL_CHAINS);
            CRYSTAL_CHAINS_CRYSTALIZE_Timer = HeroicMode ? 30000 : 11000;
        }else CRYSTAL_CHAINS_CRYSTALIZE_Timer -= diff;

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

			if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold) {
				std::list<HostileReference*> ThreatList =
						me->getThreatManager().getThreatList();
				for (std::list<HostileReference*>::const_iterator itr =
						ThreatList.begin(); itr != ThreatList.end(); ++itr) {
					Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
					if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER)
						continue;

					Aura *AuraIntenseCold = pTarget->GetAura(
							SPELL_INTENSE_COLD_TRIGGERED);
					if (AuraIntenseCold
							&& AuraIntenseCold->GetStackAmount() > 2) {
						bMoreThanTwoIntenseCold = true;
						break;
					}
				}
				uiCheckIntenseColdTimer = 2 * IN_MILLISECONDS;
			} else
				uiCheckIntenseColdTimer -= diff;

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

			if (uiCrystalfireBreathTimer <= diff) {
				DoCast(me->getVictim(), SPELL_CRYSTALFIRE_BREATH);
				uiCrystalfireBreathTimer = 14 * IN_MILLISECONDS;
			} else
				uiCrystalfireBreathTimer -= diff;

			if (uiTailSweepTimer <= diff) {
				DoCast(me, SPELL_TAIL_SWEEP);
				uiTailSweepTimer = 5 * IN_MILLISECONDS;
			} else
				uiTailSweepTimer -= diff;

			if (uiCrystalChainsCrystalizeTimer <= diff) {
				DoScriptText(SAY_CRYSTAL_NOVA, me);
				if (IsHeroic())
					DoCast(me, SPELL_CRYSTALIZE);
				else if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
					DoCast(pTarget, SPELL_CRYSTAL_CHAINS);
				uiCrystalChainsCrystalizeTimer = DUNGEON_MODE(
						30 * IN_MILLISECONDS, 11 * IN_MILLISECONDS);
			} else
				uiCrystalChainsCrystalizeTimer -= diff;

			DoMeleeAttackIfReady();
		}
Beispiel #8
0
		void UpdateAI(const uint32 diff) {
			//Return since we have no target
			if (!UpdateVictim())
				return;

			if (uiSpawnTimer <= diff) {
				uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5));
				for (uint8 i = 0; i < spawnNumber; ++i)
					DoSummon(
							RAND(NPC_DRAKKARI_INVADER_1,
									NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0,
							TEMPSUMMON_DEAD_DESPAWN);
				uiSpawnTimer = urand(30 * IN_MILLISECONDS,
						40 * IN_MILLISECONDS);
			} else
				uiSpawnTimer -= diff;

			if (uiConsumeTimer <= diff) {
				DoScriptText(SAY_CONSUME, me);
				DoCast(SPELL_CONSUME);
				uiConsumeTimer = 15 * IN_MILLISECONDS;
			} else
				uiConsumeTimer -= diff;

			if (bAchiev) {
				Aura *pConsumeAura = me->GetAura(
						DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA));
				if (pConsumeAura && pConsumeAura->GetStackAmount() > 9)
					bAchiev = false;
			}

			if (uiCrushTimer <= diff) {
				DoCastVictim(SPELL_CRUSH);
				uiCrushTimer = urand(10 * IN_MILLISECONDS,
						15 * IN_MILLISECONDS);
			} else
				uiCrushTimer -= diff;

			if (uiInfectedWoundTimer <= diff) {
				DoCastVictim(SPELL_INFECTED_WOUND);
				uiInfectedWoundTimer = urand(25 * IN_MILLISECONDS,
						35 * IN_MILLISECONDS);
			} else
				uiInfectedWoundTimer -= diff;

			if (uiExplodeCorpseTimer <= diff) {
				DoCast(SPELL_CORPSE_EXPLODE);
				DoScriptText(SAY_EXPLODE, me);
				uiExplodeCorpseTimer = urand(15 * IN_MILLISECONDS,
						19 * IN_MILLISECONDS);
			} else
				uiExplodeCorpseTimer -= diff;

			DoMeleeAttackIfReady();
		}
    void UpdateAI(const uint32 diff)
    {
        //Return since we have no target
        if (!UpdateVictim())
            return;

        if (uiSpawnTimer <= diff)
        {
            for (uint8 i = 0; i < urand(2,HEROIC(3,5)); ++i)
                DoSpawnCreature(RAND(NPC_DRAKKARI_INVADER_1,NPC_DRAKKARI_INVADER_2), AddSpawnPoint.GetPositionX(), AddSpawnPoint.GetPositionY(), AddSpawnPoint.GetPositionZ(), AddSpawnPoint.GetOrientation(), TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 90000);
            uiSpawnTimer = urand(30000,40000);
        } else uiSpawnTimer -= diff;

        if (uiConsumeTimer <= diff)
        {
            DoScriptText(SAY_CONSUME, m_creature);
            DoCast(HEROIC(SPELL_CONSUME, H_SPELL_CONSUME));
            uiConsumeTimer = 15000;
        } else uiConsumeTimer -= diff;

        if (bAchiev)
        {
            if (uiAuraCountTimer <= diff)
            {
                if (m_creature->HasAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME)))
                {
                    Aura *pConsumeAura = m_creature->GetAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME));
                    if (pConsumeAura && pConsumeAura->GetStackAmount() > 9)
                        bAchiev = false;
                }
                uiAuraCountTimer = 16000;
            } else uiAuraCountTimer -= diff;
        }

        if (uiCrushTimer <= diff)
        {
            DoCastVictim(SPELL_CRUSH);
            uiCrushTimer = urand(10000,15000);
        } else uiCrushTimer -= diff;

        if (uiInfectedWoundTimer <= diff)
        {
            DoCastVictim(SPELL_INFECTED_WOUND);
            uiInfectedWoundTimer = urand(25000,35000);
        } else uiInfectedWoundTimer -= diff;

        if (uiExplodeCorpseTimer <= diff)
        {
            DoCast(HEROIC(SPELL_CORPSE_EXPLODE, H_SPELL_CORPSE_EXPLODE));
            DoScriptText(SAY_EXPLODE, m_creature);
            uiExplodeCorpseTimer = urand(15000,19000);
        } else uiExplodeCorpseTimer -= diff;

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

                events.Update(diff);

                if (me->HasUnitState(UNIT_STATE_CASTING))
                    return;

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_CONSUME:
                            Talk(SAY_CONSUME);
                            DoCastAOE(SPELL_CONSUME);
                            events.ScheduleEvent(EVENT_CONSUME, 15000);
                            break;
                        case EVENT_CRUSH:
                            DoCastVictim(SPELL_CRUSH);
                            events.ScheduleEvent(EVENT_CRUSH, urand(10000, 15000));
                            break;
                        case EVENT_INFECTED_WOUND:
                            DoCastVictim(SPELL_INFECTED_WOUND);
                            events.ScheduleEvent(EVENT_INFECTED_WOUND, urand(25000, 35000));
                            break;
                        case EVENT_CORPSE_EXPLODE:
                            Talk(SAY_EXPLODE);
                            DoCastAOE(SPELL_CORPSE_EXPLODE);
                            events.ScheduleEvent(EVENT_CORPSE_EXPLODE, urand(15000, 19000));
                            break;
                        case EVENT_SPAWN:
                            for (uint8 i = 0; i < 3; ++i)
                                if (Creature* trigger = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_TROLLGORE_INVADER_SUMMONER_1 + i)))
                                    trigger->CastSpell(trigger, RAND(SPELL_SUMMON_INVADER_A, SPELL_SUMMON_INVADER_B, SPELL_SUMMON_INVADER_C), true, NULL, NULL, me->GetGUID());

                            events.ScheduleEvent(EVENT_SPAWN, urand(30000, 40000));
                            break;
                        default:
                            break;
                    }
                }

                if (_consumptionJunction)
                {
                    Aura* ConsumeAura = me->GetAura(SPELL_CONSUME_BUFF_HELPER);
                    if (ConsumeAura && ConsumeAura->GetStackAmount() > 9)
                        _consumptionJunction = false;
                }

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

            if (SpawnTimer <= diff)
            {
                uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5));
                for (uint8 i = 0; i < spawnNumber; ++i)
                    DoSummon(RAND(NPC_DRAKKARI_INVADER_1, NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN);
                SpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS);
            }
			else SpawnTimer -= diff;

            if (ConsumeTimer <= diff)
            {
                DoSendQuantumText(SAY_CONSUME, me);
                DoCastAOE(DUNGEON_MODE(SPELL_CONSUME_5N, SPELL_CONSUME_5H));
                ConsumeTimer = 15*IN_MILLISECONDS;
            }
			else ConsumeTimer -= diff;

            if (bAchiev)
            {
                Aura* ConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA_5N, SPELL_CONSUME_AURA_5H));
                if (ConsumeAura && ConsumeAura->GetStackAmount() > 9)
                    bAchiev = false;
            }

            if (CrushTimer <= diff)
            {
                DoCastVictim(SPELL_CRUSH);
                CrushTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
            }
			else CrushTimer -= diff;

            if (InfectedWoundTimer <= diff)
            {
                DoCastVictim(SPELL_INFECTED_WOUND);
                InfectedWoundTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS);
            }
			else InfectedWoundTimer -= diff;

            if (ExplodeCorpseTimer <= diff)
            {
                DoCast(DUNGEON_MODE(SPELL_CORPSE_EXPLODE_5N, SPELL_CORPSE_EXPLODE_5H));
                DoSendQuantumText(SAY_EXPLODE, me);
                ExplodeCorpseTimer = urand(15*IN_MILLISECONDS, 19*IN_MILLISECONDS);
            }
			else ExplodeCorpseTimer -= diff;

            DoMeleeAttackIfReady();
        }
Beispiel #12
0
bool Spell_arcane_torrent(Unit* caster, std::list<Unit*> &, SpellCastTargets const&, SpellEntry const *spellInfo, uint32 effectIndex)
{
    if (effectIndex != 0)
        return true;

    switch (spellInfo->Id)
    {
        case 28730:                                 // Arcane Torrent (Mana)
        case 33390:                                 // Arcane Torrent (mana Wretched Devourer)
        {
            Aura* dummy = caster->GetDummyAura(28734);
            if (dummy)
            {
                int32 bp = (2.17*caster->getLevel() + 9.136) * dummy->GetStackAmount();
                caster->CastCustomSpell(caster, 28733, &bp, NULL, NULL, true);
                caster->RemoveAurasDueToSpell(28734);
            }
            break;
        }

        // Arcane Torrent (Energy)
        case 25046:
        {
            // Search Mana Tap auras on caster
            Aura* dummy = caster->GetDummyAura(28734);
            if (dummy)
            {
                int32 bp = dummy->GetStackAmount() * 10;
                caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true);
                caster->RemoveAurasDueToSpell(28734);
            }
            break;
        }
    }
    return true;
}
void MountedChampionAI::executeEvent(uint32 eventID)
{
    uint32 timer = 0;

    switch (eventID)
    {
        case EVENT_SPELL_CHARGE:
        {
            if (Unit* pUnit = SelectTarget(SELECT_TARGET_FARTHEST))
            {
                DoResetThreat();
                me->AddThreat(pUnit, 5.0f);
                DoCast(pUnit, SPELL_CHARGE, true);
            }

            timer = 5000;
        }break;

        case EVENT_SPELL_SHIELD_BREAKER:
        {
            if (Unit* pUnit = SelectTarget(SELECT_TARGET_FARTHEST))
                DoCast(pUnit, SPELL_SHIELD_BREAKER, true);

            timer = 7 * IN_MILLISECONDS;
        }break;

        case EVENT_SPELL_SHIELD:
        {
            Aura* pAura = me->GetAura(SPELL_SHIELD);
            if (!pAura || pAura->GetStackAmount() < 3)
            {
                DoCast(SPELL_SHIELD);
                timer = urand(4 * IN_MILLISECONDS, 5 * IN_MILLISECONDS);
            }
            else
                timer = urand(1 * IN_MILLISECONDS, 2 * IN_MILLISECONDS);
        }break;
    }

    if (eventID && timer)
        eventMap.ScheduleEvent(eventID, timer);
}
Beispiel #14
0
            void UpdateAI(uint32 const diff)
            {
                events.Update(diff);

                switch (events.ExecuteEvent())
                {
                    case EVENT_DUMMY_RECAST_DEFEND:
                        switch (me->GetEntry())
                        {
                            case NPC_CHARGE_TARGET:
                            {
                                if (!me->HasAura(SPELL_CHARGE_DEFEND))
                                    DoCast(SPELL_CHARGE_DEFEND);
                                break;
                            }
                            case NPC_RANGED_TARGET:
                            {
                                Aura* defend = me->GetAura(SPELL_RANGED_DEFEND);
                                if (!defend || defend->GetStackAmount() < 3 || defend->GetDuration() <= 8000)
                                    DoCast(SPELL_RANGED_DEFEND);
                                break;
                            }
                        }
                        isVulnerable = false;
                        events.ScheduleEvent(EVENT_DUMMY_RECAST_DEFEND, 5000);
                        break;
                    case EVENT_DUMMY_RESET:
                        if (UpdateVictim())
                        {
                            EnterEvadeMode();
                            events.ScheduleEvent(EVENT_DUMMY_RESET, 10000);
                        }
                        break;
                }

                if (!UpdateVictim())
                    return;

                if (!me->HasUnitState(UNIT_STATE_STUNNED))
                    me->SetControlled(true, UNIT_STATE_STUNNED);
            }
Beispiel #15
0
            void HandleScript(SpellEffIndex /*effIndex*/)
            {
                if (!(GetHitCreature() && GetHitCreature()->IsAlive()))
                    return;

                Aura *unstable = GetCaster()->GetAura(SPELL_UNSTABLE_OOZE);
                if (unstable != NULL)
                {
                    Aura *targetAura = GetHitCreature()->GetAura(SPELL_UNSTABLE_OOZE);
                    if (targetAura != NULL)
                        unstable->ModStackAmount(targetAura->GetStackAmount());
                    else
                        unstable->ModStackAmount(1);

                    // no idea why, but this does not trigger explosion on retail (only small+large do)
                }

                // just for safety
                GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
                GetHitCreature()->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
                GetHitCreature()->DespawnOrUnsummon();
            }
Beispiel #16
0
            void HandleScriptEffect(SpellEffIndex /*effIndex*/)
            {
                Unit* caster = GetCaster();
                if (Unit* unitTarget = GetHitUnit())
                {
                    uint32 spellId = 0;
                    int32 basePoint = 0;
                    Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
                    for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
                    {
                        Aura* aura = i->second->GetBase();
                        if (aura->GetCasterGUID() != caster->GetGUID())
                            continue;

                        // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
                        flag96 familyFlag = aura->GetSpellInfo()->SpellFamilyFlags;
                        if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
                            continue;
                        if (AuraEffect* aurEff = aura->GetEffect(0))
                        {
                            // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
                            if (familyFlag[0] & 0x4000)
                            {
                                int32 TickCount = aurEff->GetTotalTicks();
                                spellId = SPELL_HUNTER_CHIMERA_SHOT_SERPENT;
                                basePoint = (aurEff->GetAmount() + aurEff->GetBonusAmount()) * aurEff->GetDonePct();
                                ApplyPct(basePoint, TickCount * 40);
                                basePoint = unitTarget->SpellDamageBonusTaken(caster, aura->GetSpellInfo(), basePoint, DOT, aura->GetStackAmount());
                                if (Player* modOwner = caster->GetSpellModOwner())
                                    modOwner->ApplySpellMod(aura->GetSpellInfo()->Id, SPELLMOD_DOT, basePoint);

                                aurEff->SetBonusAmount(caster->SpellDamageBonusDone(unitTarget, aurEff->GetSpellInfo(), 0, DOT));
                            }
                            // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
                            else if (familyFlag[1] & 0x00000080)
                            {
                                int32 TickCount = aura->GetEffect(0)->GetTotalTicks();
                                spellId = SPELL_HUNTER_CHIMERA_SHOT_VIPER;

                                // Amount of one aura tick
                                basePoint = int32(CalculatePct(unitTarget->GetMaxPower(POWER_MANA), aurEff->GetAmount()));
                                int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50; /// @todo WTF? caster uses unitTarget?
                                if (basePoint > casterBasePoint)
                                    basePoint = casterBasePoint;
                                ApplyPct(basePoint, TickCount * 60);
                            }
                            // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
                            else if (familyFlag[0] & 0x00008000)
                                spellId = SPELL_HUNTER_CHIMERA_SHOT_SCORPID;
                            // ?? nothing say in spell desc (possibly need addition check)
                            //if (familyFlag & 0x0000010000000000LL || // dot
                            //    familyFlag & 0x0000100000000000LL)   // stun
                            //{
                            //    spellId = 53366; // 53366 Chimera Shot - Wyvern
                            //}

                            // Refresh aura duration
                            aura->RefreshDuration();
                        }
                        break;
                    }
                    if (spellId)
                        caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true);
                    if (spellId == SPELL_HUNTER_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown
                        caster->GetSpellHistory()->AddCooldown(spellId, 0, std::chrono::minutes(1));
                }
            }
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // This needs to be checked only on heroic
        if (!m_bIsRegularMode && m_uiCheckPermafrostTimer)
        {
            if (m_uiCheckPermafrostTimer <= uiDiff)
            {
                ThreatList playerList = m_creature->getThreatManager().getThreatList();
                for (ThreatList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
                {
                    if (Player* pTarget = m_creature->GetMap()->GetPlayer((*itr)->getUnitGuid()))
                    {
                        Aura* pAuraIntenseCold = pTarget->GetAura(SPELL_PERMAFROST_AURA_H, EFFECT_INDEX_2);

                        if (pAuraIntenseCold)
                        {
                            if (pAuraIntenseCold->GetStackAmount() > MAX_PERMAFROST_STACK)
                            {
                                if (m_pInstance)
                                    m_pInstance->SetSpecialAchievementCriteria(TYPE_ACHIEV_DOESNT_GO_ELEVEN, false);

                                m_uiCheckPermafrostTimer = 0;
                                return;
                            }
                        }
                    }
                }
                m_uiCheckPermafrostTimer = 1000;
            }
            else
                m_uiCheckPermafrostTimer -= uiDiff;
        }

        // Do nothing more while moving
        if (m_uiPhase == PHASE_MOVEMENT)
            return;

        // Casted in every phase
        if (m_uiThrowSaroniteTimer < uiDiff)
        {
            // TODO - only target players?
            if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
            {
                if (DoCastSpellIfCan(pTarget, SPELL_THROW_SARONITE) == CAST_OK)
                {
                    DoScriptText(EMOTE_THROW_SARONITE, m_creature, pTarget);
                    m_uiThrowSaroniteTimer = 16000;
                }
            }
        }
        else
            m_uiThrowSaroniteTimer -= uiDiff;

        switch (m_uiPhase)
        {
            case PHASE_NO_ENCHANTMENT:
            {
                if (m_creature->GetHealthPercent() < 66.0f)
                {
                    DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS);
                    SetCombatMovement(false);

                    m_creature->GetMotionMaster()->MoveJump(aGarfrostMoveLocs[0][0], aGarfrostMoveLocs[0][1], aGarfrostMoveLocs[0][2], 3 * m_creature->GetSpeed(MOVE_RUN), 10.0f, PHASE_BLADE_ENCHANTMENT);
                    m_uiPhase = PHASE_MOVEMENT;

                    // Stop further action
                    return;
                }
                break;
            }
            case PHASE_BLADE_ENCHANTMENT:
            {
                if (m_creature->GetHealthPercent() < 33.0f)
                {
                    DoCastSpellIfCan(m_creature, SPELL_THUNDERING_STOMP, CAST_INTERRUPT_PREVIOUS);
                    SetCombatMovement(false);

                    m_creature->GetMotionMaster()->MoveJump(aGarfrostMoveLocs[1][0], aGarfrostMoveLocs[1][1], aGarfrostMoveLocs[1][2], 3 * m_creature->GetSpeed(MOVE_RUN), 10.0f, PHASE_MACE_ENCHANTMENT);
                    m_uiPhase = PHASE_MOVEMENT;

                    // Stop further action
                    return;
                }

                if (m_uiChillingWaveTimer < uiDiff)
                {
                    if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_CHILLING_WAVE) == CAST_OK)
                        m_uiChillingWaveTimer = 14000;
                }
                else
                    m_uiChillingWaveTimer -= uiDiff;

                break;
            }
            case PHASE_MACE_ENCHANTMENT:
            {
                if (m_uiDeepFreezeTimer < uiDiff)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    {
                        if (DoCastSpellIfCan(pTarget, SPELL_DEEP_FREEZE) == CAST_OK)
                        {
                            DoScriptText(EMOTE_DEEP_FREEZE, m_creature, pTarget);
                            m_uiDeepFreezeTimer = 20000;
                        }
                    }
                }
                else
                    m_uiDeepFreezeTimer -= uiDiff;

                break;
            }
        }

        DoMeleeAttackIfReady();
    }
void PlayerbotMageAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

    #pragma region Choose Actions
    // Choose actions accoring to talents (MAGE is always ranged dps)
    m_role = BOT_ROLE_DPS_RANGED;

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

    TakePosition(pTarget);
    // If there's a cast stop
    if (m_bot->HasUnitState(UNIT_STAT_CASTING)) { return; }

    if (DoSupportRaid(m_bot,30,0,0,0,1,1)) { return; }

    if (m_tank->GetGUID() != m_bot->GetGUID() && pVictim && pVictim->GetGUID() == m_bot->GetGUID() )
    {
        //if (CastSpell(INVISIBILITY, m_bot)) { return; }
        if (ai->GetHealthPercent(*pTarget) > 50 && CastSpell(POLYMORPH)) { return; }
        //if (m_bot->getRace() == (uint8) RACE_NIGHTELF && isUnderAttack() && CastSpell(R_SHADOWMELD, m_bot)) { return; }
    }
    if (isUnderAttack() && pDist > 5 && CastSpell(FROST_NOVA, pTarget)) { return; }
    if (DEEP_FREEZE && pTarget->isFrozen() && CastSpell(DEEP_FREEZE,pTarget)) { return; }
    if (isUnderAttack() && CastSpell(DRAGONS_BREATH, pTarget)) { return; }
    if ((isUnderAttack() || ai->GetHealthPercent() < 75 && !HasAuraName(m_bot, MANA_SHIELD))  && ai->GetManaPercent() > 40 && CastSpell(MANA_SHIELD,m_bot)) { return; }
    if (m_bot->getRace() == (uint8) RACE_DWARF && ai->GetHealthPercent() < 75 && CastSpell(R_STONEFORM,m_bot)) { } //no gcd
    if (m_bot->getRace() == (uint8) RACE_DRAENEI && ai->GetHealthPercent() < 55 && CastSpell(R_GIFT_OF_NAARU,m_bot)) { return; } //no Gcd, but has cast
    if (m_bot->getRace() == (uint8) RACE_TAUREN && pDist < 8 && CastSpell(R_WAR_STOMP, pTarget)) { return; } //no gcd but is cast
    if ((ai->GetHealthPercent() < 65 || ai->GetManaPercent() < 5) && CastSpell(ICE_BLOCK,m_bot)) { return; }
    if (isUnderAttack() && CastSpell(ICE_BARRIER, pTarget)) { return; }
    if (ai->GetManaPercent() < 30 && CastSpell (EVOCATION, m_bot)) { return; }


    //Break spells
    if (m_bot->getRace() == (uint8) RACE_BLOODELF && pDist < 8 && (pTarget->IsNonMeleeSpellCasted(true) || ai->GetManaPercent() < 40) && CastSpell(R_ARCANE_TORRENT, pTarget)) { } //no gcd
    else if (pThreat < threatThreshold && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(COUNTER_SPELL, pTarget)) { return; } //High threat
	if (!m_bot->HasAura(MOLTEN_ARMOR) && CastSpell(MOLTEN_ARMOR,m_bot)) { return; }

    if (ai->GetHealthPercent(*pTarget) > 96) { return; } // dont dps too early

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

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


    // buff up
    if (CastSpell(ICY_VEINS,m_bot)) {} //nogcd
    if (m_bot->getRace() == (uint8) RACE_TROLL && CastSpell(R_BERSERKING,m_bot)) {} //no GCD
    if (m_bot->getRace() == (uint8) RACE_ORC && CastSpell(R_BLOOD_FURY,m_bot)) {} //no GCD
    if (CastSpell(POM,m_bot)) {} //nogcd

	if (TALENT_ARCANE)
	{
		if (CastSpell(ARCANE_POWER,m_bot)) {} //nogcd
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }
		//AOE
		if (isUnderAttack(m_tank,5))
		{
			if (CastSpell(BLIZZARD,pTarget)) { return; }
		}
		//DPS
		if (ARCANE_BLAST)
        {
            Aura *abaura = m_bot->GetAura(P_ARCANE_BLAST);
            if (abaura && abaura->GetStackAmount() >= 3)
			{
				if (m_bot->HasAura(P_MISSILE_BARRAGE) && CastSpell(ARCANE_MISSILES,pTarget)) { return; }
				else if (CastSpell(ARCANE_BARRAGE,pTarget)) { return; }
			}
        }
        if (CastSpell(ARCANE_BARRAGE,pTarget) ) { return; }

	}
	if (TALENT_FIRE)
	{
		if (CastSpell(COMBUSTION,m_bot)) { } //nogcd
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }

		//AOE
		if (isUnderAttack(m_tank,5))
		{
			if (CastSpell(FLAMESTRIKE,pTarget)) { return; }
			if (CastSpell(BLAST_WAVE,pTarget)) { return; }
			if (CastSpell(LIVING_BOMB,pTarget)) { return; }
			if (CastSpell(DRAGONS_BREATH,pTarget)) { return; }
		}

		//DPS
		if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget)) { return; }
		if (!pTarget->HasAura(LIVING_BOMB,m_bot->GetGUID()) && CastSpell(LIVING_BOMB,pTarget)) { return; }
		//if (!pTarget->HasAura(IMP_SCORCH) && CastSpell(SCORCH,pTarget)) { return; }
		if (CastSpell(FIREBALL,pTarget)) { return; }
	}
	if (TALENT_FROST)
	{
		if (CastSpell(MIRROR_IMAGE,m_bot)) { return; }
        if (CastSpell(WATER_ELEMENTAL,m_bot)) { return; }

        uint64 pet_guid = m_bot->GetPetGUID();
        if (pet_guid>0){
            Pet* pet = ObjectAccessor::GetPet(*m_bot, pet_guid);
            Unit *unit = ObjectAccessor::GetUnit(*m_bot, pet_guid);
            if (unit!=NULL){
				if (!unit->isInCombat()) {
                    m_bot->GetSession()->HandlePetActionHelper(unit, pet_guid, COMMAND_ATTACK, ACT_COMMAND, pTarget->GetGUID());
				}
            }
        }

        //if (CastSpell(33395, pTarget)) // pet freeze spell
        //    sLog.outError ("successfully casted freeze");

        //AOE
        if (isUnderAttack(m_tank,5))
        {
            if (CastSpell(BLIZZARD,pTarget)) { return; }
        }

        //DPS
        if (m_bot->HasAura(P_FINGERS_OF_FROST) && CastSpell(DEEP_FREEZE,pTarget)) { return; }
        if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FROSTFIRE_BOLT,pTarget)) { return; }
        if (CastSpell(FROSTBOLT,pTarget,true,true)) { return; }

    }

    // Defaults especialy for lower levels
    if (m_bot->HasAura(P_BRAIN_FREEZE) && CastSpell(FIREBALL,pTarget,1,1)) { return; }
        if (m_bot->HasAura(P_FIRESTARTER) && CastSpell(FLAMESTRIKE,pTarget,1,1)) { return; }
        if (m_bot->HasAura(P_HOT_STREAK) && CastSpell(PYROBLAST,pTarget,1,1)) { return; }
        if (m_bot->HasAura(POM) && (CastSpell(PYROBLAST,pTarget,1,1) || CastSpell(FIREBALL,pTarget,1,1) || CastSpell(FROSTBOLT,pTarget,1,1))) { return; }
        if (pTarget->isFrozen() && CastSpell(ICE_LANCE,pTarget)) { return; }
        if (m_bot->isMoving() && (CastSpell(FIRE_BLAST,pTarget,1,1) || CastSpell(ARCANE_BARRAGE,pTarget) || CastSpell(ICE_LANCE,pTarget))) { return; }
        if (CastSpell(FIREBALL,pTarget)) { return; }
        if (CastSpell(FROSTBOLT,pTarget)) { return; }
        if (CastSpell(ARCANE_MISSILES,pTarget)) { return; }

    // drink potion
    if(ai->GetManaPercent() < 5 )
    {
        Item *pItem = ai->FindPotion();
        if(pItem != NULL)
        {
            if (pItem->GetSpell() && m_bot->HasSpellCooldown(pItem->GetSpell()) ) { return; } //pot is in cooldown
            ai->UseItem(*pItem);
        }
    }

    // if we get down here, it means we are out of mana, so use wand
    CastSpell(SHOOT, pTarget);

} //end DoNextCombatManeuver
Beispiel #19
0
        void HandleScriptEffect(SpellEffIndex /*effIndex*/)
        {
            Unit* caster = GetCaster();
            Unit* unitTarget = GetHitUnit();
            if (!unitTarget)
                return;

            uint32 spellId = 0;
            int32 basePoint = 0;
            Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
            for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
            {
                Aura* aura = i->second->GetBase();
                if (aura->GetCasterGUID() != caster->GetGUID())
                    continue;

                // Search only Serpent Sting, Viper Sting, Scorpid Sting auras
                flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
                if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
                    continue;
                if (AuraEffect const * aurEff = aura->GetEffect(0))
                {
                    // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
                    if (familyFlag[0] & 0x4000)
                    {
                        int32 TickCount = aurEff->GetTotalTicks();
                        spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT;
                        basePoint = caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), aurEff->GetAmount(), DOT, aura->GetStackAmount());
                        basePoint = basePoint * TickCount * 40 / 100;
                    }
                    // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
                    else if (familyFlag[1] & 0x00000080)
                    {
                        int32 TickCount = aura->GetEffect(0)->GetTotalTicks();
                        spellId = HUNTER_SPELL_CHIMERA_SHOT_VIPER;

                        // Amount of one aura tick
                        basePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 100 ;
                        int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ;
                        if (basePoint > casterBasePoint)
                            basePoint = casterBasePoint;
                        basePoint = basePoint * TickCount * 60 / 100;
                    }
                    // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
                    else if (familyFlag[0] & 0x00008000)
                        spellId = HUNTER_SPELL_CHIMERA_SHOT_SCORPID;
                    // ?? nothing say in spell desc (possibly need addition check)
                    //if (familyFlag & 0x0000010000000000LL || // dot
                    //    familyFlag & 0x0000100000000000LL)   // stun
                    //{
                    //    spellId = 53366; // 53366 Chimera Shot - Wyvern
                    //}

                    // Refresh aura duration
                    aura->RefreshDuration();
                }
                break;
            }
            if (spellId)
                caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, true);
            if (spellId == HUNTER_SPELL_CHIMERA_SHOT_SCORPID && caster->ToPlayer()) // Scorpid Sting - Add 1 minute cooldown
                caster->ToPlayer()->AddSpellCooldown(spellId,0,uint32(time(NULL) + 60));
        }
Beispiel #20
0
    void UpdateAI(const uint32 uiDiff)
    {  
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_bTimeToDie)
        {
            FakeDeath();
            return;
        }
        
        if (m_bDead)
        {
            if (m_uiRespawnTimer < uiDiff)
            {
                m_creature->SetHealth(m_creature->GetMaxHealth());
                m_creature->SetVisibility(VISIBILITY_OFF);
                Init();
                m_creature->MonsterTextEmote("%s appears to defend Emalon!", 0, true);
                if (m_pInstance)
                {
                    Creature* pEmalon = (Creature*)Unit::GetUnit((*m_creature), m_pInstance->GetData64(DATA_EMALON));
                    if (pEmalon)
                    {
                        Unit* pTarget = pEmalon->getVictim();
                        if (pTarget)
                            m_creature->GetMotionMaster()->MoveChase(pTarget);
                    }
                }
                return;
            }
            else
            {
                m_uiRespawnTimer -= uiDiff;
                return;
            }
        }

        Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, 0);
        if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10)
        {
            DoCast(m_creature, SPELL_OVERCHARGED_BLAST);
            m_bTimeToDie = true;
            return;
        }

        if(m_uiShockTimer < uiDiff)
        {
            DoCast(m_creature->getVictim(), SPELL_SHOCK);
            m_uiShockTimer = 8000+rand()%4000;
        }
        else
            m_uiShockTimer -= uiDiff;

	if(m_uiEvadeCheckTimer < uiDiff)
	  {
	    if(m_creature->GetDistance2d(-229.11f, -289.03f) > 70.0f)
	      EnterEvadeMode();

	    m_uiEvadeCheckTimer = 2000;
	  }
	else
	  m_uiEvadeCheckTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Beispiel #21
0
    void UpdateAI(const uint32 uiDiff)
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (m_uiEvadeCheckCooldown < uiDiff)
        {
            Creature* pEmalon = m_pInstance->GetSingleCreatureFromStorage(NPC_EMALON);
            if ((pEmalon && pEmalon->IsInEvadeMode()) || (m_creature->GetDistance2d(-219.119f, -289.037f) > 80.0f))
            {
                EnterEvadeMode();
                return;
            }
            m_uiEvadeCheckCooldown = 2000;
        }
        else
            m_uiEvadeCheckCooldown -= uiDiff;

        if (m_bTimeToDie)
        {
            FakeDeath();
            return;
        }

        if (m_bDead)
        {
            if (m_uiRespawnTimer < uiDiff)
            {
                m_creature->SetHealth(m_creature->GetMaxHealth());
                m_creature->SetVisibility(VISIBILITY_OFF);
                Init();
                m_creature->MonsterTextEmote("%s appears to defend Emalon!", NULL, true);
                m_creature->SetInCombatWithZone();
                DoResetThreat();
                if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
                    m_creature->GetMotionMaster()->MoveChase(pTarget);
            }
            else
                m_uiRespawnTimer -= uiDiff;

            return;
        }

        if (m_uiOverchargedStacksCheckTimer < uiDiff)
        {
            m_uiOverchargedStacksCheckTimer = 2000;
            Aura* pAuraOvercharged = m_creature->GetAura(SPELL_OVERCHARGED, EFFECT_INDEX_0);
            if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10)
            {
                DoCastSpellIfCan(m_creature, SPELL_OVERCHARGED_BLAST);
                m_bTimeToDie = true;
                return;
            }
        }
        else
            m_uiOverchargedStacksCheckTimer -= uiDiff;

        if (m_uiShockTimer < uiDiff)
        {
            DoCastSpellIfCan(m_creature->getVictim(), SPELL_SHOCK);
            m_uiShockTimer = 8000+rand()%4000;
        }
        else
            m_uiShockTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
void PlayerbotShamanAI::DoNextCombatManeuver(Unit *pTarget)
{
    if (!pTarget || pTarget->isDead()) return;
    PlayerbotAI *ai = GetAI();
    if (!ai) return;
    Player *m_bot = GetPlayerBot();
    if (!m_bot || m_bot->isDead()) return;
    Unit *pVictim = pTarget->getVictim();
    Unit *m_tank = FindMainTankInRaid(GetMaster());
    if (!m_tank && m_bot->GetGroup() && GetMaster()->GetGroup() != m_bot->GetGroup()) { FindMainTankInRaid(m_bot); }
    if (!m_tank) { m_tank = m_bot; }
    uint32 masterHP = GetMaster()->GetHealth()*100 / GetMaster()->GetMaxHealth();
    float pDist = m_bot->GetDistance(pTarget);
    uint8 pThreat = GetThreatPercent(pTarget);

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

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

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


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

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

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

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

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

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

            break;
        #pragma endregion

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

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

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

            break;
        #pragma endregion
    }
    #pragma region ShamanCommon


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

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


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

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


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

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

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

    #pragma endregion


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


} //end DoNextCombatManeuver
        void UpdateAI(const uint32 diff)
        {
            //Return since we have no target
            if (!UpdateVictim())
                return;

            if (uiSpawnTimer <= diff)
            {
                uint32 spawnNumber = urand(2, DUNGEON_MODE(3, 5));
                for (uint8 i = 0; i < spawnNumber; ++i)
                    if (Creature* temp = DoSummon(RAND(NPC_DRAKKARI_INVADER_1, NPC_DRAKKARI_INVADER_2), AddSpawnPoint, 0, TEMPSUMMON_DEAD_DESPAWN))
                    {
                        if (temp->GetAI())
                        {
                            temp->GetAI()->AttackStart(me);
                            temp->AddThreat(me, 5000000.0f);
                        }
                    }
                uiSpawnTimer = urand(30*IN_MILLISECONDS, 40*IN_MILLISECONDS);
            } else uiSpawnTimer -= diff;

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

                if (!t_list.empty())
                {
                    for (std::list<HostileReference *>::const_iterator itr = t_list.begin(); itr!= t_list.end(); ++itr)
                    {
                        if (Unit* target = Unit::GetUnit((*me), (*itr)->getUnitGuid()))
                        {
                            if (me->GetDistance(target) <= 50.0f && target->isAlive() && me->IsValidAttackTarget(target))
                            {
                                // Apply aura for every target in 50yards ~ 45m
                                DoCast(me, DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME), true);
                            }
                        }
                    }
                }

                DoScriptText(SAY_CONSUME, me);
                DoCast(SPELL_CONSUME);
                uiConsumeTimer = 15*IN_MILLISECONDS;
            } else uiConsumeTimer -= diff;

            if (consumptionJunction)
            {
                Aura* ConsumeAura = me->GetAura(DUNGEON_MODE(SPELL_CONSUME_AURA, H_SPELL_CONSUME_AURA));
                if (ConsumeAura && ConsumeAura->GetStackAmount() > 9)
                    consumptionJunction = false;
            }

            if (uiCrushTimer <= diff)
            {
                DoCastVictim(SPELL_CRUSH);
                uiCrushTimer = urand(10*IN_MILLISECONDS, 15*IN_MILLISECONDS);
            } else uiCrushTimer -= diff;

            if (uiInfectedWoundTimer <= diff)
            {
                DoCastVictim(SPELL_INFECTED_WOUND);
                uiInfectedWoundTimer = urand(25*IN_MILLISECONDS, 35*IN_MILLISECONDS);
            } else uiInfectedWoundTimer -= diff;

            if (uiExplodeCorpseTimer <= diff)
            {
                std::list<Creature*> addList;
                me->GetCreatureListWithEntryInGrid(addList,NPC_DRAKKARI_INVADER_1, 10.0f);
                me->GetCreatureListWithEntryInGrid(addList,NPC_DRAKKARI_INVADER_2, 10.0f);

                if(!addList.empty())
                {
                    DoCast(SPELL_CORPSE_EXPLODE);
                    DoScriptText(SAY_EXPLODE, me);

                    for(std::list<Creature*>::iterator i = addList.begin(); i != addList.end(); i++)
                    {
                        if ((*i))
                        {
                            if(!(*i)->isAlive())
                            {
                                DoCast((*i), DUNGEON_MODE(SPELL_CORPSE_EXPLODE_NH, SPELL_CORPSE_EXPLODE_HC), true);
                                (*i)->DespawnOrUnsummon();
                            }
                        }
                    }
                }
                uiExplodeCorpseTimer = urand(15*IN_MILLISECONDS, 19*IN_MILLISECONDS);
            } else uiExplodeCorpseTimer -= diff;

            DoMeleeAttackIfReady();
        }
Beispiel #24
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;
            
        if (me->getVictim() && !me->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
            me->Kill(me->getVictim());

        events.Update(diff);
        
        if (me->hasUnitState(UNIT_STAT_CASTING))
            return;
                    
        if (uiCheckIntenseColdTimer < diff && !bMoreThanTwoIntenseCold)
        {
            std::list<HostileReference*> ThreatList = me->getThreatManager().getThreatList();
            for (std::list<HostileReference*>::const_iterator itr = ThreatList.begin(); itr != ThreatList.end(); ++itr)
            {
                Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
                if (!pTarget || pTarget->GetTypeId() != TYPEID_PLAYER)
                    continue;

                Aura *AuraIntenseCold = pTarget->GetAura(SPELL_BITING_COLD_TRIGGERED);
                if (AuraIntenseCold && AuraIntenseCold->GetStackAmount() > 2)
                {
                    bMoreThanTwoIntenseCold = true;
                    break;
                }
            }
            uiCheckIntenseColdTimer = 2000;
        } else uiCheckIntenseColdTimer -= diff;

        while(uint32 eventId = events.ExecuteEvent())
        {
            switch(eventId)
            {
                case EVENT_FREEZE:
                    DoCastAOE(SPELL_FREEZE);
                    events.ScheduleEvent(EVENT_FREEZE, urand(30000, 35000));
                    break;
                case EVENT_ICICLE:
                    if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        if (pTarget->isAlive())
                            DoCast(pTarget, SPELL_ICICLE);
                    events.ScheduleEvent(EVENT_ICICLE, 2000);
                    break;
                case EVENT_FLASH_CAST:
                    DoScriptText(SAY_FLASH_FREEZE, me);
                    me->MonsterTextEmote(EMOTE_FREEZE, 0, true);
                    for (uint32 i = 0; i < RAID_MODE(2,3); ++i)
                        if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            if (pTarget->isAlive())
                                pTarget->CastSpell(pTarget, SPELL_ICICLE_SNOWDRIFT, true);
                    DoCast(SPELL_FLASH_FREEZE);
                    events.RescheduleEvent(EVENT_ICICLE, 15000);
                    events.ScheduleEvent(EVENT_FLASH_CAST, 50000);
                    events.ScheduleEvent(EVENT_FLASH_EFFECT, 9000);
                    break;
                case EVENT_FLASH_EFFECT:
                    DoCast(SPELL_FLASH_FREEZE_VISUAL);
                    FlashFreeze();
                    events.CancelEvent(EVENT_FLASH_EFFECT);
                    break;
                case EVENT_BLOWS:
                    DoScriptText(SAY_STALACTITE, me);
                    me->MonsterTextEmote(EMOTE_BLOWS, 0, true);
                    DoCast(me, RAID_MODE(SPELL_FROZEN_BLOWS_10, SPELL_FROZEN_BLOWS_25));
                    events.ScheduleEvent(EVENT_BLOWS, urand(60000, 65000));
                    break;
                case EVENT_RARE_CACHE:
                    DoScriptText(SAY_HARD_MODE_MISSED, me);
                    RareCache = false;
                    events.CancelEvent(EVENT_RARE_CACHE);
                    break;
                case EVENT_BERSERK:
                    DoCast(me, SPELL_BERSERK, true);
                    DoScriptText(SAY_BERSERK, me);
                    events.CancelEvent(EVENT_BERSERK);
                    break;
            }
        }

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

                if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
                {
                    if (!rotface->IsAlive())
                        me->Kill(me); // Meurt si Rotface meurt
                }
                else
                    me->Kill(me); // Meurt si pas de Rotface

                events.Update(diff);

                while (uint32 eventId = events.ExecuteEvent())
                {
                    switch (eventId)
                    {
                        case EVENT_STICKY_OOZE:
                            DoCastVictim(SPELL_STICKY_OOZE);
                            events.ScheduleEvent(EVENT_STICKY_OOZE, 15000);
                            break;
                        case EVENT_CHECK_EXPLODE:
                        {
                            if (hasExploded)
                                break;

                            Aura *unstable = me->GetAura(SPELL_UNSTABLE_OOZE);
                            if (unstable != NULL)
                            {
                                uint8 stack = uint8(unstable->GetStackAmount());

                                // explode!
                                if (stack >= 5)
                                {
                                    me->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_BUFF_COMBINE);
                                    me->RemoveAurasDueToSpell(SPELL_LARGE_OOZE_COMBINE);
                                    if (InstanceScript* instance = me->GetInstanceScript())
                                        if (Creature* rotface = Unit::GetCreature(*me, instance->GetData64(DATA_ROTFACE)))
                                            if (rotface->IsAlive())
                                            {
                                                rotface->AI()->Talk(EMOTE_UNSTABLE_EXPLOSION);
                                                rotface->AI()->Talk(SAY_UNSTABLE_EXPLOSION);
                                            }

                                    DoAction(EVENT_STICKY_OOZE);

                                    me->CastSpell(me, SPELL_UNSTABLE_OOZE_EXPLOSION, false, NULL, NULL, me->GetGUID());

                                    if (InstanceScript* instance = me->GetInstanceScript())
                                        instance->SetData(DATA_OOZE_DANCE_ACHIEVEMENT, uint32(false));

                                    hasExploded = true;
                                }
                            }


                            events.ScheduleEvent(EVENT_CHECK_EXPLODE, 500);
                            break;
                        }
                        default:
                            break;
                    }
                }

                if (me->IsVisible())
                    DoMeleeAttackIfReady();
            }
Beispiel #26
0
    void UpdateAI(const uint32 diff)
    {
		if (!CanDoSomething())
            return;

        if (m_uiEvadeCheckCooldown < diff)
        {
            Creature* pEmalon = (Creature*)Unit::GetUnit((*me), pInstance->GetData64(DATA_EMALON));
            if ((pEmalon && pEmalon->IsInEvadeMode()) || (me->GetDistance2d(-219.119f, -289.037f) > 80.0f))
            {
                EnterEvadeMode();
                return;
            }
            m_uiEvadeCheckCooldown = 2000;
        }
        else
            m_uiEvadeCheckCooldown -= diff;

        if (m_bTimeToDie)
        {
            FakeDeath();
            return;
        }

        if (m_bDead)
        {
            if (m_uiRespawnTimer < diff)
            {
                me->SetHealth(me->GetMaxHealth());
                me->SetVisibility(VISIBILITY_OFF);
                Init();
				Speak(CHAT_TYPE_BOSS_EMOTE,0,"Un seide de la tempete vient defendre Emalon !");
                me->SetInCombatWithZone();
                DoResetThreat();
                if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    me->GetMotionMaster()->MoveChase(pTarget);

            }
            else
                m_uiRespawnTimer -= diff;

            return;
        }

        if (m_uiOverchargedStacksCheckTimer < diff)
        {
            m_uiOverchargedStacksCheckTimer = 2000;
            Aura* pAuraOvercharged = me->GetAura(SPELL_OVERCHARGED, 0);
            if(pAuraOvercharged && pAuraOvercharged->GetStackAmount() >= 10)
            {
                DoCast(me, SPELL_OVERCHARGED_BLAST);
                m_bTimeToDie = true;
                return;
            }
        }
        else
            m_uiOverchargedStacksCheckTimer -= diff;

		Tasks.UpdateEvent(diff);

        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff)
    {
        //despawn after 1 hour timer
        if(!IsFirstTime)
        {
            if(m_uiDespawnTimer < uiDiff)
            {
                IsFirstTime = true;
                DoStopAttack();
                CombatStopped = true;
                m_creature->RemoveAllAuras();
                m_creature->setFaction(35); //friendly
                events.Reset();

                //schedule says
                SayEvents.Reset();
                SayEvents.ScheduleEvent(SAYEVENT_END1, 0);
                SayEvents.ScheduleEvent(SAYEVENT_END2, (10)*IN_MILLISECONDS);
                SayEvents.ScheduleEvent(SAYEVENT_END3, (10+8)*IN_MILLISECONDS);
            }
            else
                m_uiDespawnTimer -= uiDiff;
        }

        SayEvents.Update(uiDiff);
        while (uint32 eventId = SayEvents.ExecuteEvent())
        {
            switch (eventId)
                {
                case SAYEVENT_END1:
                    DoScriptText(SAY_END_1, m_creature);
                    break;
                case SAYEVENT_END2:
                    DoScriptText(SAY_END_2, m_creature);
                    break;
                case SAYEVENT_END3:
                    DoScriptText(SAY_END_3, m_creature);
                    m_creature->SetVisibility(VISIBILITY_OFF);
                    EnterEvadeMode();
                    break;

                case SAYEVENT_ENTER1:
                    DoScriptText(SAY_ENTER_1, m_creature);
                    break;
                case SAYEVENT_ENTER2:
                    DoScriptText(SAY_ENTER_2, m_creature);
                    break;
                case SAYEVENT_ENTER3:
                    DoScriptText(SAY_ENTER_3, m_creature);
                    HasSaidBeginningStuff = true;
                    break;

                case SAYEVENT_DEFEATED1:
                    DoScriptText(SAY_DEFEATED_1, m_creature);
                    break;
                case SAYEVENT_DEFEATED2:
                    DoScriptText(SAY_DEFEATED_2, m_creature);
                    break;
                case SAYEVENT_DEFEATED3:
                    DoScriptText(SAY_DEFEATED_3, m_creature);
                    break;
                case SAYEVENT_DEFEATED4:
                    DoScriptText(SAY_DEFEATED_4, m_creature);
                    break;
                case SAYEVENT_DEFEATED5:
                    DoScriptText(SAY_DEFEATED_5, m_creature);
                    m_creature->SetVisibility(VISIBILITY_OFF);
                    EnterEvadeMode();
                    break;

                default:
                    break;
            }
        }

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

        if (IsOutOfCombatArea(m_creature))
        {
            EnterEvadeMode();
            return;
        }

        //check for phase 2 at 20% health
        if(!IsPhase2)
        {
            if(m_creature->GetHealthPercent() < 20.0f)
            {
                IsPhase2 = true;
                DoScriptText(SAY_START_PHASE_2, m_creature);
                events.CancelEvent(EVENT_SUMMON_STARS);
                events.CancelEvent(EVENT_SUMMON_CONSTELLATION);
                UnSummonAllCreatures();

                //4 black holes in square pattern
                const float pos[4][2] = {{10,0}, {-10,0}, {0,10}, {0,-10}};
                for (int i = 0; i < 4; i++)
                    DoSpawnCreature(NPC_BLACK_HOLE, pos[i][0], pos[i][1], 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000);

                DoScriptText(SAY_SUMMON_STARS, m_creature);
                events.ScheduleEvent(EVENT_SUMMON_STARS,SUMMON_STARS_TIMER);
            }
        }

        //switch targets to next top aggro if phase punch stacks >= 5
        if (Unit *TopAggro = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO_PLAYER, 0))
        {
            Aura *aur = TopAggro->GetAura(SPELL_PHASE_PUNCH, EFFECT_INDEX_0);
            if (aur && aur->GetStackAmount() >= 5)
                if (Unit *NextTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO_PLAYER, 1))
                    m_creature->Attack(NextTarget, true);
        }

        events.Update(uiDiff);
        while (uint32 eventId = events.ExecuteEvent())
        {
            switch (eventId)
            {
                case EVENT_BERSERK:
                    DoCast(m_creature, SPELL_BERSERK);
                    //events.ScheduleEvent(EVENT_BERSERK, 10*IN_MILLISECONDS);
                    DoScriptText(SAY_BERSERK, m_creature);
                    DoScriptText(EMOTE_BERSERK, m_creature);
                    break;
                case EVENT_QUANTUM_STRIKE:
                    DoCast(m_creature->getVictim(), HEROIC(SPELL_QUANTUM_STRIKE, SPELL_QUANTUM_STRIKE_H));
                    events.ScheduleEvent(EVENT_QUANTUM_STRIKE, QUANTUM_STRIKE_TIMER);
                    break;
                case EVENT_PHASE_PUNCH:
                    DoCast(m_creature->getVictim(), SPELL_PHASE_PUNCH);
                    events.ScheduleEvent(EVENT_PHASE_PUNCH, PHASE_PUNCH_TIMER);
                    break;
                case EVENT_ASCEND_TO_HEAVENS:
                    DoCast(m_creature->getVictim(), SPELL_ASCEND_TO_HEAVENS);
                    events.ScheduleEvent(EVENT_ASCEND_TO_HEAVENS, 5*IN_MILLISECONDS); //just in case they survive... hehehe
                    break;
                case EVENT_SUMMON_STARS:
                    if(!IsPhase2)
                    {
                        size_t n_stars = CurrSummons.count(NPC_COLLAPSING_STAR);
                        if (n_stars > MAX_STARS) //shouldnt happen
                            break;
                        for(size_t i = 0; i < MAX_STARS-n_stars; i++) //respawn missing stars
                        {
                            float x, y;
                            GetRandomPointInCircle(30.0f, x, y);
                            DoSpawnCreature(NPC_COLLAPSING_STAR, x, y, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000);
                        }
                        if (MAX_STARS-n_stars > 0) //summoned at least one
                            DoScriptText(SAY_SUMMON_STARS, m_creature);
                        events.ScheduleEvent(EVENT_SUMMON_STARS, SUMMON_STARS_TIMER);
                    }
                    break;
                case EVENT_SUMMON_CONSTELLATION:
                    if (CurrSummons.count(NPC_LIVING_CONSTELLATION) > MAX_CONSTELLATIONS) //just to avoid infinite summons
                        break;
                    for(int i=0; i<3; i++)
                    {
                        float x, y;
                        GetRandomPointInCircle(30.0f, x, y);
                        DoSpawnCreature(NPC_LIVING_CONSTELLATION, x, y, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 1000);
                    }
                    events.ScheduleEvent(EVENT_SUMMON_CONSTELLATION, SUMMON_CONSTELLATION_TIMER);
                    break;
                case EVENT_COSMIC_SMASH:
                    //TODO: mark destination point (don't know the spell)
                    DoScriptText(EMOTE_COSMIC_SMASH, m_creature);
                    events.ScheduleEvent(EVENT_COSMIC_SMASH_EFFECT, 2*IN_MILLISECONDS);
                    events.ScheduleEvent(EVENT_COSMIC_SMASH, COSMIC_SMASH_TIMER);
                    break;
                case EVENT_COSMIC_SMASH_EFFECT:
                    for (int i = 0; i < HEROIC(1, 3); i++)
                    {
                        float x, y;
                        GetRandomPointInCircle(30.0f, x, y);
                        m_creature->CastSpell(m_creature->GetPositionX()+x, m_creature->GetPositionY()+y, m_creature->GetPositionZ()+0.5f,
                                HEROIC(SPELL_COSMIC_SMASH, SPELL_COSMIC_SMASH_H), true);
                    }
                    break;
                default:
                    break;
            }
        }

        DoMeleeAttackIfReady();
    }
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // This needs to be checked only on heroic
        if (!m_bIsRegularMode)
        {
            if (uiCheckIntenseColdTimer < uiDiff)
            {
                ThreatList playerList = m_creature->GetThreatManager().getThreatList();
                for (ThreatList::const_iterator itr = playerList.begin(); itr != playerList.end(); ++itr)
                {
                    if (Player* pTarget = m_creature->GetMap()->GetPlayer((*itr)->getUnitGuid()))
                    {
                        Aura* pAuraIntenseCold = pTarget->GetAura(SPELL_INTENSE_COLD_AURA, EFFECT_INDEX_0);

                        if (pAuraIntenseCold)
                        {
                            if (pAuraIntenseCold->GetStackAmount() > MAX_INTENSE_COLD_STACK)
                            {
                                if (m_pInstance)
                                    m_pInstance->SetData(TYPE_INTENSE_COLD_FAILED, pTarget->GetGUIDLow());
                            }
                        }
                    }
                }
                uiCheckIntenseColdTimer = 1000;
            }
            else
                uiCheckIntenseColdTimer -= uiDiff;
        }

        if (!m_bIsEnraged && m_creature->GetHealthPercent() < 25.0f)
        {
            if (!m_creature->IsNonMeleeSpellCasted(false))
            {
                m_bIsEnraged = true;
                DoScriptText(SAY_ENRAGE, m_creature);
                DoCastSpellIfCan(m_creature, SPELL_ENRAGE);
            }
        }

        if (uiCrystalChainTimer < uiDiff)
        {
            if (!m_creature->IsNonMeleeSpellCasted(false))
            {
                if (m_bIsRegularMode)
                {
                    if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1))
                    {
                        if (Player* pPlayer = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
                            DoCastSpellIfCan(pPlayer, SPELL_CRYSTAL_CHAINS);

                        uiCrystalChainTimer = 30000;
                    }
                }
                else
                {
                    if (Unit* pSource = m_creature->getVictim())
                    {
                        uiCrystalChainTimer = 15000;

                        Player* pPlayer = pSource->GetCharmerOrOwnerPlayerOrPlayerItself();

                        if (!pPlayer)
                            return;

                        if (Group* pGroup = pPlayer->GetGroup())
                        {
                            for (GroupReference* pRef = pGroup->GetFirstMember(); pRef != NULL; pRef = pRef->next())
                            {
                                if (Player* pMember = pRef->getSource())
                                {
                                    if (pMember->IsAlive() && pMember->IsWithinDistInMap(m_creature, 50.0f))
                                        m_creature->CastSpell(pMember, SPELL_CRYSTAL_CHAINS, true);
                                }
                            }
                        }
                        else
                            m_creature->CastSpell(pPlayer, SPELL_CRYSTAL_CHAINS, false);
                    }
                }
            }
        }
        else
            uiCrystalChainTimer -= uiDiff;

        if (uiTailSweepTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_TAIL_SWEEP) == CAST_OK)
                uiTailSweepTimer = urand(2500, 7500);
        }
        else
            uiCrystalChainTimer -= uiDiff;

        if (uiCrystalfireBreathTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, m_bIsRegularMode ? SPELL_CRYSTALFIRE_BREATH : SPELL_CRYSTALFIRE_BREATH_H) == CAST_OK)
                uiCrystalfireBreathTimer = urand(15000, 20000);
        }
        else
            uiCrystalfireBreathTimer -= uiDiff;

        if (!m_bIsRegularMode)
        {
            if (uiCrystallizeTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_CRYSTALLIZE) == CAST_OK)
                {
                    uiCrystallizeTimer = urand(15000, 25000);
                    DoScriptText(SAY_CRYSTAL_NOVA, m_creature);
                }
            }
            else
                uiCrystallizeTimer -= uiDiff;
        }

        DoMeleeAttackIfReady();
    }