diff options
author | markzd <markzd@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-12-12 00:21:47 +0000 |
---|---|---|
committer | markzd <markzd@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2012-12-12 00:21:47 +0000 |
commit | 2ad53bc87be9c4c5e071e3d9372f38edd327e892 (patch) | |
tree | 5dff3f7175b93dbfde2f118b96ad939f16cb7c10 /src/map | |
parent | 9c09b5aa848716f478b55624a7fb1bd1bc5fba82 (diff) | |
download | hercules-2ad53bc87be9c4c5e071e3d9372f38edd327e892.tar.gz hercules-2ad53bc87be9c4c5e071e3d9372f38edd327e892.tar.bz2 hercules-2ad53bc87be9c4c5e071e3d9372f38edd327e892.tar.xz hercules-2ad53bc87be9c4c5e071e3d9372f38edd327e892.zip |
- Follow up r17004 & bugreport:6995, added safer calculation to strategic points at battle.c&status.c.
- Implemented reading of renewal exp_guild.txt. (tid:75398)
- Fixed Status Fogwall(Blinding Mist) to be reduced by status/card. (bugreport:4543)
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@17017 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/battle.c | 36 | ||||
-rw-r--r-- | src/map/skill.c | 2 | ||||
-rw-r--r-- | src/map/status.c | 74 |
3 files changed, 54 insertions, 58 deletions
diff --git a/src/map/battle.c b/src/map/battle.c index 0c3c2c24d..f79de79f4 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -1364,7 +1364,7 @@ static int battle_calc_drain(int damage, int rate, int per) int diff = 0; if (per && rnd()%1000 < rate) { - diff = (damage * per) / 100; + diff = ((int64)damage * per) / 100; if (diff == 0) { if (per > 0) diff = 1; @@ -1495,7 +1495,7 @@ int battle_addmastery(struct map_session_data *sd,struct block_list *target,int */ static int battle_calc_base_damage(struct status_data *status, struct weapon_atk *wa, struct status_change *sc, unsigned short t_size, struct map_session_data *sd, int flag) { - unsigned short atkmin=0, atkmax=0; + unsigned int atkmin=0, atkmax=0; short type = 0; int damage = 0; @@ -2763,11 +2763,11 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo break; case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] % { - int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100, - sp = sstatus->max_sp * (6 + skill_lv) / 100; - skillratio = (hp+sp) / 4; + int hp = (int64)sstatus->max_hp * (10 + 2 * skill_lv) / 100, + sp = (int64)sstatus->max_sp * (6 + skill_lv) / 100; + skillratio = ((int64)hp+sp) / 4; if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] % - skillratio = (hp+sp) / 2; + skillratio = ((int64)hp+sp) / 2; RE_LVL_DMOD(100); } break; @@ -2975,9 +2975,9 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo case SR_GATEOFHELL: ATK_ADD (sstatus->max_hp - status_get_hp(src)); if(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE){ - ATK_ADD ( (sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src) ); + ATK_ADD ( ((int64)sstatus->sp * (1 + skill_lv * 2 / 10)) + 10 * status_get_lv(src) ); }else{ - ATK_ADD ( (sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src) ); + ATK_ADD ( ((int64)sstatus->max_sp * (1 + skill_lv * 2 / 10)) + 40 * status_get_lv(src) ); } break; case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) @@ -3120,7 +3120,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo { //Defense reduction short vit_def; defType def1 = status_get_def(target); //Don't use tstatus->def1 due to skill timer reductions. - short def2 = (short)tstatus->def2; + short def2 = tstatus->def2; if( sd ) { @@ -3195,14 +3195,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo **/ if (def1 > 900) def1 = 900; ATK_RATE2( - flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(1+(900-def1)/9)), - flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(1+(900-def1)/9)) + flag.idef ?100:(flag.pdef ? (flag.pdef*(def1+vit_def)) : (1+(900-def1)/9)), + flag.idef2?100:(flag.pdef2 ? (flag.pdef2*(def1+vit_def)) : (1+(900-def1)/9)) ); #else if (def1 > 100) def1 = 100; ATK_RATE2( - flag.idef ?100:(flag.pdef ?(int)(flag.pdef *(def1+vit_def)):(100-def1)), - flag.idef2?100:(flag.pdef2?(int)(flag.pdef2*(def1+vit_def)):(100-def1)) + flag.idef ?100:(flag.pdef ? (flag.pdef*(def1+vit_def)) : (100-def1)), + flag.idef2?100:(flag.pdef2? (flag.pdef2*(def1+vit_def)) : (100-def1)) ); #endif ATK_ADD2( @@ -3474,7 +3474,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo int hp= sstatus->max_hp; if (sd && tsd) { hp = 8*hp/100; - if (100*sstatus->hp <= 20*sstatus->max_hp) + if (((int64)sstatus->hp * 100) <= ((int64)sstatus->max_hp * 20)) hp = sstatus->hp; } else hp = 2*hp/100; //2% hp loss per hit @@ -3779,7 +3779,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list break; case WZ_VERMILION: { - int interval = 0, per = interval , ratio = per; + int interval = 0, per = interval, ratio = per; while( (per++) < skill_lv ){ ratio += interval; if(per%3==0) interval += 20; @@ -4190,7 +4190,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * case HT_BLASTMINE: case HT_CLAYMORETRAP: md.damage = skill_lv * sstatus->dex * (3+status_get_lv(src)/100) * (1+sstatus->int_/35); - md.damage += (int64)md.damage * (rnd()%20-10) / 100; + md.damage += md.damage * (rnd()%20-10) / 100; md.damage += 40 * (sd?pc_checkskill(sd,RA_RESEARCHTRAP):0); break; #else @@ -4221,7 +4221,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * damage_div_fix(md.damage, skill); //Falcon Assault Modifier - md.damage=md.damage*(150+70*skill_lv)/100; + md.damage=(int64)md.damage*(150+70*skill_lv)/100; } break; case TF_THROWSTONE: @@ -4273,7 +4273,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = sd?sd->status.job_level:status_get_lv(src); break; case HVAN_EXPLOSION: //[orn] - md.damage = sstatus->max_hp * (50 + 50 * skill_lv) / 100 ; + md.damage = (int64)sstatus->max_hp * (50 + 50 * skill_lv) / 100 ; break ; case ASC_BREAKER: md.damage = 500+rnd()%500 + 5*skill_lv * sstatus->int_; diff --git a/src/map/skill.c b/src/map/skill.c index 1939fe948..f61c6e480 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1102,7 +1102,7 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int case PF_FOGWALL: if (src != bl && !tsc->data[SC_DELUGE]) - status_change_start(bl,SC_BLIND,10000,skilllv,0,0,0,skill_get_time2(skillid,skilllv),8); + sc_start(bl,SC_BLIND,100,skilllv,skill_get_time2(skillid,skilllv)); break; case LK_HEADCRUSH: //Headcrush has chance of causing Bleeding status, except on demon and undead element diff --git a/src/map/status.c b/src/map/status.c index d9081ede8..d02af4c3f 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1309,7 +1309,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s ((TBL_MOB*)target)->state.rebirth = 1; return hp+sp; - } + } if(target->type == BL_PC){ TBL_PC *sd = BL_CAST(BL_PC,target); TBL_HOM *hd = sd->hd; @@ -1431,38 +1431,34 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe status = status_get_status_data(target); - //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. + + //It's safe now [MarkZD] 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; + ((int64)hp_rate*status->hp)/100; else if (hp_rate < -99) hp = status->max_hp; else if (hp_rate < 0) hp = status->max_hp>10000? (-hp_rate)*(status->max_hp/100): - (-hp_rate*status->max_hp)/100; + ((int64)-hp_rate*status->max_hp)/100; if (hp_rate && !hp) hp = 1; if (flag == 2 && hp >= status->hp) hp = status->hp-1; //Must not kill target. - //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; + sp = ((int64)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; + sp = ((int64)-sp_rate)*status->max_sp/100; if (sp_rate && !sp) sp = 1; @@ -1497,8 +1493,8 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per if (status == &dummy_status) return 0; //Invalid target. - hp = status->max_hp * per_hp/100; - sp = status->max_sp * per_sp/100; + hp = (int64)status->max_hp * per_hp/100; + sp = (int64)status->max_sp * per_sp/100; if(hp > status->max_hp - status->hp) hp = status->max_hp - status->hp; @@ -2234,8 +2230,8 @@ static void status_calc_sigma(void) /// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D } static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct status_data* status) { - unsigned int val = pc_class2idx(sd->status.class_); - val = 35 + sd->status.base_level*hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level]; + uint64 val = pc_class2idx(sd->status.class_); + val = 35 + sd->status.base_level*(int64)hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level]; if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER) val += 100; //Since their HP can't be approximated well enough without this. @@ -2250,14 +2246,14 @@ static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct sta val += val * 25/100; //Trans classes get a 25% hp bonus else if (sd->class_&JOBL_BABY) val -= val * 30/100; //Baby classes get a 30% hp penalty - return val; + return (unsigned int)val; } static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_data *status) { - unsigned int val; + uint64 val; - val = 10 + sd->status.base_level*sp_coefficient[pc_class2idx(sd->status.class_)]/100; + val = 10 + sd->status.base_level*(int64)sp_coefficient[pc_class2idx(sd->status.class_)]/100; val += val * status->int_/100; if (sd->class_&JOBL_UPPER) @@ -2267,7 +2263,7 @@ static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct sta if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON)) val *= 3; //Triple max SP for top ranking Taekwons over level 90. - return val; + return (unsigned int)val; } //Calculates player data from scratch without counting SC adjustments. @@ -2278,9 +2274,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) struct status_data *status; // pointer to the player's base status const struct status_change *sc = &sd->sc; struct s_skill b_skill[MAX_SKILL]; // previous skill tree - int b_weight, b_max_weight, b_cart_weight_max; // previous weight - int i,index; - int skill,refinedef=0; + int b_weight, b_max_weight, b_cart_weight_max, // previous weight + i, index, skill,refinedef=0; + int64 i64; if (++calculating > 10) //Too many recursive calls! return -1; @@ -2717,7 +2713,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) //We hold the standard Max HP here to make it faster to recalculate on vit changes. sd->status.max_hp = status_base_pc_maxhp(sd,status); //This is done to handle underflows from negative Max HP bonuses - i = sd->status.max_hp + (int)status->max_hp; + i64 = sd->status.max_hp + (int)status->max_hp; status->max_hp = cap_value(i, 0, INT_MAX); // Absolute modifiers from passive skills @@ -2728,9 +2724,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(sd->hprate < 0) sd->hprate = 0; if(sd->hprate!=100) - status->max_hp = status->max_hp * sd->hprate/100; + status->max_hp = (int64)status->max_hp * sd->hprate/100; if(battle_config.hp_rate != 100) - status->max_hp = status->max_hp * battle_config.hp_rate/100; + status->max_hp = (int64)status->max_hp * battle_config.hp_rate/100; if(status->max_hp > (unsigned int)battle_config.max_hp) status->max_hp = battle_config.max_hp; @@ -2742,16 +2738,16 @@ int status_calc_pc_(struct map_session_data* sd, bool first) // Basic MaxSP value sd->status.max_sp = status_base_pc_maxsp(sd,status); //This is done to handle underflows from negative Max SP bonuses - i = sd->status.max_sp + (int)status->max_sp; + i64 = sd->status.max_sp + (int)status->max_sp; status->max_sp = cap_value(i, 0, INT_MAX); // Absolute modifiers from passive skills if((skill=pc_checkskill(sd,SL_KAINA))>0) status->max_sp += 30*skill; if((skill=pc_checkskill(sd,HP_MEDITATIO))>0) - status->max_sp += status->max_sp * skill/100; + status->max_sp += (int64)status->max_sp * skill/100; if((skill=pc_checkskill(sd,HW_SOULDRAIN))>0) - status->max_sp += status->max_sp * 2*skill/100; + status->max_sp += (int64)status->max_sp * 2*skill/100; if( (skill = pc_checkskill(sd,RA_RESEARCHTRAP)) > 0 ) status->max_sp += 200 + 20 * skill; if( (skill = pc_checkskill(sd,WM_LESSON)) > 0 ) @@ -2762,9 +2758,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(sd->sprate < 0) sd->sprate = 0; if(sd->sprate!=100) - status->max_sp = status->max_sp * sd->sprate/100; + status->max_sp = (int64)status->max_sp * sd->sprate/100; if(battle_config.sp_rate != 100) - status->max_sp = status->max_sp * battle_config.sp_rate/100; + status->max_sp = (int64)status->max_sp * battle_config.sp_rate/100; if(status->max_sp > (unsigned int)battle_config.max_sp) status->max_sp = battle_config.max_sp; @@ -2781,13 +2777,13 @@ int status_calc_pc_(struct map_session_data* sd, bool first) } else { if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2) && battle_config.restart_hp_rate < 50) - status->hp=status->max_hp>>1; + status->hp = status->max_hp>>1; else - status->hp=status->max_hp * battle_config.restart_hp_rate/100; + status->hp = (int64)status->max_hp * battle_config.restart_hp_rate/100; if(!status->hp) status->hp = 1; - status->sp = status->max_sp * battle_config.restart_sp_rate /100; + status->sp = (int64)status->max_sp * battle_config.restart_sp_rate /100; if( !status->sp ) /* the minimum for the respawn setting is SP:1 */ status->sp = 1; @@ -3217,7 +3213,7 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) { status->mdef += ele->mdef; status->flee = ele->flee; status->hit = ele->hit; - + memcpy(&ed->battle_status,status,sizeof(struct status_data)); } else { status_calc_misc(&ed->bl, status, 0); @@ -3251,7 +3247,7 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c static short status_calc_aspd(struct block_list *bl, struct status_change *sc, short flag); #endif static short status_calc_fix_aspd(struct block_list *bl, struct status_change *sc, int); -static unsigned int status_calc_maxhp(struct block_list *,struct status_change *,unsigned int); +static unsigned int status_calc_maxhp(struct block_list *,struct status_change *,uint64); static unsigned int status_calc_maxsp(struct block_list *,struct status_change *,unsigned int); static unsigned char status_calc_element(struct block_list *bl, struct status_change *sc, int element); static unsigned char status_calc_element_lv(struct block_list *bl, struct status_change *sc, int lv); @@ -5472,10 +5468,10 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c return (unsigned short)cap_value(dmotion,0,USHRT_MAX); } -static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, unsigned int maxhp) +static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, uint64 maxhp) { if(!sc || !sc->count) - return cap_value(maxhp,1,UINT_MAX); + return (unsigned int)cap_value(maxhp,1,UINT_MAX); if(sc->data[SC_INCMHPRATE]) maxhp += maxhp * sc->data[SC_INCMHPRATE]->val1/100; @@ -5528,7 +5524,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang if (sc->data[SC_GOLDENE_FERSE]) maxhp += maxhp * sc->data[SC_GOLDENE_FERSE]->val2 / 100; - return cap_value(maxhp,1,UINT_MAX); + return (unsigned int)cap_value(maxhp,1,UINT_MAX); } static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) @@ -7150,7 +7146,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val val2 = val1*20; //SP gained break; case SC_KYRIE: - val2 = status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb + val2 = (int64)status->max_hp * (val1 * 2 + 10) / 100; //%Max HP to absorb val3 = (val1 / 2 + 5); //Hits break; case SC_MAGICPOWER: |