Beispiel #1
0
Unit* ScriptedAI::SelectCastTarget(uint32 spellId, castTargetMode targetMode)
{
    switch (targetMode)
    {
        case CAST_TANK:
            return me->getVictim();
        case CAST_NULL:
            return NULL;
        case CAST_RANDOM:
        case CAST_RANDOM_WITHOUT_TANK:
        {
            SpellEntry const* pSpell = GetSpellStore()->LookupEntry(spellId);
            return SelectUnit(SELECT_TARGET_RANDOM, 0, GetSpellMaxRange(spellId), pSpell->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY, targetMode == CAST_RANDOM_WITHOUT_TANK ? me->getVictimGUID() : 0);
        }
        case CAST_SELF:
            return me;
        case CAST_LOWEST_HP_FRIENDLY:
        {
            SpellEntry const* pSpell = GetSpellStore()->LookupEntry(spellId);
            return SelectLowestHpFriendly(GetSpellMaxRange(spellId));
        }
        case CAST_THREAT_SECOND:
        {
            SpellEntry const* pSpell = GetSpellStore()->LookupEntry(spellId);
            return SelectUnit(SELECT_TARGET_TOPAGGRO, 1, GetSpellMaxRange(spellId), pSpell->AttributesEx3 & SPELL_ATTR_EX3_PLAYERS_ONLY);
        }
        default:
            return NULL;
    };
}
Beispiel #2
0
void
TotemAI::UpdateAI(const uint32 /*diff*/)
{
    if (i_totem.GetTotemType() != TOTEM_ACTIVE)
        return;

    if (!i_totem.isAlive() || i_totem.IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_totem.GetSpell());
    if (!spellInfo)
        return;

    // Get spell rangy
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float max_range = GetSpellMaxRange(srange);

    // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems

    // pointer to appropriate target if found any
    Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(i_totem, i_victimGuid) : NULL;

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if (!victim ||
        !victim->isTargetableForAttack() || !i_totem.IsWithinDistInMap(victim, max_range) ||
        i_totem.IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(&i_totem,false))
    {
        CellPair p(BlizzLike::ComputeCellPair(i_totem.GetPositionX(),i_totem.GetPositionY()));
        Cell cell(p);
        cell.data.Part.reserved = ALL_DISTRICT;

        victim = NULL;

        BlizzLike::NearestAttackableUnitInObjectRangeCheck u_check(&i_totem, &i_totem, max_range);
        BlizzLike::UnitLastSearcher<BlizzLike::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);

        TypeContainerVisitor<BlizzLike::UnitLastSearcher<BlizzLike::NearestAttackableUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
        TypeContainerVisitor<BlizzLike::UnitLastSearcher<BlizzLike::NearestAttackableUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);

        //TODO: Backport BLizzLike Add to CreatureAI field pointing to creature itself
        //cell.Visit(p, grid_object_checker,  *m_creature.GetMap(), *m_creature, max_range);
        //cell.Visit(p, world_object_checker, *m_creature.GetMap(), *m_creature, max_range);
        cell.Visit(p, grid_object_checker,  *i_totem.GetMap());
        cell.Visit(p, world_object_checker, *i_totem.GetMap());
    }

    // If have target
    if (victim)
    {
        // remember
        i_victimGuid = victim->GetGUID();

        // attack
        i_totem.SetInFront(victim);                         // client change orientation by self
        i_totem.CastSpell(victim, i_totem.GetSpell(), false);
    }
    else
        i_victimGuid = 0;
}
Beispiel #3
0
TurretAI::TurretAI(Creature *c) : CreatureAI(c)
{
    ASSERT(me->m_spells[0]);
    m_minRange = GetSpellMinRange(me->m_spells[0], false);
    me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
    me->m_SightDistance = me->m_CombatDistance;
}
Beispiel #4
0
void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target)
{
    GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(trapEntry);
    if(!trapInfo || trapInfo->type!=GAMEOBJECT_TYPE_TRAP)
        return;

    SpellEntry const* trapSpell = sSpellStore.LookupEntry(trapInfo->trap.spellId);
    if(!trapSpell)                                          // checked at load already
        return;

    float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(trapSpell->rangeIndex));

    // search nearest linked GO
    GameObject* trapGO = NULL;
    {
        // using original GO distance
        CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
        Cell cell(p);
        cell.data.Part.reserved = ALL_DISTRICT;

        MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range);
        MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(trapGO,go_check);

        TypeContainerVisitor<MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker);
        CellLock<GridReadGuard> cell_lock(cell, p);
        cell_lock->Visit(cell_lock, object_checker, *GetMap());
    }

    // found correct GO
    // FIXME: when GO casting will be implemented trap must cast spell to target
    if(trapGO)
        target->CastSpell(target,trapSpell,true);
}
Beispiel #5
0
ArchorAI::ArchorAI(Creature *c) : CreatureAI(c)
{
    ASSERT(me->m_spells[0]);
    m_minRange = GetSpellMinRange(me->m_spells[0], false);
    if (!m_minRange)
        m_minRange = MELEE_RANGE;
    me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
    me->m_SightDistance = me->m_CombatDistance;
}
Beispiel #6
0
TurretAI::TurretAI(Creature *c) : CreatureAI(c)
{
    if (!me->m_spells[0])
        sLog.outError("TurretAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());

    m_minRange = GetSpellMinRange(me->m_spells[0], false);
    me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
    me->m_SightDistance = me->m_CombatDistance;
}
Beispiel #7
0
ArchorAI::ArchorAI(Creature *c) : CreatureAI(c)
{
    if (!me->m_spells[0])
        sLog->outError("ArchorAI set for creature (entry = %u) with spell1=0. AI will do nothing", me->GetEntry());

    m_minRange = GetSpellMinRange(me->m_spells[0], false);
    if (!m_minRange)
        m_minRange = MELEE_RANGE;
    me->m_CombatDistance = GetSpellMaxRange(me->m_spells[0], false);
    me->m_SightDistance = me->m_CombatDistance;
}
Beispiel #8
0
ArcherAI::ArcherAI(Creature* c) : CreatureAI(c)
{
    SpellEntry const* spellInfo = sSpellStore.LookupEntry(me->m_spells[0]);
    m_minRange = spellInfo ? GetSpellMinRange(spellInfo) : 0;

    if (!m_minRange)
        m_minRange = MELEE_RANGE;

    me->SetCombatDistance(spellInfo ? GetSpellMaxRange(spellInfo) : 0);
    me->m_SightDistance = me->GetCombatDistance();
}
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        //IceArmor_Timer
        if (IceArmor_Timer < diff)
        {
            DoCast(m_creature, SPELL_ICEARMOR);
            IceArmor_Timer = 180000;
        }else IceArmor_Timer -= diff;

        //Frostbolt_Timer
        if (Frostbolt_Timer < diff)
        {
            Unit* target = NULL;
            target = SelectUnit(SELECT_TARGET_RANDOM,0, GetSpellMaxRange(SPELL_FROSTBOLT), true);
            if (target)
                DoCast(target,SPELL_FROSTBOLT);

            Frostbolt_Timer = 8000;
        }else Frostbolt_Timer -= diff;

        //Freeze_Timer
        if (Freeze_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_FREEZE);
            Freeze_Timer = 24000;
        }else Freeze_Timer -= diff;

        //Fear_Timer
        if (Fear_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_FEAR);
            Fear_Timer = 30000;
        }else Fear_Timer -= diff;

        //ChillNova_Timer
        if (ChillNova_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_CHILLNOVA);
            ChillNova_Timer = 14000;
        }else ChillNova_Timer -= diff;

        //FrostVolley_Timer
        if (FrostVolley_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_FROSTVOLLEY);
            FrostVolley_Timer = 15000;
        }else FrostVolley_Timer -= diff;

        DoMeleeAttackIfReady();
    }
