Example #1
0
// The pHatingUnit is not used yet
float ThreatCalcHelper::CalcThreat(Unit* pHatedUnit, Unit* /*pHatingUnit*/, float threat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell)
{
    // all flat mods applied early
    if (fabs(threat) < M_NULL_F)
        return 0.0f;

    if (pThreatSpell)
    {
        if (pThreatSpell->AttributesEx & SPELL_ATTR_EX_NO_THREAT && !IsSpellReduceThreat(pThreatSpell))
            return 0.0f;

        if (Player* modOwner = pHatedUnit->GetSpellModOwner())
            modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, threat);

        if (crit)
            threat *= pHatedUnit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CRITICAL_THREAT, schoolMask);
    }

    threat = pHatedUnit->ApplyTotalThreatModifier(threat, schoolMask);
    return threat;
}
Example #2
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()
        );
}