Формула заточки предметов на pts

sergebaz

Прославленный
Местный
Сообщения
540
Розыгрыши
0
Решения
1
Репутация
230
Реакции
105
Баллы
1 478
Доброго времени, подскажите интересует шанс заточки на птсе и примерная формула расчета нашел вот это:
Не магическое оружие:
+3 --> +15 = 2/3 каждый энчант
+15 --> ∞ = 1/3 каждый энчант
Магическое оружие:
+3 --> +15 = 40% каждый энчант
+15 --> ∞ = 20% каждый энчант
Бижа, рубашки, пояса, щиты и броня (кроме фуллбоди):
+3 --> +4 = 2/3
+n --> +(n+1) = 1/(n-2)
Фуллбоди:
+4 --> +5 = 2/3
+n --> +(n+1) = 1/(n-2)

Верная ли формула?
 

Доброго времени, подскажите интересует шанс заточки на птсе и примерная формула расчета нашел вот это:
Не магическое оружие:
+3 --> +15 = 2/3 каждый энчант
+15 --> ∞ = 1/3 каждый энчант
Магическое оружие:
+3 --> +15 = 40% каждый энчант
+15 --> ∞ = 20% каждый энчант
Бижа, рубашки, пояса, щиты и броня (кроме фуллбоди):
+3 --> +4 = 2/3
+n --> +(n+1) = 1/(n-2)
Фуллбоди:
+4 --> +5 = 2/3
+n --> +(n+1) = 1/(n-2)

