Browse Source

- Now when a player logs out while it's running an attached npctimer, OnTimerQuit of that npc will be invoked.
- Updated scripts_command to add info on OnTimerQuit
- Corrected the double login check in pc_authok


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9926 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 18 years ago
parent
commit
8c52b6b21d
3 changed files with 47 additions and 13 deletions
  1. 6 0
      doc/script_commands.txt
  2. 39 3
      src/map/npc.c
  3. 2 10
      src/map/pc.c

+ 6 - 0
doc/script_commands.txt

@@ -65,6 +65,8 @@
 //=       initnpctimer [Skotlex]
 //=       initnpctimer [Skotlex]
 //= 3.03.20070226
 //= 3.03.20070226
 //=       Updated makeitem and how to include " in strings [Lupus]
 //=       Updated makeitem and how to include " in strings [Lupus]
+//= 3.03.20070228
+//=       Added info on OnTimerQuit label to npctimer section. [Skotlex]
 //===== Compatible With ===================================
 //===== Compatible With ===================================
 //= LOL, can be used by anyone hopefully
 //= LOL, can be used by anyone hopefully
 //===== Description =======================================
 //===== Description =======================================
@@ -4872,6 +4874,10 @@ The other method to attach/detach a RID is through the script commands
 character the target for all character-referencing commands and functions,
 character the target for all character-referencing commands and functions,
 not to mention variables.
 not to mention variables.
 
 
+If the player that is attached to the npctimer logs out, the "OnTimerQuit:"
+event label of that npc will be triggered, so you can do the appropiate
+cleanup (the player is still attached when this event is triggered).
+
 'setnpctimer' will explicitly set the timer to a given tick. To make it useful, 
 'setnpctimer' will explicitly set the timer to a given tick. To make it useful, 
 you will need the 'getnpctimer' function, which the type of information argument 
 you will need the 'getnpctimer' function, which the type of information argument 
 means:
 means:

+ 39 - 3
src/map/npc.c

@@ -598,7 +598,7 @@ int npc_timerevent(int tid,unsigned int tick,int id,int data)
 	struct npc_timerevent_list *te;
 	struct npc_timerevent_list *te;
 	struct timer_event_data *ted = (struct timer_event_data*)data;
 	struct timer_event_data *ted = (struct timer_event_data*)data;
 	struct map_session_data *sd=NULL;
 	struct map_session_data *sd=NULL;
-	
+
 	if( nd==NULL ){
 	if( nd==NULL ){
 		ShowError("npc_timerevent: NPC not found??\n");
 		ShowError("npc_timerevent: NPC not found??\n");
 		return 0;
 		return 0;
@@ -743,6 +743,8 @@ int npc_timerevent_stop(struct npc_data *nd)
  */
  */
 void npc_timerevent_quit(struct map_session_data *sd) {
 void npc_timerevent_quit(struct map_session_data *sd) {
 	struct TimerData *td;
 	struct TimerData *td;
+	struct npc_data* nd;
+	struct timer_event_data *ted;
 	if (sd->npc_timer_id == -1)
 	if (sd->npc_timer_id == -1)
 		return;
 		return;
 	td = get_timer(sd->npc_timer_id);
 	td = get_timer(sd->npc_timer_id);
@@ -750,9 +752,43 @@ void npc_timerevent_quit(struct map_session_data *sd) {
 		sd->npc_timer_id = -1;
 		sd->npc_timer_id = -1;
 		return; //??
 		return; //??
 	}
 	}
-	delete_timer(sd->npc_timer_id,npc_timerevent);
+	nd = (struct npc_data *)map_id2bl(td->id);
+	ted = (struct timer_event_data*)td->data;
+	delete_timer(sd->npc_timer_id, npc_timerevent);
 	sd->npc_timer_id = -1;
 	sd->npc_timer_id = -1;
-	ers_free(timer_event_ers, (struct event_timer_data*)td->data);
+	if (nd && nd->bl.type == BL_NPC)
+	{	//Execute OnTimerQuit
+		char buf[sizeof(nd->exname)+sizeof("::OnTimerQuit")+1];
+		struct event_data *ev;
+		sprintf(buf,"%s::OnTimerQuit",nd->exname);
+		ev = strdb_get(ev_db,(unsigned char*)buf);
+		if(ev && ev->nd != nd) {
+			ShowWarning("npc_timerevent_quit: Unable to execute \"OnTimerQuit\", two NPCs have the same event name [%s]!\n",buf);
+			ev = NULL;
+		}
+		if (ev) {
+			int old_rid,old_timer;
+			unsigned int old_tick;
+			//Set timer related info.
+			old_rid = nd->u.scr.rid;
+			nd->u.scr.rid = sd->bl.id;
+
+			old_tick = nd->u.scr.timertick;
+			nd->u.scr.timertick=ted->otick;
+
+			old_timer = nd->u.scr.timer;
+			nd->u.scr.timer=ted->time;
+		
+			//Execute label
+			run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
+
+			//Restore previous data.
+			nd->u.scr.rid = old_rid;
+			nd->u.scr.timer = old_timer;
+			nd->u.scr.timertick = old_tick;
+		}
+	}
+	ers_free(timer_event_ers, ted);
 }
 }
 
 
 /*==========================================
 /*==========================================

+ 2 - 10
src/map/pc.c

@@ -573,9 +573,9 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
 		return 1;
 		return 1;
 	}
 	}
 
 
-	if( (old_sd=map_id2sd(sd->status.account_id)) != NULL ){
+	if( (old_sd=map_id2sd(st->account_id)) != NULL ){
 		if (old_sd->state.finalsave || !old_sd->state.auth)
 		if (old_sd->state.finalsave || !old_sd->state.auth)
-			; //Previous player is not done loading, No need to kick.
+			; //Previous player is not done loading/quiting, No need to kick.
 		else if (old_sd->fd)
 		else if (old_sd->fd)
 			clif_authfail_fd(old_sd->fd, 2); // same id
 			clif_authfail_fd(old_sd->fd, 2); // same id
 		else 
 		else 
@@ -583,14 +583,6 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
 		clif_authfail_fd(sd->fd, 8); // still recognizes last connection
 		clif_authfail_fd(sd->fd, 8); // still recognizes last connection
 		return 1;
 		return 1;
 	}
 	}
-
-	if (map_id2sd(st->account_id) != NULL)
-	{	//Somehow a second connection has managed to go through the double-connection
-		//check in clif_parse_WantToConnection! [Skotlex]
-		clif_authfail_fd(sd->fd, 0);
-		return 1;
-	}
-
 	memcpy(&sd->status, st, sizeof(*st));
 	memcpy(&sd->status, st, sizeof(*st));
 
 
 	//Set the map-server used job id. [Skotlex]
 	//Set the map-server used job id. [Skotlex]