This is a modified sleep code based off of mpsleep and an updated snippet by Jason De Leon. This version not only does mprogs, but all progs and I even made the timer go by seconds, not pulses, so pause 4 literally is 4 seconds of waiting. -Bojack Example: obj echo The fountain's water turns {Ggreen{x because of $n's presence. pause 4 obj echo The water recirculates and becomes {Bblue{x again. OR obj echo The fountain's water turns {Ggreen{x because of $n's presence. wait 4 obj echo The water recirculates and becomes {Bblue{x again. --------Installation---------- ---merc.h--- Find: /* * Structure types. */ Add somewhere in there: typedef struct prog_pause_data PROG_PAUSE_DATA; Find: /* * Prog types */ Add after #define PRG_RPROG 2: /* Moved from mob_prog.c for pause code */ #define MAX_NESTED_LEVEL 12 /* Maximum nested if-else-endif's (stack size) */ #define BEGIN_BLOCK 0 /* Flag: Begin of if-else-endif block */ #define IN_BLOCK -1 /* Flag: Executable statements */ #define END_BLOCK -2 /* Flag: End of if-else-endif block */ #define MAX_CALL_LEVEL 12 /* Maximum nested calls */ --Note: We use 12 max level calls, set it to whatever you like Find: struct prog_code { sh_int vnum; char * code; PROG_CODE * next; }; Add after: //For pausing mprogs/oprogs/rprogs struct prog_pause_data { PROG_PAUSE_DATA * next; PROG_PAUSE_DATA * prev; CHAR_DATA * player; CHAR_DATA * actor; OBJ_DATA * obj; ROOM_INDEX_DATA * room; char * code; sh_int vnum; int pause; const void * arg1; const void * arg2; int lines; int state[MAX_NESTED_LEVEL]; bool cond[MAX_NESTED_LEVEL]; int level; bool set; bool valid; }; Find: void program_flow args( ( After: const void *arg2 ) ); Add: , PROG_PAUSE_DATA *tmp ) ); So it looks like this: const void *arg2, PROG_PAUSE_DATA *tmp ) ); At the bottom after: /* * Global variables */ Add this in somewhere: extern PROG_PAUSE_DATA * first_pause; extern PROG_PAUSE_DATA * last_pause; ---mob_cmds.c--- In this file change every: extern void program_flow( to this: extern void program_flow( sh_int, char *, CHAR_DATA *, OBJ_DATA *, ROOM_INDEX_DATA *, CHAR_DATA *, const void *, const void *, PROG_PAUSE_DATA * ); And for every: program_flow( prg->vnum call, add a NULL after: (void *)obj2 An EXAMPLE looks like this: program_flow( prg->vnum, prg->code, ch, NULL, NULL, vch, (void *)obj1, (void *)obj2, NULL ); --Note: DO not copy and paste that ^, it is just an example! ---mob_prog.c--- At the top with the includes, add at the end of those: #include "recycle.h" //For pause data After: extern int flag_lookup Add: PROG_PAUSE_DATA *first_pause = NULL; PROG_PAUSE_DATA *last_pause = NULL; Find: void program_flow( Add after: const void *arg2 , PROG_PAUSE_DATA *tmp ) So void program_flow should look like this: void program_flow( sh_int pvnum, /* For diagnostic purposes */ char *source, /* the actual MOBprog code */ CHAR_DATA *mob, OBJ_DATA *obj, ROOM_INDEX_DATA *room, CHAR_DATA *ch, const void *arg1, const void *arg2, PROG_PAUSE_DATA *tmp ) Add after: sh_int mvnum = 0, ovnum = 0, rvnum = 0; PROG_PAUSE_DATA *pause; int count = 0; Find: if( ++call_level > MAX_CALL_LEVEL ) Change To: if( !tmp && ++call_level > MAX_CALL_LEVEL ) Find: /* * Reset "stack" */ Change To: if ( tmp && tmp->set == TRUE ) { for ( level = 0; level < MAX_NESTED_LEVEL; level++ ) { state[level] = tmp->state[level]; cond[level] = tmp->cond[level]; } level = tmp->level; } else { for ( level = 0; level < MAX_NESTED_LEVEL; level++ ) { state[level] = IN_BLOCK; cond[level] = TRUE; } level = 0; } Find: /* * Match control words */ Right after that, add this: //If paused, find lines and start there if ( ( tmp ) && count++ < tmp->lines ) continue; Then above: if (!str_cmp( control, "if" ) ) Add this: count++; --Note: The count has to be after the tmp check, otherwise the lines get thrown off. Find: else if ( cond[level] == TRUE && ( !str_cmp( control, "break" ) || !str_cmp( control, "end" ) ) ) Add after: return; } else if ( !str_cmp( control, "pause" ) || !str_cmp( control, "wait" ) ) { //First check to see if its in an if statement if ( level && cond[level-1] == FALSE ) continue; //Secondly check to see if this pause is the same one returned if ( ( tmp ) && count == tmp->lines ) continue; int amount, roll; line = one_argument( line, control ); //Check first if (!is_number( control ) || (amount = atoi( control )) <= 0) amount = 1; //Get amount else { amount = atoi( control ); } //Save information pause = new_pause(); pause->player = ch; if ( mob ) pause->actor = mob; else pause->actor = NULL; if ( obj ) pause->obj = obj; else pause->obj = NULL; if ( room ) pause->room = room; else pause->room = NULL; pause->pause = amount; pause->vnum = pvnum; pause->code = source; pause->lines = count; pause->arg1 = arg1; pause->arg2 = arg2; for (roll = 0; roll < MAX_NESTED_LEVEL; roll++) { pause->state[roll] = state[roll]; pause->cond[roll] = cond[roll]; } pause->level = level; pause->set = TRUE; pause->next = first_pause; if (first_pause) first_pause->prev = pause; first_pause = pause; return; //Stop the program here } --Now before doing the below changes, first go through this whole file looking for program_flow () calls and add at the end after arg2 this: , NULL ) An EXAMPLE would look like this: program_flow( prg->vnum, prg->code, mob, NULL, NULL, ch, arg1, arg2 ); program_flow( prg->vnum, prg->code, mob, NULL, NULL, ch, arg1, arg2, NULL ); Once that is all complete, start the below changes. Find: void p_act_trigger( Add after PROG_LIST *prg; PROG_PAUSE_DATA *pause; In the same function, find: if ( mob ) Right before program_flow( prg->vnum, prg->code, mob, NULL .... Add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->player == ch && pause->vnum == prg->vnum) return; Do the same for: else if ( obj ) and: else if ( room ) Find: bool p_percent_trigger( Add after PROG_LIST *prg; PROG_PAUSE_DATA *pause; In the same function, find: if ( mob ) Right before program_flow( prg->vnum, prg->code, mob, NULL .... Add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->actor == mob && pause->vnum == prg->vnum) return ( TRUE ); In else if ( obj ) before program_flow( prg->vnum, prg->code ... Add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->obj == obj && pause->vnum == prg->vnum) return ( TRUE ); In else if ( room ) before program_flow( prg->vnum, prg->code ... Add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->room == room && pause->vnum == prg->vnum) return ( TRUE ); Reason we aren't using if(pause->player == ch for the above codes is p_percent_trigger doesnt have to have a person near to have the trigger go off. Using random as a trigger is one example. Find: void p_bribe_trigger( Add after PROG_LIST *prg; PROG_PAUSE_DATA *pause; Right before program_flow( prg->vnum, prg->code, mob, NULL ... Add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->player == ch && pause->vnum == prg->vnum) return; Find: bool p_exit_trigger( Add after PROG_LIST *prg; PROG_PAUSE_DATA *pause; In this function BEFORE ALL program_flow calls, add this: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->player == ch && pause->vnum == prg->vnum) return TRUE; Find: void p_give_trigger( Add after PROG_LIST *prg; PROG_PAUSE_DATA *pause; In if ( mob ) before both program_flow calls, add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->player == ch && pause->vnum == prg->vnum) return; In else if ( obj ) before program_flow, add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->obj == obj && pause->vnum == prg->vnum) return; In else if ( room ) before both program_flow calls, add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->room == room && pause->vnum == prg->vnum) return; Find: void p_hprct_trigger Before the program_flow call, add: for(pause = first_pause; pause != NULL; pause = pause->next) if(pause->player == ch && pause->vnum == prg->vnum) return; ---recycle.c--- At the bottom of this file, add: PROG_PAUSE_DATA *pause_free; PROG_PAUSE_DATA *new_pause( void ) { static PROG_PAUSE_DATA pause_zero; PROG_PAUSE_DATA *tmp; int count; if (pause_free == NULL) tmp = alloc_perm(sizeof(*tmp)); else { tmp = pause_free; pause_free = pause_free->next; } *tmp = pause_zero; tmp->room = NULL; tmp->obj = NULL; tmp->actor = NULL; tmp->player = NULL; tmp->pause = 0; tmp->vnum = 0; tmp->code = str_dup(""); tmp->arg1 = NULL; tmp->arg2 = NULL; tmp->lines = 0; for (count = 0; count < MAX_NESTED_LEVEL; count++) { tmp->state[count] = 0; tmp->cond[count] = FALSE; } tmp->level = 0; tmp->set = FALSE; VALIDATE (tmp); return tmp; } void free_pause( PROG_PAUSE_DATA *tmp ) { if (!IS_VALID(tmp)) return; INVALIDATE (tmp); tmp->room = NULL; tmp->obj = NULL; tmp->actor = NULL; tmp->arg1 = NULL; tmp->arg2 = NULL; free_string(tmp->code); tmp->next = pause_free; pause_free = tmp; } ---recycle.h--- Add at the bottom of this file: PROG_PAUSE_DATA *new_pause args( ( void ) ); void free_pause args( ( PROG_PAUSE_DATA * ) ); ---update.c--- Add with the Local functions. void prog_update args ( ( void ) ); Find: void update_handler (void) Add before that and the int pulse_backup (if its there): //See if any progs need to continue void prog_update( void ) { PROG_PAUSE_DATA *tmp, *tmp_next; for (tmp = first_pause; tmp != NULL; tmp = tmp_next) { tmp_next = tmp->next; if (tmp->actor == NULL && tmp->obj == NULL && tmp->room == NULL) { //Delete pause data logstr (LOG_GAME, "Prog update: Found null progs, deleting.", 0); if (tmp->prev) tmp->prev->next = tmp->next; if (tmp->next) tmp->next->prev = tmp->prev; if (tmp == first_pause && (tmp->next == NULL || tmp->prev == NULL) ) first_pause = tmp->next; free_pause( tmp ); continue; } //Takes away 1 sec and checks it if (--tmp->pause <= 0) { //Continue prog if (tmp->vnum > 0) program_flow( tmp->vnum, tmp->code, tmp->actor, tmp->obj, tmp->room, tmp->player, tmp->arg1, tmp->arg2, tmp ); //Delete pause data if (tmp->prev) tmp->prev->next = tmp->next; if (tmp->next) tmp->next->prev = tmp->prev; if (tmp == first_pause && (tmp->next == NULL || tmp->prev == NULL) ) first_pause = tmp->next; free_pause( tmp ); } } return; } In: void update_handler (void) Add with the static int's: static int pulse_progs = 0; Before: aggr_update (); Add: if (--pulse_progs <= 0) { pulse_progs = PULSE_SECOND; prog_update(); } --This above sets every call to prog update to an actual second instead of having it each pulse. 4 pulses = 1 second PULSE_SECOND should be defined in merc.h, if it is not then change: pulse_progs = PULSE_SECOND; to: pulse_progs = 4; Thats it for the installation, just do a make/copyover and you should be set. Enjoy!