Browse Source

Fixed atcommands for NPC loading (fixes #203)
* Resolves atcommand loadnpc not working in sequence with atcommand unloadnpc multiple times on the same NPC.
* Added atcommand reloadnpc.
Thanks to @Tokeiburu!

aleos89 8 năm trước cách đây
mục cha
commit
9c2026d216
6 tập tin đã thay đổi với 55 bổ sung17 xóa
  1. 1 1
      conf/msg_conf/map_msg.conf
  2. 10 0
      doc/atcommands.txt
  3. 26 8
      src/map/atcommand.c
  4. 3 3
      src/map/map.c
  5. 14 4
      src/map/npc.c
  6. 1 1
      src/map/npc.h

+ 1 - 1
conf/msg_conf/map_msg.conf

@@ -770,7 +770,7 @@
 
 732: Item cannot be opened when your inventory is full.
 
-//733 free
+733: Please enter a NPC name (usage: @reloadnpc <NPC_name>).
 
 // @cloneequip/@clonestat
 734: Cannot clone your own %s.

+ 10 - 0
doc/atcommands.txt

@@ -1435,6 +1435,16 @@ Example:
 
 ---------------------------------------
 
+@reloadnpc <npc name>
+
+Unloads and loads an NPC.
+Same as @unloadnpc and @loadnpc but ran as one command.
+
+Example:
+@reloadnpc npc/custom/jobmaster.txt
+
+---------------------------------------
+
 =====================
 | 6. Party Commands |
 =====================

+ 26 - 8
src/map/atcommand.c

@@ -4611,15 +4611,12 @@ ACMD_FUNC(loadnpc)
 		clif_displaymessage(fd, msg_txt(sd,1132)); // Please enter a script file name (usage: @loadnpc <file name>).
 		return -1;
 	}
-
-	// add to list of script sources and run it
-        if( !npc_addsrcfile(message)  //try to read file
-            || !npc_parsesrcfile(message,true)
-        ){
-            clif_displaymessage(fd, msg_txt(sd,261));
-            return -1;
-        }	
 	
+	if (!npc_addsrcfile(message, true)) {
+		clif_displaymessage(fd, msg_txt(sd,261));
+		return -1;
+	}
+
 	npc_read_event_script();
 
 	clif_displaymessage(fd, msg_txt(sd,262));
@@ -4651,6 +4648,26 @@ ACMD_FUNC(unloadnpc)
 	return 0;
 }
 
+ACMD_FUNC(reloadnpc) {
+	if (!message || !*message) {
+		clif_displaymessage(fd, msg_txt(sd,733)); // Please enter a NPC name (usage: @reloadnpc <NPC_name>).
+		return -1;
+	}
+
+	if (npc_unloadfile(message))
+		clif_displaymessage(fd, msg_txt(sd,1386)); // File unloaded. Be aware that mapflags and monsters spawned directly are not removed.
+
+	if (!npc_addsrcfile(message, true)) {
+		clif_displaymessage(fd, msg_txt(sd,261));
+		return -1;
+	}
+
+	npc_read_event_script();
+
+	clif_displaymessage(fd, msg_txt(sd,262));
+	return 0;
+}
+
 /*==========================================
  * time in txt for time command (by [Yor])
  *------------------------------------------*/
@@ -10063,6 +10080,7 @@ void atcommand_basecommands(void) {
 		ACMD_DEF(hidenpc),
 		ACMD_DEF(loadnpc),
 		ACMD_DEF(unloadnpc),
+		ACMD_DEF(reloadnpc),
 		ACMD_DEF2("time", servertime),
 		ACMD_DEF(jail),
 		ACMD_DEF(unjail),

+ 3 - 3
src/map/map.c

@@ -3851,7 +3851,7 @@ int map_config_read(char *cfgName)
 		else if (strcmpi(w1, "delmap") == 0)
 			map_delmap(w2);
 		else if (strcmpi(w1, "npc") == 0)
-			npc_addsrcfile(w2);
+			npc_addsrcfile(w2, false);
 		else if (strcmpi(w1, "delnpc") == 0)
 			npc_delsrcfile(w2);
 		else if (strcmpi(w1, "autosave_time") == 0) {
@@ -3928,7 +3928,7 @@ void map_reloadnpc_sub(char *cfgName)
 		*ptr = '\0';
 
 		if (strcmpi(w1, "npc") == 0)
-			npc_addsrcfile(w2);
+			npc_addsrcfile(w2, false);
 		else if (strcmpi(w1, "delnpc") == 0)
 			npc_delsrcfile(w2);
 		else if (strcmpi(w1, "import") == 0)
@@ -3943,7 +3943,7 @@ void map_reloadnpc_sub(char *cfgName)
 void map_reloadnpc(bool clear)
 {
 	if (clear)
-		npc_addsrcfile("clear"); // this will clear the current script list
+		npc_addsrcfile("clear", false); // this will clear the current script list
 
 #ifdef RENEWAL
 	map_reloadnpc_sub("npc/re/scripts_main.conf");

+ 14 - 4
src/map/npc.c

@@ -2093,13 +2093,19 @@ int npc_unload(struct npc_data* nd, bool single) {
 
 	if( single && nd->path ) {
 		struct npc_path_data* npd = NULL;
-		if( nd->path && nd->path != npc_last_ref ) {
+		if( nd->path ) {
 			npd = (struct npc_path_data*)strdb_get(npc_path_db, nd->path);
 		}
 
 		if( npd && --npd->references == 0 ) {
 			strdb_remove(npc_path_db, nd->path);/* remove from db */
 			aFree(nd->path);/* remove now that no other instances exist */
+
+			if (npd == npc_last_npd) {
+				npc_last_npd = NULL;
+				npc_last_ref = NULL;
+				npc_last_path = NULL;
+			}
 		}
 	}
 	
@@ -2181,9 +2187,10 @@ static void npc_clearsrcfile(void)
 /**
  * Adds a npc source file (or removes all)
  * @param name : file to add
+ * @param loadscript : flag to parse the script immediately after adding the src file
  * @return 0=error, 1=sucess
  */
-int npc_addsrcfile(const char* name)
+int npc_addsrcfile(const char* name, bool loadscript)
 {
 	struct npc_src_list* file;
 	struct npc_src_list* file_prev = NULL;
@@ -2217,8 +2224,11 @@ int npc_addsrcfile(const char* name)
 		npc_src_files = file;
 	else
 		file_prev->next = file;
-        
-        return 1;
+
+	if (loadscript)
+		return npc_parsesrcfile(file->name, true);
+
+	return 1;
 }
 
 /// Removes a npc source file (or all)

+ 1 - 1
src/map/npc.h

@@ -162,7 +162,7 @@ bool npc_isnear(struct block_list * bl);
 
 int npc_get_new_npc_id(void);
 
-int npc_addsrcfile(const char* name);
+int npc_addsrcfile(const char* name, bool loadscript);
 void npc_delsrcfile(const char* name);
 int npc_parsesrcfile(const char* filepath, bool runOnInit);
 void do_clear_npc(void);