rm4/
rm4/boards/
rm4/clans/
rm4/councils/
rm4/deity/
rm4/gods/
rm4/guilds/
rm4/player/a/
rm4/src/utils/
rm4/watch/
rm4/web/public_html/
To install MOBprograms.
Please start by making a copy of all your source files to a backup place 
just in case somthing weird happens. (I dont want you to hate me forever)

0. Edit Makefile
----------------
	Add in mob_commands.o and mob_prog.o to the list of O_FILES
	(any order is fine here)

	Also, you may need to add the CFLAG -DDUNNO_STRSTR.
	If your system complains about not knowing this, then put it in.

1. Deal with merc.h
-------------------
        There are six changes to make here.
        a. Add the following lines to the end of the Structure types section

            typedef struct  mob_prog_data           MPROG_DATA;
            typedef struct  mob_prog_act_list       MPROG_ACT_LIST;

        b. Add the following lines in the mob_index_data structure:

            MPROG_DATA *        mobprogs;
	    int			progtypes;

        c. Add the following lines in the char_data structure:

	    MPROG_ACT_LIST *    mpact;
	    int                 mpactnum;

        d. Add the following code block wherever you desire:

struct  mob_prog_act_list
{
    MPROG_ACT_LIST * next;
    char *           buf;
    CHAR_DATA *      ch;
    OBJ_DATA *       obj;
    void *           vo;
};

struct  mob_prog_data
{
    MPROG_DATA *next;
    int         type;
    char *      arglist;
    char *      comlist;
};

bool    MOBtrigger;

#define ERROR_PROG        -1
#define IN_FILE_PROG       0
#define ACT_PROG           1
#define SPEECH_PROG        2
#define RAND_PROG          4
#define FIGHT_PROG         8
#define DEATH_PROG        16
#define HITPRCNT_PROG     32
#define ENTRY_PROG        64
#define GREET_PROG       128
#define ALL_GREET_PROG   256
#define GIVE_PROG        512
#define BRIBE_PROG      1024

	e. Add this to the PLAYER_DIR, NULL_FILE #defines

#define MOB_DIR		"MOBProgs/"	/* MOBProg files		*/

	   or if you are using MSDOS or Macintosh, add this

#define MOB_DIR		""		/* MOBProg files		*/

        f. Add in the global prototypes for the mob_progs

/* act_wiz.c */
ROOM_INDEX_DATA *	find_location	args( ( CHAR_DATA *ch, char *arg ) );

/* fight.c */
void			death_cry	args( ( CHAR_DATA *ch ) );

/* mob_prog.c */
#ifdef DUNNO_STRSTR
char *  strstr                  args ( (const char *s1, const char *s2 ) );
#endif

void    mprog_wordlist_check    args ( ( char * arg, CHAR_DATA *mob,
                			CHAR_DATA* actor, OBJ_DATA* object,
					void* vo, int type ) );
void    mprog_percent_check     args ( ( CHAR_DATA *mob, CHAR_DATA* actor,
					OBJ_DATA* object, void* vo,
					int type ) );
void    mprog_act_trigger       args ( ( char* buf, CHAR_DATA* mob,
		                        CHAR_DATA* ch, OBJ_DATA* obj,
					void* vo ) );
void    mprog_bribe_trigger     args ( ( CHAR_DATA* mob, CHAR_DATA* ch,
		                        int amount ) );
void    mprog_entry_trigger     args ( ( CHAR_DATA* mob ) );
void    mprog_give_trigger      args ( ( CHAR_DATA* mob, CHAR_DATA* ch,
                		        OBJ_DATA* obj ) );
void    mprog_greet_trigger     args ( ( CHAR_DATA* mob ) );
void    mprog_fight_trigger     args ( ( CHAR_DATA* mob, CHAR_DATA* ch ) );
void    mprog_hitprcnt_trigger  args ( ( CHAR_DATA* mob, CHAR_DATA* ch ) );
void    mprog_death_trigger     args ( ( CHAR_DATA* mob ) );
void    mprog_random_trigger    args ( ( CHAR_DATA* mob ) );
void    mprog_speech_trigger    args ( ( char* txt, CHAR_DATA* mob ) );

