Расчет физического урона по цели в Lineage 2
calcPhysDam(...) дотошно - в каком порядке что влияет и работает, где мультипликативно, где аддитивно, линейно и так далее и тому подобное.
1) База урона (до деления на защиту)
double defence = target.getPDef(attacker);
// (+ шитовая защита при partial block)
double damage = attacker.getPAtk(target); // 1) чистая базовая атака
damage += calcValakasAttribute(attacker, target, skill); // 2) аддитив к базе (Валакас/серверная механика)
if (ss) damage *= 2; // 3) соски: УДВАИВАЮТ ТОЛЬКО базовый P.Atk (+Валакас), см. ниже
if (skill != null) {
double skillpower = skill.getPower(attacker);// 4) сила скилла — отдельная «полка»
if (skill.getSSBoost() > 0 && ss) // бустуется СВОИМ множителем, если соски активны
skillpower *= skill.getSSBoost();
damage += skillpower; // 5) СП сначала считалась отдельно, потом ДОБАВЛЯЕТСЯ
}
Ключевая тонкость:
🔵соски (ss) не удваивают "всё подряд", они удваивают именно базу P.Atk
🔵сила скилла добавляется после этого, и при наличии SSBoost — множится своим коэффициентом (например, ×2)
Поэтому авто-атака (skill==null) и скилл ведут себя по-разному:
у авто-атаки соски → ×2 всей текущей базе (она только из P.Atk + Valakas),
у скилла - база ×2 + отдельно "полка" skillpower, которая множится через ssBoost, а не тем же ×2.
2) Деление на защиту и крит
Базовый скейл "розничной формулы": 70 * damage / defence.
🟢Без крита:
final double base = 70 * damage / defence;
damage = base;
🟢Крит:
final double base = 70 * damage / defence;
damage = 2
* attacker.calcStat(CRITICAL_DAMAGE, 1, target, skill) // мультипликативный мод к крит-урону
* attacker.calcStat(CRITICAL_DAMAGE_POS, 1, target, skill) // ещё один мультипликатор крита
* target.calcStat(CRIT_VULN, 1, target, null) // уязвимость цели к критам
* base;
// + аддитивный крит-прибавок (почти не влияет на обычных ударах)
damage += attacker.calcStat(CRITICAL_DAMAGE_ADD, 0, target, skill) * 70 / defence;
Итого по криту:
🔵Основная часть - мультипликативная: 2 × CritDmg × CritDmgPos × CritVuln × (70 * damage/def)
🔵Плюс аддитив CritDamageAdd × (70/def). Его вклад заметен, когда defence низкая.
3) Уязвимости к типу оружия (цели)
Если у атакующего есть активное оружие, то выбирается соответствующий Stats.*_WPN_VULN (меч/лук/кинжал/дубина/кастеты и т.д.) и применяется к цели:
damage = target.calcStat(stat, damage, target, null);
// чаще всего это множитель вида 0.9–1.1–1.2… (резисты/уязв)
Это мультипликативно к уже посчитанному.
4. Случайный разброс оружия
Если это не CHARGEDAM-скилл:
damage *= attacker.getRandomDamageMultiplier();
// обычно диапазон вроде 0.8–1.2 (зависит от билда), сглаживает/рандомизирует итог
В один пост не помещаемся, поэтому продолжение следует 🔥