summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/constants.conf9
-rw-r--r--doc/script_commands.txt49
-rw-r--r--src/map/script.c95
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(<ticks>, "NPC::OnLabel"{, <account id>})
-*deltimer("NPC::OnLabel"{, <account id>})
-*addtimercount("NPC::OnLabel", <ticks>{, <account id>})
-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 <acccount id> 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 <acccount id> 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"{, <account id>})
+
+Deletes timers created by addtimer() that matches the given event
+label. Refer to addtimer() for additional information.
+
+---------------------------------------
+
+*addtimercount("NPC::OnLabel", <ticks>{, <account id>})
+
+Delays a timer that was created with addtimer() by <ticks> ticks
+if it matches the given event label. Refer to addtimer() for additional
+information.
+
+---------------------------------------
+
+*gettimer(<type>{, <account id>{, "<event>"}})
+
+Returns informations on timers that were created by addtimer().
+
+valid <type> for gettimer() are:
+
+(0) TIMER_COUNT
+ Will return the total number of timers for the specified or
+ attached player. Can be filtered by <event>.
+(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 <event>.
+(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 <event>.
+
+---------------------------------------
+
*initnpctimer({ "<NPC name>" {, <Attach Flag>} } |
{ "<NPC name>" | <Attach Flag> })
*stopnpctimer({ "<NPC name>" {, <Detach Flag>} } |
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,"??"),