diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 90120713ea..5e9a7b555d 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -6395,7 +6395,7 @@ sleep and sleep2 will pause the script for the given amount of milliseconds. Awake is used to cancel a sleep. When awake is called on a NPC it will run as if the sleep timer ran out, and thus making the script continue. Sleep and sleep2 basically do the same, but the main difference is that sleep will not keep the rid, -while sleep2 does. +while sleep2 does. Also sleep2 will stop the script if there is no unit attached. Examples: sleep 10000; //pause the script for 10 seconds and ditch the RID (so no player is attached anymore) diff --git a/src/map/script.c b/src/map/script.c index 0da23e6f28..f272db1283 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -4087,10 +4087,8 @@ int run_script_timer(int tid, unsigned int tick, int id, intptr_t data) if( id != 0 && st->rid ){ struct map_session_data *sd = map_id2sd(st->rid); - // Attached player is offline or another unit type - should not happen + // Attached player is offline(logout) or another unit type(should not happen) if( !sd ){ - ShowWarning( "Script sleep timer called by an offline character or non player unit.\n" ); - script_reportsrc(st); st->rid = 0; st->state = END; // Character mismatch. Cancel execution. @@ -18451,54 +18449,73 @@ BUILDIN_FUNC(unitskillusepos) /// sleep ; BUILDIN_FUNC(sleep) { - int ticks; + // First call(by function call) + if (st->sleep.tick == 0) { + int ticks; - ticks = script_getnum(st,2); + ticks = script_getnum(st, 2); - // detach the player - script_detach_rid(st); + if (ticks <= 0) { + ShowError("buildin_sleep2: negative amount('%d') of milli seconds is not supported\n", ticks); + return SCRIPT_CMD_FAILURE; + } - if( ticks <= 0 ) - {// do nothing - } - else if( st->sleep.tick == 0 ) - {// sleep for the target amount of time + // detach the player + script_detach_rid(st); + + // sleep for the target amount of time st->state = RERUNLINE; st->sleep.tick = ticks; - } - else - {// sleep time is over + // Second call(by timer after sleeping time is over) + } else { + // Continue the script st->state = RUN; st->sleep.tick = 0; } + return SCRIPT_CMD_SUCCESS; } /// Pauses the execution of the script, keeping the unit attached -/// Returns if the unit is still attached +/// Stops the script if no unit is attached /// -/// sleep2() -> +/// sleep2() BUILDIN_FUNC(sleep2) { - int ticks; + // First call(by function call) + if (st->sleep.tick == 0) { + int ticks; - ticks = script_getnum(st,2); + ticks = script_getnum(st, 2); - if( ticks <= 0 ) - {// do nothing - script_pushint(st, (map_id2bl(st->rid)!=NULL)); - } - else if( !st->sleep.tick ) - {// sleep for the target amount of time + if (ticks <= 0) { + ShowError( "buildin_sleep2: negative amount('%d') of milli seconds is not supported\n", ticks ); + return SCRIPT_CMD_FAILURE; + } + + if (map_id2bl(st->rid) == NULL) { + ShowError( "buildin_sleep2: no unit is attached\n" ); + return SCRIPT_CMD_FAILURE; + } + + // sleep for the target amount of time st->state = RERUNLINE; st->sleep.tick = ticks; + // Second call(by timer after sleeping time is over) + } else { + // Check if the unit is still attached + // NOTE: This should never happen, since run_script_timer already checks this + if (map_id2bl(st->rid) == NULL) { + // The unit is not attached anymore - terminate the script + st->rid = 0; + st->state = END; + } else { + // The unit is still attached - continue the script + st->state = RUN; + st->sleep.tick = 0; + } } - else - {// sleep time is over - st->state = RUN; - st->sleep.tick = 0; - script_pushint(st, (map_id2bl(st->rid)!=NULL)); - } + return SCRIPT_CMD_SUCCESS; }