Верная ли формула?
Код:
bool __cdecl CItem::EnchantItem(struct CItem *a1, struct User *a2, enum SkillFxChangeType a3, double a10)
{
    int v4; // er9@0
    double v5; // xmm0_8@0
    __m128i v6; // xmm6@0
    __m128i v7; // xmm7@0
    __m128i v8; // xmm8@0
    __m128i v9; // xmm9@0
    int v10; // ebx@1
    __int64 v11; // r12@1
    struct User *v12; // rbp@1
    struct CItem *v13; // r14@1
    __int64 v14; // r15@1
    __int64 v15; // r10@1
    __int64 v16; // rdx@1
    bool result; // al@2
    __int64 v18; // rax@3
    __int64 v19; // rdi@3
    char v20; // si@3
    struct CItem *v21; // r13@3
    double v22; // xmm9_8@3
    __int64 v23; // rax@6
    double v24; // xmm6_8@8
    double v25; // xmm6_8@11
    double v26; // xmm6_8@17
    double v27; // xmm6_8@20
    double v28; // xmm6_8@29
    double v29; // xmm6_8@34
    double v30; // xmm0_8@38
    int v31; // ecx@40
    struct User *v32; // [sp+20h] [bp-B8h]@0
    __int128 v33; // [sp+50h] [bp-88h]@1
    __int128 v34; // [sp+60h] [bp-78h]@1
    __int128 v35; // [sp+70h] [bp-68h]@1
    __int128 v36; // [sp+80h] [bp-58h]@1
    double a10a; // [sp+100h] [bp+28h]@0

    _mm_store_si128((__m128i *)&v36, v6);
    _mm_store_si128((__m128i *)&v35, v7);
    _mm_store_si128((__m128i *)&v34, v8);
    _mm_store_si128((__m128i *)&v33, v9);
    v10 = v4;
    v11 = *(_QWORD *)&a3;
    v12 = a2;
    v13 = a1;
    v14 = *(_QWORD *)(*MK_FP(__GS__, 88i64) + 8i64 * (unsigned int)TlsIndex);
    v15 = *(_DWORD *)(v14 + 32024);
    v16 = dword_228EC90[v15];
    dword_228EC90[v15] = v16 + 1;
    qword_226F890[v16 + 1000 * v15] = (__int64)L"bool __cdecl CItem::EnchantItem(class CItem *,class User *,enum SkillFxChangeType,double)";

    if (!v12)
    {
        --dword_228EC90[*(_DWORD *)(v14 + 32024)];
        return 0;
    }

    v18 = *((_QWORD *)v12 + 9);
    v19 = *(_DWORD *)(v18 + 144);
    v20 = (*(_DWORD *)(v18 + 128) >> 15) & 1;
    v21 = User::GetPendingUseETCItem((enum PendingUseItemType)a3);
    v22 = 0.0;

    if (v21)
    {
        v22 = (double)(signed int)floor(*(double *)(v11 + 14624));
    }

    if ((unsigned __int8)(*(int (__fastcall **)(struct User *))(*(_QWORD *)v12 + 576i64))(v12))
    {
        v23 = *((_QWORD *)v12 + 10);
        if (*(_DWORD *)(v23 + 324) >= 2 && *(_BYTE *)(v23 + 132))
        {
            v24 = 40.0; // Шанс на заточку Маг. Оружия от 4+
            if ((signed int)v19 >= 3)
            {
                if ((signed int)v19 >= 15)
                    v24 = 20.0; // Шанс на заточку Маг. Оружия от 15+
            
                v25 = v24 + v22; // v22 - Бонус для заточки.
        
                if (v10)
                {
                    if (v10 == 1)
                    {
                        v5 = a10a * 100.0;
                        v25 = v25 + a10a * 100.0;
                    }
                }
                else
                {
                    v5 = a10a / 100.0 + 1.0;
                    v25 = v25 * v5;
                }
                sub_94D9B8();
                if (v25 < v5 * (100.0 - 0.0) + 0.0)
                {
                    LABEL_40:
                    v31 = *(_DWORD *)(*((_QWORD *)v13 + 10) + 8i64);
            
                    if (v31 == 21 || v31 == 22)
                    {
                        LODWORD(v32) = 0;
                        CDB::RequestEnchantItem((struct CItem *)&qword_149AE80, v13, v21, (int)v12, v32, v11);
                    }
                    else if (v31 == 31 || v31 == 32)
                    {
                        LODWORD(v32) = v19;
                        CDB::RequestEnchantItem((struct CItem *)&qword_149AE80, v13, v21, (int)v12, v32, v11);
                    }
                    else
                    {
                        CDB::RequestEnchantItemFail(&qword_149AE80, (__int64)v13, (__int64)v21, (__int64)v12, v11);
                    }
            
                    goto LABEL_48;
                }
            }
        }
        else
        {
            v26 = 70.0; // Шанс на заточку Физ. Оружия от 4+
            if ((signed int)v19 >= 3)
            {
                if ((signed int)v19 >= 15)
                    v26 = 35.0; // Шанс на заточку Физ. Оружия от 15+
        
                v27 = v26 + v22; // v22 - Бонус для заточки.
        
                if (v10)
                {
                    if (v10 == 1)
                    {
                        v5 = a10a * 100.0;
                        v27 = v27 + a10a * 100.0;
                    }
                }
                else
                {
                    v5 = a10a / 100.0 + 1.0;
                    v27 = v27 * v5;
                }
                sub_94D9B8();
        
                if (v27 < v5 * (100.0 - 0.0) + 0.0)
                    goto LABEL_40;
            }
        }
    }
    else if ((signed int)v19 >= 3)
    {
        if ((signed int)v19 >= 20)
        {
            v28 = 0.0;
        }
        else if (v20)
        {
            v5 = *(double *)&qword_B5EF60[v19] * 100.0;
            v28 = 100.0 - v5;
        }
        else
        {
            v5 = *(double *)&qword_B5EEC0[v19] * 100.0;
            v28 = 100.0 - v5;
        }
 
        if ((signed int)v19 >= 15)
            v28 = v28 * 0.5;
        v29 = v28 + v22; // v22 - Бонус для заточки.
 
        if (v10)
        {
            if (v10 == 1)
            {
                v5 = a10a * 100.0;
                v29 = v29 + a10a * 100.0;
            }
        }
        else
        {
            v5 = a10a / 100.0 + 1.0;
            v29 = v29 * v5;
        }
 
        sub_94D9B8();
        v30 = v5 * (100.0 - 0.0) + 0.0;
 
        if ((signed int)v19 >= 20 || v29 < v30)
            goto LABEL_40;
    }

    LODWORD(v32) = v19 + 1;  // Затачиваем на (текущая точка + 1)
    CDB::RequestEnchantItem((struct CItem *)&qword_149AE80, v13, v21, (int)v12, v32, v11);
    LABEL_48:
    result = 1;
    --dword_1E8EC90[*(_DWORD *)(v14 + 32024) + 0x100000];
    return result;
}
Это с грации финал
 
