Browse Source

Hotfix for issue 3277 (#3279)

Fixes #3277 

Thanks to @cydh and @aleos89
Lemongrass3110 6 years ago
parent
commit
6b3f0717c7
5 changed files with 37 additions and 24 deletions
  1. 12 15
      src/map/clif.cpp
  2. 4 6
      src/map/pc.cpp
  3. 1 2
      src/map/script.cpp
  4. 1 0
      src/map/script.hpp
  5. 19 1
      src/map/status.cpp

+ 12 - 15
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);
-		return;
-	}
+		clif_msg( sd, WORK_IN_PROGRESS );
 #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)

+ 4 - 6
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];

+ 1 - 2
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)

+ 1 - 0
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);

+ 19 - 1
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