Esempio n. 1
0
bool EffectScriptEffectCreature_spell_unstable_ooze(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Creature* pCreatureTarget, ObjectGuid /*originalCasterGuid*/)
{
    if (uiSpellId == SPELL_UNSTABLE_OOZE && uiEffIndex == EFFECT_INDEX_2 && pCreatureTarget->GetEntry() == NPC_BIG_OOZE)
    {
        // send AI event on 5 stacks of unstable Ooze
        SpellAuraHolder* pOozeHolder = pCreatureTarget->GetSpellAuraHolder(uiSpellId);
        if (pOozeHolder)
        {
            // Note: stacks are increased after the effect is processed, so we need to use (stacks - 1)
            switch (pOozeHolder->GetStackAmount())
            {
                case 1:
                    DoScriptText(EMOTE_OOZE_GROW_1, pCreatureTarget);
                    break;
                case 2:
                    DoScriptText(EMOTE_OOZE_GROW_2, pCreatureTarget);
                    break;
                case 4:
                    pCreatureTarget->AI()->SendAIEvent(AI_EVENT_CUSTOM_A, pCaster, pCreatureTarget);
                    // no break;
                case 3:
                    DoScriptText(EMOTE_OOZE_GROW_3, pCreatureTarget);
                    break;
            }
        }

        return true;
    }

    return false;
}
Esempio n. 2
0
    void UpdateAI(const uint32 diff) override
    {
        if (!zealot)
        {
            if (Unit* owner = m_creature->GetCreator())
                zealot = owner;
        }

        if (channelTarget == NULL/* || lastTarget == NULL */|| zealot == NULL)
            return;

        if (zealot->HasAura(SPELL_TWILIGHT_EVOLUTION) || zealot->isDead())
            return;

        if (uiCheckPlayerIsBetween <= diff)
        {
            channelTarget = zealot;
            Map::PlayerList const &PlayerList = m_creature->GetMap()->GetPlayers();

            if (!PlayerList.isEmpty())
            {
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                {
                    if(i->getSource()->IsInBetween(m_creature, zealot, 1.0f))
                        channelTarget = i->getSource();
                }
            }

            SpellAuraHolder* holder = channelTarget->GetSpellAuraHolder(SPELL_EVOLUTION, zealot->GetObjectGuid());
            if (!holder)
                holder = channelTarget->_AddAura(SPELL_EVOLUTION, 15000, zealot);

            if (holder)
            {
                holder->ModStackAmount(1);
                holder->RefreshHolder();

                if (holder->GetStackAmount() >= holder->GetSpellProto()->GetStackAmount())
                {
                    if(channelTarget == zealot)
                        channelTarget->RemoveAllAuras();

                    zealot->CastSpell(channelTarget, SPELL_TWILIGHT_EVOLUTION, true);
                }
            }

            uiCheckPlayerIsBetween = 500;
        }
        else
            uiCheckPlayerIsBetween -= diff;

        if (uiNetherEssenceVisual <= diff)
        {
            m_creature->CastSpell(m_creature, SPELL_NETHERESSENCE_VISUAL, true);
            uiNetherEssenceVisual = urand(3500,4000);
        }
        else
            uiNetherEssenceVisual -= diff;
    }
Esempio n. 3
0
void WorldSession::HandleCancelAuraOpcode(WorldPacket& recvPacket)
{
    uint32 spellId;
    recvPacket >> spellId;

    SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
    if (!spellInfo)
        return;

    if (spellInfo->HasAttribute(SPELL_ATTR_CANT_CANCEL))
        return;

    if (IsPassiveSpell(spellInfo))
        return;

    if (!IsPositiveSpell(spellId))
    {
        // ignore for remote control state
        if (!_player->IsSelfMover())
        {
            // except own aura spells
            bool allow = false;
            for (int k = 0; k < MAX_EFFECT_INDEX; ++k)
            {
                SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(SpellEffectIndex(k));
                if (spellEffect && (spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_POSSESS ||
                    spellEffect->EffectApplyAuraName == SPELL_AURA_MOD_POSSESS_PET))
                {
                    allow = true;
                    break;
                }
            }

            // this also include case when aura not found
            if (!allow)
                return;
        }
        else
            return;
    }

    // channeled spell case (it currently casted then)
    if (IsChanneledSpell(spellInfo))
    {
        if (Spell* curSpell = _player->GetCurrentSpell(CURRENT_CHANNELED_SPELL))
            if (curSpell->m_spellInfo->Id == spellId)
                _player->InterruptSpell(CURRENT_CHANNELED_SPELL);
        return;
    }

    SpellAuraHolder* holder = _player->GetSpellAuraHolder(spellId);

    // not own area auras can't be cancelled (note: maybe need to check for aura on holder and not general on spell)
    if (holder && holder->GetCasterGuid() != _player->GetObjectGuid() && HasAreaAuraEffect(holder->GetSpellProto()))
        return;

    // non channeled case
    _player->RemoveAurasDueToSpellByCancel(spellId);
}
/**
 * GetDispelTarget()
 * return Unit* Returns unit to be dispelled. First checks 'critical' Healer(s), next Tank(s), next Master (if different from:), next DPS.
 *
 * return NULL If NULL is returned, no healing is required. At all.
 *
 * Will need extensive re-write for co-operation amongst multiple healers. As it stands, multiple healers would all pick the same 'ideal'
 * healing target.
 */
