Skip to content

Commit

Permalink
Corrected vanish damage with some physical damage statuses (fixes #1262)
Browse files Browse the repository at this point in the history
* Resolves Exceed Break, Spell Fist, and Giant Growth being able to do more damage with Vellum-type weapons.
* Optimized the battle_vanish calculations to their respective case.
  • Loading branch information
aleos89 committed May 19, 2016
1 parent 0bd54c4 commit db0f231
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 32 deletions.
65 changes: 34 additions & 31 deletions src/map/battle.c
Expand Up @@ -6805,45 +6805,33 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
* @param target: Target to vanish HP/SP
* @param wd: Reference to Damage struct
*/
void battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd)
bool battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd)
{
struct status_data *tstatus;
int hp = 0, sp = 0, race = status_get_race(target);
short vrate_hp = 0, vrate_sp = 0, v_hp = 0, v_sp = 0,
vellum_rate_hp = 0, vellum_rate_sp = 0, vellum_hp = 0, vellum_sp = 0;
uint8 i = 0;

nullpo_retv(sd);
nullpo_retv(target);
nullpo_retr(false, sd);
nullpo_retr(false, target);

tstatus = status_get_status_data(target);
wd->isspdamage = false;

// bHPVanishRate
hp = (sd->bonus.hp_vanish_rate * 10);
vrate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->bonus.hp_vanish_per;
v_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);

// bHPVanishRaceRate
hp = sd->hp_vanish_race[race].rate + sd->hp_vanish_race[RC_ALL].rate;
vellum_rate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->hp_vanish_race[race].per + sd->hp_vanish_race[RC_ALL].per;
vellum_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);

// bSPVanishRate
sp = (sd->bonus.sp_vanish_rate * 10);
vrate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->bonus.sp_vanish_per + sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
v_sp = cap_value(sp, SHRT_MIN, SHRT_MAX);

// bSPVanishRaceRate
sp = sd->sp_vanish_race[race].rate + sd->sp_vanish_race[RC_ALL].rate;
vellum_rate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
vellum_sp = cap_value(sp, SHRT_MIN, SHRT_MAX);

if (wd->flag) {
// bHPVanishRaceRate
hp = sd->hp_vanish_race[race].rate + sd->hp_vanish_race[RC_ALL].rate;
vellum_rate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->hp_vanish_race[race].per + sd->hp_vanish_race[RC_ALL].per;
vellum_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);

// bSPVanishRaceRate
sp = sd->sp_vanish_race[race].rate + sd->sp_vanish_race[RC_ALL].rate;
vellum_rate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
vellum_sp = cap_value(sp, SHRT_MIN, SHRT_MAX);

// The HP and SP vanish bonus from these items can't stack because of the special damage display.
if (vellum_hp && vellum_rate_hp && (vellum_rate_hp >= 10000 || rnd()%10000 < vellum_rate_hp))
i = 1;
Expand All @@ -6859,14 +6847,28 @@ void battle_vanish(struct map_session_data *sd, struct block_list *target, struc
wd->damage2 = 0;
wd->isspdamage = true;
}
return true;
} else {
// bHPVanishRate
hp = (sd->bonus.hp_vanish_rate * 10);
vrate_hp = cap_value(hp, 0, SHRT_MAX);
hp = sd->bonus.hp_vanish_per;
v_hp = cap_value(hp, SHRT_MIN, SHRT_MAX);

// bSPVanishRate
sp = (sd->bonus.sp_vanish_rate * 10);
vrate_sp = cap_value(sp, 0, SHRT_MAX);
sp = sd->bonus.sp_vanish_per + sd->sp_vanish_race[race].per + sd->sp_vanish_race[RC_ALL].per;
v_sp = cap_value(sp, SHRT_MIN, SHRT_MAX);

if (v_hp && vrate_hp && (vrate_hp >= 10000 || rnd()%10000 < vrate_hp))
i |= 1;
if (v_sp && vrate_sp && (vrate_sp >= 10000 || rnd()%10000 < vrate_sp))
i |= 2;

if (i)
status_percent_damage(&sd->bl, target, (i&1) ? (int8)(-v_hp) : 0, (i&2) ? (int8)(-v_sp) : 0, false);
return false;
}
}

Expand Down Expand Up @@ -6996,6 +6998,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
int64 damage;
int skillv;
struct Damage wd;
bool vanish_damage = false;

nullpo_retr(ATK_NONE, src);
nullpo_retr(ATK_NONE, target);
Expand Down Expand Up @@ -7169,16 +7172,16 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
wd.isspdamage = false; // Default normal attacks to non-SP Damage attack until battle_vanish is determined

if (sd && wd.damage + wd.damage2 > 0)
battle_vanish(sd, target, &wd);
vanish_damage = battle_vanish(sd, target, &wd);

if( sc && sc->count ) {
if (sc->data[SC_EXEEDBREAK]) {
if (!is_infinite_defense(target, wd.flag))
if (!is_infinite_defense(target, wd.flag) && !vanish_damage)
wd.damage *= sc->data[SC_EXEEDBREAK]->val2 / 100;
status_change_end(src, SC_EXEEDBREAK, INVALID_TIMER);
}
if( sc->data[SC_SPELLFIST] ) {
if( --(sc->data[SC_SPELLFIST]->val1) >= 0 ){
if( --(sc->data[SC_SPELLFIST]->val1) >= 0 && !vanish_damage ){
if (!is_infinite_defense(target, wd.flag)) {
struct Damage ad = battle_calc_attack(BF_MAGIC, src, target, sc->data[SC_SPELLFIST]->val3, sc->data[SC_SPELLFIST]->val4, flag | BF_SHORT);

Expand All @@ -7191,7 +7194,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
} else
status_change_end(src,SC_SPELLFIST,INVALID_TIMER);
}
if( sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 && !is_infinite_defense(target, wd.flag) )
if( sc->data[SC_GIANTGROWTH] && (wd.flag&BF_SHORT) && rnd()%100 < sc->data[SC_GIANTGROWTH]->val2 && !is_infinite_defense(target, wd.flag) && !vanish_damage )
wd.damage *= 3; // Triple Damage

if( sd && battle_config.arrow_decrement && sc->data[SC_FEARBREEZE] && sc->data[SC_FEARBREEZE]->val4 > 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/map/battle.h
Expand Up @@ -87,7 +87,7 @@ struct Damage battle_calc_attack_plant(struct Damage wd, struct block_list *src,
int64 battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, bool status_reflect);

void battle_drain(struct map_session_data *sd, struct block_list *tbl, int64 rdamage, int64 ldamage, int race, int class_);
void battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd);
bool battle_vanish(struct map_session_data *sd, struct block_list *target, struct Damage *wd);

int battle_attr_ratio(int atk_elem,int def_type, int def_lv);
int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 damage,int atk_elem,int def_type, int def_lv);
Expand Down

0 comments on commit db0f231

Please sign in to comment.