From 9c0abf37f912ff2a4192ec72ac8d48da0d84ba33 Mon Sep 17 00:00:00 2001 From: gumi Date: Wed, 15 Mar 2017 11:02:32 -0400 Subject: add gettimer() buildin --- db/constants.conf | 9 +++-- doc/script_commands.txt | 49 +++++++++++++++++++------ src/map/script.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 12 deletions(-) diff --git a/db/constants.conf b/db/constants.conf index 09c0fa9e4..79530e7d1 100644 --- a/db/constants.conf +++ b/db/constants.conf @@ -3664,14 +3664,14 @@ constants_db: { PC_PARTY: 1 PC_GUILD: 2 PC_MAP: 3 - + comment__: "strnpcinfo" NPC_NAME: 0 NPC_NAME_VISIBLE: 1 NPC_NAME_HIDDEN: 2 NPC_NAME_UNIQUE: 3 NPC_MAP: 4 - + comment__: "getcharid" CHAR_ID_CHAR: 0 CHAR_ID_PARTY: 1 @@ -3709,6 +3709,11 @@ constants_db: { GETTIME_YEAR: 7 GETTIME_DAYOFYEAR: 8 + comment__: "gettimer" + TIMER_COUNT: 0 + TIMER_TICK_NEXT: 1 + TIMER_TICK_LAST: 2 + comment__: "unit types" UNITTYPE_PC: 0 UNITTYPE_NPC: 1 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index b202f1b6b..581ec182c 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -6479,17 +6479,13 @@ Size is 0 = normal 1 = small 2 = big. --------------------------------------- *addtimer(, "NPC::OnLabel"{, }) -*deltimer("NPC::OnLabel"{, }) -*addtimercount("NPC::OnLabel", {, }) -These commands will create, destroy, and delay a countdown timer - -addtimer() to create, deltimer() to destroy and addtimercount() to delay -it by the specified number of ticks. For all three cases, the event label -given is the identifier of that timer. The timer runs on the character -object that is attached to the script, and can have multiple instances. -If is passed, this player will be used instead. -When the label is run, it is run as if the player that the timer runs on -has clicked the NPC. +This command will create a countdown timer. +The event label given is the identifier of that timer. +The timer runs on the character object that is attached to the script, +and can have multiple instances. If is passed, this player +will be used instead. When the label is run, it is run as if the player +that the timer runs on has clicked the NPC. When this timer runs out, a new execution thread will start in the specified NPC object at the specified label. @@ -6513,6 +6509,39 @@ On5secs: --------------------------------------- +*deltimer("NPC::OnLabel"{, }) + +Deletes timers created by addtimer() that matches the given event +label. Refer to addtimer() for additional information. + +--------------------------------------- + +*addtimercount("NPC::OnLabel", {, }) + +Delays a timer that was created with addtimer() by ticks +if it matches the given event label. Refer to addtimer() for additional +information. + +--------------------------------------- + +*gettimer({, {, ""}}) + +Returns informations on timers that were created by addtimer(). + +valid for gettimer() are: + +(0) TIMER_COUNT + Will return the total number of timers for the specified or + attached player. Can be filtered by . +(1) TIMER_TICK_NEXT + Will return the number of ticks until the next timer runs + for the specified or attached player. Can be filtered by . +(2) TIMER_TICK_LAST + Will return the number of ticks until the last timer runs + for the specified or attached player. Can be filtered by . + +--------------------------------------- + *initnpctimer({ "" {, } } | { "" | }) *stopnpctimer({ "" {, } } | diff --git a/src/map/script.c b/src/map/script.c index 48c377d24..ce740e81b 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10861,6 +10861,100 @@ BUILDIN(addtimercount) return true; } +enum gettimer_mode { + GETTIMER_COUNT = 0, + GETTIMER_TICK_NEXT = 1, + GETTIMER_TICK_LAST = 2, +}; + +BUILDIN(gettimer) +{ + struct map_session_data *sd; + const struct TimerData *td; + int i; + int tick; + const char *event = NULL; + int val = 0; + bool first = true; + short mode = script_getnum(st, 2); + + if (script_hasdata(st, 3)) + sd = map->id2sd(script_getnum(st, 3)); + else + sd = script->rid2sd(st); + + if (script_hasdata(st, 4)) { + event = script_getstr(st, 4); + script->check_event(st, event); + } + + if (sd == NULL) { + script_pushint(st, -1); + return true; + } + + switch (mode) { + case GETTIMER_COUNT: + // get number of timers + for (i = 0; i < MAX_EVENTTIMER; i++) { + if (sd->eventtimer[i] != INVALID_TIMER) { + if (event != NULL) { + td = timer->get(sd->eventtimer[i]); + Assert_retr(false, td != NULL); + + if (strcmp((char *)(td->data), event) == 0) { + val++; + } + } else { + val++; + } + } + } + break; + case GETTIMER_TICK_NEXT: + // get the number of tick before the next timer runs + for (i = 0; i < MAX_EVENTTIMER; i++) { + if (sd->eventtimer[i] != INVALID_TIMER) { + td = timer->get(sd->eventtimer[i]); + Assert_retr(false, td != NULL); + tick = max(0, DIFF_TICK32(td->tick, timer->gettick())); + + if (event != NULL) { + if ((first == true || tick < val) && strcmp((char *)(td->data), event) == 0) { + val = tick; + first = false; + } + } else if (first == true || tick < val) { + val = tick; + first = false; + } + } + } + break; + case GETTIMER_TICK_LAST: + // get the number of ticks before the last timer runs + for (i = MAX_EVENTTIMER - 1; i >= 0; i--) { + if (sd->eventtimer[i] != INVALID_TIMER) { + td = timer->get(sd->eventtimer[i]); + Assert_retr(false, td != NULL); + tick = max(0, DIFF_TICK32(td->tick, timer->gettick())); + + if (event != NULL) { + if (strcmp((char *)(td->data), event) == 0) { + val = max(val, tick); + } + } else { + val = max(val, tick); + } + } + } + break; + } + + script_pushint(st, val); + return true; +} + /*========================================== *------------------------------------------*/ BUILDIN(initnpctimer) @@ -21115,6 +21209,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(addtimer,"is?"), BUILDIN_DEF(deltimer,"s?"), BUILDIN_DEF(addtimercount,"si?"), + BUILDIN_DEF(gettimer,"i??"), BUILDIN_DEF(initnpctimer,"??"), BUILDIN_DEF(stopnpctimer,"??"), BUILDIN_DEF(startnpctimer,"??"), -- cgit v1.2.3-60-g2f50