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

📄 skill.cpp.svn-base

📁 絲路server源碼 Silk Road server source
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
{
}

void SKILLS::FillTargetMap()
{
    // TODO: ADD the correct target FILLS!!!!!!

    for(uint32 i=0;i<3;i++)
    {
        // not call for empty effect.
        // Also some SKILLSs use not used effect targets for store targets for dummy effect in triggered SKILLSs
        if(m_SKILLSInfo->Effect[i]==0)
            continue;

        // targets for TARGET_SCRIPT filled in SKILLS::canCast call
        if( m_SKILLSInfo->EffectImplicitTargetA[i] == TARGET_SCRIPT || m_SKILLSInfo->EffectImplicitTargetB[i] == TARGET_SCRIPT )
            continue;

        std::list<Unit*> tmpUnitMap;

        // TargetA/TargetB dependent from each other, we not switch to full support this dependences
        // but need it support in some know cases
        switch(m_SKILLSInfo->EffectImplicitTargetA[i])
        {
            case TARGET_ALL_AROUND_CASTER:
                if( m_SKILLSInfo->EffectImplicitTargetB[i]==TARGET_ALL_PARTY ||
                    m_SKILLSInfo->EffectImplicitTargetB[i]==TARGET_ALL_FRIENDLY_UNITS_AROUND_CASTER ||
                    m_SKILLSInfo->EffectImplicitTargetB[i]==TARGET_RANDOM_RAID_MEMBER )
                {
                    SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetB[i],tmpUnitMap);
                }
                // Note: this hack with search required until GO casting not implemented
                // enviromenment damage SKILLSs already have around enemies targeting but this not help in case not existed GO casting support
                // currently each eanemy selected explicitly and self cast damage
                else if(m_SKILLSInfo->EffectImplicitTargetB[i]==TARGET_ALL_ENEMY_IN_AREA && m_SKILLSInfo->Effect[i]==SKILLS_EFFECT_ENVIRONMENTAL_DAMAGE)
                {
                    if(m_targets.getUnitTarget())
                        tmpUnitMap.push_back(m_targets.getUnitTarget());
                }
                else
                {
                    SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetA[i],tmpUnitMap);
                    SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetB[i],tmpUnitMap);
                }
                break;
            case TARGET_CURRENT_SELECTED_ENEMY:
                SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetA[i],tmpUnitMap);
                break;
            default:
                SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetA[i],tmpUnitMap);
                SetTargetMap(i,m_SKILLSInfo->EffectImplicitTargetB[i],tmpUnitMap);
                break;
        }

        if( (m_SKILLSInfo->EffectImplicitTargetA[i]==0 || m_SKILLSInfo->EffectImplicitTargetA[i]==TARGET_EFFECT_SELECT) &&
            (m_SKILLSInfo->EffectImplicitTargetB[i]==0 || m_SKILLSInfo->EffectImplicitTargetB[i]==TARGET_EFFECT_SELECT) )
        {
            // add here custom effects that need default target.
            // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!!
            switch(m_SKILLSInfo->Effect[i])
            {
                //case SKILLS_EFFECT_PERSISTENT_AREA_AURA:
                case SKILLS_EFFECT_RESURRECT:
                case SKILLS_EFFECT_LEARN_SKILLS:
                case SKILLS_EFFECT_SKILL_STEP:
                case SKILLS_EFFECT_SELF_RESURRECT:
                case SKILLS_EFFECT_PROFICIENCY:
                case SKILLS_EFFECT_PARRY:
                case SKILLS_EFFECT_CREATE_ITEM:
                    if(m_targets.getUnitTarget())
                        tmpUnitMap.push_back(m_targets.getUnitTarget());
                    break;
                case SKILLS_EFFECT_DUMMY:
                {
                    switch(m_SKILLSInfo->Id)
                    {
                        case 20577:                         // Cannibalize
                        {
                            // non-standard target selection
                            SKILLSRangeid const* srange = sSKILLSRangeStore.Lookupid(m_SKILLSInfo->rangeIndex);
                            float max_range = GetSKILLSMaxRange(srange);

                            CellPair p(VENICE::ComputeCellPair(m_caster->GetPositionX(), m_caster->GetPositionY()));
                            Cell cell(p);
                            cell.data.Part.reserved = ALL_DISTRICT;
                            cell.SetNoCreate();

                            WorldObject* result = NULL;

                            VENICE::CannibalizeObjectCheck u_check(m_caster, max_range);
                            VENICE::WorldObjectSearcher<VENICE::CannibalizeObjectCheck > searcher(result, u_check);

                            TypeContainerVisitor<VENICE::WorldObjectSearcher<VENICE::CannibalizeObjectCheck >, GridTypeMapContainer > grid_searcher(searcher);
                            CellLock<GridReadGuard> cell_lock(cell, p);
                            cell_lock->Visit(cell_lock, grid_searcher, *MapManager::AREA().GetMap(m_caster->GetMapId(), m_caster));

                            if(!result)
                            {
                                TypeContainerVisitor<VENICE::WorldObjectSearcher<VENICE::CannibalizeObjectCheck >, WorldTypeMapContainer > world_searcher(searcher);
                                cell_lock->Visit(cell_lock, world_searcher, *MapManager::AREA().GetMap(m_caster->GetMapId(), m_caster));
                            }

                            if(result)
                            {
                                switch(result->GetTypeId())
                                {
                                    case TYPEID_UNIT:
                                    case TYPEID_PLAYER:
                                        tmpUnitMap.push_back((Unit*)result);
                                        break;
                                    case TYPEID_CORPSE:
                                        m_targets.setCorpseTarget((Corpse*)result);
                                        if(Player* owner = ObjectAccessor::FindPlayer(((Corpse*)result)->GetOwnerGUID()))
                                            tmpUnitMap.push_back(owner);
                                        break;
                                }
                            }
                            else
                            {
                                // clear cooldown at fail
                                if(m_caster->GetTypeId()==TYPEID_PLAYER)
                                {
                                    ((Player*)m_caster)->RemoveSKILLSCooldown(m_SKILLSInfo->Id);

                                    WorldPacket data(SMSG_CLEAR_COOLDOWN, (4+8));
                                    data << uint32(m_SKILLSInfo->Id);
                                    data << uint64(m_caster->GetGUID());
                                    ((Player*)m_caster)->GetSession()->SendPacket(&data);
                                }

                                SendCastResult(SKILLS_FAILED_NO_EDIBLE_CORPSES);
                                finish(false);
                            }
                            break;
                        }
                        default:
                            if(m_targets.getUnitTarget())
                                tmpUnitMap.push_back(m_targets.getUnitTarget());
                            break;
                    }
                    break;
                }
                case SKILLS_EFFECT_SUMMON_PLAYER:
                    if(m_caster->GetTypeId()==TYPEID_PLAYER && ((Player*)m_caster)->GetSelection())
                    {
                        Player* target = objmgr.GetPlayer(((Player*)m_caster)->GetSelection());
                        if(target)
                            tmpUnitMap.push_back(target);
                    }
                    break;
                case SKILLS_EFFECT_RESURRECT_NEW:
                    if(m_targets.getUnitTarget())
                        tmpUnitMap.push_back(m_targets.getUnitTarget());
                    if(m_targets.getCorpseTargetGUID())
                    {
                        Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID());
                        if(corpse)
                        {
                            Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
                            if(owner)
                                tmpUnitMap.push_back(owner);
                        }
                    }
                    break;
                case SKILLS_EFFECT_SKILL:
                case SKILLS_EFFECT_SUMMON_CHANGE_ITEM:
                case SKILLS_EFFECT_SUMMON_GUARDIAN:
                case SKILLS_EFFECT_SUMMON:
                case SKILLS_EFFECT_SUMMON_WILD:
                case SKILLS_EFFECT_STUCK:
                case SKILLS_EFFECT_ADD_FARSIGHT:
                case SKILLS_EFFECT_DESTROY_ALL_TOTEMS:
                case SKILLS_EFFECT_SUMMON_DEMON:
                case SKILLS_EFFECT_TRANS_DOOR:
                    tmpUnitMap.push_back(m_caster);
                    break;
                case SKILLS_EFFECT_LEARN_PET_SKILLS:
                    if(Pet* pet = m_caster->GetPet())
                        tmpUnitMap.push_back(pet);
                    break;
                case SKILLS_EFFECT_FEED_PET:
                case SKILLS_EFFECT_PROSPECTING:
                case SKILLS_EFFECT_DISENCHANT:
                case SKILLS_EFFECT_ENCHANT_ITEM:
                case SKILLS_EFFECT_ENCHANT_ITEM_TEMPORARY:
                    if(m_targets.getItemTarget())
                        AddItemTarget(m_targets.getItemTarget(), i);
                    break;
                case SKILLS_EFFECT_APPLY_AURA:
                    switch(m_SKILLSInfo->EffectApplyAuraName[i])
                    {
                        case SKILLS_AURA_ADD_FLAT_MODIFIER:  // some SKILLS mods auras have 0 target modes instead expected TRAGET_SELF(1) (and present for other ranks for same SKILLS for example)
                        case SKILLS_AURA_ADD_PCT_MODIFIER:
                            tmpUnitMap.push_back(m_caster);
                            break;
                        default:                            // apply to target in other case
                            if(m_targets.getUnitTarget())
                                tmpUnitMap.push_back(m_targets.getUnitTarget());
                            break;
                    }
                    break;
                case SKILLS_EFFECT_APPLY_AREA_AURA:
                                                            // AreaAura
                    if(m_SKILLSInfo->Attributes == 0x9050000 || m_SKILLSInfo->Attributes == 0x10000)
                        SetTargetMap(i,TARGET_AREAEFFECT_PARTY,tmpUnitMap);
                    break;
                case SKILLS_EFFECT_SKIN_PLAYER_CORPSE:
                    if(m_targets.getUnitTarget())
                    {
                        tmpUnitMap.push_back(m_targets.getUnitTarget());
                    }
                    else if (m_targets.getCorpseTargetGUID())
                    {
                        Corpse *corpse = ObjectAccessor::GetCorpse(*m_caster,m_targets.getCorpseTargetGUID());
                        if(corpse)
                        {
                            Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
                            if(owner)
                                tmpUnitMap.push_back(owner);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        if(IsChanneledSKILLS(m_SKILLSInfo) && !tmpUnitMap.empty())
            m_needAliveTargetMask  |= (1<<i);

        if(m_caster->GetTypeId() == TYPEID_PLAYER && (!m_caster->IsPvP() || ((Player*)m_caster)->pvpInfo.endTimer != 0))
        {
            Player *me = (Player*)m_caster;
            for (std::list<Unit*>::const_iterator itr = tmpUnitMap.begin(); itr != tmpUnitMap.end(); itr++)
            {
                Unit *owner = (*itr)->GetOwner();
                Unit *u = owner ? owner : (*itr);
                if(u->IsPvP() && (!me->duel || me->duel->opponent != u))
                    me->UpdatePvP(true);
            }
        }

        for (std::list<Unit*>::iterator itr = tmpUnitMap.begin() ; itr != tmpUnitMap.end();)
        {
            if(!CheckTarget(*itr, i, false ))
            {
                itr = tmpUnitMap.erase(itr);
                continue;
            }
            else
                ++itr;
        }

        for(std::list<Unit*>::iterator iunit= tmpUnitMap.begin();iunit != tmpUnitMap.end();++iunit)
            AddUnitTarget((*iunit), i);
    }
}

void SKILLS::CleanupTargetList()
{
    m_UniqueTargetInfo.clear();
    m_UniqueGOTargetInfo.clear();
    m_UniqueItemInfo.clear();
    m_countOfHit = 0;
    m_countOfMiss = 0;
    m_delayMoment = 0;
}

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

    uint64 targetGUID = pVictim->GetGUID();

    // Lookup target in already in list
    for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.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

    // Get SKILLS hit result on target
    TargetInfo target;
    target.targetGUID = targetGUID;                         // Store target GUID
    target.effectMask = 1<<effIndex;                        // Store index of effect

    // Calculate hit result
    target.missCondition = m_caster->SKILLSHitResult(pVictim, m_SKILLSInfo, m_canReflect);
    if (target.missCondition == SKILLS_MISS_NONE)
        ++m_countOfHit;
    else
        ++m_countOfMiss;

    // 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);

        // Calculate minimum incoming time
        if (m_delayMoment==0 || m_delayMoment>target.timeDelay)
            m_delayMoment = target.timeDelay;
    }
    else
        target.timeDelay = 0LL;

    // If target reflect SKILLS back to caster
    if (target.missCondition==SKILLS_MISS_REFLECT)
    {
        // Calculate reflected SKILLS result on caster
        target.reflectResult =  m_caster->SKILLSHitResult(m_caster, m_SKILLSInfo, m_canReflect);

        if (target.reflectResult == SKILLS_MISS_REFLECT)     // Impossible reflect again, so simply deflect SKILLS
            target.reflectResult = SKILLS_MISS_PARRY;

        // Increase time interval for reflected SKILLSs by 1.5
        target.timeDelay+=target.timeDelay>>1;
    }
    else

⌨️ 快捷键说明

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