Renewal Simple Defense Formula Flag (#8429)

- Added a flag "SimpleDefense" to mark skills that use the simple defense formula
  * Simple defense: Damage is flat reduced by DEF+DEF2. Res is ignored.
- Dragon Breath / Water now also ignore Res
- Fixes #8419

Special thanks to everyone who helped testing all these skills to confirm this common rule.
This commit is contained in:
Playtester 2024-06-15 20:28:26 +02:00 committed by GitHub
parent 8c4d1bb0c6
commit fcf74b0dfc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 32 additions and 35 deletions

View File

@ -7235,6 +7235,7 @@ Body:
TargetType: Self TargetType: Self
DamageFlags: DamageFlags:
IgnoreDefense: true IgnoreDefense: true
SimpleDefense: true
Range: 9 Range: 9
Hit: Single Hit: Single
HitCount: 1 HitCount: 1
@ -7664,6 +7665,7 @@ Body:
TargetType: Attack TargetType: Attack
DamageFlags: DamageFlags:
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Flags: Flags:
TargetTrap: true TargetTrap: true
Range: -2 Range: -2
@ -9452,6 +9454,7 @@ Body:
DamageFlags: DamageFlags:
IgnoreAtkCard: true IgnoreAtkCard: true
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Flags: Flags:
IsNpc: true IsNpc: true
TargetSelf: true TargetSelf: true
@ -19110,6 +19113,7 @@ Body:
DamageFlags: DamageFlags:
Splash: true Splash: true
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Flags: Flags:
TargetTrap: true TargetTrap: true
Range: 9 Range: 9
@ -22655,6 +22659,7 @@ Body:
DamageFlags: DamageFlags:
Splash: true Splash: true
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Flags: Flags:
AllowOnMado: true AllowOnMado: true
Range: 9 Range: 9
@ -28789,6 +28794,7 @@ Body:
DamageFlags: DamageFlags:
Splash: true Splash: true
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Range: Range:
- Level: 1 - Level: 1
Size: 7 Size: 7
@ -33145,6 +33151,7 @@ Body:
DamageFlags: DamageFlags:
Splash: true Splash: true
IgnoreFlee: true IgnoreFlee: true
SimpleDefense: true
Flags: Flags:
TargetTrap: true TargetTrap: true
Range: 9 Range: 9

View File

@ -58,6 +58,7 @@ IgnoreFlee - Skill ignores target's flee (Magic type always ignores)
IgnoreDefCard - Skill ignores target's defense cards. IgnoreDefCard - Skill ignores target's defense cards.
IgnoreLongCard - Skill ignores caster's long range damage cards. IgnoreLongCard - Skill ignores caster's long range damage cards.
Critical - Skill can critical. Critical - Skill can critical.
SimpleDefense - (Renewal-only) Physical damage is flatly reduced by DEF+DEF2. RES is ignored.
--------------------------------------- ---------------------------------------

View File

@ -6648,42 +6648,31 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list *
} }
#ifdef RENEWAL #ifdef RENEWAL
switch(skill_id) { std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
case RK_DRAGONBREATH:
case RK_DRAGONBREATH_WATER: if (nk[NK_SIMPLEDEFENSE]) {
case NC_ARMSCANNON: // Defense reduction by flat value.
case GN_CARTCANNON: // This completely bypasses the normal RE DEF Reduction formula.
case MO_EXTREMITYFIST: wd->damage -= (def1 + vit_def);
if (attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_R) || attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_L)) if (is_attack_left_handed(src, skill_id))
return; wd->damage2 -= (def1 + vit_def);
if (is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) || is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L)) }
return; else {
[[fallthrough]];
case CR_GRANDCROSS: // Grand Cross is marked as "IgnoreDefense" in renewal as it's applied at the end after already combining ATK and MATK
case NPC_GRANDDARKNESS:
// Defense reduction by flat value.
// This completely bypasses the normal RE DEF Reduction formula.
wd->damage -= (def1 + vit_def);
if (is_attack_left_handed(src, skill_id))
wd->damage2 -= (def1 + vit_def);
break;
/** /**
* RE DEF Reduction * RE DEF Reduction
* Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF * Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF
* Pierce defence gains 1 atk per def/2 * Pierce defence gains 1 atk per def/2
*/ */
default: if (def1 == -400) /* -400 creates a division by 0 and subsequently crashes */
if( def1 == -400 ) /* -400 creates a division by 0 and subsequently crashes */ def1 = -399;
def1 = -399; ATK_ADD2(wd->damage, wd->damage2,
ATK_ADD2(wd->damage, wd->damage2, is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) ? (def1 * battle_calc_attack_skill_ratio(wd, src, target, skill_id, skill_lv)) / 200 : 0,
is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) ? (def1*battle_calc_attack_skill_ratio(wd, src, target, skill_id, skill_lv))/200 : 0, is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L) ? (def1 * battle_calc_attack_skill_ratio(wd, src, target, skill_id, skill_lv)) / 200 : 0
is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L) ? (def1*battle_calc_attack_skill_ratio(wd, src, target, skill_id, skill_lv))/200 : 0 );
); if (!attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_R) && !is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R))
if( !attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_R) && !is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) ) wd->damage = wd->damage * (4000 + def1) / (4000 + 10 * def1) - vit_def;
wd->damage = wd->damage * (4000+def1) / (4000+10*def1) - vit_def; if (is_attack_left_handed(src, skill_id) && !attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_L) && !is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L))
if( is_attack_left_handed(src, skill_id) && !attack_ignores_def(wd, src, target, skill_id, skill_lv, EQI_HAND_L) && !is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L) ) wd->damage2 = wd->damage2 * (4000 + def1) / (4000 + 10 * def1) - vit_def;
wd->damage2 = wd->damage2 * (4000+def1) / (4000+10*def1) - vit_def;
break;
} }
#else #else
if (def1 > 100) def1 = 100; if (def1 > 100) def1 = 100;
@ -7507,10 +7496,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
// Res reduces physical damage by a percentage and // Res reduces physical damage by a percentage and
// is calculated before DEF and other reductions. // is calculated before DEF and other reductions.
// TODO: It seems all skills that use the simple defense formula (damage substracted by DEF+DEF2) ignore Res // All skills that use the simple defense formula (damage substracted by DEF+DEF2) ignore Res
// TODO: We should add a flag for those skills or use the IgnoreDefense flag after confirming all
// TODO: Res formula probably should be: (2000+x)/(2000+5x), but with the reduction rounded down // TODO: Res formula probably should be: (2000+x)/(2000+5x), but with the reduction rounded down
if ((wd.damage + wd.damage2) && tstatus->res > 0 && skill_id != MO_EXTREMITYFIST && skill_id != GN_CARTCANNON && skill_id != NC_ARMSCANNON) { if ((wd.damage + wd.damage2) && tstatus->res > 0 && !nk[NK_SIMPLEDEFENSE]) {
short res = tstatus->res; short res = tstatus->res;
short ignore_res = 0;// Value used as a percentage. short ignore_res = 0;// Value used as a percentage.
@ -8786,7 +8774,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
#ifdef RENEWAL #ifdef RENEWAL
// MRes reduces magical damage by a percentage and // MRes reduces magical damage by a percentage and
// is calculated before MDEF and other reductions. // is calculated before MDEF and other reductions.
// TODO: Check if there are skills that ignore Mres, similar to skills that ignore Res
// TODO: MRes formula probably should be: (2000+x)/(2000+5x), but with the reduction rounded down // TODO: MRes formula probably should be: (2000+x)/(2000+5x), but with the reduction rounded down
if (ad.damage && tstatus->mres > 0) { if (ad.damage && tstatus->mres > 0) {
short mres = tstatus->mres; short mres = tstatus->mres;

View File

@ -10654,6 +10654,7 @@
export_constant(NK_IGNOREDEFCARD); export_constant(NK_IGNOREDEFCARD);
export_constant(NK_IGNORELONGCARD); export_constant(NK_IGNORELONGCARD);
export_constant(NK_CRITICAL); export_constant(NK_CRITICAL);
export_constant(NK_SIMPLEDEFENSE);
/* skill inf */ /* skill inf */
export_constant(INF_PASSIVE_SKILL); export_constant(INF_PASSIVE_SKILL);

View File

@ -58,6 +58,7 @@ enum e_skill_nk : uint8 {
NK_IGNOREDEFCARD, NK_IGNOREDEFCARD,
NK_CRITICAL, NK_CRITICAL,
NK_IGNORELONGCARD, NK_IGNORELONGCARD,
NK_SIMPLEDEFENSE,
NK_MAX, NK_MAX,
}; };