void
TotemAI::UpdateAI(const uint32 /*diff*/)
{
    if (getTotem().GetTotemType() != TOTEM_ACTIVE)
        return;

    if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellEntry const *spellInfo = sSpellStore.LookupEntry(getTotem().GetSpell());
    if (!spellInfo)
        return;

    SpellMiscEntry const* spellMisc = sSpellMiscStore.LookupEntry(spellInfo->Id);

    // Get spell rangy
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellMisc->rangeIndex);
    float max_range = GetSpellMaxRange(srange);

    // SPELLMOD_RANGE not applied in this place just because nonexistent range mods for attacking totems

    // pointer to appropriate target if found any
    Unit* victim = m_creature->GetMap()->GetUnit(i_victimGuid);

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if( !victim ||
            !victim->isTargetableForAttack() || !m_creature->IsWithinDistInMap(victim, max_range) ||
            m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature,m_creature,false) )
    {
        victim = NULL;

        Strawberry::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, max_range);
        Strawberry::UnitLastSearcher<Strawberry::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);
        Cell::VisitAllObjects(m_creature, checker, max_range);
    }

    // If have target
    if (victim)
    {
        // remember
        i_victimGuid = victim->GetObjectGuid();

        // attack
        m_creature->SetInFront(victim);                      // client change orientation by self
        m_creature->CastSpell(victim, getTotem().GetSpell(), false);
    }
    else
        i_victimGuid.Clear();
}
Beispiel #11
0
    void UpdateAI(const uint32 diff)
    {
        if(!UpdateVictim())
            return;

        if( BerserkerCharge_Timer < diff )
        {
            Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_BERSERKER_CHARGE), true);
            if( target )
                DoCast(target,SPELL_BERSERKER_CHARGE);
            BerserkerCharge_Timer = 25000;
        }else BerserkerCharge_Timer -= diff;

        if( Uppercut_Timer < diff )
        {
            DoCast(m_creature->getVictim(),SPELL_UPPERCUT);
            Uppercut_Timer = 20000;
        }else Uppercut_Timer -= diff;

        if( Thunderclap_Timer < diff )
        {
            DoCast(m_creature->getVictim(),SPELL_THUNDERCLAP);
            Thunderclap_Timer = 15000;
        }else Thunderclap_Timer -= diff;

        if( MortalStrike_Timer < diff )
        {
            DoCast(m_creature->getVictim(),SPELL_MORTAL_STRIKE);
            MortalStrike_Timer = 15000;
        }else MortalStrike_Timer -= diff;

        if( Cleave_Timer < diff )
        {
            DoCast(m_creature->getVictim(),SPELL_CLEAVE);
            Cleave_Timer = 7000;
        }else Cleave_Timer -= diff;

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

        //Bomb_Timer
        if (Bomb_Timer < diff)
        {
            if (Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0, GetSpellMaxRange(SPELL_BOMB), true))
            {
                DoCast(target, SPELL_BOMB);
                Bomb_Timer = 5000;
            }
        }
        else
            Bomb_Timer -= diff;

        //Check_Timer
        if (Check_Timer < diff)
        {
            if (pInstance)
            {
                if (pInstance->GetData(DATA_JEKLIKEVENT) == DONE)
                {
                    m_creature->setDeathState(JUST_DIED);
                    m_creature->RemoveCorpse();
                }
            }

            Check_Timer = 1000;
        }
        else
            Check_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Beispiel #13
