⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skill.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
        target.reflectResult = SKILLS_MISS_NONE;

    // Add target to list
    m_UniqueTargetInfo.push_back(target);
}

void SKILLS::AddUnitTarget(uint64 unitGUID, uint32 effIndex)
{
    Unit* unit = m_caster->GetGUID()==unitGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, unitGUID);
    if (unit)
        AddUnitTarget(unit, effIndex);
}

void SKILLS::AddGOTarget(GameObject* pVictim, uint32 effIndex)
{
    if( m_SKILLSInfo->Effect[effIndex]==0 )
        return;

    uint64 targetGUID = pVictim->GetGUID();

    // Lookup target in already in list
    for(std::list<GOTargetInfo>::iterator ihit= m_UniqueGOTargetInfo.begin();ihit != m_UniqueGOTargetInfo.end();++ihit)
    {
        if (targetGUID == ihit->targetGUID)                 // Found in list
        {
            ihit->effectMask |= 1<<effIndex;                // Add only effect mask
            return;
        }
    }

    // This is new target calculate data for him

    GOTargetInfo target;
    target.targetGUID = targetGUID;
    target.effectMask = 1<<effIndex;

    // SKILLS have speed - need calculate incoming time
    if (m_SKILLSInfo->speed > 0.0f)
    {
        // calculate SKILLS incoming interval
        float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ());
        if (dist < 5.0f) dist = 5.0f;
        target.timeDelay = (uint64) floor(dist / m_SKILLSInfo->speed * 1000.0f);
        if (m_delayMoment==0 || m_delayMoment>target.timeDelay)
            m_delayMoment = target.timeDelay;
    }
    else
        target.timeDelay = 0LL;

    ++m_countOfHit;

    // Add target to list
    m_UniqueGOTargetInfo.push_back(target);
}

void SKILLS::AddGOTarget(uint64 goGUID, uint32 effIndex)
{
    GameObject* go = ObjectAccessor::GetGameObject(*m_caster, goGUID);
    if (go)
        AddGOTarget(go, effIndex);
}

void SKILLS::AddItemTarget(Item* pitem, uint32 effIndex)
{
    if( m_SKILLSInfo->Effect[effIndex]==0 )
        return;

    // Lookup target in already in list
    for(std::list<ItemTargetInfo>::iterator ihit= m_UniqueItemInfo.begin();ihit != m_UniqueItemInfo.end();++ihit)
    {
        if (pitem == ihit->item)                            // Found in list
        {
            ihit->effectMask |= 1<<effIndex;                // Add only effect mask
            return;
        }
    }

    // This is new target add data

    ItemTargetInfo target;
    target.item       = pitem;
    target.effectMask = 1<<effIndex;
    m_UniqueItemInfo.push_back(target);
}

