From b1865b31fe09d31d75adf11534fdfe94f3fc984c Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 23 Jan 2019 12:42:23 -0500 Subject: [PATCH] Corrected skills that give bonuses while sitting (#3876) * Fixes #3611. * Corrected Gangster's Paradise not releasing the monster invulnerability state when standing up around multiple Rogue's that know Gangster's Paradise. * Same fix goes for Taekwon's Peaceful Break and Happy Break. * Cleaned up some various parts of these functions as well. Thanks to @Indigo000! --- src/map/clif.cpp | 4 +- src/map/skill.cpp | 96 ++++++++++++++++++++++++++++------------------ src/map/skill.hpp | 2 +- src/map/status.cpp | 8 ++-- src/map/unit.cpp | 2 +- 5 files changed, 66 insertions(+), 46 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 0b0c7383d1..e1cc9b5556 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -11188,7 +11188,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, sd->idletime = last_tick; pc_setsit(sd); - skill_sit(sd, 1); + skill_sit(sd, true); clif_sitting(&sd->bl); break; case 0x03: // standup @@ -11204,7 +11204,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type, if (pc_setstand(sd, false)) { if (battle_config.idletime_option&IDLE_SIT) sd->idletime = last_tick; - skill_sit(sd, 0); + skill_sit(sd, false); clif_standing(&sd->bl); } break; diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 6772c6a153..3234006307 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -4270,7 +4270,7 @@ static TIMER_FUNC(skill_timerskill){ struct map_session_data *tsd = NULL; if( (tsd = ((TBL_PC*)target)) && !pc_issit(tsd) ) { pc_setsit(tsd); - skill_sit(tsd, 1); + skill_sit(tsd, true); clif_sitting(&tsd->bl); } } @@ -17033,41 +17033,47 @@ int skill_autospell(struct map_session_data *sd, uint16 skill_id) return 0; } -/*========================================== - * Sitting skills functions. - *------------------------------------------*/ +/** + * Count the number of players with Gangster Paradise, Peaceful Break, or Happy Break. + * @param bl: Player object + * @param ap: va_arg list + * @return 1 if the player has learned Gangster Paradise, Peaceful Break, or Happy Break otherwise 0 + */ static int skill_sit_count(struct block_list *bl, va_list ap) { - struct map_session_data *sd; - int type =va_arg(ap,int); - sd=(struct map_session_data*)bl; + struct map_session_data *sd = (struct map_session_data*)bl; + int flag = va_arg(ap, int); - if(!pc_issit(sd)) + if (!pc_issit(sd)) return 0; - if(type&1 && pc_checkskill(sd,RG_GANGSTER) > 0) + if (flag&1 && pc_checkskill(sd, RG_GANGSTER) > 0) return 1; - if(type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0)) + if (flag&2 && (pc_checkskill(sd, TK_HPTIME) > 0 || pc_checkskill(sd, TK_SPTIME) > 0)) return 1; return 0; } -static int skill_sit_in (struct block_list *bl, va_list ap) +/** + * Triggered when a player sits down to activate bonus states. + * @param bl: Player object + * @param ap: va_arg list + * @return 0 + */ +static int skill_sit_in(struct block_list *bl, va_list ap) { - struct map_session_data *sd; - int type = va_arg(ap,int); + struct map_session_data *sd = (struct map_session_data*)bl; + int flag = va_arg(ap, int); - sd = (struct map_session_data*)bl; - - if(!pc_issit(sd)) + if (!pc_issit(sd)) return 0; - if(type&1 && pc_checkskill(sd,RG_GANGSTER) > 0) + if (flag&1 && pc_checkskill(sd, RG_GANGSTER) > 0) sd->state.gangsterparadise = 1; - if(type&2 && (pc_checkskill(sd,TK_HPTIME) > 0 || pc_checkskill(sd,TK_SPTIME) > 0 )) { + if (flag&2 && (pc_checkskill(sd, TK_HPTIME) > 0 || pc_checkskill(sd, TK_SPTIME) > 0 )) { sd->state.rest = 1; status_calc_regen(bl, &sd->battle_status, &sd->regen); status_calc_regen_rate(bl, &sd->regen, &sd->sc); @@ -17076,34 +17082,48 @@ static int skill_sit_in (struct block_list *bl, va_list ap) return 0; } -static int skill_sit_out (struct block_list *bl, va_list ap) +/** + * Triggered when a player stands up to deactivate bonus states. + * @param bl: Player object + * @param ap: va_arg list + * @return 0 + */ +static int skill_sit_out(struct block_list *bl, va_list ap) { - struct map_session_data *sd; - int type = va_arg(ap,int); + struct map_session_data *sd = (struct map_session_data*)bl; + int flag = va_arg(ap, int), range = va_arg(ap, int); - sd = (struct map_session_data*)bl; + if (map_foreachinallrange(skill_sit_count, &sd->bl, range, BL_PC, flag) > 1) + return 0; - if(sd->state.gangsterparadise && type&1) + if (flag&1 && sd->state.gangsterparadise) sd->state.gangsterparadise = 0; - if(sd->state.rest && type&2) { + if (flag&2 && sd->state.rest) { sd->state.rest = 0; status_calc_regen(bl, &sd->battle_status, &sd->regen); status_calc_regen_rate(bl, &sd->regen, &sd->sc); } + return 0; } -int skill_sit (struct map_session_data *sd, int type) +/** + * Toggle Sit icon and player bonuses when sitting/standing. + * @param sd: Player data + * @param sitting: True when sitting or false when standing + * @return 0 + */ +int skill_sit(struct map_session_data *sd, bool sitting) { - int flag = 0; - int range = 0, lv; + int flag = 0, range = 0, lv; + nullpo_ret(sd); - if((lv = pc_checkskill(sd, RG_GANGSTER)) > 0) { + if ((lv = pc_checkskill(sd, RG_GANGSTER)) > 0) { flag |= 1; range = skill_get_splash(RG_GANGSTER, lv); } - if((lv = pc_checkskill(sd, TK_HPTIME)) > 0) { + if ((lv = pc_checkskill(sd, TK_HPTIME)) > 0) { flag |= 2; range = skill_get_splash(TK_HPTIME, lv); } else if ((lv = pc_checkskill(sd, TK_SPTIME)) > 0) { @@ -17111,20 +17131,20 @@ int skill_sit (struct map_session_data *sd, int type) range = skill_get_splash(TK_SPTIME, lv); } - if (type) + if (sitting) clif_status_load(&sd->bl, EFST_SIT, 1); else clif_status_load(&sd->bl, EFST_SIT, 0); - if (!flag) return 0; + if (!flag) // No need to count area if no skills are learned. + return 0; + + if (sitting) { + if (map_foreachinallrange(skill_sit_count, &sd->bl, range, BL_PC, flag) > 1) + map_foreachinallrange(skill_sit_in, &sd->bl, range, BL_PC, flag); + } else + map_foreachinallrange(skill_sit_out, &sd->bl, range, BL_PC, flag, range); - if(type) { - if (map_foreachinallrange(skill_sit_count,&sd->bl, range, BL_PC, flag) > 1) - map_foreachinallrange(skill_sit_in,&sd->bl, range, BL_PC, flag); - } else { - if (map_foreachinallrange(skill_sit_count,&sd->bl, range, BL_PC, flag) < 2) - map_foreachinallrange(skill_sit_out,&sd->bl, range, BL_PC, flag); - } return 0; } diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 0cf7d4a39b..65cb8567db 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -493,7 +493,7 @@ int skill_unit_move(struct block_list *bl,t_tick tick,int flag); void skill_unit_move_unit_group( struct skill_unit_group *group, int16 m,int16 dx,int16 dy); void skill_unit_move_unit(struct block_list *bl, int dx, int dy); -int skill_sit (struct map_session_data *sd, int type); +int skill_sit(struct map_session_data *sd, bool sitting); void skill_repairweapon(struct map_session_data *sd, int idx); void skill_identify(struct map_session_data *sd,int idx); void skill_weaponrefine(struct map_session_data *sd,int idx); // [Celest] diff --git a/src/map/status.cpp b/src/map/status.cpp index c338c0e6f6..81b8327bcd 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -9910,7 +9910,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_TENSIONRELAX: if (sd) { pc_setsit(sd); - skill_sit(sd, 1); + skill_sit(sd, true); clif_sitting(&sd->bl); } val2 = 12; // SP cost @@ -10655,7 +10655,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty case SC_BANANA_BOMB_SITDOWN: if( sd && !pc_issit(sd) ) { pc_setsit(sd); - skill_sit(sd, 1); + skill_sit(sd, true); clif_sitting(bl); } break; @@ -12507,7 +12507,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const case SC_SITDOWN_FORCE: case SC_BANANA_BOMB_SITDOWN: if( sd && pc_issit(sd) && pc_setstand(sd, false) ) - skill_sit(sd,0); + skill_sit(sd, false); break; case SC_KYOUGAKU: clif_status_load(bl, EFST_KYOUGAKU, 0); // Avoid client crash @@ -13582,7 +13582,7 @@ TIMER_FUNC(status_change_timer){ status_charge(bl,0,sce->val2); // Reduce 8 every 10 seconds. if( sd && !pc_issit(sd) ) { // Force to sit every 10 seconds. pc_setsit(sd); - skill_sit(sd, 1); + skill_sit(sd, true); clif_sitting(bl); } sc_timer_next(10000 + tick); diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 9089a974f0..ea9f5b859c 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -2977,7 +2977,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, duel_leave(sd->duel_group, sd); if(pc_issit(sd) && pc_setstand(sd, false)) - skill_sit(sd,0); + skill_sit(sd, false); party_send_dot_remove(sd);// minimap dot fix [Kevin] guild_send_dot_remove(sd);