2. Make adjustments to db.c
---------------------------
	There are 4 changes in here.

        a. import the file: mprog_add_to_db.c
	   (the prototypes will need to be moved to the beginning
	   of the db.c file, otherwise this can go wherever) 

	b. in boot_db, add the following line between the MOBILES and the
	   OBJECTS lines which look mighty similar:

           else if ( !str_cmp( word, "MOBPROGS" ) ) load_mobprogs( fpArea );

	c. in load_mobiles, add the following lines between the
           letter != 'S' and iHash = vnum... sections. (note that the line
	   goes after the closing brace for the if statement:

        letter = fread_letter( fp );
        if ( letter == '>' )
        {
          ungetc( letter, fp );
          mprog_read_programs( fp, pMobIndex );
        }
        else ungetc( letter,fp );

	d. In "Fix up exits" section right after the load_notes( )
	   in boot_db(..)

	Initialize MOBtrigger by adding MOBtrigger = TRUE;

3. Adjust your files a little
-----------------------------
     	a. Do this to your comm.c in void act( ... )

	replace

            write_to_buffer ( to->desc, buf, point - buf );

	at the end of the routine with

            if (to->desc)
	       write_to_buffer( to->desc, buf, point - buf );
	    if (MOBtrigger)
	       mprog_act_trigger( buf, to, ch, obj1, vch );

	and right before the return add,

            MOBtrigger = TRUE;

     	b. Where you want the player to NOT trigger MOBprograms add a
		MOBtrigger = FALSE;
	   before the appropriate act(..) call in various *.c files.

4. Stick in the triggers
------------------------

	In update.c in mobile_update just before the Scavenge section
	(after the busy/sleeping check) add the following line:

           if ( ch->in_room->area->nplayer > 0 ) mprog_random_trigger( ch );

        Also, in update.c in aggr_update just after: wch_next = wch->next;
        add the following code chunk to process the act triggers. These are
	performed here to allow everyone in the room to see what just
	happenened before the mobile reacts - call them mob-reflexes:

        if ( IS_NPC( wch ) && wch->mpactnum > 0
	    && wch->in_room->area->nplayer > 0 )
        {
            MPROG_ACT_LIST * tmp_act, *tmp2_act;
            for ( tmp_act = wch->mpact; tmp_act != NULL;
		 tmp_act = tmp_act->next )
	    {
                 mprog_wordlist_check( tmp_act->buf,wch, tmp_act->ch,
                               	      tmp_act->obj, tmp_act->vo, ACT_PROG );
                 free_string( tmp_act->buf );
            }
            for ( tmp_act = wch->mpact; tmp_act != NULL; tmp_act = tmp2_act )
	    {
                 tmp2_act = tmp_act->next;
                 free_mem( tmp_act, sizeof( MPROG_ACT_LIST ) );
            }
            wch->mpactnum = 0;
            wch->mpact    = NULL;
        }

        In act_comm.c in do_say just before the final return add:

           mprog_speech_trigger( argument, ch );

        In act_move.c in move_char just before the final return add:

           mprog_entry_trigger( ch );
           mprog_greet_trigger( ch );

        In act_obj.c in do_give just before the final return add:

           mprog_give_trigger( victim, ch, obj );

        and earlier in do_give just after: send_to_char( "OK.\n\r", ch );

           mprog_bribe_trigger( victim, ch, amount );

        In fight.c in violence_update just before the Fun for the whole
	family, add

           mprog_hitprcnt_trigger( ch, victim );
           mprog_fight_trigger( ch, victim );

	and in raw_kill replace death_cry(); with

           mprog_death_trigger( victim );

5. MobCommands
--------------

	If you so desire, use the normal methods described in the merc docs
        to add the commands. place the following into interp.c in cmd_table:

    /*
     * MOBprogram commands.
     */
    { "mpstat",         do_mpstat,      POS_DEAD,       38,  LOG_NORMAL },
    { "mpasound",       do_mpasound,    POS_DEAD,        0,  LOG_NORMAL },
    { "mpjunk",         do_mpjunk,      POS_DEAD,        0,  LOG_NORMAL },
    { "mpecho",         do_mpecho,      POS_DEAD,        0,  LOG_NORMAL },
    { "mpechoat",       do_mpechoat,    POS_DEAD,        0,  LOG_NORMAL },
    { "mpechoaround",   do_mpechoaround,POS_DEAD,        0,  LOG_NORMAL },
    { "mpkill",         do_mpkill      ,POS_DEAD,        0,  LOG_NORMAL },
    { "mpmload",        do_mpmload     ,POS_DEAD,        0,  LOG_NORMAL },
    { "mpoload",        do_mpoload     ,POS_DEAD,        0,  LOG_NORMAL },
    { "mppurge",        do_mppurge     ,POS_DEAD,        0,  LOG_NORMAL },
    { "mpgoto",         do_mpgoto      ,POS_DEAD,        0,  LOG_NORMAL },
    { "mpat",           do_mpat        ,POS_DEAD,        0,  LOG_NORMAL },
    { "mptransfer",     do_mptransfer  ,POS_DEAD,        0,  LOG_NORMAL },
    { "mpforce",        do_mpforce     ,POS_DEAD,        0,  LOG_NORMAL },
 
	Place the following into merc.h with all the other DO_FUN's:

DECLARE_DO_FUN( do_mpasound     );
DECLARE_DO_FUN( do_mpat         );
DECLARE_DO_FUN( do_mpecho       );
DECLARE_DO_FUN( do_mpechoaround );
DECLARE_DO_FUN( do_mpechoat     );
DECLARE_DO_FUN( do_mpforce      );
DECLARE_DO_FUN( do_mpgoto       );
DECLARE_DO_FUN( do_mpjunk       );
DECLARE_DO_FUN( do_mpkill       );
DECLARE_DO_FUN( do_mpmload      );
DECLARE_DO_FUN( do_mpoload      );
DECLARE_DO_FUN( do_mppurge      );
DECLARE_DO_FUN( do_mpstat       );
DECLARE_DO_FUN( do_mptransfer   );

	Sorry there are no accompanying help files here, but they are fairly
	basic and obvious commands. Most of the code is stripped from the
	act_wiz stuff itself.

6.  A few bug fixes.
--------------------

	In update.c in mobile_update(...), along with the MOBprogram
	random trigger:

	if ( ch->in_room->area->nplayer > 0 )
	    mprog_random_trigger( ch );

	should be:

	/* MOBprogram random trigger */
	if ( ch->in_room->area->nplayer > 0 )
	{
	    mprog_random_trigger( ch );
						/* If ch dies or changes
						position due to it's random
						trigger, continue - Kahn */
	    if ( ch->position < POS_STANDING )
	        continue;
	}

	Also in mobile_update after move_char(...) in the /* Wander */
	block right before the /* Flee */ block it should be:

	..
	..
	&&   !IS_SET(pexit->to_room->room_flags, ROOM_NO_MOB)
	&& ( !IS_SET(ch->act, ACT_STAY_AREA)
	||   pexit->to_room->area == ch->in_room->area ) )
	{
	    move_char( ch, door );
						/* If ch changes position due
						to it's or someother mob's
						movement via MOBProgs,
						continue - Kahn */
	    if ( ch->position < POS_STANDING )
	        continue;
	}

	This is to prevent the server from referencing a bad pointer
