浏览代码

* Shinomori's method (kinda) of remote script execution with interaction.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6151 54d463be-8e91-2dee-dedb-b68131a5f0ec
Lance 19 年之前
父节点
当前提交
c0b1eb7787
共有 6 个文件被更改,包括 33 次插入17 次删除
  1. 3 0
      Changelog-Trunk.txt
  2. 3 14
      src/map/clif.c
  3. 1 0
      src/map/map.h
  4. 8 2
      src/map/npc.c
  5. 2 0
      src/map/npc.h
  6. 16 1
      src/map/script.c

+ 3 - 0
Changelog-Trunk.txt

@@ -3,6 +3,9 @@ Date	Added
 AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
+2006/04/28
+	* Shinomori's method (kinda) of remote script execution with interaction. [Lance]
+
 2006/04/17
 	* skill_clear_unitgroup is now invoked in unit_remove_map only on death if
 	  the applicable battle setting is set. [Skotlex]

+ 3 - 14
src/map/clif.c

@@ -1705,9 +1705,6 @@ int clif_scriptclose(struct map_session_data *sd, int npcid) {
 	WFIFOW(fd,0)=0xb6;
 	WFIFOL(fd,2)=npcid;
 	WFIFOSET(fd,packet_len_table[0xb6]);
-	
-	if(map_id2bl(npcid)->m < 0)
-		clif_clearchar_id(npcid, 0, fd);
 
 	return 0;
 }
@@ -1718,11 +1715,12 @@ int clif_scriptclose(struct map_session_data *sd, int npcid) {
  */
 void clif_sendfakenpc(struct map_session_data *sd, int npcid) {
 	int fd = sd->fd;
+	sd->npc_id = npcid;
+	sd->state.using_fake_npc = 1;
 	memset(WFIFOP(fd,0), 0, packet_len_table[0x78]);
 	WFIFOW(fd,0)=0x78;
 	WFIFOL(fd,2)=npcid;
-	WFIFOW(fd,12)=OPTION_HIDE;
-	WFIFOW(fd,14)=123;
+	WFIFOW(fd,14)=111;
 	WFIFOPOS(fd,46,sd->bl.x,sd->bl.y);
 	WFIFOB(fd,49)=5;
 	WFIFOB(fd,50)=5;
@@ -1741,9 +1739,6 @@ int clif_scriptmenu(struct map_session_data *sd, int npcid, char *mes) {
 
 	nullpo_retr(0, sd);
 
-	if(map_id2bl(npcid)->m < 0)
-		clif_sendfakenpc(sd, npcid);
-
 	fd=sd->fd;
 	WFIFOW(fd,0)=0xb7;
 	WFIFOW(fd,2)=slen;
@@ -1763,9 +1758,6 @@ int clif_scriptinput(struct map_session_data *sd, int npcid) {
 
 	nullpo_retr(0, sd);
 	
-	if(map_id2bl(npcid)->m < 0)
-		clif_sendfakenpc(sd, npcid);
-	
 	fd=sd->fd;
 	WFIFOHEAD(fd, packet_len_table[0x142]);
 	WFIFOW(fd,0)=0x142;
@@ -1783,9 +1775,6 @@ int clif_scriptinputstr(struct map_session_data *sd, int npcid) {
 	int fd;
 
 	nullpo_retr(0, sd);
-	
-	if(map_id2bl(npcid)->m < 0)
-		clif_sendfakenpc(sd, npcid);
 
 	fd=sd->fd;
 	WFIFOHEAD(fd, packet_len_table[0x1d4]);

+ 1 - 0
src/map/map.h

@@ -494,6 +494,7 @@ struct map_session_data {
 		unsigned night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
 		unsigned finalsave :1; //Signals whether the final save for the char was done or not yet. Meant to prevent exploits and the like. [Skotlex]
 		unsigned blockedmove :1;
+		unsigned using_fake_npc :1;
 		unsigned short autoloot;
 		struct guild *gmaster_flag;
 	} state;

+ 8 - 2
src/map/npc.c

@@ -985,6 +985,9 @@ int npc_checknear(struct map_session_data *sd,int id)
 
 	nullpo_retr(0, sd);
 
+	if(sd->state.using_fake_npc)
+		return 0;
+
 	nd=(struct npc_data *)map_id2bl(id);
 	if (nd==NULL || nd->bl.type!=BL_NPC) {
 		if (battle_config.error_log)
@@ -992,8 +995,8 @@ int npc_checknear(struct map_session_data *sd,int id)
 		return 1;
 	}
 
-	if (nd->class_<0)	// イベント系は常にOK
-		return 0;
+	//if (nd->class_<0)	// イベント系は常にOK
+	//	return 0;
 
 	// エリア判定
 	if (nd->bl.m!=sd->bl.m ||
@@ -2783,6 +2786,9 @@ int do_init_npc(void)
 	add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
 	add_timer_func_list(npc_timerevent,"npc_timerevent");
 
+	// Init dummy NPC
+	dummy_npc_id = npc_get_new_npc_id();
+
 	return 0;
 }
 // [Lance]

+ 2 - 0
src/map/npc.h

@@ -66,6 +66,8 @@ int npc_remove_map(struct npc_data *nd);
 int npc_unload(struct npc_data *nd);
 int npc_reload(void);
 
+static int dummy_npc_id;
+
 extern char *current_file;
 
 #endif

+ 16 - 1
src/map/script.c

@@ -10856,6 +10856,7 @@ int run_func(struct script_state *st)
 int run_script_main(struct script_state *st)
 {
 	int c/*,rerun_pos*/;
+	struct block_list *bl;
 	int cmdcount=script_config.check_cmdcount;
 	int gotocount=script_config.check_gotocount;
 	struct script_stack *stack=st->stack;
@@ -10868,6 +10869,15 @@ int run_script_main(struct script_state *st)
 		}
 	} else {
 		st->state = RUN;
+		if(st->oid && st->rid && (bl = map_id2bl(st->oid))){
+			if(bl->type == BL_PC){
+				clif_sendfakenpc(((TBL_PC *)bl),dummy_npc_id);
+				st->oid = dummy_npc_id;
+			} else if(bl->type == BL_NPC){
+				if(npc_checknear(((TBL_PC *)bl), bl->id))
+					clif_sendfakenpc(((struct map_session_data *)bl),st->oid);
+			}
+		}
 	}
 	while( st->state == RUN) {
 		c= get_com((unsigned char *) st->script,&st->pos);
@@ -10965,8 +10975,13 @@ int run_script_main(struct script_state *st)
 		{
 			struct map_session_data *sd=map_id2sd(st->rid);
 			st->pos=-1;
-			if(sd && sd->npc_id==st->oid)
+			if(sd && sd->npc_id==st->oid){
+				if(sd->state.using_fake_npc){
+					clif_clearchar_id(sd->npc_id, 0, sd->fd);
+					sd->state.using_fake_npc = 0;
+				}
 				npc_event_dequeue(sd);
+			}
 		}
 		break;
 	case RERUNLINE: