From 6b3f0717c749c1bdb86ddbb7ec9c921afda646b7 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Tue, 24 Jul 2018 22:55:17 +0200 Subject: [PATCH] Hotfix for issue 3277 (#3279) Fixes #3277 Thanks to @cydh and @aleos89 --- src/map/clif.cpp | 27 ++++++++++++--------------- src/map/pc.cpp | 10 ++++------ src/map/script.cpp | 3 +-- src/map/script.hpp | 1 + src/map/status.cpp | 20 +++++++++++++++++++- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 1179ccd28d..8fb30b0294 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -11558,14 +11558,14 @@ void clif_parse_NpcClicked(int fd,struct map_session_data *sd) clif_clearunit_area(&sd->bl,CLR_DEAD); return; } + + if( pc_cant_act2(sd) || sd->npc_id || pc_hasprogress( sd, WIP_DISABLE_NPC ) ){ #ifdef RENEWAL - if (sd->npc_id || pc_hasprogress(sd, WIP_DISABLE_NPC)) { - clif_msg(sd, WORK_IN_PROGRESS); + clif_msg( sd, WORK_IN_PROGRESS ); +#endif return; } -#endif - if (pc_cant_act2(sd) || sd->npc_id) - return; + if( sd->state.mail_writing ) return; @@ -12189,16 +12189,13 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd) if (battle_config.idletime_option&IDLE_USESKILLTOID) sd->idletime = last_tick; - if (sd->npc_id) { + if( sd->npc_id ){ + if( pc_hasprogress( sd, WIP_DISABLE_SKILLITEM ) || !sd->npc_item_flag || !( inf & INF_SELF_SKILL ) ){ #ifdef RENEWAL - if (pc_hasprogress(sd, WIP_DISABLE_SKILLITEM)) { - clif_msg(sd, WORK_IN_PROGRESS); + clif_msg( sd, WORK_IN_PROGRESS ); +#endif return; } -#else - if (!sd->npc_item_flag || !(inf&INF_SELF_SKILL)) - return; -#endif } if( (pc_cant_act2(sd) || sd->chatID) && skill_id != RK_REFRESH && !(skill_id == SR_GENTLETOUCH_CURE && @@ -12286,12 +12283,12 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin return; } + if( pc_hasprogress( sd, WIP_DISABLE_SKILLITEM ) ){ #ifdef RENEWAL - if (pc_hasprogress(sd, WIP_DISABLE_SKILLITEM)) { - clif_msg(sd, WORK_IN_PROGRESS); + clif_msg( sd, WORK_IN_PROGRESS ); +#endif return; } -#endif //Whether skill fails or not is irrelevant, the char ain't idle. [Skotlex] if (battle_config.idletime_option&IDLE_USESKILLTOPOS) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 2255a7c7fd..7a3c799dad 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -5050,15 +5050,13 @@ int pc_useitem(struct map_session_data *sd,int n) clif_progressbar_abort(sd); return 0; // First item use attempt cancels the progress bar } + + if( pc_hasprogress( sd, WIP_DISABLE_SKILLITEM ) || !sd->npc_item_flag ){ #ifdef RENEWAL - if (pc_hasprogress(sd, WIP_DISABLE_SKILLITEM)) { - clif_msg(sd, WORK_IN_PROGRESS); + clif_msg( sd, WORK_IN_PROGRESS ); +#endif return 0; } -#else - if (!sd->npc_item_flag) - return 0; -#endif } item = sd->inventory.u.items_inventory[n]; id = sd->inventory_data[n]; diff --git a/src/map/script.cpp b/src/map/script.cpp index aa2f9af309..b9e260da57 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -4197,8 +4197,7 @@ static void script_detach_state(struct script_state* st, bool dequeue_event) /// Attaches script state to possibly attached character and backups it's previous script, if any. /// /// @param st Script state to attach. -static void script_attach_state(struct script_state* st) -{ +void script_attach_state(struct script_state* st){ struct map_session_data* sd; if(st->rid && (sd = map_id2sd(st->rid))!=NULL) diff --git a/src/map/script.hpp b/src/map/script.hpp index b204738a93..9445601707 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -1930,6 +1930,7 @@ void pop_stack(struct script_state* st, int start, int end); TIMER_FUNC(run_script_timer); void script_stop_sleeptimers(int id); struct linkdb_node *script_erase_sleepdb(struct linkdb_node *n); +void script_attach_state(struct script_state* st); void run_script_main(struct script_state *st); void script_stop_scriptinstances(struct script_code *code); diff --git a/src/map/status.cpp b/src/map/status.cpp index 9aec61e6bd..0f33b55b3b 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -3330,7 +3330,7 @@ bool status_calc_cart_weight(struct map_session_data *sd, enum e_status_calc_wei * @param opt: Whether it is first calc (login) or not * @return (-1) for too many recursive calls, (1) recursive call, (0) success */ -int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) +int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt) { static int calculating = 0; ///< Check for recursive call preemption. [Skotlex] struct status_data *base_status; ///< Pointer to the player's base status @@ -4233,6 +4233,24 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) return 0; } +/// Intermediate function since C++ does not have a try-finally syntax +int status_calc_pc_( struct map_session_data* sd, enum e_status_calc_opt opt ){ + // Save the old script the player was attached to + struct script_state* previous_st = sd->st; + + // Store the return value of the original function + int ret = status_calc_pc_sub( sd, opt ); + + // If an old script is present + if( previous_st ){ + // Reattach the player to it, so that the limitations of that script kick back in + script_attach_state( previous_st ); + } + + // Return the original return value + return ret; +} + /** * Calculates Mercenary data * @param md: Mercenary object