ладно раз уж тут декомпилами кидаем... вот чуток более читабельный
C++:
char __thiscall CWorldItem::EnchantItem(CWorldItem *this, CWorldItem *itemToEnchant, CWorldUser *user)
{
  int enchantLevel; // esi@3
  CSharedItemConstData *constSharedData; // eax@4
  CUserSocket *userSocket; // eax@11 MAPDST
  double dice2; // st7@28
  int itemClassId; // [sp-4h] [bp-3Ch]@11 MAPDST
  int v11; // [sp+0h] [bp-38h]@1
  double dice; // [sp+Ch] [bp-2Ch]@9
  double chance; // [sp+14h] [bp-24h]@6
  int *v15; // [sp+28h] [bp-10h]@1
  int v16; // [sp+34h] [bp-4h]@1

  v15 = &v11;
  v16 = 0;
  if ( !itemToEnchant )                         // Add lock/unlock!!
  {
    return false;
  }
  enchantLevel = itemToEnchant->m_d.m_sharedData->enchantLevel;
  if ( itemToEnchant->vtable->m_v.IsWeapon(itemToEnchant) )
  {
    constSharedData = itemToEnchant->m_d.m_constSharedData;
    if ( constSharedData->crystalType >= 2 && constSharedData->isMagicWeapon )
    {
      chance = 100.0 - 60.0;
      if ( enchantLevel < 3 )
      {
LABEL_11:
        userSocket = user->m_d.m_userSocket;
        itemClassId = itemToEnchant->m_d.m_sharedData->itemClassId;
        if ( enchantLevel )
        {
          CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddddd", ServerToClientPacket_SystemMessage, SystemMessageId_s1s2_has_been_successfully_enchanted, 2, 1, enchantLevel, 3, itemClassId);
        }
        else
        {
          CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddd", ServerToClientPacket_SystemMessage, SystemMessageId_s1_has_been_successfully_enchanted, 1, 3, itemClassId);
        }
        CDB::RequestEnchantItem(&g_cacheD, this, itemToEnchant, enchantLevel + 1, user);
        return true;
      }
      if ( enchantLevel >= 15 )
      {
        chance = chance * 0.5;
      }
      dice = Utils::GetRandomNumber(0.0, 100.0);
      if ( dice <= chance )
      {
        CLog::Add(&g_winlog, LOG_REQUEST, L"magic weapon enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
        goto LABEL_11;
      }
      CLog::Add(&g_winlog, LOG_REQUEST, L"magic weapon enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
    }
    else
    {
      chance = 100.0 - 30.0;
      if ( enchantLevel < 3 )
      {
        goto LABEL_11;
      }
      if ( enchantLevel >= 15 )
      {
        chance = chance * 0.5;
      }
      dice = Utils::GetRandomNumber(0.0, 100.0);
      if ( dice <= chance )
      {
        CLog::Add(&g_winlog, LOG_REQUEST, L"weapon enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
        goto LABEL_11;
      }
      CLog::Add(&g_winlog, LOG_REQUEST, L"weapon enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
    }
  }
  else
  {
    if ( enchantLevel < 3 )
    {
      goto LABEL_11;
    }
    if ( enchantLevel >= 20 )
    {
      chance = 0.0;
    }
    else
    {
      chance = 100.0 - g_armorEnchantFailureChances[enchantLevel] * 100.0;
    }
    if ( enchantLevel >= 15 )
    {
      chance = chance * 0.5;
    }
    dice2 = Utils::GetRandomNumber(0.0, 100.0);
    dice = dice2;
    if ( enchantLevel < 20 && dice2 <= chance )
    {
      CLog::Add(&g_winlog, LOG_REQUEST, L"armor enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
      goto LABEL_11;
    }
    CLog::Add(&g_winlog, LOG_REQUEST, L"armor enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
  }
  userSocket = user->m_d.m_userSocket;
  itemClassId = itemToEnchant->m_d.m_sharedData->itemClassId;
  if ( enchantLevel )
  {
    CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddddd", ServerToClientPacket_SystemMessage, SystemMessageId_Enchantment_has_failed_s1s2_has_been_evaporated, 2, 1, enchantLevel, 3, itemClassId);
  }
  else
  {
    CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddd", ServerToClientPacket_SystemMessage, SystemMessageId_Enchantment_has_failed_s1_has_been_evaporated, 1, 3, itemClassId);
  }
  CDB::RequestEnchantItemFail(&g_cacheD, this, itemToEnchant, user);
  return true;
}
 
ладно раз уж тут декомпилами кидаем... вот чуток более читабельный
C++:
char __thiscall CWorldItem::EnchantItem(CWorldItem *this, CWorldItem *itemToEnchant, CWorldUser *user)
{
  int enchantLevel; // esi@3
  CSharedItemConstData *constSharedData; // eax@4
  CUserSocket *userSocket; // eax@11 MAPDST
  double dice2; // st7@28
  int itemClassId; // [sp-4h] [bp-3Ch]@11 MAPDST
  int v11; // [sp+0h] [bp-38h]@1
  double dice; // [sp+Ch] [bp-2Ch]@9
  double chance; // [sp+14h] [bp-24h]@6
  int *v15; // [sp+28h] [bp-10h]@1
  int v16; // [sp+34h] [bp-4h]@1

  v15 = &v11;
  v16 = 0;
  if ( !itemToEnchant )                         // Add lock/unlock!!
  {
    return false;
  }
  enchantLevel = itemToEnchant->m_d.m_sharedData->enchantLevel;
  if ( itemToEnchant->vtable->m_v.IsWeapon(itemToEnchant) )
  {
    constSharedData = itemToEnchant->m_d.m_constSharedData;
    if ( constSharedData->crystalType >= 2 && constSharedData->isMagicWeapon )
    {
      chance = 100.0 - 60.0;
      if ( enchantLevel < 3 )
      {
LABEL_11:
        userSocket = user->m_d.m_userSocket;
        itemClassId = itemToEnchant->m_d.m_sharedData->itemClassId;
        if ( enchantLevel )
        {
          CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddddd", ServerToClientPacket_SystemMessage, SystemMessageId_s1s2_has_been_successfully_enchanted, 2, 1, enchantLevel, 3, itemClassId);
        }
        else
        {
          CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddd", ServerToClientPacket_SystemMessage, SystemMessageId_s1_has_been_successfully_enchanted, 1, 3, itemClassId);
        }
        CDB::RequestEnchantItem(&g_cacheD, this, itemToEnchant, enchantLevel + 1, user);
        return true;
      }
      if ( enchantLevel >= 15 )
      {
        chance = chance * 0.5;
      }
      dice = Utils::GetRandomNumber(0.0, 100.0);
      if ( dice <= chance )
      {
        CLog::Add(&g_winlog, LOG_REQUEST, L"magic weapon enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
        goto LABEL_11;
      }
      CLog::Add(&g_winlog, LOG_REQUEST, L"magic weapon enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
    }
    else
    {
      chance = 100.0 - 30.0;
      if ( enchantLevel < 3 )
      {
        goto LABEL_11;
      }
      if ( enchantLevel >= 15 )
      {
        chance = chance * 0.5;
      }
      dice = Utils::GetRandomNumber(0.0, 100.0);
      if ( dice <= chance )
      {
        CLog::Add(&g_winlog, LOG_REQUEST, L"weapon enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
        goto LABEL_11;
      }
      CLog::Add(&g_winlog, LOG_REQUEST, L"weapon enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
    }
  }
  else
  {
    if ( enchantLevel < 3 )
    {
      goto LABEL_11;
    }
    if ( enchantLevel >= 20 )
    {
      chance = 0.0;
    }
    else
    {
      chance = 100.0 - g_armorEnchantFailureChances[enchantLevel] * 100.0;
    }
    if ( enchantLevel >= 15 )
    {
      chance = chance * 0.5;
    }
    dice2 = Utils::GetRandomNumber(0.0, 100.0);
    dice = dice2;
    if ( enchantLevel < 20 && dice2 <= chance )
    {
      CLog::Add(&g_winlog, LOG_REQUEST, L"armor enchant success, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
      goto LABEL_11;
    }
    CLog::Add(&g_winlog, LOG_REQUEST, L"armor enchant fail, prev enchanted[%d], dice[%f], prob[%f]", enchantLevel, dice, chance);
  }
  userSocket = user->m_d.m_userSocket;
  itemClassId = itemToEnchant->m_d.m_sharedData->itemClassId;
  if ( enchantLevel )
  {
    CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddddd", ServerToClientPacket_SystemMessage, SystemMessageId_Enchantment_has_failed_s1s2_has_been_evaporated, 2, 1, enchantLevel, 3, itemClassId);
  }
  else
  {
    CServerSocketBase::Send((CServerSocketBase *)userSocket, (const char *)"cdddd", ServerToClientPacket_SystemMessage, SystemMessageId_Enchantment_has_failed_s1_has_been_evaporated, 1, 3, itemClassId);
  }
  CDB::RequestEnchantItemFail(&g_cacheD, this, itemToEnchant, user);
  return true;
}
Ну а здесь намного все понятнее, спасибо)

с армором только пока не разобрался)

chance = 100.0 - g_armorEnchantFailureChances[enchantLevel] * 100.0;
g_armorEnchantFailureChances[enchantLevel] что за значение и откуда берется
 
Последнее редактирование модератором:
Назад
Сверху Снизу