Player* PlayerbotClassAI::GetDispelTarget(DispelType dispelType, JOB_TYPE type, bool bMustBeOOC)
{
    if (!m_ai)  return nullptr;
    if (!m_bot) return nullptr;
    if (!m_bot->isAlive() || m_bot->IsInDuel()) return nullptr;
    if (bMustBeOOC && m_bot->isInCombat()) return nullptr;

    // First, fill the list of targets
    if (m_bot->GetGroup())
    {
        // define seperately for sorting purposes - DO NOT CHANGE ORDER!
        std::vector<heal_priority> targets;

        Group::MemberSlotList const& groupSlot = m_bot->GetGroup()->GetMemberSlots();
        for (Group::member_citerator itr = groupSlot.begin(); itr != groupSlot.end(); itr++)
        {
            Player *groupMember = sObjectMgr.GetPlayer(itr->guid);
            if (!groupMember || !groupMember->isAlive())
                continue;
            JOB_TYPE job = GetTargetJob(groupMember);
            if (job & type)
            {
                uint32 dispelMask  = GetDispellMask(dispelType);
                Unit::SpellAuraHolderMap const& auras = groupMember->GetSpellAuraHolderMap();
                for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
                {
                    SpellAuraHolder *holder = itr->second;
                    // Only return group members with negative magic effect
                    if (dispelType == DISPEL_MAGIC && holder->IsPositive())
                        continue;
                    // poison, disease and curse are always negative: return everyone
                    if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
                        targets.push_back( heal_priority(groupMember, 0, job) );
                }
            }
        }

        // Sorts according to type: Healers first, tanks next, then master followed by DPS, thanks to the order of the TYPE enum
        std::sort(targets.begin(), targets.end());

        if (targets.size())
            return targets.at(0).p;
    }

    return nullptr;
}
Esempio n. 5
0
void Player::UpdateMasteryAuras()
{
    if (!HasAuraType(SPELL_AURA_MASTERY))
    {
        SetFloatValue(PLAYER_MASTERY, 0.0f);
        return;
    }

    float masteryValue = GetTotalAuraModifier(SPELL_AURA_MASTERY) + GetRatingBonusValue(CR_MASTERY);
    SetFloatValue(PLAYER_MASTERY, masteryValue);

    std::vector<uint32> const* masterySpells = GetTalentTreeMasterySpells(m_talentsPrimaryTree[m_activeSpec]);
    if (!masterySpells)
        return;

    for (uint32 i = 0; i < masterySpells->size(); ++i)
    {
        SpellAuraHolder* holder = GetSpellAuraHolder(masterySpells->at(i));
        if (!holder)
            continue;

        SpellEntry const* spellEntry = holder->GetSpellProto();

        // calculate mastery scaling coef
        int32 masteryCoef = GetMasteryCoefficient(spellEntry);
        if (!masteryCoef)
            continue;

        // update aura modifiers
        for (uint32 j = 0; j < MAX_EFFECT_INDEX; ++j)
        {
            Aura* aura = holder->GetAuraByEffectIndex(SpellEffectIndex(j));
            if (!aura)
                continue;

            if (spellEntry->CalculateSimpleValue(SpellEffectIndex(j)))
                continue;

            aura->ApplyModifier(false, false);
            aura->GetModifier()->m_amount = int32(masteryValue * masteryCoef / 100.0f);
            aura->ApplyModifier(true, false);
        }
    }
}
Esempio n. 6
0
bool GOGossipSelect_go_ulduar_teleporter(Player *pPlayer, GameObject* pGo, uint32 sender, uint32 action)
{
    int32 damage = 0;
    if(sender != GOSSIP_SENDER_MAIN) return false;

    if(!pPlayer->getAttackers().empty()) return false;

    if(action >= 0 && action <= PORTALS_COUNT)
    pPlayer->TeleportTo(PortalLoc[action].map_num, PortalLoc[action].x, PortalLoc[action].y, PortalLoc[action].z, PortalLoc[action].o);
    if (PortalLoc[action].spellID != 0 )
           if (SpellEntry const* spell = (SpellEntry *)GetSpellStore()->LookupEntry(PortalLoc[action].spellID))
           {
               SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pPlayer, pPlayer);
               Aura *aura = CreateAura(spell, EFFECT_INDEX_2, NULL, holder, pPlayer);
               holder->AddAura(aura, EFFECT_INDEX_2);
           }

    pPlayer->CLOSE_GOSSIP_MENU();
    return true;
}
Esempio n. 7
0
void DynamicObject::Delay(int32 delaytime)
{
    m_aliveDuration -= delaytime;
    for(AffectedSet::iterator iter = m_affected.begin(); iter != m_affected.end(); )
    {
        Unit *target = GetMap()->GetUnit((*iter));
        if (target)
        {
            SpellAuraHolder *holder = target->GetSpellAuraHolder(m_spellId, GetCasterGuid().GetRawValue());
            if (!holder)
            {
                ++iter;
                continue;
            }

            bool foundAura = false;
            for (int32 i = m_effIndex + 1; i < MAX_EFFECT_INDEX; ++i)
            {
                SpellEffectEntry const* effect = holder->GetSpellProto()->GetSpellEffect(SpellEffectIndex(i));
                if(!effect)
                    continue;
                if ((effect->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA || effect->Effect == SPELL_EFFECT_ADD_FARSIGHT) && holder->m_auras[i])
                {
                    foundAura = true;
                    break;
                }
            }

            if (foundAura)
            {
                ++iter;
                continue;
            }

            target->DelaySpellAuraHolder(m_spellId, delaytime, GetCasterGuid().GetRawValue());
            ++iter;
        }
        else
            m_affected.erase(iter++);
    }
}
Esempio n. 8
0
bool PlayerbotPriestAI::HealTarget(Unit* target)
{
    PlayerbotAI* ai = GetAI();
    uint8 hp = target->GetHealth() * 100 / target->GetMaxHealth();

    if (CURE_DISEASE > 0 && ai->GetCombatOrder() != PlayerbotAI::ORDERS_NODISPEL)
    {
        uint32 dispelMask  = GetDispellMask(DISPEL_DISEASE);
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder *holder = itr->second;
            if ((1<<holder->GetSpellProto()->Dispel) & dispelMask)
            {
                if(holder->GetSpellProto()->Dispel == DISPEL_DISEASE)
                    ai->CastSpell(CURE_DISEASE, *target);
                return false;
            }
        }
    }

    if (hp >= 80)
        return false;

    if (hp < 25 && FLASH_HEAL && ai->CastSpell(FLASH_HEAL, *target))
        return true;
    else if (hp < 30 && GREATER_HEAL > 0 && ai->CastSpell(GREATER_HEAL, *target))
        return true;
    else if (hp < 33 && BINDING_HEAL > 0 && ai->CastSpell(BINDING_HEAL, *target))
        return true;
    else if (hp < 40 && PRAYER_OF_HEALING > 0 && ai->CastSpell(PRAYER_OF_HEALING, *target))
        return true;
    else if (hp < 50 && CIRCLE_OF_HEALING > 0 && ai->CastSpell(CIRCLE_OF_HEALING, *target))
        return true;
    else if (hp < 60 && HEAL > 0 && ai->CastSpell(HEAL, *target))
        return true;
    else if (hp < 80 && RENEW > 0 && !target->HasAura(RENEW) &&  ai->CastSpell(RENEW, *target))
        return true;
    else
        return false;
} // end HealTarget
Esempio n. 9
0
bool EffectAuraDummy_spell_aura_dummy_living_flare(const Aura* pAura, bool bApply)
{
    if (pAura->GetId() == SPELL_LIVING_FLARE_MASTER && pAura->GetEffIndex() == EFFECT_INDEX_0 && bApply)
    {
        if (Creature* pTarget = (Creature*)pAura->GetTarget())
        {
            pTarget->CastSpell(pTarget, SPELL_FEL_FLAREUP, TRIGGERED_OLD_TRIGGERED);

            SpellAuraHolder* pHolder = pTarget->GetSpellAuraHolder(SPELL_FEL_FLAREUP);
            if (pHolder)
            {
                if (pHolder->GetStackAmount() >= MAX_FLAREUP_STACKS)
                    pTarget->AI()->SendAIEvent(AI_EVENT_CUSTOM_A, pTarget, pTarget);
                // Note: cosmetic aura is removed, so we need to add it back. This needs to be fixed
                else
                    pTarget->CastSpell(pTarget, SPELL_LIVING_COSMETIC, TRIGGERED_OLD_TRIGGERED);
            }
        }
    }
    return true;
}
Esempio n. 10
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        // Unstable Ooze
        if (m_uiUnstableExplosionCheckTimer)
        {
            if (m_uiUnstableExplosionCheckTimer <= uiDiff)
            {
                m_uiUnstableExplosionCheckTimer = 1000;

                SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(SPELL_UNSTABLE_OOZE);
                if (holder && holder->GetStackAmount() >= 5)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_UNSTABLE_EXPLOSION) == CAST_OK)
                    {
                        if (m_pInstance)
                        {
                            if (Creature* pRotface = m_pInstance->GetSingleCreatureFromStorage(NPC_ROTFACE))
                                DoScriptText(SAY_OOZE_EXPLODE, pRotface);
                        }
                    }
                }
            }
            else
                m_uiUnstableExplosionCheckTimer -= uiDiff;
        }

        // Sticky Ooze
        if (m_uiStickyOozeTimer <= uiDiff)
        {
            if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_STICKY_OOZE) == CAST_OK)
                m_uiStickyOozeTimer = urand(10000, 15000);
        }
        else
            m_uiStickyOozeTimer -= uiDiff;

        DoMeleeAttackIfReady();
    }
