Explorar o código

Fixes NPC_RUN behavior (#5236)

* Fixes #3622 and fixes #5220.
* Monsters now properly escape from the attacker.
* NPC_RUN should determine distance based on skill level > 1.
* Resolves Sphere Mine when summoned by an Alchemist not escaping.
Thanks to @Balferian, @Indigo000, and @Daegaladh!
Aleos %!s(int64=4) %!d(string=hai) anos
pai
achega
fcdcce2cfa
Modificáronse 6 ficheiros con 25 adicións e 13 borrados
  1. 3 4
      db/pre-re/mob_skill_db.txt
  2. 3 4
      db/re/mob_skill_db.txt
  3. 1 0
      src/map/mob.cpp
  4. 8 2
      src/map/skill.cpp
  5. 9 2
      src/map/unit.cpp
  6. 1 1
      src/map/unit.hpp

+ 3 - 4
db/pre-re/mob_skill_db.txt

@@ -714,12 +714,11 @@
 1141,Marina@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
 1141,Marina@NPC_EMOTION,walk,197,1,2000,0,5000,yes,self,always,0,19,,,,,,
 1141,Marina@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
-1142,Marine Sphere@NPC_RUN,idle,354,7,10000,0,30000,no,master,alchemist,,,,,,,26,
-1142,Marine Sphere@NPC_SELFDESTRUCTION,any,173,1,10000,3000,0,no,self,afterskill,354,,,,,,,
+1142,Marine Sphere@NPC_RANDOMMOVE,idle,331,1,10000,0,30000,yes,target,alchemist,,,,,,,,
+1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,3000,0,yes,self,alchemist,,,,,,,,
 1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,500,2000,5000,no,self,myhpltmaxrate,99,,,,,,,
 1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,2000,5000,no,self,skillused,173,,,,,,,
-//1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,0,0,yes,self,always,0,,,,,,,
-//1142,Marine Sphere@NPC_SPEEDUP,any,332,1,10000,0,700,yes,self,always,0,,,,,,,
+1142,Marine Sphere@NPC_SPEEDUP,idle,332,1,10000,0,700,yes,target,always,,,,,,,,
 1143,Marionette@HT_FREEZINGTRAP,idle,121,5,500,0,300000,yes,around2,always,0,,,,,,29,
 1143,Marionette@MG_FIREWALL,chase,18,5,500,500,5000,yes,target,always,0,,,,,,2,
 1143,Marionette@NPC_TELEKINESISATTACK,attack,191,5,500,0,5000,yes,target,always,0,,,,,,6,

+ 3 - 4
db/re/mob_skill_db.txt

@@ -714,12 +714,11 @@
 1141,Marina@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
 1141,Marina@NPC_EMOTION,walk,197,1,2000,0,5000,yes,self,always,0,19,,,,,,
 1141,Marina@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
-1142,Marine Sphere@NPC_RUN,idle,354,7,10000,0,30000,no,master,alchemist,,,,,,,26,
-1142,Marine Sphere@NPC_SELFDESTRUCTION,any,173,1,10000,3000,0,no,self,afterskill,354,,,,,,,
+1142,Marine Sphere@NPC_RANDOMMOVE,idle,331,1,10000,0,30000,yes,target,alchemist,,,,,,,,
+1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,3000,0,yes,self,alchemist,,,,,,,,
 1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,500,2000,5000,no,self,myhpltmaxrate,99,,,,,,,
 1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,2000,5000,no,self,skillused,173,,,,,,,
-//1142,Marine Sphere@NPC_SELFDESTRUCTION,idle,173,1,10000,0,0,yes,self,always,0,,,,,,,
-//1142,Marine Sphere@NPC_SPEEDUP,any,332,1,10000,0,700,yes,self,always,0,,,,,,,
+1142,Marine Sphere@NPC_SPEEDUP,idle,332,1,10000,0,700,yes,target,always,,,,,,,,
 1143,Marionette@HT_FREEZINGTRAP,idle,121,5,500,0,300000,yes,around2,always,0,,,,,,29,
 1143,Marionette@MG_FIREWALL,chase,18,5,500,500,5000,yes,target,always,0,,,,,,2,
 1143,Marionette@NPC_TELEKINESISATTACK,attack,191,5,500,0,5000,yes,target,always,0,,,,,,6,

+ 1 - 0
src/map/mob.cpp

@@ -2433,6 +2433,7 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage)
 	if( md->special_state.ai == AI_SPHERE ) {//LOne WOlf explained that ANYONE can trigger the marine countdown skill. [Skotlex]
 		md->state.alchemist = 1;
 		mobskill_use(md, gettick(), MSC_ALCHEMIST);
+		unit_escape(&md->bl, src, 7, 2);
 	}
 }
 

+ 8 - 2
src/map/skill.cpp

@@ -8800,8 +8800,14 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case NPC_RUN:
-		if (md && unit_escape(src, bl, rnd()%10 + 1))
-			mob_unlocktarget(md, tick);
+		if (md) {
+			block_list* tbl = map_id2bl(md->target_id);
+
+			if (tbl) {
+				mob_unlocktarget(md, tick);
+				unit_escape(src, tbl, skill_lv > 1 ? skill_lv : AREA_SIZE, 2); // Send distance in skill level > 1
+			}
+		}
 		break;
 
 	case NPC_TRANSFORMATION:

+ 9 - 2
src/map/unit.cpp

@@ -977,16 +977,17 @@ bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type t
  * @param bl: Object that is running away from target
  * @param target: Target
  * @param dist: How far bl should run
+ * @param flag: unit_walktoxy flag
  * @return 1: Success 0: Fail
  */
-int unit_escape(struct block_list *bl, struct block_list *target, short dist)
+int unit_escape(struct block_list *bl, struct block_list *target, short dist, uint8 flag)
 {
 	uint8 dir = map_calc_dir(target, bl->x, bl->y);
 
 	while( dist > 0 && map_getcell(bl->m, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], CELL_CHKNOREACH) )
 		dist--;
 
-	return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], 0) );
+	return ( dist > 0 && unit_walktoxy(bl, bl->x + dist*dirx[dir], bl->y + dist*diry[dir], flag) );
 }
 
 /**
@@ -1546,6 +1547,12 @@ int unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int typ
 	} else {
 		// Don't set walk delays when already trapped.
 		if (!unit_can_move(bl)) {
+			if (bl->type == BL_MOB) {
+				mob_data *md = BL_CAST(BL_MOB, bl);
+
+				if (md && md->state.alchemist == 1) // Sphere Mine needs to escape, don't stop it
+					return 0;
+			}
 			unit_stop_walking(bl,4); //Unit might still be moving even though it can't move
 			return 0;
 		}

+ 1 - 1
src/map/unit.hpp

@@ -121,7 +121,7 @@ int unit_can_move(struct block_list *bl);
 int unit_is_walking(struct block_list *bl);
 int unit_set_walkdelay(struct block_list *bl, t_tick tick, t_tick delay, int type);
 
-int unit_escape(struct block_list *bl, struct block_list *target, short dist);
+int unit_escape(struct block_list *bl, struct block_list *target, short dist, uint8 flag = 0);
 
 // Instant unit changes
 bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath);