diff -ruNbB LOP - Copy/src/h/mud.h LOP/src/h/mud.h --- LOP - Copy/src/h/mud.h 2012-01-15 21:29:16.767400000 -0500 +++ LOP/src/h/mud.h 2012-01-27 17:34:37.720600000 -0500 @@ -100,6 +100,7 @@ typedef struct lcnv_data LCNV_DATA; typedef struct lang_data LANG_DATA; typedef struct group_data GROUP_DATA; +typedef struct mpsleep_data MPSLEEP_DATA; /* Function types. */ #define CMDF( fun ) NM void fun( CHAR_DATA *ch, char *argument ) @@ -559,7 +560,16 @@ bool fix_type[ITEM_TYPE_MAX]; }; -/* Mob program structures */ +/* Mob program structures and defines */ +/* Moved these defines here from mud_prog.c as I need them -rkb */ +#define MAX_IFS 20 /* should always be generous */ +#define IN_IF 0 +#define IN_ELSE 1 +#define DO_IF 2 +#define DO_ELSE 3 + +#define MAX_PROG_NEST 20 + struct act_prog_data { struct act_prog_data *next; @@ -586,6 +596,32 @@ bool fileprog; }; +/* Used to store sleeping mud progs. -rkb */ +typedef enum { MP_MOB, MP_ROOM, MP_OBJ } mp_types; +struct mpsleep_data +{ + MPSLEEP_DATA *next; + MPSLEEP_DATA *prev; + + int timer; /* Pulses to sleep */ + mp_types type; /* Mob, Room or Obj prog */ + ROOM_INDEX_DATA*room; /* Room when type is MP_ROOM */ + + /* mprog_driver state variables */ + int ignorelevel; + int iflevel; + bool ifstate[MAX_IFS][DO_ELSE+1]; + + /* mprog_driver arguments */ + char *com_list; + CHAR_DATA *mob; + CHAR_DATA *actor; + OBJ_DATA *obj; + void *vo; + bool single_step; +}; + + /* Per-class stuff. */ struct class_type { @@ -1370,6 +1406,7 @@ EXT_BV race_restrict; /* Races that can't wear it */ MPROG_ACT_LIST *mpact; /* mudprogs */ RESET_DATA *reset; + MPSLEEP_DATA *mpsleep; /* mpsleep */ char *name; char *short_descr; /* Short description for the object */ char *description; /* Long description for the object */ @@ -2640,6 +2677,10 @@ /*------------*/ /* Mud_prog.c */ +extern MPSLEEP_DATA *first_mpwait; /* Storing sleeping mud progs */ +extern MPSLEEP_DATA *last_mpwait; /* - */ +extern MPSLEEP_DATA *current_mpwait; /* - */ +void mpsleep_update( void ); extern struct act_prog_data *mob_act_list; extern OBJ_DATA *supermob_obj; extern CHAR_DATA *supermob; diff -ruNbB LOP - Copy/src/handler.c LOP/src/handler.c --- LOP - Copy/src/handler.c 2012-01-15 21:29:16.736200000 -0500 +++ LOP/src/handler.c 2012-01-27 17:33:05.805400000 -0500 @@ -1401,6 +1401,14 @@ obj->reset->obj = NULL; obj->reset = NULL; + if( obj->mpsleep ) + { + obj->mpsleep->obj = NULL; + obj->mpsleep->mob = NULL; + obj->mpsleep->actor = NULL; + obj->mpsleep = NULL; + } + if( obj->carried_by ) obj_from_char( obj ); if( obj->in_room ) diff -ruNbB LOP - Copy/src/mud_prog.c LOP/src/mud_prog.c --- LOP - Copy/src/mud_prog.c 2012-01-15 21:29:16.751800000 -0500 +++ LOP/src/mud_prog.c 2012-01-27 17:50:24.718600000 -0500 @@ -86,15 +86,12 @@ #define IFIGNORED 8 #define ORIGNORED 9 -/* Ifstate defines, used to create and access ifstate array - in mprog_driver. */ -#define MAX_IFS 20 /* should always be generous */ -#define IN_IF 0 -#define IN_ELSE 1 -#define DO_IF 2 -#define DO_ELSE 3 +/* Moved these to mud.h as I needed two of them for mpsleep -rkb */ -#define MAX_PROG_NEST 20 +/* Global variables to handle sleeping mud progs. */ +MPSLEEP_DATA *first_mpsleep = NULL; +MPSLEEP_DATA *last_mpsleep = NULL; +MPSLEEP_DATA *current_mpsleep = NULL; /* Mudprogram additions */ CHAR_DATA *supermob; @@ -2053,12 +2050,14 @@ */ void mprog_driver( char *com_list, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, bool single_step ) { + CHAR_DATA *rndm = NULL, *vch = NULL; + MPSLEEP_DATA *mpsleep = NULL; // char tmpcmndlst[MSL], *command_list, *cmnd; char tmpcmndlst[MSL], *command_list, cmnd[MSL]; - CHAR_DATA *rndm = NULL, *vch = NULL; - int count = 0, iflevel = 0, result, ignorelevel = 0; - bool ifstate[MAX_IFS][DO_ELSE + 1]; + char arg[MIL]; + int count = 0, count2 = 0, iflevel = 0, result, ignorelevel = 0; static int prog_nest; + bool ifstate[MAX_IFS][DO_ELSE + 1]; if( IS_AFFECTED( mob, AFF_CHARM ) ) return; @@ -2118,6 +2117,25 @@ strcpy( tmpcmndlst, com_list ); command_list = tmpcmndlst; + + /* mpsleep - Restore the environment -rkb */ + if( current_mpsleep ) + { + ignorelevel = current_mpsleep->ignorelevel; + iflevel = current_mpsleep->iflevel; + + if( single_step ) + mob->mpscriptpos = 0; + + for( count = 0; count <= MAX_IFS; count++ ) + { + for( count2 = 0; count2 < DO_ELSE; count2++ ) + ifstate[count][count2] = current_mpsleep->ifstate[count][count2]; + } + + current_mpsleep = NULL; + } + if( single_step ) { if( mob->mpscriptpos > strlen( tmpcmndlst ) ) @@ -2159,6 +2177,70 @@ return; } + /* mpsleep - Check if we should sleep -rkb */ + one_argument( cmnd, arg ); + if( !str_prefix( "mpsleep", cmnd ) ) + { + if( ( ifstate[iflevel][IN_IF] == ifstate[iflevel][DO_IF]) && ( ifstate[iflevel][IN_ELSE] == ifstate[iflevel][DO_ELSE] ) ) + { + CREATE( mpsleep, MPSLEEP_DATA, 1 ); + + /* State variables */ + mpsleep->ignorelevel = ignorelevel; + mpsleep->iflevel = iflevel; + for( count = 0; count < MAX_IFS; count++ ) + { + for( count2 = 0; count2 < DO_ELSE; count2++ ) + { + mpsleep->ifstate[count][count2] = + ifstate[count][count2]; + } + } + } + + /* Driver arguments */ + mpsleep->com_list = STRALLOC( command_list ); + mpsleep->mob = mob; + mpsleep->actor = actor; + mpsleep->obj = obj; + if( mpsleep->obj ) + mpsleep->obj->mpsleep = mpsleep; + mpsleep->vo = vo; + mpsleep->single_step = single_step; + + /* Time to sleep */ + snprintf( cmnd, sizeof( cmnd ), "%s", one_argument( cmnd, arg ) ); + if( cmnd[0] == '\0' ) + mpsleep->timer = 4; + else + mpsleep->timer = atoi( cmnd );; + + if( mpsleep->timer < 1 ) + { + progbug( "mpsleep - bad arg, using default", mob ); + mpsleep->timer = 4; + } + + /* Save type of prog, room, object or mob */ + if( mpsleep->mob->pIndexData->vnum == 3 ) + { + if( !str_prefix( "Room", mpsleep->mob->description ) ) + { + mpsleep->type = MP_ROOM; + mpsleep->room = mpsleep->mob->in_room; + } + else if( !str_prefix( "Object", mpsleep->mob->description ) ) + mpsleep->type = MP_OBJ; + } + else + mpsleep->type = MP_MOB; + + LINK( mpsleep, first_mpsleep, last_mpsleep, next, prev ); + + --prog_nest; + return; + } + /* Evaluate/execute the command, check what happened. */ result = mprog_do_command( cmnd, mob, actor, obj, vo, rndm, ( ifstate[iflevel][IN_IF] && !ifstate[iflevel][DO_IF] ) @@ -3757,3 +3839,76 @@ DISPOSE( runner ); } } + +/* Global function code and brief comments. */ +/* See if there's any mud programs waiting to be continued -rkb */ +void mpsleep_update( void ) +{ + MPSLEEP_DATA *mpsleep; + MPSLEEP_DATA *tmpMpsleep; + bool delete_it; + + mpsleep = first_mpsleep; + while( mpsleep ) + { + delete_it = false; + + if( mpsleep->mob ) + delete_it = char_died( mpsleep->mob ); + + if( mpsleep->actor && !delete_it ) + delete_it = char_died( mpsleep->actor ); + + if( !delete_it && !mpsleep->actor && !mpsleep->mob && !mpsleep->obj ) + delete_it = true; + + if( delete_it ) + { + log_string( "mpsleep_update - Deleting expired prog." ); + + tmpMpsleep = mpsleep; + mpsleep = mpsleep->next; + STRFREE( tmpMpsleep->com_list ); + UNLINK( tmpMpsleep, first_mpsleep, last_mpsleep, next, prev ); + DISPOSE( tmpMpsleep ); + + continue; + } + + mpsleep = mpsleep->next; + } + + mpsleep = first_mpsleep; + while( mpsleep ) /* Find progs to continue */ + { + if( --mpsleep->timer <= 0 ) + { + current_mpsleep = mpsleep; + + if( mpsleep->type == MP_ROOM ) + rset_supermob( mpsleep->room ); + else if( mpsleep->type == MP_OBJ ) + { + set_supermob( mpsleep->obj ); + mpsleep->obj->mpsleep = mpsleep; + } + + mprog_driver( mpsleep->com_list, mpsleep->mob, mpsleep->actor, mpsleep->obj, mpsleep->vo, mpsleep->single_step ); + + if( mpsleep->obj ) + mpsleep->obj->mpsleep = NULL; + + release_supermob(); + + tmpMpsleep = mpsleep; + mpsleep = mpsleep->next; + STRFREE( tmpMpsleep->com_list ); + UNLINK( tmpMpsleep, first_mpsleep, last_mpsleep, next, prev ); + DISPOSE( tmpMpsleep ); + + continue; + } + + mpsleep = mpsleep->next; + } +} diff -ruNbB LOP - Copy/src/update.c LOP/src/update.c --- LOP - Copy/src/update.c 2012-01-15 21:29:16.767400000 -0500 +++ LOP/src/update.c 2012-01-27 17:20:53.822200000 -0500 @@ -1653,6 +1653,7 @@ trivia_update( ); } + mpsleep_update( ); tele_update( ); aggr_update( ); obj_act_update( );