Issue information

Issue ID
#1730
Status
Fixed
Severity
None
Started
Hercules Elf Bot
Jun 21, 2008 14:09
Last Post
Hercules Elf Bot
Jun 21, 2008 14:09
Confirmation
N/A

Hercules Elf Bot - Jun 21, 2008 14:09

Originally posted by [b]Inkfish[/b]
http://www.eathena.ws/board/index.php?autocom=bugtracker&showbug=1730

As I mentioned before in this thread: http://www.eathena.ws/board/index.php?auto...mp;showbug=1619
getnpctimer returns twice the value when this function is called in OnTimerXXXX event.

then, another bug. You initial the timer, you stop it, you start it, you stop it, you start it, here, you don't get the correct time, try it.

and then, another bug. you can't get the correct timetick when using 'getnpctimer' while the timer stops, the return value behaves like the npctimer didn't stop, though it did.

I made this script to check the current code:
CODE
prontera.gat,135,92,5    script    111    811,{
    initnpctimer;
    end;

OnTimer3000:
    announce getnpctimer(0),0;//Display Value:6000, theory value: 3000, timer actual value: 3000.
    end;

OnTimer5000:
    announce getnpctimer(0),0;//Display Value:10000, theory value: 5000, timer actual value: 5000.
    stopnpctimer;
    sleep 5000;
    announce getnpctimer(0),0;//Display Value:15000, theory value: 5000, timer actual value: 5000.
    startnpctimer;
    announce getnpctimer(0),0;//Display Value:5000, theory value: 5000, timer actual value: 5000.
    end;

OnTimer6000:
    announce getnpctimer(0),0;//Display Value:7000, theory value: 6000, timer actual value: 6000.
    end;

OnTimer7000:        
    stopnpctimer;
    announce getnpctimer(0),0;//Display Value:4000, theory value: 7000, timer actual value: 7000.
    startnpctimer;
    announce getnpctimer(0),0;//Display Value:2000, theory value: 7000, timer actual value: 1000. back to OnTimer3000.
    end;

OnTimer8000:
    end;
}


my solution in npc.c
CODE
int npc_timerevent(int tid, unsigned int tick, int id, int data)
...
-    nd->u.scr.timertick=ted->otick;
+    nd->u.scr.timertick=ted->otick=gettick();
    te=nd->u.scr.timer_event+ ted->next;
    
    old_timer = nd->u.scr.timer;
    t = nd->u.scr.timer=ted->time;
    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;
        ted->time+=next;
        if (sd)
            sd->npc_timer_id = add_timer(tick+next,npc_timerevent,id,(int)ted);
        else
            nd->u.scr.timerid = add_timer(tick+next,npc_timerevent,id,(int)ted);
    } else {
        if (sd)
            sd->npc_timer_id = -1;
        else
            nd->u.scr.timerid = -1;
        ers_free(timer_event_ers, ted);
+        nd->u.scr.timertick = 0;


...

int npc_timerevent_stop(struct npc_data* nd)
...

    if (*tid == -1) //Nothing to stop
        return 0;
    td = get_timer(*tid);
    if (td && td->data)
        ers_free(timer_event_ers, (void*)td->data);
    delete_timer(*tid,npc_timerevent);
    *tid = -1;
    //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?
    return 0;

...

void npc_timerevent_quit(struct map_session_data* sd)
...

        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
+            nd->u.scr.timertick=ted->otick=gettick();

            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);
+    nd->u.scr.timertick = 0;


ultramage wonders the difference between nd->u.scr.timertick and nd->u.scr.timer.
As far as I know nd->u.scr.timer means the time since the last OnTimerLabel to the next. You can see it be updated everytime the OnTimerXXX label triggers.
And the nd->u.scr.timertick, I suppose it should also be updated everytime the OnTimerXXX label triggers, and it just means when the nd->u.scr.timertick and nd->u.scr.timer are updated.

Thus
CODE
    tick=nd->u.scr.timer;
    if (nd->u.scr.timertick)
        tick+=DIFF_TICK(gettick(), nd->u.scr.timertick);

So the getnpctimer will just get the time since the timer starts to the time last OnTimer label triggers(nd->u.scr.timer) and plus, the time since when the last OnTimer label triggers to now.(nd->u.scr.timertick)



This post has been edited by Inkfish: Jun 21 2008, 10:38 AM