Esempio n. 11
0
bool BSWScriptedAI::_doAura(uint8 m_uiSpellIdx, Unit* pTarget, SpellEffectIndex index)
{
    SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx];

    if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
        {
           error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",pSpell->m_uiSpellEntry[currentDifficulty]);
           return false;
        }

    if (_hasAura(m_uiSpellIdx,pTarget))
         debug_log("BSW: adding aura stack from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);
    else debug_log("BSW: adding new aura from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);

    SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(pSpell->m_uiSpellEntry[currentDifficulty]);
    if (spell && spell->Effect[index] < TOTAL_SPELL_EFFECTS)
    {
        if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA))
        {
            SpellAuraHolder *holder = CreateSpellAuraHolder(spell, pTarget, pTarget);

            int32 basepoint = pSpell->varData ?  pSpell->varData - 1 : spell->EffectBasePoints[index] + 1;

            if ( IsAreaAuraEffect(spell->Effect[index]) ||
                spell->Effect[index] == SPELL_EFFECT_APPLY_AURA  ||
                spell->Effect[index] == SPELL_EFFECT_PERSISTENT_AREA_AURA )
                {
                    Aura *aura = CreateAura(spell, SpellEffectIndex(index), &basepoint, holder, pTarget);
                    holder->AddAura(aura, SpellEffectIndex(index));
                    return true;
                }
        }
    }

    error_log("BSW: FAILED adding aura from spell %u index %u",pSpell->m_uiSpellEntry[currentDifficulty], index);

    return false;
};
CombatManeuverReturns PlayerbotWarriorAI::DoNextCombatManeuverPVE(Unit* pTarget)
{
    if (!m_ai)  return RETURN_NO_ACTION_ERROR;
    if (!m_bot) return RETURN_NO_ACTION_ERROR;

    //float fTargetDist = m_bot->GetCombatDistance(pTarget, true);

    //Used to determine if this bot is highest on threat
    Unit* newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE)(PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot);
    Unit* pVictim = pTarget->getVictim();

    // do shouts, berserker rage, etc...
    if (BERSERKER_RAGE > 0 && !m_bot->HasAura(BERSERKER_RAGE, EFFECT_INDEX_0))
        m_ai->CastSpell(BERSERKER_RAGE);
    else if (BLOODRAGE > 0 && m_ai->GetRageAmount() <= 10)
        m_ai->CastSpell(BLOODRAGE);

    Creature* pCreature = (Creature*) pTarget;

    // Prevent low health humanoid from fleeing with Hamstring
    if ((m_bot->HasAura(BATTLE_STANCE, EFFECT_INDEX_0) || m_bot->HasAura(BERSERKER_STANCE, EFFECT_INDEX_0)) && pTarget->GetHealthPercent() < 20 && !m_ai->IsElite(pTarget, true))
    {
        if (HAMSTRING > 0 && !pTarget->HasAura(HAMSTRING, EFFECT_INDEX_0) && m_ai->CastSpell(HAMSTRING, *pTarget))
            return RETURN_CONTINUE;
    }

    CheckShouts();

    // Get bot spec. If bot has tank orders, force spec to protection
    uint32 spec = ((m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK) ? WARRIOR_SPEC_PROTECTION : m_bot->GetSpec());

    if (spec == WARRIOR_SPEC_FURY && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_ASSIST))
    {
        // Try to interrupt spell if target is casting one
        if (pTarget->IsNonMeleeSpellCasted(true))
        {
            if (PUMMEL > 0 && m_bot->IsSpellReady(PUMMEL) && m_ai->CastSpell(PUMMEL, *pTarget))
                return RETURN_CONTINUE;
        }

        if (DEATH_WISH > 0 && !m_bot->HasAura(DEATH_WISH, EFFECT_INDEX_0) && m_bot->IsSpellReady(DEATH_WISH) && m_ai->CastSpell(DEATH_WISH, *m_bot))
            return RETURN_CONTINUE;
        if (EXECUTE > 0 && pTarget->GetHealthPercent() < 20 && m_ai->CastSpell(EXECUTE, *pTarget))
            return RETURN_CONTINUE;
        if (BLOODTHIRST > 0 && m_bot->IsSpellReady(BLOODTHIRST) && m_ai->CastSpell(BLOODTHIRST, *pTarget))
            return RETURN_CONTINUE;
        if (WHIRLWIND > 0 && m_bot->IsSpellReady(WHIRLWIND) && m_ai->CastSpell(WHIRLWIND, *pTarget))
            return RETURN_CONTINUE;
        if (HEROIC_STRIKE > 0 && m_ai->CastSpell(HEROIC_STRIKE, *pTarget))
            return RETURN_CONTINUE;
    }
    else if (spec == WARRIOR_SPEC_ARMS || (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_ASSIST))
    {
        // Try to interrupt spell if target is casting one
        if (pTarget->IsNonMeleeSpellCasted(true))
        {
            if (SHIELD_BASH > 0 && m_ai->CastSpell(SHIELD_BASH, *pTarget))
                return RETURN_CONTINUE;
        }

        // If bot's target is also attacking the bot, use retaliation for extra attacks
        if (RETALIATION > 0 && pVictim == m_bot && m_ai->GetAttackerCount() >= 2 && m_bot->IsSpellReady(RETALIATION) && !m_bot->HasAura(RETALIATION, EFFECT_INDEX_0) && m_ai->CastSpell(RETALIATION, *m_bot))
            return RETURN_CONTINUE;

        if (EXECUTE > 0 && pTarget->GetHealthPercent() < 20 && m_ai->CastSpell(EXECUTE, *pTarget))
            return RETURN_CONTINUE;
        if (REND > 0 && !pTarget->HasAura(REND, EFFECT_INDEX_0) && m_ai->CastSpell(REND, *pTarget))
            return RETURN_CONTINUE;
        if (MORTAL_STRIKE > 0 && m_bot->IsSpellReady(MORTAL_STRIKE) && m_ai->CastSpell(MORTAL_STRIKE, *pTarget))
            return RETURN_CONTINUE;
        if (OVERPOWER > 0 && m_bot->IsSpellReady(OVERPOWER))
        {
            uint8 base = pTarget->RollMeleeOutcomeAgainst(m_bot, BASE_ATTACK, SPELL_SCHOOL_MASK_NORMAL);
            uint8 off = pTarget->RollMeleeOutcomeAgainst(m_bot, OFF_ATTACK, SPELL_SCHOOL_MASK_NORMAL);
            if (base == MELEE_HIT_DODGE || off == MELEE_HIT_DODGE)
            {
                if (m_bot->IsSpellReady(OVERPOWER) && m_ai->CastSpell(OVERPOWER, *pTarget))
                    return RETURN_CONTINUE;
            }
        }
        if (THUNDER_CLAP > 0 && !pTarget->HasAura(THUNDER_CLAP) && m_ai->CastSpell(THUNDER_CLAP, *pTarget))
            return RETURN_CONTINUE;
        if (HEROIC_STRIKE > 0 && m_ai->CastSpell(HEROIC_STRIKE, *pTarget))
            return RETURN_CONTINUE;
        if (SLAM > 0 && m_ai->CastSpell(SLAM, *pTarget))
            return RETURN_CONTINUE;
    }
    else if (spec == WARRIOR_SPEC_PROTECTION)
    {
        // First check: is bot's target targeting bot?
        if (!newTarget)
        {
            // Cast taunt on bot current target if the mob is targeting someone else
            if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_TANK && TAUNT > 0 && m_bot->IsSpellReady(TAUNT) && m_ai->CastSpell(TAUNT, *pTarget))
                return RETURN_CONTINUE;
        }

        // If tank is on the verge of dying but "I DON'T WANT TO DIE !!! :'-(("
        // TODO: should behaviour (or treshold) be different between elite and normal mobs? We don't want bots to burn such precious cooldown needlessly
        if (m_bot->GetHealthPercent() < 10)
        {
            // Cast Last Stand first because it has lower cooldown
            if (LAST_STAND > 0 && !m_bot->HasAura(LAST_STAND, EFFECT_INDEX_0) && m_ai->CastSpell(LAST_STAND, *m_bot))
            {
                m_ai->TellMaster("I'm using LAST STAND");
                return RETURN_CONTINUE;
            }
            // Cast Shield Wall only if Last Stand is on cooldown and not active
            if (SHIELD_WALL > 0 && (!m_bot->IsSpellReady(LAST_STAND) || LAST_STAND == 0) && !m_bot->HasAura(LAST_STAND, EFFECT_INDEX_0) && !m_bot->HasAura(SHIELD_WALL, EFFECT_INDEX_0) && m_ai->CastSpell(SHIELD_WALL, *m_bot))
            {
                m_ai->TellMaster("I'm using SHIELD WALL");
                return RETURN_CONTINUE;
            }
        }

        // Try to interrupt spell if target is casting one and target is not a worldboss (they are almost all immune to interrupt)
        if (pTarget->IsNonMeleeSpellCasted(true) && !m_ai->IsElite(pTarget, true))
        {
            if (SHIELD_BASH > 0 && m_ai->CastSpell(SHIELD_BASH, *pTarget))
                return RETURN_CONTINUE;
        }

        //Do not waste rage applying Sunder Armor if it is already stacked 5 times
        if (SUNDER_ARMOR > 0)
        {
            if (!pTarget->HasAura(SUNDER_ARMOR) && m_ai->CastSpell(SUNDER_ARMOR, *pTarget))   // no stacks: cast it
                return RETURN_CONTINUE;
            else
            {
                SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SUNDER_ARMOR);
                if (holder && (holder->GetStackAmount() < 5) && m_ai->CastSpell(SUNDER_ARMOR, *pTarget))
                    return RETURN_CONTINUE;
            }
        }

        if (REVENGE > 0 && m_bot->IsSpellReady(REVENGE))
        {
            uint8 base = pTarget->RollMeleeOutcomeAgainst(m_bot, BASE_ATTACK, SPELL_SCHOOL_MASK_NORMAL);
            uint8 off = pTarget->RollMeleeOutcomeAgainst(m_bot, OFF_ATTACK, SPELL_SCHOOL_MASK_NORMAL);
            if (base == MELEE_HIT_PARRY || base == MELEE_HIT_DODGE || base == MELEE_HIT_BLOCK || off == MELEE_HIT_PARRY || off == MELEE_HIT_DODGE || off == MELEE_HIT_BLOCK)
                if (m_ai->CastSpell(REVENGE, *pTarget))
                    return RETURN_CONTINUE;
        }
        if (REND > 0 && !pTarget->HasAura(REND, EFFECT_INDEX_0) && m_ai->CastSpell(REND, *pTarget))
            return RETURN_CONTINUE;

        if (DEMORALIZING_SHOUT > 0 && !pTarget->HasAura(DEMORALIZING_SHOUT, EFFECT_INDEX_0) && m_ai->CastSpell(DEMORALIZING_SHOUT, *pTarget))
            return RETURN_CONTINUE;
        // check that target is dangerous (elite) before casting shield block: preserve bot cooldowns
        if (SHIELD_BLOCK > 0 && m_ai->IsElite(pTarget) && !m_bot->HasAura(SHIELD_BLOCK, EFFECT_INDEX_0) && m_ai->CastSpell(SHIELD_BLOCK, *m_bot))
            return RETURN_CONTINUE;
        // TODO: only cast disarm if target has equipment?
        if (DISARM > 0 && !pTarget->HasAura(DISARM, EFFECT_INDEX_0) && m_ai->CastSpell(DISARM, *pTarget))
            return RETURN_CONTINUE;
        if (CONCUSSION_BLOW > 0 && m_bot->IsSpellReady(CONCUSSION_BLOW) && m_ai->CastSpell(CONCUSSION_BLOW, *pTarget))
            return RETURN_CONTINUE;
        if (SHIELD_SLAM > 0 && m_bot->IsSpellReady(SHIELD_SLAM) && m_ai->CastSpell(SHIELD_SLAM, *pTarget))
            return RETURN_CONTINUE;
        if (HEROIC_STRIKE > 0 && m_ai->CastSpell(HEROIC_STRIKE, *pTarget))
            return RETURN_CONTINUE;
    }

    /*    case WarriorBattle:
            if (SWEEPING_STRIKES > 0 && m_ai->GetAttackerCount() >= 2 && !m_bot->HasAura(SWEEPING_STRIKES, EFFECT_INDEX_0) && m_ai->CastSpell(SWEEPING_STRIKES, *m_bot))
                return RETURN_CONTINUE;
            if (INTIMIDATING_SHOUT > 0 && m_ai->GetAttackerCount() > 5 && m_ai->CastSpell(INTIMIDATING_SHOUT, *pTarget))
                return RETURN_CONTINUE;
            if (CHALLENGING_SHOUT > 0 && pVictim != m_bot && m_ai->GetHealthPercent() > 25 && !pTarget->HasAura(MOCKING_BLOW, EFFECT_INDEX_0) && !pTarget->HasAura(CHALLENGING_SHOUT, EFFECT_INDEX_0) && m_ai->CastSpell(CHALLENGING_SHOUT, *pTarget))
                return RETURN_CONTINUE;
            if (CLEAVE > 0 && m_ai->CastSpell(CLEAVE, *pTarget))
                return RETURN_CONTINUE;
            if (PIERCING_HOWL > 0 && && m_ai->GetAttackerCount() >= 3 && !pTarget->HasAura(WAR_STOMP, EFFECT_INDEX_0) && !pTarget->HasAura(PIERCING_HOWL, EFFECT_INDEX_0) && !pTarget->HasAura(SHOCKWAVE, EFFECT_INDEX_0) && !pTarget->HasAura(CONCUSSION_BLOW, EFFECT_INDEX_0) && m_ai->CastSpell(PIERCING_HOWL, *pTarget))
                return RETURN_CONTINUE;
            if (MOCKING_BLOW > 0 && pVictim != m_bot && m_ai->GetHealthPercent() > 25 && !pTarget->HasAura(MOCKING_BLOW, EFFECT_INDEX_0) && !pTarget->HasAura(CHALLENGING_SHOUT, EFFECT_INDEX_0) && m_ai->CastSpell(MOCKING_BLOW, *pTarget))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_TAUREN && !pTarget->HasAura(WAR_STOMP, EFFECT_INDEX_0) && !pTarget->HasAura(PIERCING_HOWL, EFFECT_INDEX_0) && !pTarget->HasAura(CONCUSSION_BLOW, EFFECT_INDEX_0) && m_ai->CastSpell(WAR_STOMP, *pTarget))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_HUMAN && m_bot->hasUnitState(UNIT_STAT_STUNNED) || m_bot->HasAuraType(SPELL_AURA_MOD_FEAR) || m_bot->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) || m_bot->HasAuraType(SPELL_AURA_MOD_CHARM) && m_ai->CastSpell(EVERY_MAN_FOR_HIMSELF, *m_bot))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_UNDEAD && m_bot->HasAuraType(SPELL_AURA_MOD_FEAR) || m_bot->HasAuraType(SPELL_AURA_MOD_CHARM) && m_ai->CastSpell(WILL_OF_THE_FORSAKEN, *m_bot))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_DWARF && m_bot->HasAuraState(AURA_STATE_DEADLY_POISON) && m_ai->CastSpell(STONEFORM, *m_bot))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_GNOME && m_bot->hasUnitState(UNIT_STAT_STUNNED) || m_bot->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED) && m_ai->CastSpell(ESCAPE_ARTIST, *m_bot))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_ORC && !m_bot->HasAura(BLOOD_FURY, EFFECT_INDEX_0) && m_ai->CastSpell(BLOOD_FURY, *m_bot))
                return RETURN_CONTINUE;
            if (m_bot->getRace() == RACE_TROLL && !m_bot->HasAura(BERSERKING, EFFECT_INDEX_0) && m_ai->CastSpell(BERSERKING, *m_bot))
                return RETURN_CONTINUE;
            break;*/

    return RETURN_NO_ACTION_OK;
}
CombatManeuverReturns PlayerbotShamanAI::HealPlayer(Player* target)
{
    CombatManeuverReturns r = PlayerbotClassAI::HealPlayer(target);
    if (r != RETURN_NO_ACTION_OK)
        return r;

    if (!target->isAlive())
    {
        if (ANCESTRAL_SPIRIT && m_ai->CastSpell(ANCESTRAL_SPIRIT, *target))
        {
            std::string msg = "Resurrecting ";
            msg += target->GetName();
            m_bot->Say(msg, LANG_UNIVERSAL);
            return RETURN_CONTINUE;
        }
        return RETURN_NO_ACTION_ERROR; // not error per se - possibly just OOM
    }

    // Dispel if necessary
    if ((CURE_DISEASE_SHAMAN > 0 || CURE_POISON_SHAMAN > 0) && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_NODISPEL) == 0)
    {
        uint32 dispelMask  = GetDispellMask(DISPEL_POISON);
        uint32 dispelMask2  = GetDispellMask(DISPEL_DISEASE);
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder *holder = itr->second;
            if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_POISON)
                {
                    if (m_ai->CastSpell(CURE_POISON_SHAMAN, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask2)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_DISEASE)
                {
                    if (m_ai->CastSpell(CURE_DISEASE_SHAMAN, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
        }
    }

    // Everyone is healthy enough, return OK. MUST correlate to highest value below (should be last HP check)
    if (target->GetHealthPercent() >= 80)
        return RETURN_NO_ACTION_OK;

    // Technically the best rotation is CHAIN + LHW + LHW subbing in HW for trouble (bad mana efficiency)
    if (target->GetHealthPercent() < 30 && HEALING_WAVE > 0 && m_ai->CastSpell(HEALING_WAVE, *target))
        return RETURN_CONTINUE;
    if (target->GetHealthPercent() < 50 && LESSER_HEALING_WAVE > 0 && m_ai->CastSpell(LESSER_HEALING_WAVE, *target))
        return RETURN_CONTINUE;
    if (target->GetHealthPercent() < 80 && CHAIN_HEAL > 0 && m_ai->CastSpell(CHAIN_HEAL, *target))
        return RETURN_CONTINUE;

    return RETURN_NO_ACTION_UNKNOWN;
} // end HealTarget
Esempio n. 14
0
CombatManeuverReturns PlayerbotPriestAI::HealPlayer(Player* target)
{
    CombatManeuverReturns r = PlayerbotClassAI::HealPlayer(target);
    if (r != RETURN_NO_ACTION_OK)
        return r;

    if (!target->isAlive())
    {
        if (RESURRECTION && m_ai->CastSpell(RESURRECTION, *target))
        {
            std::string msg = "Resurrecting ";
            msg += target->GetName();
            m_bot->Say(msg, LANG_UNIVERSAL);
            return RETURN_CONTINUE;
        }
        return RETURN_NO_ACTION_ERROR; // not error per se - possibly just OOM
    }

    if (CURE_DISEASE > 0 && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_NODISPEL) == 0)
    {
        uint32 dispelMask  = GetDispellMask(DISPEL_DISEASE);
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder *holder = itr->second;
            if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_DISEASE)
                {
                    m_ai->CastSpell(CURE_DISEASE, *target);
                    return RETURN_CONTINUE;
                }
            }
        }
    }

    uint8 hp = target->GetHealthPercent();
    uint8 hpSelf = m_ai->GetHealthPercent();

    if (hp >= 90)
        return RETURN_NO_ACTION_OK;

    // TODO: Integrate shield here
    if (hp < 35 && FLASH_HEAL > 0 && m_ai->CastSpell(FLASH_HEAL, *target))
        return RETURN_CONTINUE;
    if (hp < 45 && GREATER_HEAL > 0 && m_ai->CastSpell(GREATER_HEAL, *target))
        return RETURN_CONTINUE;
    // Heals target AND self for equal amount
    if (hp < 60 && hpSelf < 80 && BINDING_HEAL > 0 && m_ai->CastSpell(BINDING_HEAL, *target))
        return RETURN_CONTINUE;
    if (hp < 60 && PRAYER_OF_MENDING > 0 && !target->HasAura(PRAYER_OF_MENDING, EFFECT_INDEX_0) && CastSpell(PRAYER_OF_MENDING, target))
        return RETURN_FINISHED_FIRST_MOVES;
    if (hp < 60 && HEAL > 0 && m_ai->CastSpell(HEAL, *target))
        return RETURN_CONTINUE;
    if (hp < 90 && RENEW > 0 && !target->HasAura(RENEW) && m_ai->CastSpell(RENEW, *target))
        return RETURN_CONTINUE;

    // Group heal. Not really useful until a group check is available?
    //if (hp < 40 && PRAYER_OF_HEALING > 0 && m_ai->CastSpell(PRAYER_OF_HEALING, *target) & RETURN_CONTINUE)
    //    return RETURN_CONTINUE;
    // Group heal. Not really useful until a group check is available?
    //if (hp < 50 && CIRCLE_OF_HEALING > 0 && m_ai->CastSpell(CIRCLE_OF_HEALING, *target) & RETURN_CONTINUE)
    //    return RETURN_CONTINUE;

    return RETURN_NO_ACTION_OK;
} // end HealTarget
Esempio n. 15
0
bool PlayerbotDruidAI::HealTarget(Unit *target)
{
    PlayerbotAI* ai = GetAI();
    uint8 hp = target->GetHealth() * 100 / target->GetMaxHealth();

    //If spell exists and orders say we should be dispelling
    if ((REMOVE_CURSE > 0 || ABOLISH_POISON > 0) && ai->GetCombatOrder() != PlayerbotAI::ORDERS_NODISPEL)
    {
        //This does something important(lol)
        uint32 dispelMask  = GetDispellMask(DISPEL_CURSE);
        uint32 dispelMask2  = GetDispellMask(DISPEL_POISON);
        //Get a list of all the targets auras(spells affecting target)
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        //Iterate through the auras
        for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder *holder = itr->second;
            //I dont know what this does but it doesn't work without it
            if ((1<<holder->GetSpellProto()->Dispel) & dispelMask)
            {
                //If the spell is dispellable and we can dispel it, do so
                if((holder->GetSpellProto()->Dispel == DISPEL_CURSE) & (REMOVE_CURSE > 0))
                    ai->CastSpell(REMOVE_CURSE, *target);
                return false;
            }
            else if ((1<<holder->GetSpellProto()->Dispel) & dispelMask2)
            {
                if((holder->GetSpellProto()->Dispel == DISPEL_POISON) & (ABOLISH_POISON > 0))
                    ai->CastSpell(ABOLISH_POISON, *target);
                return false;
            }
        }
    }

    if (hp >= 70)
        return false;

    // Reset form if needed
    GoBuffForm(GetPlayerBot());

    if (hp < 70 && REJUVENATION > 0 && ai->In_Reach(target,REJUVENATION) && !target->HasAura(REJUVENATION) && ai->CastSpell(REJUVENATION, *target))
        return true;

    if (hp < 60 && LIFEBLOOM > 0 && ai->In_Reach(target,LIFEBLOOM) && !target->HasAura(LIFEBLOOM) && ai->CastSpell(LIFEBLOOM, *target))
        return true;

    if (hp < 55 && REGROWTH > 0 && ai->In_Reach(target,REGROWTH) && !target->HasAura(REGROWTH) && ai->CastSpell(REGROWTH, *target))
        return true;

    if (hp < 50 && SWIFTMEND > 0  && ai->In_Reach(target,SWIFTMEND) && (target->HasAura(REJUVENATION) || target->HasAura(REGROWTH)) && ai->CastSpell(SWIFTMEND, *target))
        return true;

    if (hp < 45 && WILD_GROWTH > 0 && ai->In_Reach(target,WILD_GROWTH) && !target->HasAura(WILD_GROWTH) && ai->CastSpell(WILD_GROWTH, *target))
        return true;

    if (hp < 30 && NOURISH > 0 && ai->In_Reach(target,NOURISH) && ai->CastSpell(NOURISH, *target))
        return true;

    if (hp < 25 && HEALING_TOUCH > 0 && ai->In_Reach(target,HEALING_TOUCH) && ai->CastSpell(HEALING_TOUCH, *target))
        return true;

    return false;
} // end HealTarget
Esempio n. 16
0
bool BSWScriptedAI::_doAura(uint32 SpellID, Unit* pTarget, SpellEffectIndex index, int32 basepoint, bool isStack)
{
    if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
    {
        error_log("BSW: FAILED adding aura of spell number %u - no target or target not in map or target is dead",SpellID);
        return false;
    }

    if (_hasAura(SpellID,pTarget))
         debug_log("BSW: adding aura stack from spell %u index %u",SpellID, index);
    else debug_log("BSW: adding new aura from spell %u index %u",SpellID, index);

    SpellEntry const *spell = (SpellEntry *)GetSpellStore()->LookupEntry(SpellID);

    if (spell)
    {
        if (IsSpellAppliesAura(spell, (1 << EFFECT_INDEX_0) | (1 << EFFECT_INDEX_1) | (1 << EFFECT_INDEX_2)) || IsSpellHaveEffect(spell, SPELL_EFFECT_PERSISTENT_AREA_AURA))
        {
            int32 _basepoint = basepoint ?  basepoint - 1 : spell->EffectBasePoints[index] + 1;

            bool addedToExisting = true;

            SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SpellID, pTarget->GetGUID());

            Aura* aura = NULL;

            if (!holder)
            {
                holder = CreateSpellAuraHolder(spell, pTarget, pTarget);
                addedToExisting = false;
            }


            if (aura = holder->GetAuraByEffectIndex(index))
            {
                if (isStack)
                    holder->ModStackAmount(1);
            }
            else 
            {
                aura = CreateAura(spell, index, &_basepoint, holder, pTarget);
                aura->SetAuraDuration(aura->GetAuraMaxDuration());
                holder->AddAura(aura, index);
            }

            if (addedToExisting)
            {
                pTarget->AddAuraToModList(aura);
                holder->SetInUse(true);
                aura->ApplyModifier(true,true);
                holder->SetInUse(false);
            }
            else
                pTarget->AddSpellAuraHolder(holder);

            return true;
        }
    }

    error_log("BSW: FAILED adding aura from spell %u index %u",SpellID, index);

    return false;
};
Esempio n. 17
0
CombatManeuverReturns PlayerbotDruidAI::HealPlayer(Player* target)
{
    CombatManeuverReturns r = PlayerbotClassAI::HealPlayer(target);
    if (r != RETURN_NO_ACTION_OK)
        return r;

    if (!target->isAlive())
    {
        if (m_bot->isInCombat())
        {
            // TODO: Add check for cooldown
            if (REBIRTH && m_ai->In_Reach(target,REBIRTH) && m_ai->CastSpell(REBIRTH, *target))
            {
                std::string msg = "Resurrecting ";
                msg += target->GetName();
                m_bot->Say(msg, LANG_UNIVERSAL);
                return RETURN_CONTINUE;
            }
        }
        else
        {
            if (REVIVE && m_ai->In_Reach(target,REVIVE) && m_ai->CastSpell(REVIVE, *target))
            {
                std::string msg = "Resurrecting ";
                msg += target->GetName();
                m_bot->Say(msg, LANG_UNIVERSAL);
                return RETURN_CONTINUE;
            }
        }
        return RETURN_NO_ACTION_ERROR; // not error per se - possibly just OOM
    }

    //If spell exists and orders say we should be dispelling
    if ((REMOVE_CURSE > 0 || ABOLISH_POISON > 0) && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_NODISPEL) == 0)
    {
        //This does something important(lol)
        uint32 dispelMask  = GetDispellMask(DISPEL_CURSE);
        uint32 dispelMask2  = GetDispellMask(DISPEL_POISON);
        //Get a list of all the targets auras(spells affecting target)
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        //Iterate through the auras
        for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++)
        {
            SpellAuraHolder *holder = itr->second;
            //I dont know what this does but it doesn't work without it
            if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
            {
                //If the spell is dispellable and we can dispel it, do so
                if ((holder->GetSpellProto()->Dispel == DISPEL_CURSE) & (REMOVE_CURSE > 0))
                {
                    if (CastSpell(REMOVE_CURSE, target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask2)
            {
                if ((holder->GetSpellProto()->Dispel == DISPEL_POISON) & (ABOLISH_POISON > 0))
                {
                    if (CastSpell(ABOLISH_POISON, target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
        }
    }

    uint8 hp = target->GetHealthPercent();

    // Everyone is healthy enough, return OK. MUST correlate to highest value below (should be last HP check)
    if (hp >= 90)
        return RETURN_NO_ACTION_OK;

    // Reset form if needed
    if (!m_bot->HasAura(TREE_OF_LIFE) || TREE_OF_LIFE == 0)
        GoBuffForm(GetPlayerBot());

    // Start heals. Do lowest HP checks at the top
    if (hp < 30)
    {
        // TODO: Use in conjunction with Nature's Swiftness
        if (HEALING_TOUCH > 0 && m_ai->In_Reach(target,HEALING_TOUCH) && (NOURISH == 0 /*|| CastSpell(NATURES_SWIFTNESS)*/ ) && CastSpell(HEALING_TOUCH, target))
            return RETURN_CONTINUE;

        if (NOURISH > 0 && m_ai->In_Reach(target,NOURISH) && CastSpell(NOURISH, target))
            return RETURN_CONTINUE;
    }

    if (hp < 45 && WILD_GROWTH > 0 && m_ai->In_Reach(target,WILD_GROWTH) && !target->HasAura(WILD_GROWTH) && CastSpell(WILD_GROWTH, target))
        return RETURN_CONTINUE;

    if (hp < 50 && SWIFTMEND > 0 && m_ai->In_Reach(target,SWIFTMEND) && (target->HasAura(REJUVENATION) || target->HasAura(REGROWTH)) && CastSpell(SWIFTMEND, target))
        return RETURN_CONTINUE;

    if (hp < 60 && REGROWTH > 0 && m_ai->In_Reach(target,REGROWTH) && !target->HasAura(REGROWTH) && CastSpell(REGROWTH, target))
        return RETURN_CONTINUE;

    if (hp < 65 && LIFEBLOOM > 0 && m_ai->In_Reach(target,LIFEBLOOM) && !target->HasAura(LIFEBLOOM) && CastSpell(LIFEBLOOM, target))
        return RETURN_CONTINUE;

    if (hp < 90 && REJUVENATION > 0 && m_ai->In_Reach(target,REJUVENATION) && !target->HasAura(REJUVENATION) && CastSpell(REJUVENATION, target))
        return RETURN_CONTINUE;

    return RETURN_NO_ACTION_UNKNOWN;
} // end HealTarget
Esempio n. 18
0
CombatManeuverReturns PlayerbotMageAI::DoNextCombatManeuverPVE(Unit *pTarget)
{
    if (!m_ai)  return RETURN_NO_ACTION_ERROR;
    if (!m_bot) return RETURN_NO_ACTION_ERROR;

    Unit* pVictim = pTarget->getVictim();
    bool meleeReach = m_bot->CanReachWithMeleeAttack(pTarget);

    uint32 spec = m_bot->GetSpec();

    if (m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_RANGED && !meleeReach)
        m_ai->SetCombatStyle(PlayerbotAI::COMBAT_RANGED);
    // switch to melee if in melee range AND can't shoot OR have no ranged (wand) equipped
    else if(m_ai->GetCombatStyle() != PlayerbotAI::COMBAT_MELEE
            && meleeReach
            && (SHOOT == 0 || !m_bot->GetWeaponForAttack(RANGED_ATTACK, true, true)))
        m_ai->SetCombatStyle(PlayerbotAI::COMBAT_MELEE);

    //Used to determine if this bot is highest on threat
    Unit *newTarget = m_ai->FindAttacker((PlayerbotAI::ATTACKERINFOTYPE) (PlayerbotAI::AIT_VICTIMSELF | PlayerbotAI::AIT_HIGHESTTHREAT), m_bot);

    // Remove curse on group members
    if (Player* pCursedTarget = GetDispelTarget(DISPEL_CURSE))
    {
        if (MAGE_REMOVE_CURSE > 0 && CastSpell(MAGE_REMOVE_CURSE, pCursedTarget))
            return RETURN_CONTINUE;
    }

    if (newTarget && !m_ai->IsNeutralized(newTarget)) // Bot has aggro and the mob is not already crowd controled
    {
        if (newTarget->GetHealthPercent() > 25)
        {
            // If elite
            if (m_ai->IsElite(newTarget))
            {
                // If the attacker is a beast or humanoid, let's the bot give it a form more suited to the low intellect of something fool enough to attack a mage
                Creature * pCreature = (Creature*) newTarget;
                if (pCreature && (pCreature->GetCreatureInfo()->CreatureType == CREATURE_TYPE_HUMANOID || pCreature->GetCreatureInfo()->CreatureType == CREATURE_TYPE_BEAST))
                {
                    if (POLYMORPH > 0 && CastSpell(POLYMORPH, newTarget))
                        return RETURN_CONTINUE;
                }

                // Things are getting dire: cast Ice block
                if (ICE_BLOCK > 0 && !m_bot->HasSpellCooldown(ICE_BLOCK) && m_ai->GetHealthPercent() < 30 && !m_bot->HasAura(ICE_BLOCK, EFFECT_INDEX_0) && m_ai->CastSpell(ICE_BLOCK))
                    return RETURN_CONTINUE;

                // Cast Ice Barrier if health starts to goes low
                if (ICE_BARRIER > 0 && !m_bot->HasSpellCooldown(ICE_BARRIER) && m_ai->GetHealthPercent() < 50 && !m_bot->HasAura(ICE_BARRIER) && m_ai->SelfBuff(ICE_BARRIER))
                    return RETURN_CONTINUE;

                // Have threat, can't quickly lower it. 3 options remain: Stop attacking, lowlevel damage (wand), keep on keeping on.
                return CastSpell(SHOOT, pTarget);
            }
            else // not elite
            {
                // Cast mana shield if no shield is already up
                if (MANA_SHIELD > 0 && m_ai->GetHealthPercent() < 70 && !m_bot->HasAura(MANA_SHIELD) && !m_bot->HasAura(ICE_BARRIER) && m_ai->SelfBuff(MANA_SHIELD))
                    return RETURN_CONTINUE;
            }
        }
    }

    // Mana check and replenishment
    if (EVOCATION && m_ai->GetManaPercent() <= 10 && !m_bot->HasSpellCooldown(EVOCATION) && !newTarget && m_ai->SelfBuff(EVOCATION))
        return RETURN_CONTINUE;
    if (m_ai->GetManaPercent() <= 20)
    {
        Item* gem = FindManaGem();
        if (gem)
            m_ai->UseItem(gem);
    }

    // If bot has frost/fire resist order use Frost/Fire Ward when available
    if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_RESIST_FROST && FROST_WARD && !m_bot->HasSpellCooldown(FROST_WARD) && m_ai->SelfBuff(FROST_WARD))
        return RETURN_CONTINUE;
    if (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_RESIST_FIRE && FIRE_WARD && !m_bot->HasSpellCooldown(FIRE_WARD) && m_ai->SelfBuff(FIRE_WARD))
        return RETURN_CONTINUE;

    if (COUNTERSPELL > 0 && !m_bot->HasSpellCooldown(COUNTERSPELL) && pTarget->IsNonMeleeSpellCasted(true) && CastSpell(COUNTERSPELL, pTarget))
        return RETURN_CONTINUE;

    // If Clearcasting is active, cast arcane missiles
    // Bot could also cast flamestrike or blizzard for free, but the AoE could break some crowd control
    // or add threat on mobs ignoring the bot currently, so only focus on the bot's current target
    if (m_bot->HasAura(CLEARCASTING_1) && ARCANE_MISSILES > 0 && CastSpell(ARCANE_MISSILES, pTarget))
    {
        m_ai->SetIgnoreUpdateTime(3);
        return RETURN_CONTINUE;
    }

    switch (spec)
    {
    case MAGE_SPEC_FROST:
        if (COLD_SNAP && !m_bot->HasSpellCooldown(COLD_SNAP) && CheckFrostCooldowns() > 2 && m_ai->SelfBuff(COLD_SNAP))  // Clear frost spell cooldowns if bot has more than 2 active
            return RETURN_CONTINUE;
        if (CONE_OF_COLD > 0 && !m_bot->HasSpellCooldown(CONE_OF_COLD) && meleeReach)
        {
            // Cone of Cold does not require a target, so ensure that the bot faces the current one before casting
            m_ai->FaceTarget(pTarget);
            if (m_ai->CastSpell(CONE_OF_COLD))
                return RETURN_CONTINUE;
        }
        if (FROSTBOLT > 0 && m_ai->In_Reach(pTarget,FROSTBOLT) && !pTarget->HasAura(FROSTBOLT, EFFECT_INDEX_0) && CastSpell(FROSTBOLT, pTarget))
            return RETURN_CONTINUE;
        if (FROST_NOVA > 0 && !m_bot->HasSpellCooldown(FROST_NOVA) && meleeReach && !pTarget->HasAura(FROST_NOVA, EFFECT_INDEX_0) && CastSpell(FROST_NOVA, pTarget))
            return RETURN_CONTINUE;
        // Default frost spec action
        if (FROSTBOLT > 0 && m_ai->In_Reach(pTarget,FROSTBOLT))
            return CastSpell(FROSTBOLT, pTarget);
        /*
        if (BLIZZARD > 0 && m_ai->In_Reach(pTarget,BLIZZARD) && m_ai->GetAttackerCount() >= 5 && CastSpell(BLIZZARD, pTarget))
        {
            m_ai->SetIgnoreUpdateTime(8);
            return RETURN_CONTINUE;
        }
        */
        break;

    case MAGE_SPEC_FIRE:
        if (COMBUSTION > 0 && m_ai->SelfBuff(COMBUSTION))
            return RETURN_CONTINUE;
        if (BLAST_WAVE > 0 && m_ai->GetAttackerCount() >= 3 && meleeReach && CastSpell(BLAST_WAVE, pTarget))
            return RETURN_CONTINUE;
        // Try to have 3 scorch stacks to let tank build aggro while getting a nice crit% bonus
        if (IMPROVED_SCORCH > 0 && SCORCH > 0)
        {
            if (!pTarget->HasAura(FIRE_VULNERABILITY, EFFECT_INDEX_0) && CastSpell(SCORCH, pTarget))   // no stacks: cast it
                return RETURN_CONTINUE;
            else
            {
                SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(FIRE_VULNERABILITY);
                if (holder && (holder->GetStackAmount() < 3) && CastSpell(SCORCH, pTarget))
                    return RETURN_CONTINUE;
            }
        }
        // At least 3 stacks of Scorch: cast an opening fireball
        if (FIREBALL > 0 && !pTarget->HasAura(FIREBALL, EFFECT_INDEX_1) && CastSpell(FIREBALL, pTarget))
            return RETURN_CONTINUE;
        // 3 stacks of Scorch and fireball DoT: use fire blast if available
        if (FIRE_BLAST > 0 && !m_bot->HasSpellCooldown(FIRE_BLAST) && CastSpell(FIRE_BLAST, pTarget))
            return RETURN_CONTINUE;
        // All DoTs, cooldowns used, try to maximise scorch stacks (5) to get a even nicer crit% bonus
        if (IMPROVED_SCORCH > 0 && SCORCH > 0)
        {
            SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(FIRE_VULNERABILITY);
            if (holder && (holder->GetStackAmount() < 5) && CastSpell(SCORCH, pTarget))
                return RETURN_CONTINUE;
        }
        // Default fire spec action
        if (FIREBALL > 0 && m_ai->In_Reach(pTarget,FIREBALL))
            return CastSpell(FIREBALL, pTarget);
        /*
        if (FLAMESTRIKE > 0 && m_ai->In_Reach(pTarget,FLAMESTRIKE) && CastSpell(FLAMESTRIKE, pTarget))
            return RETURN_CONTINUE;
        */
        break;

    case MAGE_SPEC_ARCANE:
        if (ARCANE_POWER > 0 && !m_bot->HasSpellCooldown(ARCANE_POWER) && m_ai->IsElite(pTarget) && m_ai->CastSpell(ARCANE_POWER))    // Do not waste Arcane Power on normal NPCs as the bot is likely in a group
            return RETURN_CONTINUE;
        if (PRESENCE_OF_MIND > 0 && !m_bot->HasAura(PRESENCE_OF_MIND) && !m_bot->HasSpellCooldown(PRESENCE_OF_MIND) && m_ai->IsElite(pTarget) && m_ai->SelfBuff(PRESENCE_OF_MIND))
            return RETURN_CONTINUE;
        // If bot has presence of mind active, cast long casting time spells
        if (PRESENCE_OF_MIND && m_bot->HasAura(PRESENCE_OF_MIND))
        {
            // Instant Pyroblast, yeah! Tanks will probably hate this, but what do they know about power? Nothing...
            if (PYROBLAST > 0 && CastSpell(PYROBLAST, pTarget))
                return RETURN_CONTINUE;
            if (FIREBALL > 0 && CastSpell(FIREBALL, pTarget))
                return RETURN_CONTINUE;
        }
        if (ARCANE_EXPLOSION > 0 && m_ai->GetAttackerCount() >= 3 && meleeReach && CastSpell(ARCANE_EXPLOSION, pTarget))
            return RETURN_CONTINUE;
        // Default arcane spec actions (yes, two fire spells)
        if (FIRE_BLAST > 0 && !m_bot->HasSpellCooldown(FIRE_BLAST) && CastSpell(FIRE_BLAST, pTarget))
            return RETURN_CONTINUE;
        if (FIREBALL > 0 && m_ai->In_Reach(pTarget,FIREBALL))
            return CastSpell(FIREBALL, pTarget);
        // If no fireball, arcane missiles
        if (ARCANE_MISSILES > 0 && CastSpell(ARCANE_MISSILES, pTarget))
        {
            m_ai->SetIgnoreUpdateTime(3);
            return RETURN_CONTINUE;
        }
        break;
    }

    // No spec due to low level OR no spell found yet
    if (FROSTBOLT > 0 && m_ai->In_Reach(pTarget,FROSTBOLT) && !pTarget->HasAura(FROSTBOLT, EFFECT_INDEX_0) && CastSpell(FROSTBOLT, pTarget))
        return RETURN_CONTINUE;
    if (FIREBALL > 0 && m_ai->In_Reach(pTarget,FIREBALL) && CastSpell(FIREBALL, pTarget)) // Very low levels
        return RETURN_CONTINUE;

    // Default: shoot with wand
    return CastSpell(SHOOT, pTarget);

    return RETURN_NO_ACTION_ERROR; // What? Not even Fireball or wand are available?
} // end DoNextCombatManeuver
CombatManeuverReturns PlayerbotPaladinAI::HealPlayer(Player* target)
{
    CombatManeuverReturns r = PlayerbotClassAI::HealPlayer(target);
    if (r != RETURN_NO_ACTION_OK)
        return r;

    if (!target->isAlive())
    {
        if (REDEMPTION && m_ai->CastSpell(REDEMPTION, *target))
        {
            std::string msg = "Resurrecting ";
            msg += target->GetName();
            m_bot->Say(msg, LANG_UNIVERSAL);
            return RETURN_CONTINUE;
        }
        return RETURN_NO_ACTION_ERROR; // not error per se - possibly just OOM
    }

    if (PURIFY > 0 && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_NODISPEL) == 0)
    {
        uint32 DISPEL = CLEANSE > 0 ? CLEANSE : PURIFY;
        uint32 dispelMask  = GetDispellMask(DISPEL_DISEASE);
        uint32 dispelMask2 = GetDispellMask(DISPEL_POISON);
        uint32 dispelMask3 = GetDispellMask(DISPEL_MAGIC);
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        for(Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder *holder = itr->second;
            if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_DISEASE)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask2)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_POISON)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask3 & (DISPEL == CLEANSE))
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_MAGIC)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
        }
    }

    // Define a tank bot will look at
    Unit* pMainTank = GetHealTarget(JOB_TANK);

    // If target is out of range (40 yards) and is a tank: move towards it
    // Other classes have to adjust their position to the healers
    // TODO: This code should be common to all healers and will probably
    // move to a more suitable place
    if (pMainTank && !m_ai->In_Reach(pMainTank, FLASH_OF_LIGHT))
    {
        m_bot->GetMotionMaster()->MoveFollow(target, 39.0f, m_bot->GetOrientation());
        return RETURN_CONTINUE;
    }

    uint8 hp = target->GetHealthPercent();

    // Everyone is healthy enough, return OK. MUST correlate to highest value below (should be last HP check)
    if (hp >= 90)
        return RETURN_NO_ACTION_OK;

    if (hp < 10 && LAY_ON_HANDS && !m_bot->HasSpellCooldown(LAY_ON_HANDS) && m_ai->In_Reach(target,LAY_ON_HANDS) && m_ai->CastSpell(LAY_ON_HANDS, *target))
        return RETURN_CONTINUE;

    // Target is a moderately wounded healer or a badly wounded not tank? Blessing of Protection!
    if (BLESSING_OF_PROTECTION > 0
        && ((hp < 25 && (GetTargetJob(target) & JOB_HEAL)) || (hp < 15 && !(GetTargetJob(target) & JOB_TANK)))
        && !m_bot->HasSpellCooldown(BLESSING_OF_PROTECTION) && m_ai->In_Reach(target,BLESSING_OF_PROTECTION)
        && !target->HasAura(FORBEARANCE, EFFECT_INDEX_0)
        && !target->HasAura(BLESSING_OF_PROTECTION, EFFECT_INDEX_0) && !target->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0)
        && !target->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0)
        && m_ai->CastSpell(BLESSING_OF_PROTECTION, *target))
        return RETURN_CONTINUE;

    // Low HP : activate Divine Favor to make next heal a critical heal
    if (hp < 25 && DIVINE_FAVOR > 0 && !m_bot->HasAura(DIVINE_FAVOR, EFFECT_INDEX_0) && !m_bot->HasSpellCooldown(DIVINE_FAVOR) && m_ai->CastSpell (DIVINE_FAVOR, *m_bot))
        return RETURN_CONTINUE;

    if (hp < 40 && FLASH_OF_LIGHT && m_ai->In_Reach(target,FLASH_OF_LIGHT) && m_ai->CastSpell(FLASH_OF_LIGHT, *target))
        return RETURN_CONTINUE;

    if (hp < 60 && HOLY_SHOCK && m_ai->In_Reach(target,HOLY_SHOCK) && m_ai->CastSpell(HOLY_SHOCK, *target))
        return RETURN_CONTINUE;

    if (hp < 90 && HOLY_LIGHT && m_ai->In_Reach(target,HOLY_LIGHT) && m_ai->CastSpell(HOLY_LIGHT, *target))
        return RETURN_CONTINUE;

    return RETURN_NO_ACTION_UNKNOWN;
} // end HealTarget
Esempio n. 20
0
    void UpdateAI(const uint32 uiDiff) override
    {
        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
            return;

        if (!m_pInstance)
            return;

        // Berserk
        if (m_uiBerserkTimer)
        {
            if (m_uiBerserkTimer <= uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_BERSERK) == CAST_OK)
                {
                    DoScriptText(SAY_BERSERK, m_creature);
                    m_uiBerserkTimer = 0;
                }
            }
            else
                m_uiBerserkTimer -= uiDiff;
        }

        if (m_uiGaseousBlightTimer)
        {
            if (m_uiGaseousBlightTimer <= uiDiff)
            {
                // two stage event; first trigger all the puddle stalkers around then set the room in gas
                switch (m_uiGaseousBlightStage)
                {
                    case 0:
                        if (Creature* pProfessor = m_pInstance->GetSingleCreatureFromStorage(NPC_PROFESSOR_PUTRICIDE))
                        {
                            pProfessor->HandleEmote(EMOTE_ONESHOT_TALK_NOSHEATHE);
                            pProfessor->CastSpell(pProfessor, SPELL_GASEOUS_BLIGHT_INIT, true);
                            DoScriptText((m_pInstance->GetData(TYPE_ROTFACE) == DONE && m_pInstance->IsHeroicDifficulty()) ? SAY_BLIGHT_ROTFACE_DEAD : SAY_BLIGHT, pProfessor);
                        }
                        m_uiGaseousBlightTimer = 1000;
                        break;
                    case 1:
                        if (DoCastSpellIfCan(m_creature, SPELL_GASEOUS_BLIGHT_1) == CAST_OK)
                            m_uiGaseousBlightTimer = 0;
                        break;
                }
                ++m_uiGaseousBlightStage;
            }
            else
                m_uiGaseousBlightTimer -= uiDiff;
        }

        // Inhale Blight and Pungent Blight
        if (m_uiInhaleBlightTimer < uiDiff)
        {
            SpellAuraHolder* pHolder = m_creature->GetSpellAuraHolder(m_pInstance->Is25ManDifficulty() ? SPELL_INHALED_BLIGHT_25 : SPELL_INHALED_BLIGHT_10);

            // inhale the gas or if already have 3 stacks - release it
            if (pHolder && pHolder->GetStackAmount() >= 3)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_PUNGENT_BLIGHT) == CAST_OK)
                {
                    DoScriptText(SAY_PUNGUENT_BLIGHT, m_creature);
                    m_uiInhaleBlightTimer = 38000;
                }
            }
            else
            {
                if (DoCastSpellIfCan(m_creature, SPELL_INHALE_BLIGHT) == CAST_OK)
                    m_uiInhaleBlightTimer = 36000;
            }
        }
        else
            m_uiInhaleBlightTimer -= uiDiff;

        // Gas Spore
        if (m_uiGasSporeTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_GAS_SPORE) == CAST_OK)
            {
                DoScriptText(EMOTE_SPORES, m_creature);
                m_uiGasSporeTimer = 40000;
            }
        }
        else
            m_uiGasSporeTimer -= uiDiff;

        // Vile Gas
        if (m_uiVileGasTimer < uiDiff)
        {
            if (DoCastSpellIfCan(m_creature, SPELL_VILE_GAS) == CAST_OK)
                m_uiVileGasTimer = 30000;
        }
        else
            m_uiVileGasTimer -= uiDiff;

        // Heroic spells
        if (m_pInstance->IsHeroicDifficulty())
        {
            if (m_uiMalleableGooTimer < uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_MALLEABLE_GOO_SUMMON) == CAST_OK)
                    m_uiMalleableGooTimer = 15000;
            }
            else
                m_uiMalleableGooTimer -= uiDiff;
        }

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

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

            // Inhale Blight and Pungent Blight
            if (m_uiInhaleBlightTimer <= uiDiff)
            {
                SpellAuraHolder* holder = m_creature->GetSpellAuraHolder(SPELL_INHALED_BLIGHT_10);

                if (!holder)
                    holder = m_creature->GetSpellAuraHolder(SPELL_INHALED_BLIGHT_25);

                // inhale the gas or if already have 3 stacks - release it
                if (holder && holder->GetStackAmount() >= 3)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_PUNGENT_BLIGHT) == CAST_OK)
                    {
                        DoScriptText(SAY_PUNGUENT_BLIGHT_EMOTE, m_creature);
                        DoScriptText(SAY_PUNGUENT_BLIGHT, m_creature);
                        m_uiInhaleBlightTimer = 35000;
                    }
                }
                else if (DoCastSpellIfCan(m_creature, SPELL_INHALE_BLIGHT) == CAST_OK)
                {
                    if (m_pInstance)
                    {
                        if (Creature* pProfessor = m_pInstance->GetSingleCreatureFromStorage(NPC_PROFESSOR_PUTRICIDE))
                            DoScriptText(SAY_BLIGHT, pProfessor);
                    }
                    m_uiInhaleBlightTimer = 30000;
                }
            }
            else
                m_uiInhaleBlightTimer -= uiDiff;

            // Gas Spore
            if (m_uiGasSporeTimer <= uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_GAS_SPORE) == CAST_OK)
                {
                    DoScriptText(SAY_SPORE, m_creature);
                    m_uiGasSporeTimer = 40000;
                }
            }
            else
                m_uiGasSporeTimer -= uiDiff;

            // Vile Gas
            if (m_uiVileGasTimer <= uiDiff)
            {
                if (DoCastSpellIfCan(m_creature, SPELL_VILE_GAS_SUMMON, CAST_TRIGGERED) == CAST_OK)
                {
                    if (DoCastSpellIfCan(m_creature, SPELL_VILE_GAS) == CAST_OK)
                        m_uiVileGasTimer = 30000;
                }
            }
            else
                m_uiVileGasTimer -= uiDiff;

            DoMeleeAttackIfReady();
        }
