diff options
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 170 |
1 files changed, 87 insertions, 83 deletions
diff --git a/src/map/status.c b/src/map/status.c index ddc3ce745..75c877140 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -34,6 +34,7 @@ //For specifying where in the SkillStatusChangeTableArray the "out of bounds" skills get stored. [Skotlex] #define SC_HM_BASE 800 #define SC_GD_BASE 900 + //Regen related flags. #define RGN_HP 0x01 #define RGN_SP 0x02 @@ -4415,7 +4416,7 @@ void status_change_init(struct block_list *bl) //Applies SC defense to a given status change. //Returns the adjusted duration based on flag values. //the flag values are the same as in status_change_start. -int status_get_sc_def(struct block_list *bl, int type, int rate, int tick, int flag) +int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int tick, int flag) { int sc_def, tick_def = 0; struct status_data* status; @@ -4579,16 +4580,16 @@ int status_get_sc_def(struct block_list *bl, int type, int rate, int tick, int f /*========================================== * Starts a status change. - * type = type, val1~4 depend on the type. - * rate = base success rate. 10000 = 100% - * Tick is base duration - * flag: + * 'type' = type, 'val1~4' depend on the type. + * 'rate' = base success rate. 10000 = 100% + * 'tick' is base duration + * 'flag': * &1: Cannot be avoided (it has to start) * &2: Tick should not be reduced (by vit, luk, lv, etc) * &4: sc_data loaded, no value has to be altered. * &8: rate should not be reduced *------------------------------------------*/ -int status_change_start(struct block_list *bl,int type,int rate,int val1,int val2,int val3,int val4,int tick,int flag) +int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val1,int val2,int val3,int val4,int tick,int flag) { struct map_session_data *sd = NULL; struct status_change* sc; @@ -4597,39 +4598,42 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val int opt_flag, calc_flag, undead_flag; nullpo_retr(0, bl); - sc=status_get_sc(bl); + sc = status_get_sc(bl); status = status_get_status_data(bl); - if (!sc || status_isdead(bl)) - return 0; - - switch (bl->type) + if( type < 0 || type >= SC_MAX ) { - case BL_PC: - sd=(struct map_session_data *)bl; - break; - case BL_MOB: - if (((struct mob_data*)bl)->class_ == MOBID_EMPERIUM && type != SC_SAFETYWALL) - return 0; //Emperium can't be afflicted by status changes. - break; + if( battle_config.error_log ) + ShowError("status_change_start: invalid status change (%d)!\n", type); + return 0; } - if(type < 0 || type >= SC_MAX) { - if(battle_config.error_log) - ShowError("status_change_start: invalid status change (%d)!\n", type); + if( !sc ) + return 0; //Unable to receive status changes + + if( status_isdead(bl) ) return 0; + + if( bl->type == BL_MOB && ((TBL_MOB*)bl)->class_ == MOBID_EMPERIUM ) + { + if( type != SC_SAFETYWALL ) + return 0; //Emperium can't be afflicted by status changes } - //Check resistance. - if (!(flag&(1|4))) { + BL_CAST(BL_PC, bl, sd); + + //Adjust tick according to status resistances + if( !(flag&(1|4)) ) + { tick = status_get_sc_def(bl, type, rate, tick, flag); - if (!tick) return 0; + if( !tick ) return 0; } - undead_flag=battle_check_undead(status->race,status->def_ele); + undead_flag = battle_check_undead(status->race,status->def_ele); //Check for inmunities / sc fails - switch (type) { + switch (type) + { case SC_FREEZE: case SC_STONE: //Undead are immune to Freeze/Stone @@ -4696,7 +4700,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val //if (sd && val1 < 3 && skill_check_cloaking(bl)) if (sd && pc_checkskill(sd, AS_CLOAKING)< 3 && skill_check_cloaking(bl,sc)) return 0; - break; + break; case SC_MODECHANGE: { int mode; @@ -4716,8 +4720,8 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return status_change_end(bl, type, -1); return 0; } - break; } + break; //Strip skills, need to divest something or it fails. case SC_STRIPWEAPON: if (sd) { @@ -4743,7 +4747,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if (!opt_flag) return 0; } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; + break; case SC_STRIPSHIELD: if (sd) { int i; @@ -4756,7 +4760,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val pc_unequipitem(sd,i,3); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; + break; case SC_STRIPARMOR: if (sd) { int i; @@ -4768,7 +4772,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val pc_unequipitem(sd,i,3); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; + break; case SC_STRIPHELM: if (sd) { int i; @@ -4780,7 +4784,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val pc_unequipitem(sd,i,3); } if (tick == 1) return 1; //Minimal duration: Only strip without causing the SC - break; + break; } //Check for BOSS resistances @@ -4806,8 +4810,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val return 0; } } + //Before overlapping fail, one must check for status cured. - switch (type) { + switch (type) + { case SC_BLESSING: if ((!undead_flag && status->race!=RC_DEMON) || bl->type == BL_PC) { if (sc->data[SC_CURSE].timer!=-1) @@ -4929,9 +4935,12 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val status_change_end(bl,SC_ADJUSTMENT,-1); break; } + //Check for overlapping fails - if(sc->data[type].timer != -1){ - switch (type) { + if(sc->data[type].timer != -1) + { + switch (type) + { case SC_ADRENALINE: case SC_ADRENALINE2: case SC_WEAPONPERFECTION: @@ -4997,7 +5006,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val default: if(sc->data[type].val1 > val1) return 1; //Return true to not mess up skill animations. [Skotlex - } + } (sc->count)--; delete_timer(sc->data[type].timer, status_change_timer); sc->data[type].timer = -1; @@ -5005,8 +5014,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val vd = status_get_viewdata(bl); calc_flag = StatusChangeFlagTable[type]; - if(!(flag&4)) //Do not parse val settings when loading SCs - switch(type){ + + if(!(flag&4)) //&4 - Do not parse val settings when loading SCs + switch(type) + { case SC_DECREASEAGI: case SC_INCREASEAGI: val2 = 2 + val1; //Agi change @@ -5849,9 +5860,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val //associated, and yet are not wrong/unknown. [Skotlex] break; default: - if (calc_flag == SCB_NONE && - StatusSkillChangeTable[type]==0 && - StatusIconChangeTable[type]==0) + if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 ) { //Status change with no calc, no icon, and no skill associated...? if(battle_config.error_log) ShowError("UnknownStatusChange [%d]\n", type); @@ -5859,7 +5868,8 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val } } else //Special considerations when loading SC data. - switch (type) { + switch( type ) + { case SC_WEDDING: case SC_XMAS: case SC_SUMMER: @@ -5871,8 +5881,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val case SC_KAAHI: val4 = -1; break; - //In case the speed reduction comes loaded incorrectly, - //prevent division by 0. + //In case the speed reduction comes loaded incorrectly, prevent division by 0. case SC_DONTFORGETME: case SC_CLOAKING: case SC_LONGING: @@ -5882,13 +5891,11 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val if (!val3) return 0; break; - case SC_GUILDAURA: - //Compatibility Upgrade due to Guild Aura code rewrite - //(older saved SC versions would load up with huge bonuses) - return 0; } + //Those that make you stop attacking/walking.... - switch (type) { + switch (type) + { case SC_FREEZE: case SC_STUN: case SC_SLEEP: @@ -5922,7 +5929,8 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val // Set option as needed. opt_flag = 1; - switch(type){ + switch(type) + { //OPT1 case SC_STONE: case SC_FREEZE: @@ -6041,8 +6049,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val opt_flag = 0; } - //On Aegis, when turning on a status change, first goes the option packet, - // then the sc packet. + //On Aegis, when turning on a status change, first goes the option packet, then the sc packet. if(opt_flag) clif_changeoption(bl); @@ -6068,8 +6075,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val sc->data[type].val3 = val3; sc->data[type].val4 = val4; - sc->data[type].timer = add_timer( - gettick() + tick, status_change_timer, bl->id, type); + sc->data[type].timer = add_timer(gettick() + tick, status_change_timer, bl->id, type); if (calc_flag) status_calc_bl(bl,calc_flag); @@ -6095,7 +6101,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val /*========================================== * ステータス異常全解除 *------------------------------------------*/ -int status_change_clear(struct block_list *bl,int type) +int status_change_clear(struct block_list* bl, enum sc_type type) { struct status_change* sc; int i; @@ -6153,7 +6159,7 @@ int status_change_clear(struct block_list *bl,int type) /*========================================== * ステータス異常終了 *------------------------------------------*/ -int status_change_end( struct block_list* bl , int type,int tid ) +int status_change_end(struct block_list* bl, enum sc_type type, int tid) { struct map_session_data *sd; struct status_change *sc; @@ -6628,7 +6634,7 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, int data) *------------------------------------------*/ int status_change_timer(int tid, unsigned int tick, int id, int data) { - int type = data; + enum sc_type type = data; struct block_list *bl; struct map_session_data *sd; struct status_data *status; @@ -6959,31 +6965,29 @@ int status_change_timer(int tid, unsigned int tick, int id, int data) /*========================================== * ステータス異常タイマー範囲処理 *------------------------------------------*/ -int status_change_timer_sub(struct block_list *bl, va_list ap ) +int status_change_timer_sub(struct block_list* bl, va_list ap) { - struct block_list *src; - struct status_change *sc, *tsc; - struct map_session_data* sd=NULL; - struct map_session_data* tsd=NULL; - - int type; - unsigned int tick; - - src=va_arg(ap,struct block_list*); - sc=va_arg(ap,struct status_change*); - type=va_arg(ap,int); - tick=va_arg(ap,unsigned int); - tsc=status_get_sc(bl); - + struct map_session_data *sd, *tsd; + struct status_change* tsc; + + struct block_list* src = va_arg(ap,struct block_list*); + struct status_change* sc = va_arg(ap,struct status_change*); + enum sc_type type = va_arg(ap,enum sc_type); + unsigned int tick = va_arg(ap,unsigned int); + if (status_isdead(bl)) return 0; - if (src->type==BL_PC) sd= (struct map_session_data*)src; - if (bl->type==BL_PC) tsd= (struct map_session_data*)bl; - switch( type ){ + tsc = status_get_sc(bl); + + BL_CAST(BL_PC, src, sd); + BL_CAST(BL_PC, bl, tsd); + + switch( type ) + { case SC_SIGHT: /* サイト */ case SC_CONCENTRATE: - if (tsc && tsc->count) { + if (tsc) { if (tsc->data[SC_HIDING].timer != -1) status_change_end( bl, SC_HIDING, -1); if (tsc->data[SC_CLOAKING].timer != -1) @@ -6991,8 +6995,7 @@ int status_change_timer_sub(struct block_list *bl, va_list ap ) } break; case SC_RUWACH: /* ルアフ */ - if (tsc && tsc->count && (tsc->data[SC_HIDING].timer != -1 || // if the target is using a special hiding, i.e not using normal hiding/cloaking, don't bother - tsc->data[SC_CLOAKING].timer != -1)) { + if (tsc && (tsc->data[SC_HIDING].timer != -1 || tsc->data[SC_CLOAKING].timer != -1)) { status_change_end( bl, SC_HIDING, -1); status_change_end( bl, SC_CLOAKING, -1); if(battle_check_target( src, bl, BCT_ENEMY ) > 0) @@ -7009,7 +7012,7 @@ int status_change_timer_sub(struct block_list *bl, va_list ap ) break; case SC_CLOSECONFINE: //Lock char has released the hold on everyone... - if (tsc && tsc->count && tsc->data[SC_CLOSECONFINE2].timer != -1 && tsc->data[SC_CLOSECONFINE2].val2 == src->id) { + if (tsc && tsc->data[SC_CLOSECONFINE2].timer != -1 && tsc->data[SC_CLOSECONFINE2].val2 == src->id) { tsc->data[SC_CLOSECONFINE2].val2 = 0; status_change_end(bl, SC_CLOSECONFINE2, -1); } @@ -7022,7 +7025,7 @@ int status_change_timer_sub(struct block_list *bl, va_list ap ) * Clears buffs/debuffs of a character. * type&1 -> buffs, type&2 -> debuffs *------------------------------------------*/ -int status_change_clear_buffs (struct block_list *bl, int type) +int status_change_clear_buffs (struct block_list* bl, enum sc_type type) { int i; struct status_change *sc= status_get_sc(bl); @@ -7031,13 +7034,14 @@ int status_change_clear_buffs (struct block_list *bl, int type) return 0; if (type&2) //Debuffs - for (i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++) { + for( i = SC_COMMON_MIN; i <= SC_COMMON_MAX; i++ ) + { if(sc->data[i].timer != -1) status_change_end(bl,i,-1); } - for (i = SC_COMMON_MAX+1; i < SC_MAX; i++) { - + for( i = SC_COMMON_MAX+1; i < SC_MAX; i++ ) + { if(sc->data[i].timer == -1) continue; |