0
void PetAI::Reset()
{
    m_primaryTargetGuid.Clear();
    m_savedTargetGuid.Clear();
    m_attackDistanceRecheckTimer.SetInterval(TIME_INTERVAL_LOOK);
    m_attackDistanceRecheckTimer.Reset();
    m_updateAlliesTimer.SetInterval(ALLIES_UPDATE_TIME);
    m_updateAlliesTimer.Reset();
    UpdateAllies();

    for (uint8 i = PET_SPELL_PASSIVE; i < PET_SPELL_MAX; ++i)
        m_spellType[i].clear();

    m_AIType = PET_AI_PASSIVE;
    m_attackDistance  = 0.0f;
    float f_range   = 0.0f;

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

    uint32 spellsSize = m_creature->IsPet() ? ((Pet*)m_creature)->GetPetAutoSpellSize() : m_creature->GetPetAutoSpellSize();
    uint8 rangedDamageSpells = 0;
    uint8 meleeDamageSpells = 0;

    // classification for pet spells
    for (uint32 i = 0; i < spellsSize; ++i)
    {
        uint32 spellID = m_creature->IsPet() ? ((Pet*)m_creature)->GetPetAutoSpellOnPos(i) : m_creature->GetPetAutoSpellOnPos(i);
        if (!spellID)
            continue;

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

        if (IsPassiveSpell(spellInfo))
        {
            m_spellType[PET_SPELL_PASSIVE].insert(spellID);
            continue;
        }

        if (IsNonCombatSpell(spellInfo))
        {
            // Voidwalker Consume Shadows
            if (IsChanneledSpell(spellInfo))
                m_spellType[PET_SPELL_HEAL].insert(spellID);
            else
                m_spellType[PET_SPELL_NONCOMBAT].insert(spellID);
            continue;
        }

        // need more correct define this type
        if (IsSpellReduceThreat(spellInfo) || IsChanneledSpell(spellInfo))
        {
            m_spellType[PET_SPELL_DEFENCE].insert(spellID);
            continue;
        }

        // Voracious Appetite && Cannibalize && Carrion Feeder
        if (spellInfo->HasAttribute(SPELL_ATTR_ABILITY) && spellInfo->HasAttribute(SPELL_ATTR_EX2_ALLOW_DEAD_TARGET))
        {
            m_spellType[PET_SPELL_HEAL].insert(spellID);
            continue;
        }

        if (IsPositiveSpell(spellInfo) && IsSpellAppliesAura(spellInfo))
        {
            m_spellType[PET_SPELL_BUFF].insert(spellID);
            continue;
        }

        if (spellInfo->HasAttribute(SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY))
        {
            m_spellType[PET_SPELL_FREEACTION].insert(spellID);
            continue;
        }

        // don't have SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY !
        if (spellInfo->HasAttribute(SPELL_ATTR_EX_CANT_REFLECTED) ||
            spellInfo->HasAttribute(SPELL_ATTR_EX7_HAS_CHARGE_EFFECT))
        {
            m_spellType[PET_SPELL_ATTACKSTART].insert(spellID);
            continue;
        }

        if (IsSpellIncreaseThreat(spellInfo))
        {
            m_spellType[PET_SPELL_THREAT].insert(spellID);
            continue;
        }

        // all non-combat spells classified.
        switch (spellInfo->rangeIndex)
        {
            case SPELL_RANGE_IDX_COMBAT:
            {
                if (IsSpellCauseDamage(spellInfo))
                {
                    m_spellType[PET_SPELL_MELEE].insert(spellID);
                    ++meleeDamageSpells;
                }
                else
                {
                    m_spellType[PET_SPELL_SPECIAL].insert(spellID);
                }
                break;
            }
            // possible debuffs or auras?
            case SPELL_RANGE_IDX_SELF_ONLY:
            case SPELL_RANGE_IDX_ANYWHERE:
            {
                m_spellType[PET_SPELL_SPECIAL].insert(spellID);
                break;
            }
            default:
            {
                float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(spellInfo->rangeIndex), false);
                if (f_range < M_NULL_F || (range > M_NULL_F && range < f_range))
                    f_range = range;
                if (IsSpellCauseDamage(spellInfo))
                {
                    m_spellType[PET_SPELL_RANGED].insert(spellID);
                    ++rangedDamageSpells;
                }
                else
                {
                    m_spellType[PET_SPELL_SPECIAL].insert(spellID);
                }
                break;
            }
        }
    }

    // define initial AI type
    if (m_creature->IsVehicle())
        m_AIType = PET_AI_PASSIVE;

    if (m_spellType[PET_SPELL_RANGED].size() > 0 && (m_spellType[PET_SPELL_MELEE].size() < m_spellType[PET_SPELL_RANGED].size()))
    {
        m_AIType = PET_AI_RANGED;
        m_attackDistance = f_range - m_creature->GetObjectBoundingRadius() - 2.0f;
        if (m_attackDistance < 20.0f)
            m_attackDistance = 18.0f;
    }
    else
    {
        m_AIType = PET_AI_MELEE;
        m_attackDistance = 0.0f;
    }
    m_savedAIType = m_AIType;

    m_creature->GetMotionMaster()->MoveTargetedHome();

    DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS,"PetAI::Reset %s, AI %u dist %f, spells: "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD" "SIZEFMTD ,
        m_creature->GetObjectGuid().GetString().c_str(),
        m_AIType,
        m_attackDistance,
        m_spellType[PET_SPELL_PASSIVE].size(),
        m_spellType[PET_SPELL_NONCOMBAT].size(),
        m_spellType[PET_SPELL_BUFF].size(),
        m_spellType[PET_SPELL_DEBUFF].size(),
        m_spellType[PET_SPELL_FREEACTION].size(),
        m_spellType[PET_SPELL_ATTACKSTART].size(),
        m_spellType[PET_SPELL_THREAT].size(),
        m_spellType[PET_SPELL_MELEE].size(),
        m_spellType[PET_SPELL_RANGED].size(),
        m_spellType[PET_SPELL_DEFENCE].size(),
        m_spellType[PET_SPELL_SPECIAL].size(),
        m_spellType[PET_SPELL_HEAL].size()
        );
}
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim() )
            return;

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

            CheckTimer = 3000;
        }
        else
            CheckTimer -= diff;

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

        if(Holyground_Timer < diff)
        {
            DoCast(m_creature, SPELL_HOLYGROUND, true);     //Triggered so it doesn't interrupt her at all
            Holyground_Timer = 3000;
        }
        else
            Holyground_Timer -= diff;

        if (Repentance_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_REPENTANCE);

            DoScriptText(RAND(SAY_REPENTANCE1, SAY_REPENTANCE2), m_creature);

            Repentance_Timer = 30000 + rand()%15000;        //A little randomness on that spell
            Holyfire_Timer += 6000;
        }
        else
            Repentance_Timer -= diff;

        if(Holyfire_Timer < diff)
        {
            if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_HOLYFIRE), true))
                DoCast(target,SPELL_HOLYFIRE);

                Holyfire_Timer = 8000 + rand()%17000; //Anywhere from 8 to 25 seconds, good luck having several of those in a row!
        }
        else
            Holyfire_Timer -= diff;

        if(Holywrath_Timer < diff)
        {
            if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_HOLYWRATH), true))
                DoCast(target,SPELL_HOLYWRATH);

            Holywrath_Timer = 20000+(rand()%10000);     //20-30 secs sounds nice

        }
        else
            Holywrath_Timer -= diff;

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

        //BrainWashTotem_Timer
        if (BrainWashTotem_Timer < diff)
        {
            DoCast(m_creature, SPELL_BRAINWASHTOTEM);
            BrainWashTotem_Timer = 18000 + rand()%8000;
        }
        else
            BrainWashTotem_Timer -= diff;

        //HealingWard_Timer
        if (HealingWard_Timer < diff)
        {
            DoCast(m_creature, SPELL_POWERFULLHEALINGWARD);
            HealingWard_Timer = 14000 + rand()%6000;
        }
        else
            HealingWard_Timer -= diff;

        //Hex_Timer
        if (Hex_Timer < diff)
        {
            DoCast(m_creature->getVictim(), SPELL_HEX);

            if(DoGetThreat(m_creature->getVictim()))
                DoModifyThreatPercent(m_creature->getVictim(),-80);

            Hex_Timer = 12000 + rand()%8000;
        }
        else
            Hex_Timer -= diff;

        //Casting the delusion curse with a shade. So shade will attack the same target with the curse.
        if(Delusions_Timer < diff)
        {
            if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0, GetSpellMaxRange(SPELL_DELUSIONSOFJINDO), true))
            {
                DoCast(target, SPELL_DELUSIONSOFJINDO);

                Shade = m_creature->SummonCreature(14986, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Shade)
                    Shade->AI()->AttackStart(target);
            }
            Delusions_Timer = 4000 + rand()%8000;
        }
        else
            Delusions_Timer -= diff;

        //Teleporting a random gamer and spawning 9 skeletons that will attack this gamer
        if(Teleport_Timer < diff)
        {
            if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0, 200, true))
            {
                DoTeleportPlayer(target, -11583.7783,-1249.4278,77.5471,4.745);

                if(DoGetThreat(m_creature->getVictim()))
                    DoModifyThreatPercent(target,-100);

                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-2, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()-4, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-2, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()+4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX(), target->GetPositionY()-4, target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
                Skeletons = m_creature->SummonCreature(14826, target->GetPositionX()+3, target->GetPositionY(), target->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Skeletons)
                    Skeletons->AI()->AttackStart(target);
            }

            Teleport_Timer = 15000 + rand()%8000;
        }
        else
            Teleport_Timer -= diff;

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

        if (checkTimer2 < diff)
        {
            if (!m_creature->IsWithinDistInMap(&wLoc, 50))
                EnterEvadeMode();
            else
                DoZoneInCombat();
            checkTimer2 = 3000;
        }
        else
            checkTimer2 -= diff;

        if(BerserkTimer < diff)
        {
            AddSpellToCastWithScriptText(m_creature, SPELL_BERSERK, YELL_BERSERK);
            BerserkTimer = 60000;
        }else BerserkTimer -= diff;

        if(Phase == PHASE_LYNX || Phase == PHASE_ENRAGE)
        {
            if(SaberlashTimer < diff)
            {
                AddSpellToCastWithScriptText(m_creature->getVictim(), SPELL_SABER_LASH, RAND(YELL_SABER_ONE, YELL_SABER_TWO));
                SaberlashTimer = 5000 + rand() % 10000;
            }else SaberlashTimer -= diff;

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

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

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

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

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

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

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

        if(m_creature->getVictim() && m_creature->isAlive())
        {
            if(PoisonVolley_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_POISONVOLLEY);
                PoisonVolley_Timer = 10000 + rand()%10000;
            }
            else
                PoisonVolley_Timer -= diff;

            if(!PhaseTwo && Aspect_Timer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_ASPECT_OF_MARLI);
                Aspect_Timer = 13000 + rand()%5000;
            }
            else
                Aspect_Timer -= diff;

            if(!Spawned && SpawnStartSpiders_Timer < diff)
            {
                DoScriptText(SAY_SPIDER_SPAWN, m_creature);

                Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if(!target)
                    return;

                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Spider)
                    Spider->AI()->AttackStart(target);
                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Spider)
                    Spider->AI()->AttackStart(target);

                Spawned = true;
            }
            else
                SpawnStartSpiders_Timer -= diff;

            if(SpawnSpider_Timer < diff)
            {
                Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);
                if(!target)
                    return;

                Spider = m_creature->SummonCreature(15041,target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(),0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                if(Spider)
                    Spider->AI()->AttackStart(target);
                SpawnSpider_Timer = 12000 + rand()%5000;
            }
            else
                SpawnSpider_Timer -= diff;

            if(!PhaseTwo && Transform_Timer < diff)
            {
                DoScriptText(SAY_TRANSFORM, m_creature);
                DoCast(m_creature,SPELL_SPIDER_FORM);
                const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
                m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 35)));
                m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 35)));
                m_creature->UpdateDamagePhysical(BASE_ATTACK);
                DoCast(m_creature->getVictim(),SPELL_ENVOLWINGWEB);

                if(DoGetThreat(m_creature->getVictim()))
                    DoModifyThreatPercent(m_creature->getVictim(),-100);

                PhaseTwo = true;
                Transform_Timer = 35000 + rand()%25000;
            }
            else
                Transform_Timer -= diff;

            if(PhaseTwo)
            {
                if(Charge_Timer < diff)
                {
                    Unit* target = NULL;
                    int i = 0 ;
                    while (i < 3)                           // max 3 tries to get a random target with power_mana
                    {
                        ++i;                                //not aggro leader
                        target = SelectUnit(SELECT_TARGET_RANDOM,1, GetSpellMaxRange(SPELL_CHARGE), true, m_creature->getVictimGUID());
                        if(target)
                            if (target->getPowerType() == POWER_MANA)
                                i=3;
                    }

                    if(target)
                    {
                        DoCast(target, SPELL_CHARGE);
                        //m_creature->Relocate(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0);
                        //m_creature->SendMonsterMove(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 0, true,1);
                        AttackStart(target);
                    }

                    Charge_Timer = 8000;
                }
                else
                    Charge_Timer -= diff;

                if(TransformBack_Timer < diff)
                {
                    m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,15220);
                    const CreatureInfo *cinfo = m_creature->GetCreatureInfo();
                    m_creature->SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, (cinfo->mindmg +((cinfo->mindmg/100) * 1)));
                    m_creature->SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, (cinfo->maxdmg +((cinfo->maxdmg/100) * 1)));
                    m_creature->UpdateDamagePhysical(BASE_ATTACK);

                    PhaseTwo = false;
                    TransformBack_Timer = 25000 + rand()%15000;
                }
                else
                    TransformBack_Timer -= diff;

            }

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

        if(Check_Timer < diff)
        {
            if(!m_creature->IsWithinDistInMap(&wLoc, 80.0f))
                EnterEvadeMode();

            Check_Timer = 2000;
        }else Check_Timer -= diff;

        //Spell Enrage, when hp <= 20% gain enrage
        if (((m_creature->GetHealth()*100)/ m_creature->GetMaxHealth()) <= 20)
        {
            if(Enrage_Timer < diff)
            {
                m_creature->RemoveAurasDueToSpell(SPELL_ENRAGE);
                DoCast(m_creature,SPELL_ENRAGE);
                Enrage_Timer = 600000;
                InEnrage = true;
            }else Enrage_Timer -= diff;
        }

        //Spell Overrun
        if (Overrun_Timer < diff)
        {
            DoScriptText(RAND(SAY_OVERRUN_1, SAY_OVERRUN_2), m_creature);

            DoCast(m_creature->getVictim(),SPELL_OVERRUN);

            DoResetThreat();

            Overrun_Timer = 25000 + rand()%15000;
        }else Overrun_Timer -= diff;

        //Spell Earthquake
        if (Quake_Timer < diff)
        {
            if (rand()%2)
                return;

            DoScriptText(RAND(SAY_EARTHQUAKE_1, SAY_EARTHQUAKE_2), m_creature);

            //remove enrage before casting earthquake because enrage + earthquake = 16000dmg over 8sec and all dead
            if (InEnrage)
                m_creature->RemoveAura(SPELL_ENRAGE, 0);

            DoCast(m_creature,SPELL_EARTHQUAKE);
            Enrage_Timer = 8000;
            Quake_Timer = 30000 + rand()%25000;
        }else Quake_Timer -= diff;

        //Spell Chain Lightning
        if (Chain_Timer < diff)
        {
            Unit* target = NULL;
            target = SelectUnit(SELECT_TARGET_RANDOM,1, GetSpellMaxRange(SPELL_CHAIN_LIGHTNING), true, m_creature->getVictimGUID());

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

            if (target)
                DoCast(target,SPELL_CHAIN_LIGHTNING);

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

        //Spell Sunder Armor
        if (Armor_Timer < diff)
        {
            DoCast(m_creature->getVictim(),SPELL_SUNDER_ARMOR);
            Armor_Timer = 10000 + rand()%15000;
        }else Armor_Timer -= diff;

        DoMeleeAttackIfReady();
    }
