diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index a59998bcc9..4e37fb410b 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -7235,6 +7235,7 @@ Body: TargetType: Self DamageFlags: IgnoreDefense: true + SimpleDefense: true Range: 9 Hit: Single HitCount: 1 @@ -7664,6 +7665,7 @@ Body: TargetType: Attack DamageFlags: IgnoreFlee: true + SimpleDefense: true Flags: TargetTrap: true Range: -2 @@ -9452,6 +9454,7 @@ Body: DamageFlags: IgnoreAtkCard: true IgnoreFlee: true + SimpleDefense: true Flags: IsNpc: true TargetSelf: true @@ -19110,6 +19113,7 @@ Body: DamageFlags: Splash: true IgnoreFlee: true + SimpleDefense: true Flags: TargetTrap: true Range: 9 @@ -22655,6 +22659,7 @@ Body: DamageFlags: Splash: true IgnoreFlee: true + SimpleDefense: true Flags: AllowOnMado: true Range: 9 @@ -28789,6 +28794,7 @@ Body: DamageFlags: Splash: true IgnoreFlee: true + SimpleDefense: true Range: - Level: 1 Size: 7 @@ -33145,6 +33151,7 @@ Body: DamageFlags: Splash: true IgnoreFlee: true + SimpleDefense: true Flags: TargetTrap: true Range: 9 diff --git a/doc/skill_db.txt b/doc/skill_db.txt index 6b6461b975..265fe9a3d4 100644 --- a/doc/skill_db.txt +++ b/doc/skill_db.txt @@ -58,6 +58,7 @@ IgnoreFlee - Skill ignores target's flee (Magic type always ignores) IgnoreDefCard - Skill ignores target's defense cards. IgnoreLongCard - Skill ignores caster's long range damage cards. Critical - Skill can critical. +SimpleDefense - (Renewal-only) Physical damage is flatly reduced by DEF+DEF2. RES is ignored. --------------------------------------- diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 2682071ffc..d87fdb8990 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -6648,42 +6648,31 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list * } #ifdef RENEWAL - switch(skill_id) { - case RK_DRAGONBREATH: - case RK_DRAGONBREATH_WATER: - case NC_ARMSCANNON: - case GN_CARTCANNON: - case MO_EXTREMITYFIST: - 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)) - return; - 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; - [[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; + std::bitset nk = battle_skill_get_damage_properties(skill_id, wd->miscflag); + + if (nk[NK_SIMPLEDEFENSE]) { + // 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); + } + else { /** * RE DEF Reduction * Damage = Attack * (4000+eDEF)/(4000+eDEF*10) - sDEF * Pierce defence gains 1 atk per def/2 */ - default: - if( def1 == -400 ) /* -400 creates a division by 0 and subsequently crashes */ - def1 = -399; - 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_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) ) - 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) ) - wd->damage2 = wd->damage2 * (4000+def1) / (4000+10*def1) - vit_def; - break; + if (def1 == -400) /* -400 creates a division by 0 and subsequently crashes */ + def1 = -399; + 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_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)) + 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)) + wd->damage2 = wd->damage2 * (4000 + def1) / (4000 + 10 * def1) - vit_def; } #else 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 // 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 - // TODO: We should add a flag for those skills or use the IgnoreDefense flag after confirming all + // All skills that use the simple defense formula (damage substracted by DEF+DEF2) ignore Res // 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 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 // MRes reduces magical damage by a percentage and // 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 if (ad.damage && tstatus->mres > 0) { short mres = tstatus->mres; diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index 6a111ebcfe..1e459f6e6f 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -10654,6 +10654,7 @@ export_constant(NK_IGNOREDEFCARD); export_constant(NK_IGNORELONGCARD); export_constant(NK_CRITICAL); + export_constant(NK_SIMPLEDEFENSE); /* skill inf */ export_constant(INF_PASSIVE_SKILL); diff --git a/src/map/skill.hpp b/src/map/skill.hpp index e485ce8b12..5956955adf 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -58,6 +58,7 @@ enum e_skill_nk : uint8 { NK_IGNOREDEFCARD, NK_CRITICAL, NK_IGNORELONGCARD, + NK_SIMPLEDEFENSE, NK_MAX, };