diff options
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/src/map/status.c b/src/map/status.c index f4fcf32a2..38a9d382d 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -812,16 +812,34 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe unsigned int hp =0, sp = 0; status = status_get_status_data(target); - - if (hp_rate > 0) - hp = (hp_rate*status->hp)/100; + + //Change the equation when the values are high enough to discard the + //imprecision in exchange of overflow protection [Skotlex] + //Also add 100% checks since those are the most used cases where we don't + //want aproximation errors. + if (hp_rate > 99) + hp = status->hp; + else if (hp_rate > 0) + hp = status->hp>10000? + hp_rate*(status->hp/100): + (hp_rate*status->hp)/100; + else if (hp_rate < -99) + hp = status->max_hp; else if (hp_rate < 0) - hp = (-hp_rate)*status->max_hp/100; + hp = status->max_hp>10000? + (-hp_rate)*(status->max_hp/100): + (-hp_rate*status->max_hp)/100; if (hp_rate && !hp) hp = 1; - if (sp_rate > 0) + //Should be safe to not do overflow protection here, noone should have + //millions upon millions of SP + if (sp_rate > 99) + sp = status->sp; + else if (sp_rate > 0) sp = (sp_rate*status->sp)/100; + else if (sp_rate < -99) + sp = status->max_sp; else if (sp_rate < 0) sp = (-sp_rate)*status->max_sp/100; if (sp_rate && !sp) |