Beispiel #19
0
    void UpdateAI(const uint32 diff)
    {
        if(isFlameBreathing)
        {
            if(!m_creature->IsNonMeleeSpellCasted(false))
            {
                isFlameBreathing = false;
            }else 
            {
                if(EnrageTimer > diff)
                    EnrageTimer -= diff;
                else
                    EnrageTimer = 0;
                if(HatcherTimer > diff)
                    HatcherTimer -= diff;
                else
                    HatcherTimer = 0;
                return;
            }
        }

        if(isBombing)
        {
            if(BombSequenceTimer < diff)
            {
                HandleBombSequence();
            }else 
                BombSequenceTimer -= diff;
    
            if(EnrageTimer > diff)
                EnrageTimer -= diff;
            else
                EnrageTimer = 0;
            if(HatcherTimer > diff)
                HatcherTimer -= diff;
            else
                HatcherTimer = 0;
            return;
        }

        if(!UpdateVictim())
            return;

        if (checkTimer < diff)
        {
            if (!m_creature->IsWithinDistInMap(&wLoc, 25))
                EnterEvadeMode();
            else
                DoZoneInCombat();
            checkTimer = 3000;
        }
        else
            checkTimer -= diff;

        //enrage if under 25% hp before 5 min.
        if(!enraged && m_creature->GetHealth() * 4 < m_creature->GetMaxHealth())
            EnrageTimer = 0;

        if(EnrageTimer < diff)
        {
            if(!enraged)
            {
                m_creature->CastSpell(m_creature, SPELL_ENRAGE, true);
                enraged = true;
                EnrageTimer = 300000;
            }
            else
            {
                DoScriptText(SAY_BERSERK, m_creature);
                m_creature->CastSpell(m_creature, SPELL_BERSERK, true);
                EnrageTimer = 300000;
            }
        }else EnrageTimer -= diff;

        if(BombTimer < diff)
        {
            DoScriptText(SAY_FIRE_BOMBS, m_creature);

            m_creature->AttackStop();
            m_creature->GetMotionMaster()->Clear();
            DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]);
            m_creature->StopMoving();
            m_creature->CastSpell(m_creature, SPELL_FIRE_BOMB_CHANNEL, false);
            //DoTeleportPlayer(m_creature, JanalainPos[0][0], JanalainPos[0][1],JanalainPos[0][2], 0);
            //m_creature->CastSpell(m_creature, SPELL_TELE_TO_CENTER, true);

            FireWall();
            SpawnBombs();
            isBombing = true;
            BombSequenceTimer = 100;

            //Teleport every Player into the middle
            Map *map = m_creature->GetMap();
            if(!map->IsDungeon()) return;
            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())
                        DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0);
            }
            //m_creature->CastSpell(Temp, SPELL_SUMMON_PLAYERS, true); // core bug, spell does not work if too far
            return;
        }else BombTimer -= diff;

        if(!noeggs)
        {
            if(100 * m_creature->GetHealth() < 35 * m_creature->GetMaxHealth())
            {
                DoScriptText(SAY_ALL_EGGS, m_creature);

                m_creature->AttackStop();
                m_creature->GetMotionMaster()->Clear();
                DoTeleportTo(JanalainPos[0][0],JanalainPos[0][1],JanalainPos[0][2]);
                m_creature->StopMoving();
                m_creature->CastSpell(m_creature, SPELL_HATCH_ALL, false);
                HatchAllEggs(2);
                noeggs = true;
            }
            else if(HatcherTimer < diff)
            {
                if(HatchAllEggs(0))
                {
                    DoScriptText(SAY_SUMMON_HATCHER, m_creature);
                    m_creature->SummonCreature(MOB_AMANI_HATCHER,hatcherway[0][0][0],hatcherway[0][0][1],hatcherway[0][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
                    m_creature->SummonCreature(MOB_AMANI_HATCHER,hatcherway[1][0][0],hatcherway[1][0][1],hatcherway[1][0][2],0,TEMPSUMMON_CORPSE_TIMED_DESPAWN,10000);
                    HatcherTimer = 90000;
                }
                else
                    noeggs = true;
            }else HatcherTimer -= diff;
        }

        if(ResetTimer < diff)
        {
            float x, y, z, o;
            m_creature->GetHomePosition(x, y, z, o);
            if(m_creature->GetPositionZ() <= z-7)
            {
                EnterEvadeMode();
                return;
            }
            ResetTimer = 5000;
        }else ResetTimer -= diff;

        DoMeleeAttackIfReady();

        if(FireBreathTimer < diff)
        {
            if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0, GetSpellMaxRange(SPELL_FLAME_BREATH), true))
            {
                me->SetSelection(target->GetGUID());
                me->SetInFront(target);
                m_creature->CastSpell(target, SPELL_FLAME_BREATH, false);
                isFlameBreathing = true;
            }
            FireBreathTimer = 8000;
        }else FireBreathTimer -= diff;
    }
