Quellcode durchsuchen

Fixed unitwalkto calls in unit walk events (#2913)

* Fixes #2341.
* Fixed unitkill for mobs inside the walk event.
* Also fixed the state tracking of the walk event script.
Thanks to @Atemo!
Lemongrass3110 vor 7 Jahren
Ursprung
Commit
a0a55dada1
2 geänderte Dateien mit 34 neuen und 6 gelöschten Zeilen
  1. 6 2
      src/map/mob.cpp
  2. 28 4
      src/map/unit.cpp

+ 6 - 2
src/map/mob.cpp

@@ -3043,8 +3043,12 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 	}
 
-	if(!md->spawn) //Tell status_damage to remove it from memory.
-		return 5; // Note: Actually, it's 4. Oh well...
+	if(!md->spawn){ //Tell status_damage to remove it from memory.
+		struct unit_data *ud = unit_bl2ud(&md->bl);
+
+		// If the unit is currently in a walk script, it will be removed there
+		return ud->state.walk_script ? 3 : 5; // Note: Actually, it's 4. Oh well...
+	}
 
 	// MvP tomb [GreenBox]
 	if (battle_config.mvp_tomb_enabled && md->spawn->state.boss && map[md->bl.m].flag.notomb != 1)

+ 28 - 4
src/map/unit.cpp

@@ -416,11 +416,35 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 
 	if (bl->x == ud->to_x && bl->y == ud->to_y) {
 		if (ud->walk_done_event[0]){
-			npc_event_do_id(ud->walk_done_event,bl->id);
-			ud->walk_done_event[0] = 0;
+			char walk_done_event[EVENT_NAME_LENGTH];
+
+			// Copying is required in case someone uses unitwalkto inside the event code
+			safestrncpy(walk_done_event, ud->walk_done_event, EVENT_NAME_LENGTH);
+
+			ud->state.walk_script = true;
+
+			// Execute the event
+			npc_event_do_id(walk_done_event,bl->id);
+
+			ud->state.walk_script = false;
+
+			// Check if the unit was killed
+			if( status_isdead(bl) ){
+				struct mob_data* md = BL_CAST(BL_MOB, bl);
+
+				if( md && !md->spawn ){
+					unit_free(bl, CLR_OUTSIGHT);
+				}
+
+				return 0;
+			}
+
+			// Check if another event was set
+			if( !strcmp(ud->walk_done_event,walk_done_event) ){
+				// If not remove it
+				ud->walk_done_event[0] = 0;
+			}
 		}
-		if (ud->state.walk_script)
-			ud->state.walk_script = 0;
 	}
 
 	switch(bl->type) {