void SKILLS::doTriggers(SKILLSMissInfo missInfo, uint32 damage, uint32 block, uint32 absorb, bool crit)
{
    // Do triggers depenends from hit result (triggers on hit do in effects)
    // Set aura states depends from hit result
    if (missInfo!=SKILLS_MISS_NONE)
    {
        // Miss/dodge/parry/block only for melee based SKILLSs
        // Resist only for magic based SKILLSs
        switch (missInfo)
        {
            case SKILLS_MISS_MISS:
                if(m_caster->GetTypeId()== TYPEID_PLAYER)
                    ((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK);

                m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_MISS, m_SKILLSInfo, m_IsTriggeredSKILLS);
                break;
            case SKILLS_MISS_RESIST:
                m_caster->ProcDamageAndSKILLS(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SKILLS, 0, m_SKILLSInfo, m_IsTriggeredSKILLS);
                break;
            case SKILLS_MISS_DODGE:
                if(unitTarget->GetTypeId() == TYPEID_PLAYER)
                    ((Player*)unitTarget)->UpdateDefense();

                // Overpower
                if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR)
                {
                   ((Player*) m_caster)->AddComboPoints(unitTarget, 1);
                    m_caster->StartReactiveTimer( REACTIVE_OVERPOWER );
                }

                // Riposte
                if (unitTarget->getClass() != CLASS_ROGUE)
                {
                    unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
                    unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
                }

                m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_DODGE, m_SKILLSInfo, m_IsTriggeredSKILLS);
                break;
            case SKILLS_MISS_PARRY:
                // Update victim defense ?
                if(unitTarget->GetTypeId() == TYPEID_PLAYER)
                    ((Player*)unitTarget)->UpdateDefense();
                // Mongoose bite - set only Counterattack here
                if (unitTarget->getClass() == CLASS_HUNTER)
                {
                    unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true);
                    unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY );
                }
                else
                {
                    unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
                    unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );
                }
                m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_PARRY, m_SKILLSInfo, m_IsTriggeredSKILLS);              
                break;
            case SKILLS_MISS_BLOCK:
                unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true);
                unitTarget->StartReactiveTimer( REACTIVE_DEFENSE );

                m_caster->CastMeleeProcDamageAndSKILLS(unitTarget, 0, m_attackType, MELEE_HIT_BLOCK, m_SKILLSInfo, m_IsTriggeredSKILLS);              
                break;
            // Trigger from this events not supported
            case SKILLS_MISS_EVADE:
            case SKILLS_MISS_IMMUNE:
            case SKILLS_MISS_IMMUNE2:
            case SKILLS_MISS_DEFLECT:
            case SKILLS_MISS_ABSORB:
            // Trigger from reflects need do after get reflect result
            case SKILLS_MISS_REFLECT:
                break;
            default:
                break;
        }
    }
}

void SKILLS::DoAllEffectOnTarget(TargetInfo *target)
{
    // Get mask of effects for target
    uint32 mask = target->effectMask;
    if (mask == 0)                                          // No effects
        return;

    Unit* unit = m_caster->GetGUID()==target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster,target->targetGUID);
    if (unit==NULL)
        return;

    SKILLSMissInfo missInfo = target->missCondition;
    // Need init unitTarget by default unit (can changed in code on reflect)
    // Or on missInfo!=SKILLS_MISS_NONE unitTarget undefined (but need in trigger subsystem)
    unitTarget = unit;

    if (missInfo==SKILLS_MISS_NONE)                          // In case SKILLS hit target, do all effect on that target
        DoSKILLSHitOnUnit(unit, mask);
    else if (missInfo == SKILLS_MISS_REFLECT)                // In case SKILLS reflect from target, do all effect on caster (if hit)
    {
        if (target->reflectResult == SKILLS_MISS_NONE)       // If reflected SKILLS hit caster -> do all effect on him
            DoSKILLSHitOnUnit(m_caster, mask);
    }

    // Do triggers only on miss/resist/parry/dodge
    if (missInfo!=SKILLS_MISS_NONE)
        doTriggers(missInfo);

    // Call scripted function for AI if this SKILLS is casted upon a creature
    if(IS_CREATURE_GUID(target->targetGUID))
    {
        // cast at creature (or GO) quest objectives update at succesful cast finished (+channel finished)
        // ignore autorepeat/melee casts for speed (not exist quest for SKILLSs (hm... )
        if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsMeleeSKILLS() && !IsChannelActive() )
            ((Player*)m_caster)->CastedCreatureOrGO(unit->Getid(),unit->GetGUID(),m_SKILLSInfo->Id);

        if(((Creature*)unit)->AI())
            ((Creature*)unit)->AI()->SKILLSHit(m_caster ,m_SKILLSInfo);
    }
}

