From 4bc74ed1e4119ab962652308df1044fba44376e6 Mon Sep 17 00:00:00 2001 From: skotlex Date: Mon, 5 Jun 2006 19:17:44 +0000 Subject: - Cleaned up code for SC_MINDBREAKER. - Changed hit, flee, cri, flee2, def2 and mdef2 to signed short, def, mdef to signed char to correctly account for cards with penalties in said stats. - Added cap_value checks in all of the status_calc_* return paths to make sure no stat is invalid. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@6986 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 3 ++ src/map/clif.c | 1 + src/map/map.h | 10 +++-- src/map/pc.c | 16 ++++---- src/map/status.c | 109 +++++++++++++++++++++++++++++----------------------- 5 files changed, 79 insertions(+), 60 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index a6b530f8b..bba7366c2 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,9 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2006/06/05 + * Changed hit, flee, cri, flee2, def2 and mdef2 to signed short, def, mdef + to signed char to correctly account for cards with penalties in said stats. + [Skotlex] * Fog of Wall won't affect the caster now in any way. [Skotlex] * Added clif_fixpos packets before attacking for the first time to clear any position sync issues with the client. [Skotlex] diff --git a/src/map/clif.c b/src/map/clif.c index fee72a26c..716e5e7c5 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5157,6 +5157,7 @@ int clif_send0199(int map,int type) struct block_list bl; unsigned char buf[16]; + bl.id = 0; bl.type = BL_NUL; bl.m = map; WBUFW(buf,0)=0x199; diff --git a/src/map/map.h b/src/map/map.h index 8270256a9..3853905d9 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -332,16 +332,18 @@ struct status_data { str, agi, vit, int_, dex, luk, batk, matk_min, matk_max, - hit, flee, cri, flee2, - def2, mdef2, speed, amotion, adelay, dmotion, mode; - short aspd_rate; + short + hit, flee, cri, flee2, + def2, mdef2, + aspd_rate; unsigned char - def, mdef, def_ele, ele_lv, size, race; + signed char + def, mdef; struct weapon_atk rhw, *lhw; //Right Hand/Left Hand Weapon. Only players have a lhw (hence it's a pointer) }; diff --git a/src/map/pc.c b/src/map/pc.c index 60d6ae749..f07e34b2a 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -1248,50 +1248,50 @@ int pc_bonus(struct map_session_data *sd,int type,int val) case SP_DEF1: if(sd->state.lr_flag != 2) { bonus = status->def + val; - status->def = cap_value(bonus, 0, UCHAR_MAX); + status->def = cap_value(bonus, CHAR_MIN, CHAR_MAX); } break; case SP_DEF2: if(sd->state.lr_flag != 2) { bonus = status->def2 + val; - status->def2 = cap_value(bonus, 0, USHRT_MAX); + status->def2 = cap_value(bonus, SHRT_MIN, SHRT_MAX); } break; case SP_MDEF1: if(sd->state.lr_flag != 2) { bonus = status->mdef + val; - status->mdef = cap_value(bonus, 0, UCHAR_MAX); + status->mdef = cap_value(bonus, CHAR_MIN, CHAR_MAX); } break; case SP_MDEF2: if(sd->state.lr_flag != 2) { bonus = status->mdef2 + val; - status->mdef2 = cap_value(bonus, 0, USHRT_MAX); + status->mdef2 = cap_value(bonus, SHRT_MIN, SHRT_MAX); } break; case SP_HIT: if(sd->state.lr_flag != 2) { bonus = status->hit + val; - status->hit = cap_value(bonus, 0, USHRT_MAX); + status->hit = cap_value(bonus, SHRT_MIN, SHRT_MAX); } else sd->arrow_hit+=val; break; case SP_FLEE1: if(sd->state.lr_flag != 2) { bonus = status->flee + val; - status->flee = cap_value(bonus, 0, USHRT_MAX); + status->flee = cap_value(bonus, SHRT_MIN, SHRT_MAX); } break; case SP_FLEE2: if(sd->state.lr_flag != 2) { bonus = status->flee2 + val*10; - status->flee2 = cap_value(bonus, 0, USHRT_MAX); + status->flee2 = cap_value(bonus, SHRT_MIN, SHRT_MAX); } break; case SP_CRITICAL: if(sd->state.lr_flag != 2) { bonus = status->cri + val*10; - status->cri = cap_value(bonus, 0, USHRT_MAX); + status->cri = cap_value(bonus, SHRT_MIN, SHRT_MAX); } else sd->arrow_cri += val*10; break; diff --git a/src/map/status.c b/src/map/status.c index 0b057fcad..332fddc59 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2114,14 +2114,14 @@ static unsigned short status_calc_luk(struct block_list *,struct status_change * static unsigned short status_calc_batk(struct block_list *,struct status_change *,int); static unsigned short status_calc_watk(struct block_list *,struct status_change *,int); static unsigned short status_calc_matk(struct block_list *,struct status_change *,int); -static unsigned short status_calc_hit(struct block_list *,struct status_change *,int); -static unsigned short status_calc_critical(struct block_list *,struct status_change *,int); -static unsigned short status_calc_flee(struct block_list *,struct status_change *,int); -static unsigned short status_calc_flee2(struct block_list *,struct status_change *,int); -static unsigned char status_calc_def(struct block_list *,struct status_change *,int); -static unsigned short status_calc_def2(struct block_list *,struct status_change *,int); -static unsigned char status_calc_mdef(struct block_list *,struct status_change *,int); -static unsigned short status_calc_mdef2(struct block_list *,struct status_change *,int); +static signed short status_calc_hit(struct block_list *,struct status_change *,int); +static signed short status_calc_critical(struct block_list *,struct status_change *,int); +static signed short status_calc_flee(struct block_list *,struct status_change *,int); +static signed short status_calc_flee2(struct block_list *,struct status_change *,int); +static signed char status_calc_def(struct block_list *,struct status_change *,int); +static signed short status_calc_def2(struct block_list *,struct status_change *,int); +static signed char status_calc_mdef(struct block_list *,struct status_change *,int); +static signed short status_calc_mdef2(struct block_list *,struct status_change *,int); static unsigned short status_calc_speed(struct block_list *,struct status_change *,int); static short status_calc_aspd_rate(struct block_list *,struct status_change *,int); static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion); @@ -2621,7 +2621,7 @@ void status_calc_bl(struct block_list *bl, unsigned long flag) static unsigned short status_calc_str(struct block_list *bl, struct status_change *sc, int str) { if(!sc || !sc->count) - return str; + return cap_value(str,1,USHRT_MAX); if(sc->data[SC_INCALLSTATUS].timer!=-1) str += sc->data[SC_INCALLSTATUS].val1; @@ -2660,7 +2660,7 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang static unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, int agi) { if(!sc || !sc->count) - return agi; + return cap_value(agi,1,USHRT_MAX); if(sc->data[SC_CONCENTRATE].timer!=-1 && sc->data[SC_QUAGMIRE].timer == -1) agi += (agi-sc->data[SC_CONCENTRATE].val3)*sc->data[SC_CONCENTRATE].val2/100; @@ -2699,7 +2699,7 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang static unsigned short status_calc_vit(struct block_list *bl, struct status_change *sc, int vit) { if(!sc || !sc->count) - return vit; + return cap_value(vit,1,USHRT_MAX); if(sc->data[SC_INCALLSTATUS].timer!=-1) vit += sc->data[SC_INCALLSTATUS].val1; @@ -2726,7 +2726,7 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang static unsigned short status_calc_int(struct block_list *bl, struct status_change *sc, int int_) { if(!sc || !sc->count) - return int_; + return cap_value(int_,1,USHRT_MAX); if(sc->data[SC_INCALLSTATUS].timer!=-1) int_ += sc->data[SC_INCALLSTATUS].val1; @@ -2763,7 +2763,7 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang static unsigned short status_calc_dex(struct block_list *bl, struct status_change *sc, int dex) { if(!sc || !sc->count) - return dex; + return cap_value(dex,1,USHRT_MAX); if(sc->data[SC_CONCENTRATE].timer!=-1 && sc->data[SC_QUAGMIRE].timer == -1) dex += (dex-sc->data[SC_CONCENTRATE].val4)*sc->data[SC_CONCENTRATE].val2/100; @@ -2805,7 +2805,7 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang static unsigned short status_calc_luk(struct block_list *bl, struct status_change *sc, int luk) { if(!sc || !sc->count) - return luk; + return cap_value(luk,1,USHRT_MAX); if(sc->data[SC_CURSE].timer!=-1) return 0; @@ -2832,7 +2832,7 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang static unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, int batk) { if(!sc || !sc->count) - return batk; + return cap_value(batk,0,USHRT_MAX); if(sc->data[SC_ATKPOTION].timer!=-1) batk += sc->data[SC_ATKPOTION].val1; @@ -2865,7 +2865,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan static unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, int watk) { if(!sc || !sc->count) - return watk; + return cap_value(watk,0,USHRT_MAX); if(sc->data[SC_IMPOSITIO].timer!=-1) watk += sc->data[SC_IMPOSITIO].val2; @@ -2901,13 +2901,14 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan watk -= watk * 25/100; if(sc->data[SC_STRIPWEAPON].timer!=-1) watk -= watk * sc->data[SC_STRIPWEAPON].val2/100; + return cap_value(watk,0,USHRT_MAX); } static unsigned short status_calc_matk(struct block_list *bl, struct status_change *sc, int matk) { if(!sc || !sc->count) - return matk; + return cap_value(matk,0,USHRT_MAX); if(sc->data[SC_MATKPOTION].timer!=-1) matk += sc->data[SC_MATKPOTION].val1; @@ -2916,17 +2917,17 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan if(sc->data[SC_MAGICPOWER].timer!=-1) matk += matk * 5*sc->data[SC_MAGICPOWER].val1/100; if(sc->data[SC_MINDBREAKER].timer!=-1) - matk += matk * 20*sc->data[SC_MINDBREAKER].val1/100; + matk += matk * sc->data[SC_MINDBREAKER].val2/100; if(sc->data[SC_INCMATKRATE].timer!=-1) matk += matk * sc->data[SC_INCMATKRATE].val1/100; return cap_value(matk,0,USHRT_MAX); } -static unsigned short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) +static signed short status_calc_critical(struct block_list *bl, struct status_change *sc, int critical) { if(!sc || !sc->count) - return critical; + return cap_value(critical,0,SHRT_MAX); if (sc->data[SC_EXPLOSIONSPIRITS].timer!=-1) critical += sc->data[SC_EXPLOSIONSPIRITS].val2; @@ -2937,14 +2938,14 @@ static unsigned short status_calc_critical(struct block_list *bl, struct status_ if(sc->data[SC_CLOAKING].timer!=-1) critical += critical; - return cap_value(critical,0,USHRT_MAX); + return cap_value(critical,0,SHRT_MAX); } -static unsigned short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit) +static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit) { if(!sc || !sc->count) - return hit; + return cap_value(hit,0,SHRT_MAX); if(sc->data[SC_INCHIT].timer != -1) hit += sc->data[SC_INCHIT].val1; @@ -2965,16 +2966,17 @@ static unsigned short status_calc_hit(struct block_list *bl, struct status_chang if(sc->data[SC_INCREASING].timer!=-1) hit += 20; // RockmanEXE; changed based on updated [Reddozen] - return cap_value(hit,0,USHRT_MAX); + return cap_value(hit,0,SHRT_MAX); } -static unsigned short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee) +static signed short status_calc_flee(struct block_list *bl, struct status_change *sc, int flee) { if (bl->type == BL_PC && map_flag_gvg(bl->m)) //GVG grounds flee penalty, placed here because it's "like" a status change. [Skotlex] flee -= flee * battle_config.gvg_flee_penalty/100; if(!sc || !sc->count) - return flee; + return cap_value(flee,0,SHRT_MAX); + if(sc->data[SC_INCFLEE].timer!=-1) flee += sc->data[SC_INCFLEE].val1; if(sc->data[SC_FLEEFOOD].timer!=-1) @@ -3002,22 +3004,25 @@ static unsigned short status_calc_flee(struct block_list *bl, struct status_chan if(sc->data[SC_GATLINGFEVER].timer!=-1) flee -= sc->data[SC_GATLINGFEVER].val1*5; - return cap_value(flee,0,USHRT_MAX); + return cap_value(flee,0,SHRT_MAX); } -static unsigned short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2) +static signed short status_calc_flee2(struct block_list *bl, struct status_change *sc, int flee2) { if(!sc || !sc->count) - return flee2; + return cap_value(flee2,0,SHRT_MAX); + if(sc->data[SC_WHISTLE].timer!=-1) flee2 += sc->data[SC_WHISTLE].val3*10; - return cap_value(flee2,0,USHRT_MAX); + + return cap_value(flee2,0,SHRT_MAX); } -static unsigned char status_calc_def(struct block_list *bl, struct status_change *sc, int def) +static signed char status_calc_def(struct block_list *bl, struct status_change *sc, int def) { if(!sc || !sc->count) - return def; + return cap_value(def,0,CHAR_MAX); + if(sc->data[SC_BERSERK].timer!=-1) return 0; if(sc->data[SC_KEEPING].timer!=-1) @@ -3046,13 +3051,14 @@ static unsigned char status_calc_def(struct block_list *bl, struct status_change def -= def * sc->data[SC_STRIPSHIELD].val2/100; if (sc->data[SC_FLING].timer!=-1) def -= def * (sc->data[SC_FLING].val2)/100; - return cap_value(def,0,UCHAR_MAX); + + return cap_value(def,0,CHAR_MAX); } -static unsigned short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2) +static signed short status_calc_def2(struct block_list *bl, struct status_change *sc, int def2) { if(!sc || !sc->count) - return def2; + return cap_value(def2,0,SHRT_MAX); if(sc->data[SC_BERSERK].timer!=-1) return 0; @@ -3079,13 +3085,13 @@ static unsigned short status_calc_def2(struct block_list *bl, struct status_chan if(sc->data[SC_FLING].timer!=-1) def2 -= def2 * (sc->data[SC_FLING].val3)/100; - return cap_value(def2,0,USHRT_MAX); + return cap_value(def2,0,SHRT_MAX); } -static unsigned char status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) +static signed char status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) { if(!sc || !sc->count) - return mdef; + return cap_value(mdef,0,CHAR_MAX); if(sc->data[SC_BERSERK].timer!=-1) return 0; @@ -3102,25 +3108,27 @@ static unsigned char status_calc_mdef(struct block_list *bl, struct status_chang if(sc->data[SC_ENDURE].timer!=-1 && sc->data[SC_ENDURE].val4 == 0) mdef += sc->data[SC_ENDURE].val1; - return cap_value(mdef,0,UCHAR_MAX); + return cap_value(mdef,0,CHAR_MAX); } -static unsigned short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2) +static signed short status_calc_mdef2(struct block_list *bl, struct status_change *sc, int mdef2) { if(!sc || !sc->count) - return mdef2; + return cap_value(mdef2,0,SHRT_MAX); + if(sc->data[SC_BERSERK].timer!=-1) return 0; if(sc->data[SC_MINDBREAKER].timer!=-1) - mdef2 -= mdef2 * 12*sc->data[SC_MINDBREAKER].val1/100; + mdef2 -= mdef2 * sc->data[SC_MINDBREAKER].val3/100; - return cap_value(mdef2,0,USHRT_MAX); + return cap_value(mdef2,0,SHRT_MAX); } static unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc, int speed) { if(!sc || !sc->count) - return speed; + return cap_value(speed,10,USHRT_MAX); + if(sc->data[SC_CURSE].timer!=-1) speed += 450; if(sc->data[SC_SWOO].timer != -1) // [marquis007] @@ -3181,7 +3189,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha if(sc->data[SC_GATLINGFEVER].timer!=-1) speed += speed * 25/100; - return cap_value(speed,0,USHRT_MAX); + return cap_value(speed,10,USHRT_MAX); } static short status_calc_aspd_rate(struct block_list *bl, struct status_change *sc, int aspd_rate) @@ -3286,7 +3294,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) { if(!sc || !sc->count || map_flag_gvg(bl->m)) - return dmotion; + return cap_value(dmotion,0,USHRT_MAX); if (sc->data[SC_ENDURE].timer!=-1 || sc->data[SC_CONCENTRATION].timer!=-1) @@ -3298,7 +3306,7 @@ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_c static unsigned int status_calc_maxhp(struct block_list *bl, struct status_change *sc, unsigned int maxhp) { if(!sc || !sc->count) - return maxhp; + return cap_value(maxhp,1,UINT_MAX); if(sc->data[SC_INCMHPRATE].timer!=-1) maxhp += maxhp * sc->data[SC_INCMHPRATE].val1/100; @@ -3315,7 +3323,8 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang static unsigned int status_calc_maxsp(struct block_list *bl, struct status_change *sc, unsigned int maxsp) { if(!sc || !sc->count) - return maxsp; + return cap_value(maxsp,1,UINT_MAX); + if(sc->data[SC_INCMSPRATE].timer!=-1) maxsp += maxsp * sc->data[SC_INCMSPRATE].val1/100; if(sc->data[SC_SERVICE4U].timer!=-1) @@ -5023,6 +5032,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val val2 = 3*val1; //Aspd change val3 = 5+5*val1; //Atk rate change break; + case SC_MINDBREAKER: + val2 = 20*val1; //matk increase. + val3 = 12*val1; //mdef2 reduction. + break; default: if (calc_flag == SCB_NONE && StatusSkillChangeTable[type]==0) { //Status change with no calc, and no skill associated...? unknown? -- cgit v1.2.3-70-g09d2