Critical Hits on Focused Arrow Strike and Gunslinger (#8201)
- Focused Arrow Strike no longer deals max damage when it crits (pre-re) - Focused Arrow Strike no longer considers cards that increase/decrease critical damage (pre-re) - Criticals with any guns are now calculated like melee criticals, not considering bullet attack (pre-re) - Chain Action can no longer do critical hits (pre-re) - Fixes #8200
This commit is contained in:
parent
7d9a23d03f
commit
43d4e071df
@ -13856,8 +13856,6 @@ Body:
|
||||
Description: Chain Action
|
||||
MaxLevel: 10
|
||||
Type: Weapon
|
||||
DamageFlags:
|
||||
Critical: true
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: 2
|
||||
|
@ -2476,7 +2476,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
if (sc != nullptr && sc->getSCE(SC_CHANGE) != nullptr)
|
||||
return status->matk_max; // [Aegis] simply uses raw max matk for base damage when Mental Charge active
|
||||
#endif
|
||||
if(flag&4) {
|
||||
if(flag&BDMG_MAGIC) {
|
||||
atkmin = status->matk_min;
|
||||
atkmax = status->matk_max;
|
||||
} else {
|
||||
@ -2489,7 +2489,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
atkmax = wa->atk;
|
||||
type = (wa == &status->lhw)?EQI_HAND_L:EQI_HAND_R;
|
||||
|
||||
if (!(flag&1) || (flag&2)) { //Normal attacks
|
||||
if (!(flag&BDMG_CRIT) || (flag&BDMG_ARROW)) { //Normal attacks
|
||||
atkmin = status->dex;
|
||||
|
||||
if (sd->equip_index[type] >= 0 && sd->inventory_data[sd->equip_index[type]] && sd->inventory_data[sd->equip_index[type]]->type == IT_WEAPON)
|
||||
@ -2498,7 +2498,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
if (atkmin > atkmax)
|
||||
atkmin = atkmax;
|
||||
|
||||
if(flag&2 && !(flag&16)) { //Bows
|
||||
if(flag&BDMG_ARROW && !(flag&BDMG_THROW)) { //Bows
|
||||
atkmin = atkmin*atkmax/100;
|
||||
if (atkmin > atkmax)
|
||||
atkmax = atkmin;
|
||||
@ -2510,18 +2510,18 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
atkmin = atkmax;
|
||||
|
||||
//Weapon Damage calculation
|
||||
if (!(flag&1))
|
||||
if (!(flag&BDMG_CRIT))
|
||||
damage = (atkmax>atkmin? rnd()%(atkmax-atkmin):0)+atkmin;
|
||||
else
|
||||
damage = atkmax;
|
||||
|
||||
if (sd) {
|
||||
//rodatazone says the range is 0~arrow_atk-1 for non crit
|
||||
if (flag&2 && sd->bonus.arrow_atk)
|
||||
damage += ( (flag&1) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
|
||||
if (flag&BDMG_ARROW && sd->bonus.arrow_atk)
|
||||
damage += ( (flag&BDMG_CRIT) ? sd->bonus.arrow_atk : rnd()%sd->bonus.arrow_atk );
|
||||
|
||||
// Size fix only for players
|
||||
if (!(sd->special_state.no_sizefix || (flag&8)))
|
||||
if (!(sd->special_state.no_sizefix || (flag&BDMG_NOSIZE)))
|
||||
damage = damage * (type == EQI_HAND_L ? sd->left_weapon.atkmods[t_size] : sd->right_weapon.atkmods[t_size]) / 100;
|
||||
} else if (src->type == BL_ELEM) {
|
||||
status_change *ele_sc = status_get_sc(src);
|
||||
@ -2563,7 +2563,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
}
|
||||
|
||||
//Finally, add baseatk
|
||||
if(flag&4)
|
||||
if(flag&BDMG_MAGIC)
|
||||
damage += status->matk_min;
|
||||
else
|
||||
damage += status->batk;
|
||||
@ -2572,7 +2572,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
battle_add_weapon_damage(sd, &damage, type);
|
||||
|
||||
#ifdef RENEWAL
|
||||
if (flag&1)
|
||||
if (flag&BDMG_CRIT)
|
||||
damage = (damage * 14) / 10;
|
||||
#endif
|
||||
|
||||
@ -3892,7 +3892,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
map_session_data *sd = BL_CAST(BL_PC, src);
|
||||
map_session_data *tsd = BL_CAST(BL_PC, target);
|
||||
|
||||
uint16 i;
|
||||
uint16 i, bflag = BDMG_NONE;
|
||||
std::bitset<NK_MAX> nk = battle_skill_get_damage_properties(skill_id, wd->miscflag);
|
||||
|
||||
switch (skill_id) { //Calc base damage according to skill
|
||||
@ -4039,41 +4039,46 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
break;
|
||||
|
||||
default:
|
||||
// Flags that apply to both pre-renewal and renewal
|
||||
bflag = (is_attack_critical(wd, src, target, skill_id, skill_lv, false) ? BDMG_CRIT : BDMG_NONE) |
|
||||
(!skill_id && sc && sc->getSCE(SC_CHANGE) ? BDMG_MAGIC : BDMG_NONE);
|
||||
#ifdef RENEWAL
|
||||
if (sd)
|
||||
battle_calc_damage_parts(wd, src, target, skill_id, skill_lv);
|
||||
else {
|
||||
i = (is_attack_critical(wd, src, target, skill_id, skill_lv, false)?1:0)|
|
||||
(!skill_id && sc && sc->getSCE(SC_CHANGE)?4:0);
|
||||
|
||||
wd->damage = battle_calc_base_damage(src, sstatus, &sstatus->rhw, sc, tstatus->size, i);
|
||||
wd->damage = battle_calc_base_damage(src, sstatus, &sstatus->rhw, sc, tstatus->size, bflag);
|
||||
if (is_attack_left_handed(src, skill_id))
|
||||
wd->damage2 = battle_calc_base_damage(src, sstatus, &sstatus->lhw, sc, tstatus->size, i);
|
||||
wd->damage2 = battle_calc_base_damage(src, sstatus, &sstatus->lhw, sc, tstatus->size, bflag);
|
||||
}
|
||||
#else
|
||||
i = (is_attack_critical(wd, src, target, skill_id, skill_lv, false)?1:0)|
|
||||
(is_skill_using_arrow(src, skill_id)?2:0)|
|
||||
(skill_id == HW_MAGICCRASHER?4:0)|
|
||||
(!skill_id && sc && sc->getSCE(SC_CHANGE)?4:0)|
|
||||
(skill_id == MO_EXTREMITYFIST?8:0)|
|
||||
(sc && sc->getSCE(SC_WEAPONPERFECTION)?8:0);
|
||||
// Pre-renewal exclusive flags
|
||||
if (is_skill_using_arrow(src, skill_id)) bflag |= BDMG_ARROW;
|
||||
if (skill_id == HW_MAGICCRASHER) bflag |= BDMG_MAGIC;
|
||||
if (skill_id == MO_EXTREMITYFIST) bflag |= BDMG_NOSIZE;
|
||||
if (sc && sc->getSCE(SC_WEAPONPERFECTION)) bflag |= BDMG_NOSIZE;
|
||||
if (is_skill_using_arrow(src, skill_id) && sd) {
|
||||
switch(sd->status.weapon) {
|
||||
case W_BOW:
|
||||
break;
|
||||
case W_REVOLVER:
|
||||
case W_RIFLE:
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
case W_GRENADE:
|
||||
if (bflag & BDMG_CRIT) {
|
||||
bflag &= ~(BDMG_ARROW); // Criticals with any guns are calculated like melee criticals
|
||||
}
|
||||
break;
|
||||
default:
|
||||
i |= 16; // for ex. shuriken must not be influenced by DEX
|
||||
bflag |= BDMG_THROW; // for ex. shuriken must not be influenced by DEX
|
||||
break;
|
||||
}
|
||||
}
|
||||
wd->damage = battle_calc_base_damage(src, sstatus, &sstatus->rhw, sc, tstatus->size, i);
|
||||
if (skill_id == SN_SHARPSHOOTING || skill_id == MA_SHARPSHOOTING)
|
||||
bflag &= ~(BDMG_CRIT); // Sharpshooting just ignores DEF/FLEE but damage is like a normal attack
|
||||
wd->damage = battle_calc_base_damage(src, sstatus, &sstatus->rhw, sc, tstatus->size, bflag);
|
||||
if (is_attack_left_handed(src, skill_id))
|
||||
wd->damage2 = battle_calc_base_damage(src, sstatus, &sstatus->lhw, sc, tstatus->size, i);
|
||||
wd->damage2 = battle_calc_base_damage(src, sstatus, &sstatus->lhw, sc, tstatus->size, bflag);
|
||||
#endif
|
||||
if (nk[NK_SPLASHSPLIT]){ // Divide ATK among targets
|
||||
if(wd->miscflag > 0) {
|
||||
@ -4093,7 +4098,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
int skill;
|
||||
|
||||
#ifndef RENEWAL
|
||||
if(sd->bonus.crit_atk_rate && is_attack_critical(wd, src, target, skill_id, skill_lv, false)) { // add +crit damage bonuses here in pre-renewal mode [helvetica]
|
||||
if (sd->bonus.crit_atk_rate && (bflag & BDMG_CRIT)) { // add +crit damage bonuses here in pre-renewal mode [helvetica]
|
||||
ATK_ADDRATE(wd->damage, wd->damage2, sd->bonus.crit_atk_rate);
|
||||
}
|
||||
if(sd->status.party_id && (skill=pc_checkskill(sd,TK_POWER)) > 0) {
|
||||
@ -4111,7 +4116,7 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
#endif
|
||||
}
|
||||
#ifndef RENEWAL
|
||||
if(tsd != nullptr && tsd->bonus.crit_def_rate != 0 && !skill_id && is_attack_critical(wd, src, target, skill_id, skill_lv, false)) {
|
||||
if (tsd != nullptr && tsd->bonus.crit_def_rate != 0 && !skill_id && (bflag & BDMG_CRIT)) {
|
||||
ATK_ADDRATE(wd->damage, wd->damage2, -tsd->bonus.crit_def_rate);
|
||||
}
|
||||
#endif
|
||||
|
@ -30,6 +30,16 @@ enum damage_lv : uint8 {
|
||||
ATK_DEF /// Attack connected
|
||||
};
|
||||
|
||||
/// Flag for base damage calculation
|
||||
enum e_base_damage_flag : uint16 {
|
||||
BDMG_NONE = 0x0000, /// None
|
||||
BDMG_CRIT = 0x0001, /// Critical hit damage
|
||||
BDMG_ARROW = 0x0002, /// Add arrow attack and use ranged damage formula
|
||||
BDMG_MAGIC = 0x0004, /// Use MATK for base damage (e.g. Magic Crasher)
|
||||
BDMG_NOSIZE = 0x0008, /// Skip target size adjustment (e.g. Weapon Perfection, Extremity Fist)
|
||||
BDMG_THROW = 0x0010, /// Arrow attack should use melee damage formula (e.g., shuriken, kunai and venom knives)
|
||||
};
|
||||
|
||||
/// Flag of the final calculation
|
||||
enum e_battle_flag : uint16 {
|
||||
BF_NONE = 0x0000, /// None
|
||||
|
Loading…
x
Reference in New Issue
Block a user