to ch.  This bug became apparent when a MOBProgram caused a mob to die
and then continued with mobile_update by fleeing with a bad ch pointer.

7. Give it a whirl
------------------

"	Try making it and hope it all works for the best.  You may get some
	warnings from the mob_prog.c file and these are ok to ignore.
	I also got a bizzare prototype error on one platform I tested with.
	It was in mprog_translate, and I had to comment out the prototype
	before it would compile. Haven't any idea why that happened.
" - N'Atas-Ha

	Also, you may want to do the following little extras...
	change the calls to act in do_say, do_yell, do_shout, do_emote and
	also the ones in do_give to not trigger (using MOBtrigger = FALSE;).
  	This means that	these acts cannot trigger a mobile.  The do_emote is
	particularly critical, since otherwise a player can emote any trigger
	they wish. You may find other act calls which you desire to make
	"safe".

	You may also consider giving MOBProgged mobs the ability to utilize
	all the commands available.  To do this just make the necessary
	changes to interpret(...) in interp.c.  MERC 2.2 will have this
	feature with most of the necessary security loopholes closed.

Below here is the mobinfo help screen which we would sorta like you to include.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-1 MOBINFO~
.             Our Mobiles have been infused with the breath of a
             shy faeyrie to give them a slightly warmer nature.
             Perhaps you have noticed this already.  If not, do
             take a moment to ask a mobile to tea.  The code is
             written by J Murphy, N'Atas-Ha of ThePrincedom and
             based on a concept created on Worlds of Carnage by
             Aaron Buhr. questions/comments to murph@cs.cmu.edu
	     A little rewriting of the code/DOC/INSTALL done by
	     Kahn of MERC Industries and tested extensively on
             Marble Mud (marble.bu.edu 4000).
~
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++