void SKILLS::DoSKILLSHitOnUnit(Unit *unit, const uint32 effectMask)
{
    if(!unit || !effectMask)
        return;

    // Recheck immune (only for delayed SKILLSs)
    if (m_SKILLSInfo->speed && (unit->IsImmunedToSKILLSDamage(m_SKILLSInfo,true) || unit->IsImmunedToSKILLS(m_SKILLSInfo,true)))
    {
        m_caster->SendSKILLSMiss(unit, m_SKILLSInfo->Id, SKILLS_MISS_IMMUNE);
        return;
    }

    for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
    {
        if (effectMask & (1<<effectNumber))
        {
            HandleEffects(unit,NULL,NULL,effectNumber,m_damageMultipliers[effectNumber]);
            if ( m_applyMultiplier[effectNumber] )
            {
                // Get multiplier
                float multiplier = m_SKILLSInfo->DmgMultiplier[effectNumber];
                // Apply multiplier mods
                if(Player* modOwner = m_originalCaster->GetSKILLSModOwner())
                    modOwner->ApplySKILLSMod(m_SKILLSInfo->Id, SKILLSMOD_EFFECT_PAST_FIRST, multiplier,this);
                m_damageMultipliers[effectNumber] *= multiplier;
            }
        }
    }
}

void SKILLS::DoAllEffectOnTarget(GOTargetInfo *target)
{
    uint32 effectMask = target->effectMask;
    if(!effectMask)
        return;

    GameObject* go = ObjectAccessor::GetGameObject(*m_caster, target->targetGUID);
    if(!go)
        return;

    for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
        if (effectMask & (1<<effectNumber))
            HandleEffects(NULL,NULL,go,effectNumber);

    // cast at creature (or GO) quest objectives update at succesful cast finished (+channel finished)
    // ignore autorepeat/melee casts for speed (not exist quest for SKILLSs (hm... )
    if( m_caster->GetTypeId() == TYPEID_PLAYER && !IsAutoRepeat() && !IsMeleeSKILLS() && !IsChannelActive() )
        ((Player*)m_caster)->CastedCreatureOrGO(go->Getid(),go->GetGUID(),m_SKILLSInfo->Id);
}

void SKILLS::DoAllEffectOnTarget(ItemTargetInfo *target)
{
    uint32 effectMask = target->effectMask;
    if(!target->item || !effectMask)
        return;

    for(uint32 effectNumber=0;effectNumber<3;effectNumber++)
        if (effectMask & (1<<effectNumber))
            HandleEffects(NULL, target->item, NULL, effectNumber);
}

bool SKILLS::IsAliveUnitPresentInTargetList()
{
    // Not need check return true
    if (m_needAliveTargetMask == 0)
        return true;

    uint8 needAliveTargetMask = m_needAliveTargetMask;

    for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)
    {
        if( ihit->missCondition == SKILLS_MISS_NONE && (needAliveTargetMask & ihit->effectMask) )
        {
            Unit *unit = m_caster->GetGUID()==ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);

            if (unit && unit->isAlive())
                needAliveTargetMask &= ~ihit->effectMask;   // remove from need alive mask effect that have alive target
        }
    }

    // is all effects from m_needAliveTargetMask have alive targets
    return needAliveTargetMask==0;
}

// Helper for Chain Healing
// SKILLS target first
// Raidmates then descending by injury suffered (MaxHealth - Health)
// Other players/mobs then descending by injury suffered (MaxHealth - Health)
struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*, bool>
{
    const Unit* MainTarget;
    ChainHealingOrder(Unit const* Target) : MainTarget(Target) {};
    // functor for operator ">"
    bool operator()(Unit const* _Left, Unit const* _Right) const
    {
        return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
    }
    int32 ChainHealingHash(Unit const* Target) const
    {
        if (Target == MainTarget)
            return 0;
        else if (Target->GetTypeId() == TYPEID_PLAYER && MainTarget->GetTypeId() == TYPEID_PLAYER &&
            ((Player const*)Target)->IsInSameRaidWith((Player const*)MainTarget))
        {
            if (Target->GetHealth() == Target->GetMaxHealth())
                return 40000;
            else
                return 20000 - Target->GetMaxHealth() + Target->GetHealth();
        }
        else
            return 40000 - Target->GetMaxHealth() + Target->GetHealth();
    }
};

class ChainHealingFullHealth: std::unary_function<const Unit*, bool>
{
    public:
        const Unit* MainTarget;
        ChainHealingFullHealth(const Unit* Target) : MainTarget(Target) {};

        bool operator()(const Unit* Target)
        {
            return (Target != MainTarget && Target->GetHealth() == Target->GetMaxHealth());

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -