* Fix several npctimer issues (bugreport:1619, bugreport:1730)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@13718 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
Inkfish 2009-05-03 04:06:53 +00:00
parent 8cd8f32c78
commit a43c9e581b
2 changed files with 67 additions and 55 deletions

View File

@ -6,6 +6,7 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2009/05/03 2009/05/03
* Do not log damage if it's done by mob itself (bugreport:2933) [Inkfish] * Do not log damage if it's done by mob itself (bugreport:2933) [Inkfish]
* Fix 'awake' not working (bugreport:2580) [Inkfish] * Fix 'awake' not working (bugreport:2580) [Inkfish]
* Fix several npctimer issues (bugreport:1619, bugreport:1730) [Inkfish]
2009/05/02 2009/05/02
* Spirit of Bard and Dancer now only works for mastered skills (bugreport:3037) [Playtester] * Spirit of Bard and Dancer now only works for mastered skills (bugreport:3037) [Playtester]
- also fixed an outdated comment in the source code - also fixed an outdated comment in the source code

View File

@ -421,47 +421,52 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
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;
} }
if (ted->rid) {
sd = map_id2sd(ted->rid); if( ted->rid && !(sd = map_id2sd(ted->rid)) )
if (!sd) { {
ShowError("npc_timerevent: Attached player not found.\n"); ShowError("npc_timerevent: Attached player not found.\n");
ers_free(timer_event_ers, ted); ers_free(timer_event_ers, ted);
return 0; return 0;
}
} }
old_rid = nd->u.scr.rid; //To restore it later. old_rid = nd->u.scr.rid; //To restore it later.
nd->u.scr.rid = sd?sd->bl.id:0; nd->u.scr.rid = sd?sd->bl.id:0;
old_tick = nd->u.scr.timertick; old_tick = nd->u.scr.timertick;
nd->u.scr.timertick=ted->otick; nd->u.scr.timertick = ted->otick = gettick();
te=nd->u.scr.timer_event+ ted->next; te = nd->u.scr.timer_event + ted->next;
old_timer = nd->u.scr.timer; old_timer = nd->u.scr.timer;
t = nd->u.scr.timer=ted->time; t = nd->u.scr.timer = ted->time;
ted->next++; ted->next++;
if( nd->u.scr.timeramount> ted->next){ if( nd->u.scr.timeramount > ted->next)
next= nd->u.scr.timer_event[ ted->next ].timer {
- nd->u.scr.timer_event[ ted->next-1 ].timer; next = nd->u.scr.timer_event[ ted->next ].timer - nd->u.scr.timer_event[ ted->next - 1 ].timer;
ted->time+=next; ted->time += next;
if (sd) if( sd )
sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr)ted); sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
else else
nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr)ted); nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(intptr)ted);
} else { }
if (sd) else
{
if( sd )
sd->npc_timer_id = -1; sd->npc_timer_id = -1;
else else
nd->u.scr.timerid = -1; nd->u.scr.timerid = -1;
ers_free(timer_event_ers, ted); ers_free(timer_event_ers, ted);
nd->u.scr.timertick = 0;
} }
run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id); run_script(nd->u.scr.script,te->pos,nd->u.scr.rid,nd->bl.id);
//Restore previous data, only if this timer is a player-attached one. //Restore previous data, only if this timer is a player-attached one.
if (sd) { if( sd )
{
nd->u.scr.rid = old_rid; nd->u.scr.rid = old_rid;
nd->u.scr.timer = old_timer; nd->u.scr.timer = old_timer;
nd->u.scr.timertick = old_tick; nd->u.scr.timertick = old_tick;
@ -473,48 +478,44 @@ int npc_timerevent(int tid, unsigned int tick, int id, intptr data)
*------------------------------------------*/ *------------------------------------------*/
int npc_timerevent_start(struct npc_data* nd, int rid) int npc_timerevent_start(struct npc_data* nd, int rid)
{ {
int j,n, next; int j, next;
struct map_session_data *sd=NULL; //Player to whom script is attached. struct map_session_data *sd=NULL; //Player to whom script is attached.
struct timer_event_data *ted; struct timer_event_data *ted;
nullpo_retr(0, nd); nullpo_retr(0, nd);
n=nd->u.scr.timeramount; if( nd->u.scr.timeramount == 0 )
if( n==0 )
return 0; return 0;
ARR_FIND( 0, n, j, nd->u.scr.timer_event[j].timer > nd->u.scr.timer ); ARR_FIND( 0, nd->u.scr.timeramount, j, nd->u.scr.timer_event[j].timer > nd->u.scr.timer );
if(j>=n) // check if there is a timer to use !!BEFORE!! you write stuff to the structures [Shinomori] if( j >= nd->u.scr.timeramount ) // check if there is a timer to use !!BEFORE!! you write stuff to the structures [Shinomori]
return 0; return 0;
if (nd->u.scr.rid > 0) {
//Try to attach timer to this player. if( nd->u.scr.rid > 0 && !(sd = map_id2sd(nd->u.scr.rid)) )
sd = map_id2sd(nd->u.scr.rid); { //Try to attach timer to this player.
if (!sd) { ShowError("npc_timerevent_start: Attached player not found!\n");
ShowError("npc_timerevent_start: Attached player not found!\n"); return 1;
return 1;
}
} }
//Check if timer is already started. //Check if timer is already started.
if (sd) { if( (sd && sd->npc_timer_id != -1) || nd->u.scr.timerid != -1 )
if (sd->npc_timer_id != -1)
return 0;
} else if (nd->u.scr.timerid != -1)
return 0; return 0;
ted = ers_alloc(timer_event_ers, struct timer_event_data); ted = ers_alloc(timer_event_ers, struct timer_event_data);
ted->next = j; ted->next = j;
nd->u.scr.timertick=ted->otick=gettick(); nd->u.scr.timertick = ted->otick = gettick();
//Attach only the player if attachplayerrid was used. //Attach only the player if attachplayerrid was used.
ted->rid = sd?sd->bl.id:0; ted->rid = sd?sd->bl.id:0;
// Do not store it to make way to two types of timers: globals and personals. // Do not store it to make way to two types of timers: globals and personals.
// if (rid >= 0) nd->u.scr.rid=rid; // changed to: attaching to given rid by default [Shinomori] // if( rid >= 0 ) // changed to: attaching to given rid by default [Shinomori]
// nd->u.scr.rid=rid;
// if rid is less than 0 leave it unchanged [celest] // if rid is less than 0 leave it unchanged [celest]
next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer; next = nd->u.scr.timer_event[j].timer - nd->u.scr.timer;
ted->time = nd->u.scr.timer_event[j].timer; ted->time = nd->u.scr.timer_event[j].timer;
if (sd) if( sd )
sd->npc_timer_id = add_timer(gettick()+next,npc_timerevent,nd->bl.id,(intptr)ted); sd->npc_timer_id = add_timer(gettick()+next,npc_timerevent,nd->bl.id,(intptr)ted);
else else
nd->u.scr.timerid = add_timer(gettick()+next,npc_timerevent,nd->bl.id,(intptr)ted); nd->u.scr.timerid = add_timer(gettick()+next,npc_timerevent,nd->bl.id,(intptr)ted);
@ -528,27 +529,29 @@ int npc_timerevent_stop(struct npc_data* nd)
struct map_session_data *sd =NULL; struct map_session_data *sd =NULL;
const struct TimerData *td = NULL; const struct TimerData *td = NULL;
int *tid; int *tid;
nullpo_retr(0, nd); nullpo_retr(0, nd);
if (nd->u.scr.rid) { if( nd->u.scr.rid && !(sd = map_id2sd(nd->u.scr.rid)) )
sd = map_id2sd(nd->u.scr.rid); {
if (!sd) { ShowError("npc_timerevent_stop: Attached player not found!\n");
ShowError("npc_timerevent_stop: Attached player not found!\n"); return 1;
return 1;
}
} }
tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid; tid = sd?&sd->npc_timer_id:&nd->u.scr.timerid;
if (*tid == -1) //Nothing to stop if (*tid == -1) //Nothing to stop
return 0; return 0;
td = get_timer(*tid); td = get_timer(*tid);
if (td && td->data) if (td && td->data)
ers_free(timer_event_ers, (void*)td->data); ers_free(timer_event_ers, (void*)td->data);
delete_timer(*tid,npc_timerevent); delete_timer(*tid,npc_timerevent);
*tid = -1; *tid = -1;
//Set the timer tick to the time that has passed since the beginning of the timers and now. //Set the timer tick to the time that has passed since the beginning of the timers and now.
nd->u.scr.timer = DIFF_TICK(gettick(),nd->u.scr.timertick); nd->u.scr.timer += DIFF_TICK(gettick(),nd->u.scr.timertick);
nd->u.scr.timertick = 0;
// nd->u.scr.rid = 0; //Eh? why detach? // nd->u.scr.rid = 0; //Eh? why detach?
return 0; return 0;
} }
/*========================================== /*==========================================
@ -559,39 +562,46 @@ void npc_timerevent_quit(struct map_session_data* sd)
const struct TimerData *td; const struct TimerData *td;
struct npc_data* nd; struct npc_data* nd;
struct timer_event_data *ted; 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);
if (!td) { if( !(td = get_timer(sd->npc_timer_id)) )
{
sd->npc_timer_id = -1; sd->npc_timer_id = -1;
return; //?? return; //??
} }
nd = (struct npc_data *)map_id2bl(td->id); nd = (struct npc_data *)map_id2bl(td->id);
ted = (struct timer_event_data*)td->data; ted = (struct timer_event_data*)td->data;
delete_timer(sd->npc_timer_id, npc_timerevent); delete_timer(sd->npc_timer_id, npc_timerevent);
sd->npc_timer_id = -1; sd->npc_timer_id = -1;
if (nd && nd->bl.type == BL_NPC) if( nd && nd->bl.type == BL_NPC )
{ //Execute OnTimerQuit { //Execute OnTimerQuit
char buf[NAME_LENGTH*2+3]; char buf[NAME_LENGTH*2+3];
struct event_data *ev; struct event_data *ev;
snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname); snprintf(buf, ARRAYLENGTH(buf), "%s::OnTimerQuit", nd->exname);
ev = (struct event_data*)strdb_get(ev_db, buf); ev = (struct event_data*)strdb_get(ev_db, buf);
if(ev && ev->nd != nd) { if( ev && ev->nd != nd )
{
ShowWarning("npc_timerevent_quit: Unable to execute \"OnTimerQuit\", two NPCs have the same event name [%s]!\n",buf); ShowWarning("npc_timerevent_quit: Unable to execute \"OnTimerQuit\", two NPCs have the same event name [%s]!\n",buf);
ev = NULL; ev = NULL;
} }
if (ev) { if( ev )
{
int old_rid,old_timer; int old_rid,old_timer;
unsigned int old_tick; unsigned int old_tick;
//Set timer related info. //Set timer related info.
old_rid = nd->u.scr.rid; old_rid = nd->u.scr.rid;
nd->u.scr.rid = sd->bl.id; nd->u.scr.rid = sd->bl.id;
old_tick = nd->u.scr.timertick; old_tick = nd->u.scr.timertick;
nd->u.scr.timertick=ted->otick; nd->u.scr.timertick = ted->otick = gettick();
old_timer = nd->u.scr.timer; old_timer = nd->u.scr.timer;
nd->u.scr.timer=ted->time; nd->u.scr.timer = ted->time;
//Execute label //Execute label
run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id); run_script(nd->u.scr.script,ev->pos,sd->bl.id,nd->bl.id);
@ -603,6 +613,7 @@ void npc_timerevent_quit(struct map_session_data* sd)
} }
} }
ers_free(timer_event_ers, ted); ers_free(timer_event_ers, ted);
nd->u.scr.timertick = 0;
} }
/*========================================== /*==========================================