GC Wiki Исправление формулы магического урона — верификация по retail L2Server.exe

TalosTalos is verified member.

Технический Руководитель
Staff member
Supervisor
Melcosoft Family

Суть проблемы


В методе Formulas.calcMagicDam присутствовал баг, из-за которого к каждому магическому удару добавлялся лишний урон равный power скилла. Код выглядел так:

Java:
info.damage += attacker.getStat().calc(Stats.M_SKILL_POWER,
    (attacker.isServitor() ? Config.SERVITOR_M_SKILL_POWER_MODIFIER : 1.) * power);

Проблема в том, что второй аргумент calc() — это init (начальное значение калькулятора). Если на персонаже нет ни одной функции для стата M_SKILL_POWER, калькулятор пустой и метод просто возвращает init как есть — то есть power скилла. В итоге к урону всегда прибавлялось значение power, даже без каких-либо XML-бонусов.

В вакуумных условиях теста — голый персонаж без бонусов, без бафов, без экипировки — завышение составляло +19% до +25%. В реальных условиях игры с бонусами к магическому урону картина другая — об этом ниже.



Анализ retail L2Server.exe через IDA Pro


Для верификации были изучены следующие функции из retail бинаря:

L2SkillFunc::CalcAndApplyMagicAttackDamage — точка входа расчёта магического урона. Базовая формула:
C++:
v15 = sqrt(attackerInfo.m_MagicPower * SoulBonus);
damage = v15 * skillPower * 91.0 / targetInfo.m_MDefend * targetInfo.m_AttrResist;

L2SkillFunc::GetMagicAttackerInfo — сбор данных атакующего. m_MagicPower = m_dParam[3] (полный mAtk с бонусами).

L2SkillFunc::GetMagicTargetInfo — сбор данных цели. m_MDefend = m_dParam[1] (полный mdef), затем умножается на m_dMagicalPenetrateFactor.

L2SkillFunc::CalcFinalDamage — применение PvP/PvE бонусов, magic resist, weapon random damage, крит.

L2SkillFunc::ApplyBonusToAttackDamage — финальный множитель для магических скиллов (isMagic == 1):
C++:
return dDamage * Mods[54].Per + Mods[54].Diff;

CSkillEffect_p_spell_power::Pump — эффект бонуса к магическому урону:
C++:
L2SkillFunc::AddBonus(pCreature, PSpellPower, this->m_sfct, this->m_dBonus);

L2SkillFunc::AddBonus — при SFCT_PER:
C++:
*perValue = (dBonus + 100.0) / 100.0 * *perValue;
// p_spell_power;2;per → Mods[54].Per *= 1.02

Таким образом p_spell_power влияет на Mods[54].Per — финальный множитель урона. В Java это реализовано через Stats.M_SKILL_POWER как мультипликативный стат.



Сравнение урона до и после фикса


Условия теста: голый персонаж без бонусов и бафов, НПС mdef=520, 150 attribute resist ALL. Разброс урона отключён.

УсловиеPTSJava (было)Java (стало)
518 mAtk, 0 attr, no element447558 (+24.8%)446 ✓
518 mAtk, 0 attr, fire 10454567 (+24.9%)453 ✓
898 mAtk, 450 dark, no element8711035 (+18.8%)869 ✓
898 mAtk, 450 dark, fire 10598710 (+18.7%)596 ✓

Атрибутная система работала корректно — расхождение было исключительно в базовой формуле.


Верификация p_spell_power (+2% к магическому урону)


УсловиеPTS без бонусаPTS с бонусомJava без бонусаJava с бонусом
518 mAtk, no element447456 (+2.01%)446455 (+2.02%) ✓
898 mAtk, no element871888 (+1.95%)869886 (+1.96%) ✓

Расхождение в 1-2 единицы — округление int.


Видео сравнения


Проверка магического урона на нашем сервере:


Проверка магического урона на Retail Server:



Разница между нашим сервером и ретейлом составляет 1-2 единицы урона — исключительно за счёт округления int. Формула верифицирована по retail L2Server.exe.


Для игроков — нерф или не нерф?


Коротко: это не нерф, это исправление бага.

Цифры +19-25% из таблицы выше — это вакуумный тест: голый персонаж, никаких бонусов, никаких бафов. В реальных условиях игры картина совсем другая, а учитывая разброс урона вы это даже не заметите.

Суть бага была в том, что бонусы к магическому урону (mSkillPower) почти не работали — они применялись к маленькому числу (power скилла) вместо полного урона. Теперь всё работает правильно, и это частично или полностью компенсирует снижение базового урона.

Чем выше mAtk и чем больше бонус к магическому урону — тем заметнее положительный эффект. Маги с хорошей экипировкой и прокачанными пассивками могут бить сильнее, чем раньше.




Верификация магического урона — SS Extra + SS Bonus


Условия теста: SS extra +7% (энчант оружия), SS bonus +20% (камень Сапфир 5 ур.), цель mdef=512, защита атрибута 150, атака атрибута 340. Разброс урона отключён.

УсловиеPTSJavaПогрешность
mAtk=268 872, обычный удар60 47660 3960.13% ✓
mAtk=268 872, критический удар195 973195 6900.14% ✓
mAtk=534 809, обычный удар85 29285 1800.13% ✓
mAtk=534 809, критический удар276 039275 6500.14% ✓

Расхождение 0.13–0.14% является нормой — это результат округления int при финальном расчёте урона, а также незначительной разницы в mAtk между двумя клиентами. Поведение полностью соответствует retail.

Видео сравнения:

Проверка магического урона на нашем сервере:



Проверка магического урона Retail Server:
 
Last edited:
UPD: В тему добавлена верификация магического урона с полным бафом — SS Extra +7% (энчант оружия) + SS Bonus +20% (камень Сапфир 5 ур.). Погрешность между нашим сервером и retail составила 0.13–0.14% — в пределах округления int. Видео сравнения добавлены в таблицу выше.
 
Back
Top Bottom