浏览代码

Endless Loop without Official Walkpath Fix (#9095)

- Fixed an issue that could cause an endless loop when OFFICIAL_WALKPATH is disabled (fixes #9092)
- Improved comments so it's easier to understand what disabling OFFICIAL_WALKPATH actually means
Playtester 2 月之前
父节点
当前提交
322bd2cbc9
共有 2 个文件被更改,包括 13 次插入10 次删除
  1. 5 3
      src/config/core.hpp
  2. 8 7
      src/map/unit.cpp

+ 5 - 3
src/config/core.hpp

@@ -18,9 +18,11 @@
 #define MAX_SUGGESTIONS 10
 
 /// Comment to disable the official walk path
-/// The official walkpath disables users from taking non-clear walk paths,
-/// e.g. if they want to get around an obstacle they have to walk around it,
-/// while with OFFICIAL_WALKPATH disabled if they click to walk around a obstacle the server will do it automatically
+/// The official walkpath disables ranged units from taking non-clear walk paths to attack a target,
+/// e.g. if they need to get around an obstacle to attack, players will have to click to walk around it
+/// before attacking and monsters will just drop target once they get in attack range and can't attack.
+/// If disabled, the server automatically makes sure units find a position to attack from by moving closer.
+/// Disabling this also stops skills from failing when the target has walked behind an obstacle during cast.
 #define OFFICIAL_WALKPATH
 
 /// Uncomment to enable the Cell Stack Limit mod.

+ 8 - 7
src/map/unit.cpp

@@ -2965,15 +2965,16 @@ static int32 unit_attack_timer_sub(struct block_list* src, int32 tid, t_tick tic
 	}
 
 	if( !battle_check_range(src,target,range) ) {
-	  	// Within range, but no direct line of attack
-		if( ud->state.attack_continue ) {
-			if(ud->chaserange > 2)
-				ud->chaserange-=2;
+		// Within range, but no direct line of attack
+		// This code can usually only be reached if OFFICIAL_WALKPATH is disabled
+		if (ud->state.attack_continue && ud->chaserange > 1) {
+			ud->chaserange = std::max(1, ud->chaserange - 2);
 
-			unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
+			// Walk closer / around the obstacle and start attacking once you are in range
+			return unit_walktobl(src,target,ud->chaserange,ud->state.walk_easy|2);
 		}
-
-		return 1;
+		// Can't attack even though next to the target? Giving up here.
+		return 0;
 	}
 
 	// Sync packet only for players.