From 43d7a390b485a4bc46363e4136e26c92e2013515 Mon Sep 17 00:00:00 2001 From: skotlex Date: Tue, 27 Feb 2007 02:30:55 +0000 Subject: - 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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9926 54d463be-8e91-2dee-dedb-b68131a5f0ec --- doc/script_commands.txt | 6 ++++++ src/map/npc.c | 42 +++++++++++++++++++++++++++++++++++++++--- src/map/pc.c | 12 ++---------- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index c512e2b8e..5d52abaa7 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -65,6 +65,8 @@ //= initnpctimer [Skotlex] //= 3.03.20070226 //= Updated makeitem and how to include " in strings [Lupus] +//= 3.03.20070228 +//= Added info on OnTimerQuit label to npctimer section. [Skotlex] //===== Compatible With =================================== //= LOL, can be used by anyone hopefully //===== 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, 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, you will need the 'getnpctimer' function, which the type of information argument means: diff --git a/src/map/npc.c b/src/map/npc.c index ec6f143d1..59d21e7ba 100644 --- a/src/map/npc.c +++ b/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 timer_event_data *ted = (struct timer_event_data*)data; struct map_session_data *sd=NULL; - + if( nd==NULL ){ ShowError("npc_timerevent: NPC not found??\n"); return 0; @@ -743,6 +743,8 @@ int npc_timerevent_stop(struct npc_data *nd) */ void npc_timerevent_quit(struct map_session_data *sd) { struct TimerData *td; + struct npc_data* nd; + struct timer_event_data *ted; if (sd->npc_timer_id == -1) return; 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; 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; - 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); } /*========================================== diff --git a/src/map/pc.c b/src/map/pc.c index 558f0f0be..9a929f852 100644 --- a/src/map/pc.c +++ b/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; } - 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) - ; //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) clif_authfail_fd(old_sd->fd, 2); // same id 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 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)); //Set the map-server used job id. [Skotlex] -- cgit v1.2.3-70-g09d2