Beispiel #20
0
void TotemAI::UpdateAI(const uint32 diff)
{
    // Events are only updated once every EVENT_UPDATE_TIME ms to prevent lag with large amount of events
    if (m_EventUpdateTime < diff)
    {
        m_EventDiff += diff;

        // Check for time based events
        for (CreatureEventAIList::iterator i = m_CreatureEventAIList.begin(); i != m_CreatureEventAIList.end(); ++i)
        {
            // Decrement Timers
            if (i->Time)
            {
                // Do not decrement timers if event cannot trigger in this phase
                if (!(i->Event.event_inverse_phase_mask & (1 << m_Phase)))
                {
                    if (i->Time > m_EventDiff)
                        i->Time -= m_EventDiff;
                    else
                        i->Time = 0;
                }
            }

            // Skip processing of events that have time remaining or are disabled
            if (!(i->Enabled) || i->Time)
                continue;

            if (IsTimerBasedEvent(i->Event.event_type))
                ProcessEvent(*i);
        }

        m_EventDiff = 0;
        m_EventUpdateTime = EVENT_UPDATE_TIME;
    }
    else
    {
        m_EventDiff += diff;
        m_EventUpdateTime -= diff;
    }

    if (getTotem().GetTotemType() != TOTEM_ACTIVE)
        return;

    if (!m_creature->isAlive() || m_creature->IsNonMeleeSpellCasted(false))
        return;

    // Search spell
    SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(getTotem().GetSpell());
    if (!spellInfo)
        return;

    // Get spell rangy
    SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(spellInfo->rangeIndex);
    float maxRange = GetSpellMaxRange(srange);

    // SPELLMOD_RANGE not applied in this place just because nonexistent range mods for attacking totems

    // pointer to appropriate target if found any
    Unit* victim = m_creature->GetMap()->GetUnit(i_victimGuid);

    // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end)
    if (!victim ||
            !m_creature->CanAttack(victim) || !m_creature->IsWithinDistInMap(victim, maxRange) ||
            m_creature->IsFriendlyTo(victim) || !victim->isVisibleForOrDetect(m_creature, m_creature, false))
    {
        victim = nullptr;

        MaNGOS::NearestAttackableUnitInObjectRangeCheck u_check(m_creature, m_creature, maxRange);
        MaNGOS::UnitLastSearcher<MaNGOS::NearestAttackableUnitInObjectRangeCheck> checker(victim, u_check);
        Cell::VisitAllObjects(m_creature, checker, maxRange);
    }

    // If have target
    if (victim)
    {
        // remember
        i_victimGuid = victim->GetObjectGuid();

        // attack
        m_creature->SetInFront(victim);                     // client change orientation by self
        m_creature->CastSpell(victim, getTotem().GetSpell(), TRIGGERED_NONE);
    }
    else
        i_victimGuid.Clear();
}
Beispiel #21
0
    void UpdateAI(const uint32 diff)
    {
        if(waitTimer)
        {
            if(inMove)
                if(waitTimer < diff)
                {
                    (*m_creature).GetMotionMaster()->MovementExpired();
                    (*m_creature).GetMotionMaster()->MovePoint(MovePhase,NalorakkWay[MovePhase][0],NalorakkWay[MovePhase][1],NalorakkWay[MovePhase][2]);
                    waitTimer = 0;
                }else 
                    waitTimer -= diff;
        }

        if(!UpdateVictim())
            return;

        if (checkTimer < diff)
        {
            if (!m_creature->IsWithinDistInMap(&wLoc, 75) && !MoveEvent)
                EnterEvadeMode();
            else
                DoZoneInCombat();
            m_creature->SetSpeed(MOVE_RUN,2);
            checkTimer = 3000;
        }
        else
            checkTimer -= diff;

        if(Berserk_Timer < diff)
        {
            AddSpellToCastWithScriptText(m_creature, SPELL_BERSERK, YELL_BERSERK, true);
            Berserk_Timer = 600000;
        }else 
            Berserk_Timer -= diff;

        if(!inBearForm)
        {
            if(BrutalSwipe_Timer < diff)
            {
                AddSpellToCast(m_creature->getVictim(), SPELL_BRUTALSWIPE);
                BrutalSwipe_Timer = 7000 + rand()%5000;
            }else 
                BrutalSwipe_Timer -= diff;

            if(Mangle_Timer < diff)
            {
                if(m_creature->getVictim() && !m_creature->getVictim()->HasAura(SPELL_MANGLEEFFECT, 0))
                {
                    AddSpellToCast(m_creature->getVictim(), SPELL_MANGLE);
                    Mangle_Timer = 1000;
                }
                else 
                    Mangle_Timer = 10000 + rand()%5000;
            }else 
                Mangle_Timer -= diff;

            if(Surge_Timer < diff)
            {
                if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 1, GetSpellMaxRange(SPELL_SURGE), true, m_creature->getVictimGUID()))
                    AddSpellToCastWithScriptText(target, SPELL_SURGE, YELL_SURGE);
                Surge_Timer = 15000 + rand()%5000;
            }else 
                Surge_Timer -= diff;

            if(ShapeShift_Timer)
            {
                if(ShapeShift_Timer <= diff)
                {
                    AddSpellToCastWithScriptText(m_creature, SPELL_BEARFORM, YELL_SHIFTEDTOBEAR, true);
                    ShapeShift_Timer = 0;
                }else 
                    ShapeShift_Timer -= diff;
            }
        }
        else
        {
            if(LaceratingSlash_Timer < diff)
            {
                AddSpellToCast(m_creature->getVictim(), SPELL_LACERATINGSLASH);
                LaceratingSlash_Timer = 18000 + rand()%5000;
            }else
                LaceratingSlash_Timer -= diff;

            if(RendFlesh_Timer < diff)
            {
                AddSpellToCast(m_creature->getVictim(), SPELL_RENDFLESH);
                RendFlesh_Timer = 5000 + rand()%5000;
            }else
                RendFlesh_Timer -= diff;

            if(DeafeningRoar_Timer < diff)
            {
                AddSpellToCast(m_creature->getVictim(), SPELL_DEAFENINGROAR);
                DeafeningRoar_Timer = 15000 + rand()%5000;
            }else
                DeafeningRoar_Timer -= diff;
        }

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

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

        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)
            {
                Creature* Temp = NULL;
                if (AddGUID[i])
                {
                    Temp = Unit::GetCreature((*m_creature),AddGUID[i]);
                    if (Temp && Temp->isAlive())
                        if (!Temp->getVictim() )
                            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)
            {
                DoCast(m_creature, SPELL_VANISH);
                InVanish = true;
                m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                NonAttackable = true;
                NonAttackable_Timer = 12100;
                Vanish_Timer = 30000;
                Wait_Timer = 5000;
            }
            else
                Vanish_Timer -= diff;

            if(Gouge_Timer < diff)
            {
                DoCast(m_creature->getVictim(), SPELL_GOUGE);
                Gouge_Timer = 40000;
            }
            else
                Gouge_Timer -= diff;

            if(Blind_Timer < diff)
            {
                if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, GetSpellMaxRange(SPELL_BLIND), true))
                    DoCast(target, SPELL_BLIND);

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

        if(InVanish)
        {
            if(Wait_Timer < diff)
            {
                DoScriptText(RAND(SAY_SPECIAL_1, SAY_SPECIAL_2), m_creature);

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

                InVanish = false;
            }
            else
                Wait_Timer -= diff;
        }

        if(!InVanish)
            DoMeleeAttackIfReady();

        if(NonAttackable)
        {
            if(NonAttackable_Timer < diff)
            {
                m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
                NonAttackable = false;
            } else NonAttackable_Timer -= diff;
        }
    }
Beispiel #23
0
    void UpdateAI(const uint32 diff)
    {
        if (!UpdateVictim())
            return;

        if (m_creature->getVictim() && m_creature->isAlive())
        {
            if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth() > 50))
            {
                if (Charge_Timer < diff)
                {
                    if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0, GetSpellMaxRange(SPELL_CHARGE), true))
                    {
                        DoCast(target,SPELL_CHARGE);
                        AttackStart(target);
                    }

                    Charge_Timer = 15000 + rand()%15000;
                }
                else
                    Charge_Timer -= diff;

                if (SonicBurst_Timer < diff)
                {
                    DoCast(m_creature->getVictim(),SPELL_SONICBURST);
                    SonicBurst_Timer = 8000 + rand()%5000;
                }
                else
                    SonicBurst_Timer -= diff;

                if (Screech_Timer < diff)
                {
                    DoCast(m_creature->getVictim(),SPELL_SCREECH);
                    Screech_Timer = 18000 + rand()%8000;
                }
                else
                    Screech_Timer -= diff;

                if (SpawnBats_Timer < diff)
                {
                    Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0);

                    if (target)
                    {
                        Creature* Bat = NULL;
                        for (uint8 i = 0 ; i < BAT_COUNT; ++i)
                        {
                            Bat = m_creature->SummonCreature(BAT_ID, batLocations[i][0], batLocations[i][1], batLocations[i][2], 5.483, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                            if (Bat)
                                Bat->AI()->AttackStart(target);
                        }
                    }

                    SpawnBats_Timer = 60000;
                }
                else
                    SpawnBats_Timer -= diff;
            }
            else
            {
                if (PhaseTwo)
                {
                    if (PhaseTwo && ShadowWordPain_Timer < diff)
                    {
                        if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_SHADOW_WORD_PAIN), true))
                        {
                            DoCast(target, SPELL_SHADOW_WORD_PAIN);
                            ShadowWordPain_Timer = 12000 + rand()%6000;
                        }
                    }
                    else
                        ShadowWordPain_Timer -=diff;

                    if (MindFlay_Timer < diff)
                    {
                        DoCast(m_creature->getVictim(), SPELL_MIND_FLAY);
                        MindFlay_Timer = 16000;
                    }
                    else
                        MindFlay_Timer -= diff;

                    if (ChainMindFlay_Timer < diff)
                    {
                        m_creature->InterruptNonMeleeSpells(false);
                        DoCast(m_creature->getVictim(), SPELL_CHAIN_MIND_FLAY);
                        ChainMindFlay_Timer = 15000 + rand()%15000;
                    }
                    else
                        ChainMindFlay_Timer -= diff;

                    if (GreaterHeal_Timer < diff)
                    {
                        m_creature->InterruptNonMeleeSpells(false);
                        DoCast(m_creature,SPELL_GREATERHEAL);
                        GreaterHeal_Timer = 25000 + rand()%10000;
                    }
                    else
                        GreaterHeal_Timer -= diff;

                    if (SpawnFlyingBats_Timer < diff)
                    {
                        Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0);
                        if (!target)
                            return;

                        Creature* FlyingBat = m_creature->SummonCreature(14965, target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()+15, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 15000);
                        if (FlyingBat)
                            FlyingBat->AI()->AttackStart(target);

                        SpawnFlyingBats_Timer = 10000 + rand()%5000;
                    }
                    else
                        SpawnFlyingBats_Timer -=diff;
                }
                else
                {
                    m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, 15219);
                    DoResetThreat();
                    PhaseTwo = true;
                }
            }

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

        DoSpecialThings(diff, DO_EVERYTHING, 125.0f, 1.5f);

        // Void Zone
        if(VoidZoneTimer < diff)
        {
            if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM,1,GetSpellMaxRange(SPELL_VOIDZONE),true, m_creature->getVictimGUID()))
                AddSpellToCast(target,SPELL_VOIDZONE,true);

            VoidZoneTimer = 15000;
        }
        else
            VoidZoneTimer -= diff;

        // NetherInfusion Berserk
        if(!Berserk && NetherInfusionTimer < diff)
        {
            m_creature->AddAura(SPELL_NETHER_INFUSION, m_creature);
            ForceSpellCast(m_creature, SPELL_NETHERSPITE_ROAR, INTERRUPT_AND_CAST_INSTANTLY);
            Berserk = true;
        }
        else
            NetherInfusionTimer -= diff;

        if(PortalPhase) // PORTAL PHASE
        {
            // Distribute beams and buffs
            if(PortalTimer < diff)
            {
                UpdatePortals();
                PortalTimer = 1000;
            }
            else
                PortalTimer -= diff;

            // Empowerment & Nether Burn
            if(EmpowermentTimer < diff)
            {
                ForceSpellCast(m_creature, SPELL_EMPOWERMENT);
                m_creature->AddAura(SPELL_NETHERBURN_AURA, m_creature);
                EmpowermentTimer = 90000;
            }
            else
                EmpowermentTimer -= diff;

            if(PhaseTimer < diff)
            {
                if(!m_creature->IsNonMeleeSpellCast(false))
                {
                    SwitchToBanishPhase();
                    return;
                }
            }
            else
                PhaseTimer -= diff;

            DoMeleeAttackIfReady();
        }
        else // BANISH PHASE
        {
            if(m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != IDLE_MOTION_TYPE)
            {
                m_creature->GetMotionMaster()->Clear();
                m_creature->GetMotionMaster()->MoveIdle();
            }

            // Netherbreath
            if(NetherbreathTimer < diff)
            {
                if(Unit* target = SelectUnit(SELECT_TARGET_RANDOM,0,GetSpellMaxRange(SPELL_NETHERBREATH),true))
                    AddSpellToCast(target,SPELL_NETHERBREATH);

                NetherbreathTimer = 5000+rand()%2000;
            }
            else
                NetherbreathTimer -= diff;

            if(PhaseTimer < diff)
            {
                if(!m_creature->IsNonMeleeSpellCast(false))
                {
                    SwitchToPortalPhase();
                    return;
                }
            }
            else
                PhaseTimer -= diff;
        }
        CastNextSpellIfAnyAndReady();
    }
Beispiel #25
0
void ScriptedAI::CastNextSpellIfAnyAndReady(uint32 diff)
{
    // clear spell list if caster isn't alive
    if (!m_creature->isAlive())
    {
        spellList.clear();
        autocast = false;
        return;
    }

    bool casted = false;

    if (m_creature->hasUnitState(UNIT_STAT_CASTING) || me->IsNonMeleeSpellCasted(true))
        casted = true;

    if (!spellList.empty() && !casted)
    {
        SpellToCast temp(spellList.front());
        spellList.pop_front();

        // creature can't cast if lost control - moved here to drop spells if controlled instead not adding them to queue
        if (m_creature->isCrowdControlled() || m_creature->IsPolymorphed())
            return;

        if (!temp.spellId)
            return;

        if (temp.isDestCast)
        {
            m_creature->CastSpell(temp.castDest[0], temp.castDest[1], temp.castDest[2], temp.spellId, temp.triggered);
            casted = true;
            return;
        }

        if (temp.scriptTextEntry)
        {
            if (temp.targetGUID && temp.setAsTarget)
            {
                if (Unit* target = m_creature->GetUnit(temp.targetGUID))
                    DoScriptText(temp.scriptTextEntry, m_creature, target);
            }
            else
                DoScriptText(temp.scriptTextEntry, m_creature, m_creature->getVictim());
        }

        if (temp.targetGUID)
        {
            Unit * tempU = m_creature->GetUnit(*m_creature, temp.targetGUID);

            if (tempU && tempU->IsInWorld() && tempU->isAlive() && tempU->IsInMap(m_creature))
                if (temp.spellId)
                {
                    if(temp.setAsTarget && !m_creature->hasIgnoreVictimSelection())
                        m_creature->SetSelection(temp.targetGUID);
                    if(temp.hasCustomValues)
                        m_creature->CastCustomSpell(tempU, temp.spellId, &temp.damage[0], &temp.damage[1], &temp.damage[2], temp.triggered);
                    else
                        m_creature->CastSpell(tempU, temp.spellId, temp.triggered);
                }
        }
        else
        {
            if(temp.hasCustomValues)
                m_creature->CastCustomSpell((Unit*)NULL, temp.spellId, &temp.damage[0], &temp.damage[1], &temp.damage[2], temp.triggered);
            else
                m_creature->CastSpell((Unit*)NULL, temp.spellId, temp.triggered);
        }

        casted = true;
    }

    if (autocast)
    {
        if (autocastTimer < diff)
        {
            if (!casted)
            {
                Unit * victim = NULL;

                switch (autocastMode)
                {
                    case CAST_TANK:
                    {
                        victim = m_creature->getVictim();
                        // prevent from LoS exploiting, probably some general check should be implemented for this
                        uint8 i = 0;
                        SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(autocastId);

                        // while (!victim or not in los) and i < threatlist size
                        while ((!victim || (!SpellMgr::SpellIgnoreLOS(spellInfo, 0) && !m_creature->IsWithinLOSInMap(victim))) && i < m_creature->getThreatManager().getThreatList().size())
                        {
                            ++i;
                            victim = SelectUnit(SELECT_TARGET_TOPAGGRO, i, GetSpellMaxRange(autocastId), true);
                        }
                        break;
                    }
                    case CAST_NULL:
                        m_creature->CastSpell((Unit*)NULL, autocastId, false);
                        break;
                    case CAST_RANDOM:
                        victim = SelectUnit(SELECT_TARGET_RANDOM, 0, autocastTargetRange, autocastTargetPlayer);
                        break;
                    case CAST_RANDOM_WITHOUT_TANK:
                        victim = SelectUnit(SELECT_TARGET_RANDOM, 1, autocastTargetRange, autocastTargetPlayer, m_creature->getVictimGUID());
                        break;
                    case CAST_SELF:
                        victim = m_creature;
                        break;
                    case CAST_THREAT_SECOND:
                        victim = SelectUnit(SELECT_TARGET_TOPAGGRO, 1, autocastTargetRange, autocastTargetPlayer);
                        break;
                    default:    //unsupported autocast, stop
                        {
                            autocast = false;
                            return;
                        }
                }

                if (victim && !m_creature->hasIgnoreVictimSelection())
                {
                    m_creature->SetSelection(victim->GetGUID());    // for autocast always target actual victim
                    m_creature->CastSpell(victim, autocastId, false);
                }

                autocastTimer = autocastTimerDef;
            }
        }
        else
            autocastTimer -= diff;
    }
}
Beispiel #26
0
    void UpdateAI(const uint32 diff)
    {
        if (Intro)
        {
            if (IntroTimer < diff)
            {
                if (attackers.empty())
                    NextWave();

                Map* tmpMap = me->GetMap();

                if (!tmpMap)
                    return;

                if (!attackers.empty())
                {
                    bool alive = false;
                    for (std::list<uint64>::iterator itr = attackers.begin(); itr != attackers.end(); ++itr)
                    {
                        if (Creature* attacker = tmpMap->GetCreature((*itr)))
                        {
                            if (attacker->isAlive())
                            {
                                alive = true;
                                break;
                            }
                        }
                    }
                    
                    if (!alive)
                    {
                        NextWave();
                        NextTimer = 5000;
                    }
                }

                if (Creature* Thrall = tmpMap->GetCreature(ThrallGUID))
                {
                    if (!Thrall->isAlive())
                        me->ForcedDespawn();
                }

                IntroTimer = 5000;
            }
            else
                IntroTimer -= diff;

            if (Next)
            {
                if (NextTimer <= diff) 
                {
                    NextWave();
                }
                else NextTimer -= diff;
            }
        }

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

        //Sand Breath
        if (SandBreath_Timer < diff)
        {
            if (me->IsNonMeleeSpellCast(false))
                me->InterruptNonMeleeSpells(false);

            DoCast(me->getVictim(),SPELL_SAND_BREATH);

            DoScriptText(RAND(SAY_BREATH1, SAY_BREATH2), me);

            SandBreath_Timer = 25000+rand()%5000;
        }
        else
            SandBreath_Timer -= diff;

        if(ImpendingDeath_Timer < diff)
        {
            if(Unit *target = SelectUnit(SELECT_TARGET_RANDOM, 0 , GetSpellMaxRange(SPELL_IMPENDING_DEATH), true))
                DoCast(target,SPELL_IMPENDING_DEATH);
            ImpendingDeath_Timer = 30000+rand()%5000;
        }
        else
            ImpendingDeath_Timer -= diff;

        if(WingBuffet_Timer < diff)
        {
            DoCast(me,SPELL_WING_BUFFET);
            WingBuffet_Timer = 25000+rand()%10000;
        }
        else
            WingBuffet_Timer -= diff;

        if(Mda_Timer < diff)
        {
            DoCast(me,SPELL_MAGIC_DISRUPTION_AURA);
            Mda_Timer = 15000;
        }
        else
            Mda_Timer -= diff;

        DoMeleeAttackIfReady();
    }