Esempio n. 22
0
CombatManeuverReturns PlayerbotPaladinAI::HealPlayer(Player* target)
{
    CombatManeuverReturns r = PlayerbotClassAI::HealPlayer(target);
    if (r != RETURN_NO_ACTION_OK)
        return r;

    if (!target->isAlive())
    {
        if (REDEMPTION && m_ai->CastSpell(REDEMPTION, *target))
        {
            std::string msg = "Resurrecting ";
            msg += target->GetName();
            m_bot->Say(msg, LANG_UNIVERSAL);
            return RETURN_CONTINUE;
        }
        return RETURN_NO_ACTION_ERROR; // not error per se - possibly just OOM
    }

    if (PURIFY > 0 && (m_ai->GetCombatOrder() & PlayerbotAI::ORDERS_NODISPEL) == 0)
    {
        uint32 DISPEL = CLEANSE > 0 ? CLEANSE : PURIFY;
        uint32 dispelMask  = GetDispellMask(DISPEL_DISEASE);
        uint32 dispelMask2 = GetDispellMask(DISPEL_POISON);
        uint32 dispelMask3 = GetDispellMask(DISPEL_MAGIC);
        Unit::SpellAuraHolderMap const& auras = target->GetSpellAuraHolderMap();
        for (Unit::SpellAuraHolderMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
        {
            SpellAuraHolder* holder = itr->second;
            if ((1 << holder->GetSpellProto()->Dispel) & dispelMask)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_DISEASE)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask2)
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_POISON)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
            else if ((1 << holder->GetSpellProto()->Dispel) & dispelMask3 & (DISPEL == CLEANSE))
            {
                if (holder->GetSpellProto()->Dispel == DISPEL_MAGIC)
                {
                    if (m_ai->CastSpell(DISPEL, *target))
                        return RETURN_CONTINUE;
                    return RETURN_NO_ACTION_ERROR;
                }
            }
        }
    }

    uint8 hp = target->GetHealthPercent();

    // Everyone is healthy enough, return OK. MUST correlate to highest value below (should be last HP check)
    if (hp >= 90)
        return RETURN_NO_ACTION_OK;

    if (hp < 25 && m_ai->CastSpell(LAY_ON_HANDS, *target))
        return RETURN_CONTINUE;

    // You probably want to save this for tank/healer trouble
    if (hp < 30 && HAND_OF_PROTECTION > 0 && !target->HasAura(FORBEARANCE, EFFECT_INDEX_0)
            && !target->HasAura(HAND_OF_PROTECTION, EFFECT_INDEX_0) && !target->HasAura(DIVINE_PROTECTION, EFFECT_INDEX_0)
            && !target->HasAura(DIVINE_SHIELD, EFFECT_INDEX_0) && (GetTargetJob(target) & (JOB_HEAL | JOB_TANK))
            && m_ai->CastSpell(HAND_OF_PROTECTION, *target))
        return RETURN_CONTINUE;

    // Isn't this more of a group heal spell?
    if (hp < 40 && m_ai->CastSpell(FLASH_OF_LIGHT, *target))
        return RETURN_CONTINUE;

    if (hp < 60 && m_ai->CastSpell(HOLY_SHOCK, *target))
        return RETURN_CONTINUE;

    if (hp < 90 && m_ai->CastSpell(HOLY_LIGHT, *target))
        return RETURN_CONTINUE;

    return RETURN_NO_ACTION_UNKNOWN;
} // end HealTarget
Esempio n. 23
0
bool BSWScriptedAI::_doRemove(uint8 m_uiSpellIdx, Unit* pTarget, uint8 index)
{
    SpellTable* pSpell = &m_BossSpell[m_uiSpellIdx];

    debug_log("BSW: Removing effects of spell %u type %u",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);

        switch (pSpell->m_CastTarget) 
        {
                case DO_NOTHING: 
                                 return true;
                case SUMMON_NORMAL:
                case SUMMON_TEMP:
                case SUMMON_INSTANT:
                                 return false;

                case CAST_ON_SELF:
                case APPLY_AURA_SELF:
                         pTarget = m_creature;
                     break;

                case CAST_ON_SUMMONS:
                case CAST_ON_VICTIM:
                case CAST_ON_BOTTOMAGGRO:
                case CAST_ON_TARGET:
                case APPLY_AURA_TARGET:
                         if (!pTarget) return false;
                     break;

                case CAST_ON_RANDOM:
                case CAST_ON_RANDOM_PLAYER:
                case APPLY_AURA_ALLPLAYERS:
                case CAST_ON_ALLPLAYERS:
                     {
                         Map::PlayerList const& pPlayers = pMap->GetPlayers();
                         for (Map::PlayerList::const_iterator itr = pPlayers.begin(); itr != pPlayers.end(); ++itr)
                         {
                             pTarget = itr->getSource();
                             if (_hasAura(m_uiSpellIdx,pTarget))
                                 pTarget->RemoveAurasDueToSpell(pSpell->m_uiSpellEntry[currentDifficulty]);
                          }
                          return true;
                      }
                      break;
                  default: 
                      debug_log("BSW: FAILED Removing effects of spell %u type %u - unsupported type",pSpell->m_uiSpellEntry[currentDifficulty], pSpell->m_CastTarget);
                      return false;
        }

    if (!pTarget || !pTarget->IsInMap(m_creature) || !pTarget->isAlive())
        {
           error_log("BSW: FAILED removing effects of spell number %u - no target or target not in map or target is dead",pSpell->m_uiSpellEntry[currentDifficulty]);
           return false;
        }

        if (index == EFFECT_INDEX_ALL)
        {
            pTarget->RemoveAurasDueToSpell(pSpell->m_uiSpellEntry[currentDifficulty]);
            return true;
        }

        if (_auraCount(m_uiSpellIdx,pTarget,(SpellEffectIndex)index) > 1)
        {
            SpellAuraHolder *holder = pTarget->GetSpellAuraHolder(pSpell->m_uiSpellEntry[currentDifficulty], pTarget->GetGUID());
            if (holder->ModStackAmount(-1))
            {
                pTarget->RemoveSpellAuraHolder(holder, AURA_REMOVE_BY_DISPEL);
                return true;
            } else return false;
        } else pTarget->RemoveAurasDueToSpell(pSpell->m_uiSpellEntry[currentDifficulty]);
    return true;
};