Jump to content

[Duvida]Como altero a defesa dos mobs contra skills


Recommended Posts

  • 3 weeks later...
Em 14/01/2018 em 21:36, Tierri Lopes disse:

char_battle.cpp

Coloca aqui a seguinte função inteira:

Hidden Content

    Give reaction or reply to this topic to see the hidden content.

 

Aqui está

Spoiler

bool CHARACTER::Damage (LPCHARACTER pAttacker, int dam, EDamageType type)
{

    if (DAMAGE_TYPE_MAGIC == type)
    {
        dam = (int) ((float) dam * (100 + (pAttacker->GetPoint (POINT_MAGIC_ATT_BONUS_PER) + pAttacker->GetPoint (POINT_MELEE_MAGIC_ATT_BONUS_PER))) / 100.f + 0.5f);
    }

    if (GetRaceNum() == 5001)
    {
        bool bDropMoney = false;
        int iPercent = 0;

        if (GetMaxHP() >= 0)
        {
            iPercent = (GetHP() * 100) / GetMaxHP();
        }

        if (iPercent <= 10 && GetMaxSP() < 5)
        {
            SetMaxSP (5);
            bDropMoney = true;
        }
        else if (iPercent <= 20 && GetMaxSP() < 4)
        {
            SetMaxSP (4);
            bDropMoney = true;
        }
        else if (iPercent <= 40 && GetMaxSP() < 3)
        {
            SetMaxSP (3);
            bDropMoney = true;
        }
        else if (iPercent <= 60 && GetMaxSP() < 2)
        {
            SetMaxSP (2);
            bDropMoney = true;
        }
        else if (iPercent <= 80 && GetMaxSP() < 1)
        {
            SetMaxSP (1);
            bDropMoney = true;
        }

        if (bDropMoney)
        {
            DWORD dwGold = 1000;
            int iSplitCount = number (10, 13);

            sys_log (0, "WAEGU DropGoldOnHit %d times", GetMaxSP());

            for (int i = 1; i <= iSplitCount; ++i)
            {
                PIXEL_POSITION pos;
                LPITEM item;

                if ((item = ITEM_MANAGER::instance().CreateItem (1, dwGold / iSplitCount)))
                {

                    if (i != 0)
                    {
                        pos.x = (number (-14, 14) + number (-14, 14)) * 20;
                        pos.y = (number (-14, 14) + number (-14, 14)) * 20;

                        pos.x += GetX();
                        pos.y += GetY();
                    }

                    item->AddToGround (GetMapIndex(), pos);
                    item->StartDestroyEvent();
                }
            }
        }
    }

    if (type != DAMAGE_TYPE_NORMAL && type != DAMAGE_TYPE_NORMAL_RANGE)
    {
        if (IsAffectFlag (AFF_TERROR))
        {
            int pct = GetSkillPower (SKILL_TERROR) / 400;

            if (number (1, 100) <= pct)
            {
                return false;
            }
        }
    }

    int iCurHP = GetHP();
    int iCurSP = GetSP();

    bool IsCritical = false;
    bool IsPenetrate = false;
    bool IsDeathBlow = false;

    if (type == DAMAGE_TYPE_MELEE || type == DAMAGE_TYPE_RANGE || type == DAMAGE_TYPE_MAGIC)
    {

        if (pAttacker)
        {
            int iCriticalPct = pAttacker->GetPoint (POINT_CRITICAL_PCT);

            if (!IsPC())
            {
                iCriticalPct += pAttacker->GetMarriageBonus (UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);
            }

            if (iCriticalPct)
            {
                if (iCriticalPct >= 10)
                {
                    iCriticalPct = 5 + (iCriticalPct - 10) / 4;
                }
                else
                {
                    iCriticalPct /= 2;
                }

                iCriticalPct -= GetPoint (POINT_RESIST_CRITICAL);

                if (number (1, 100) <= iCriticalPct)
                {
                    IsCritical = true;
                    dam *= 2;
                    EffectPacket (SE_CRITICAL);

                    if (IsAffectFlag (AFF_MANASHIELD))
                    {
                        RemoveAffect (AFF_MANASHIELD);
                    }
                }
            }

            int iPenetratePct = pAttacker->GetPoint (POINT_PENETRATE_PCT);

            if (!IsPC())
            {
                iPenetratePct += pAttacker->GetMarriageBonus (UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);
            }

            if (iPenetratePct)
            {
                {
                    CSkillProto* pkSk = CSkillManager::instance().Get (SKILL_RESIST_PENETRATE);

                    if (NULL != pkSk)
                    {
                        pkSk->SetPointVar ("k", 1.0f * GetSkillPower (SKILL_RESIST_PENETRATE) / 100.0f);
                        iPenetratePct -= static_cast<int> (pkSk->kPointPoly.Eval());
                    }
                }

                if (iPenetratePct >= 10)
                {
                    iPenetratePct = 5 + (iPenetratePct - 10) / 4;
                }
                else
                {
                    iPenetratePct /= 2;
                }

                iPenetratePct -= GetPoint (POINT_RESIST_PENETRATE);

                if (number (1, 100) <= iPenetratePct)
                {
                    IsPenetrate = true;

                    if (test_server)
                    {
                        ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("°üÅë Ãß°¡ µ¥¹ÌÁö %d"), GetPoint (POINT_DEF_GRADE) * (100 + GetPoint (POINT_DEF_BONUS)) / 100);
                    }

                    dam += GetPoint (POINT_DEF_GRADE) * (100 + GetPoint (POINT_DEF_BONUS)) / 100;

                    if (IsAffectFlag (AFF_MANASHIELD))
                    {
                        RemoveAffect (AFF_MANASHIELD);
                    }
                    EffectPacket (SE_PENETRATE);
                }
            }
        }
    }

    else if (type == DAMAGE_TYPE_NORMAL || type == DAMAGE_TYPE_NORMAL_RANGE)
    {

        if (type == DAMAGE_TYPE_NORMAL)
        {
            if (GetPoint (POINT_BLOCK) && number (1, 100) <= GetPoint (POINT_BLOCK))
            {

                if (test_server)
                {
                    pAttacker->ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("%s ºí·°! (%d%%)"), GetName(), GetPoint (POINT_BLOCK));
                    ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("%s ºí·°! (%d%%)"), GetName(), GetPoint (POINT_BLOCK));
                }

                SendDamagePacket (pAttacker, 0, DAMAGE_BLOCK);
                return false;
            }
        }
        else if (type == DAMAGE_TYPE_NORMAL_RANGE)
        {

            if (GetPoint (POINT_DODGE) && number (1, 100) <= GetPoint (POINT_DODGE))
            {

                if (test_server)
                {
                    pAttacker->ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("%s ȸÇÇ! (%d%%)"), GetName(), GetPoint (POINT_DODGE));
                    ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("%s ȸÇÇ! (%d%%)"), GetName(), GetPoint (POINT_DODGE));
                }

                SendDamagePacket (pAttacker, 0, DAMAGE_DODGE);
                return false;
            }
        }

        if (IsAffectFlag (AFF_JEONGWIHON))
        {
            dam = (int) (dam * (100 + GetSkillPower (SKILL_JEONGWI) * 25 / 100) / 100);
        }

        if (IsAffectFlag (AFF_TERROR))
        {
            dam = (int) (dam * (95 - GetSkillPower (SKILL_TERROR) / 5) / 100);
        }

        if (IsAffectFlag (AFF_HOSIN))
        {
            dam = dam * (100 - GetPoint (POINT_RESIST_NORMAL_DAMAGE)) / 100;
        }

        if (pAttacker)
        {

            if (type == DAMAGE_TYPE_NORMAL)
            {
                if (GetPoint (POINT_REFLECT_MELEE))
                {
                    int reflectDamage = dam * GetPoint (POINT_REFLECT_MELEE) / 100;

                    if (pAttacker->IsImmune (IMMUNE_REFLECT))
                    {
                        reflectDamage = int (reflectDamage / 3.0f + 0.5f);
                    }

                    pAttacker->Damage (this, reflectDamage, DAMAGE_TYPE_SPECIAL);
                }
            }

            int iCriticalPct = pAttacker->GetPoint (POINT_CRITICAL_PCT);

            if (!IsPC())
            {
                iCriticalPct += pAttacker->GetMarriageBonus (UNIQUE_ITEM_MARRIAGE_CRITICAL_BONUS);
            }

            if (iCriticalPct)
            {
                iCriticalPct -= GetPoint (POINT_RESIST_CRITICAL);

                if (number (1, 100) <= iCriticalPct)
                {
                    IsCritical = true;
                    dam *= 2;
                    EffectPacket (SE_CRITICAL);
                }
            }
            int iPenetratePct = pAttacker->GetPoint (POINT_PENETRATE_PCT);

            if (!IsPC())
            {
                iPenetratePct += pAttacker->GetMarriageBonus (UNIQUE_ITEM_MARRIAGE_PENETRATE_BONUS);
            }

            {
                CSkillProto* pkSk = CSkillManager::instance().Get (SKILL_RESIST_PENETRATE);

                if (NULL != pkSk)
                {
                    pkSk->SetPointVar ("k", 1.0f * GetSkillPower (SKILL_RESIST_PENETRATE) / 100.0f);
                    iPenetratePct -= static_cast<int> (pkSk->kPointPoly.Eval());
                }
            }


            if (iPenetratePct)
            {
                iPenetratePct -= GetPoint (POINT_RESIST_PENETRATE);

                if (number (1, 100) <= iPenetratePct)
                {
                    IsPenetrate = true;

                    if (test_server)
                    {
                        ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("°üÅë Ãß°¡ µ¥¹ÌÁö %d"), GetPoint (POINT_DEF_GRADE) * (100 + GetPoint (POINT_DEF_BONUS)) / 100);
                    }

                    dam += GetPoint (POINT_DEF_GRADE) * (100 + GetPoint (POINT_DEF_BONUS)) / 100;
                    EffectPacket (SE_PENETRATE);
                }
            }

            if (pAttacker->GetPoint (POINT_STEAL_HP))
            {
                int pct = 1;

                if (number (1, 10) <= pct)
                {
                    int iHP = MIN (dam, MAX (0, iCurHP)) * pAttacker->GetPoint (POINT_STEAL_HP) / 100;

                    if (iHP > 0 && GetHP() >= iHP)
                    {

                        CreateFly (FLY_HP_SMALL, pAttacker);
                        pAttacker->PointChange (POINT_HP, iHP);
                        PointChange (POINT_HP, -iHP);
                    }
                }
            }

            if (pAttacker->GetPoint (POINT_STEAL_SP))
            {
                int pct = 1;

                if (number (1, 10) <= pct)
                {
                    int iCur;

                    if (IsPC())
                    {
                        iCur = iCurSP;
                    }
                    else
                    {
                        iCur = iCurHP;
                    }

                    int iSP = MIN (dam, MAX (0, iCur)) * pAttacker->GetPoint (POINT_STEAL_SP) / 100;

                    if (iSP > 0 && iCur >= iSP)
                    {
                        CreateFly (FLY_SP_SMALL, pAttacker);
                        pAttacker->PointChange (POINT_SP, iSP);

                        if (IsPC())
                        {
                            PointChange (POINT_SP, -iSP);
                        }
                    }
                }
            }

            if (pAttacker->GetPoint (POINT_STEAL_GOLD))
            {

                if (number (1, 100) <= pAttacker->GetPoint (POINT_STEAL_GOLD))
                {
                    int iAmount = number (1, GetLevel());
                    pAttacker->PointChange (POINT_GOLD, iAmount);
                    DBManager::instance().SendMoneyLog (MONEY_LOG_MISC, 1, iAmount);
                }
            }

            if (pAttacker->GetPoint (POINT_HIT_HP_RECOVERY) && number (0, 4) > 0)
            {
                int i = ((iCurHP >= 0) ? MIN (dam, iCurHP) : dam) * pAttacker->GetPoint (POINT_HIT_HP_RECOVERY) / 100;
                if (i)
                {
                    CreateFly (FLY_HP_SMALL, pAttacker);
                    pAttacker->PointChange (POINT_HP, i);
                }
            }

            if (pAttacker->GetPoint (POINT_HIT_SP_RECOVERY) && number (0, 4) > 0)
            {
                int i = ((iCurHP >= 0) ? MIN (dam, iCurHP) : dam) * pAttacker->GetPoint (POINT_HIT_SP_RECOVERY) / 100;

                if (i)
                {
                    CreateFly (FLY_SP_SMALL, pAttacker);
                    pAttacker->PointChange (POINT_SP, i);
                }
            }

            if (pAttacker->GetPoint (POINT_MANA_BURN_PCT))
            {
                if (number (1, 100) <= pAttacker->GetPoint (POINT_MANA_BURN_PCT))
                {
                    PointChange (POINT_SP, -50);
                }
            }
        }
    }

    switch (type)
    {
        case DAMAGE_TYPE_NORMAL:
        case DAMAGE_TYPE_NORMAL_RANGE:
            if (pAttacker)
            {
                if (pAttacker->GetPoint (POINT_NORMAL_HIT_DAMAGE_BONUS))
                {
                    dam = dam * (100 + pAttacker->GetPoint (POINT_NORMAL_HIT_DAMAGE_BONUS)) / 100;
                }
            }
            dam = dam * (100 - MIN (99, GetPoint (POINT_NORMAL_HIT_DEFEND_BONUS))) / 100;
            break;

        case DAMAGE_TYPE_MELEE:
        case DAMAGE_TYPE_RANGE:
        case DAMAGE_TYPE_FIRE:
        case DAMAGE_TYPE_ICE:
        case DAMAGE_TYPE_ELEC:
        case DAMAGE_TYPE_MAGIC:
            if (pAttacker)
            {
                if (pAttacker->GetPoint (POINT_SKILL_DAMAGE_BONUS))
                {
                    dam = dam * (100 + pAttacker->GetPoint (POINT_SKILL_DAMAGE_BONUS)) / 100;
                }
            }
            dam = dam * (100 - MIN (99, GetPoint (POINT_SKILL_DEFEND_BONUS))) / 100;
            break;

        default:
            break;
    }

    if (IsAffectFlag (AFF_MANASHIELD))
    {

        int iDamageSPPart = dam / 3;
        int iDamageToSP = iDamageSPPart * GetPoint (POINT_MANASHIELD) / 100;
        int iSP = GetSP();

        if (iDamageToSP <= iSP)
        {
            PointChange (POINT_SP, -iDamageToSP);
            dam -= iDamageSPPart;
        }
        else
        {
            PointChange (POINT_SP, -GetSP());
            dam -= iSP * 100 / MAX (GetPoint (POINT_MANASHIELD), 1);
        }
    }

    if (GetPoint (POINT_MALL_DEFBONUS) > 0)
    {
        int dec_dam = MIN (200, dam * GetPoint (POINT_MALL_DEFBONUS) / 100);
        dam -= dec_dam;
    }

    if (pAttacker)
    {

        if (pAttacker->GetPoint (POINT_MALL_ATTBONUS) > 0)
        {
            int add_dam = MIN (300, dam * pAttacker->GetLimitPoint (POINT_MALL_ATTBONUS) / 100);
            dam += add_dam;
        }

        if (pAttacker->IsPC())
        {

            int iEmpire = pAttacker->GetEmpire();
            long lMapIndex = pAttacker->GetMapIndex();
            int iMapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex (lMapIndex);

            if (iEmpire && iMapEmpire && iEmpire != iMapEmpire)
            {
                dam = dam * 9 / 10;
            }

            if (!IsPC() && GetMonsterDrainSPPoint())
            {
                int iDrain = GetMonsterDrainSPPoint();

                if (iDrain <= pAttacker->GetSP())
                {
                    pAttacker->PointChange (POINT_SP, -iDrain);
                }
                else
                {
                    int iSP = pAttacker->GetSP();
                    pAttacker->PointChange (POINT_SP, -iSP);
                }
            }

        }
        else if (pAttacker->IsGuardNPC())
        {
            SET_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD);
            Stun();
            return true;
        }

    }

    if (!GetSectree() || GetSectree()->IsAttr (GetX(), GetY(), ATTR_BANPK))
    {
        return false;
    }

    if (!IsPC())
    {
        if (m_pkParty && m_pkParty->GetLeader())
        {
            m_pkParty->GetLeader()->SetLastAttacked (get_dword_time());
        }
        else
        {
            SetLastAttacked (get_dword_time());
        }

        MonsterChat (MONSTER_CHAT_ATTACKED);
    }

    if (IsStun())
    {
        Dead (pAttacker);
        return true;
    }

    if (IsDead())
    {
        return true;
    }

    if (type == DAMAGE_TYPE_POISON)
    {
        if (GetHP() - dam <= 0)
        {
            dam = GetHP() - 1;
        }
    }
    if (pAttacker && pAttacker->IsPC())
    {
        int iDmgPct = CHARACTER_MANAGER::instance().GetUserDamageRate (pAttacker);
        dam = dam * iDmgPct / 100;
    }

    if (IsMonster() && IsStoneSkinner())
    {
        if (GetHPPct() < GetMobTable().bStoneSkinPoint)
        {
            dam /= 2;
        }
    }

    if (pAttacker)
    {
        if (pAttacker->IsMonster() && pAttacker->IsDeathBlower())
        {
            if (pAttacker->IsDeathBlow())
            {
                if (number (1, 4) == GetJob())
                {
                    IsDeathBlow = true;
                    dam = dam * 4;
                }
            }
        }

        dam = BlueDragon_Damage (this, pAttacker, dam);
        BYTE damageFlag = 0;

        if (type == DAMAGE_TYPE_POISON)
        {
            damageFlag = DAMAGE_POISON;
        }
        else
        {
            damageFlag = DAMAGE_NORMAL;
        }

        if (IsCritical == true)
        {
            damageFlag |= DAMAGE_CRITICAL;
        }

        if (IsPenetrate == true)
        {
            damageFlag |= DAMAGE_PENETRATE;
        }


        float damMul = this->GetDamMul();
        float tempDam = dam;
        dam = tempDam * damMul + 0.5f;


        if (pAttacker)
        {
            SendDamagePacket (pAttacker, dam, damageFlag);
        }

        if (test_server)
        {
            int iTmpPercent = 0;
            if (GetMaxHP() >= 0)
            {
                iTmpPercent = (GetHP() * 100) / GetMaxHP();
            }

            if (pAttacker)
            {
                pAttacker->ChatPacket (CHAT_TYPE_INFO, "-> %s, DAM %d HP %d(%d%%) %s%s", GetName(), dam, GetHP(), (GetHP() * 100) / GetMaxHP(), IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : "");
            }

            ChatPacket (CHAT_TYPE_PARTY, "<- %s, DAM %d HP %d(%d%%) %s%s", pAttacker ? pAttacker->GetName() : 0, dam, GetHP(), (GetHP() * 100) / GetMaxHP(), IsCritical ? "crit " : "", IsPenetrate ? "pene " : "", IsDeathBlow ? "deathblow " : "");
        }

        if (m_bDetailLog)
        {
            ChatPacket (CHAT_TYPE_INFO, LC_TEXT ("%s[%d]°¡ °ø°Ý À§Ä¡: %d %d"), pAttacker->GetName(), (DWORD) pAttacker->GetVID(), pAttacker->GetX(), pAttacker->GetY());
        }
    }

    if (!cannot_dead)
    {
        if (GetHP() - dam <= 0)
        {
            dam = GetHP();
        }

        PointChange (POINT_HP, -dam, false);
    }

    if (pAttacker && dam > 0 && IsNPC())
    {
        auto it = m_map_kDamage.find (pAttacker->GetVID());

        if (it == m_map_kDamage.end())
        {
            m_map_kDamage.insert (TDamageMap::value_type (pAttacker->GetVID(), TBattleInfo (dam, 0)));
            it = m_map_kDamage.find (pAttacker->GetVID());
        }
        else
        {
            it->second.iTotalDamage += dam;
        }
        StartRecoveryEvent();
        UpdateAggrPointEx (pAttacker, type, dam, it->second);
    }

    if (GetHP() <= 0)
    {
        Stun();

        if (pAttacker && !pAttacker->IsNPC())
        {
            m_dwKillerPID = pAttacker->GetPlayerID();
        }
        else
        {
            m_dwKillerPID = 0;
        }
    }

    return false;
}

 

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...