diff -ur src/Makefile new/Makefile
--- src/Makefile	Sat May 23 21:23:45 1998
+++ new/Makefile	Thu Mar 16 00:23:35 2000
@@ -1,14 +1,16 @@
 CC      = gcc
-PROF    = -O -g
+PROF    = -O -ggdb
 NOCRYPT =
-C_FLAGS =  -Wall $(PROF) $(NOCRYPT)
-L_FLAGS =  $(PROF)
+C_FLAGS =  -Wall $(PROF) $(NOCRYPT) -DFIRST_BOOT
+L_FLAGS =  $(PROF) -lcrypt
 
 O_FILES = act_comm.o act_enter.o act_info.o act_move.o act_obj.o act_wiz.o \
           alias.o ban.o comm.o const.o db.o db2.o effects.o fight.o flags.o \
 	  handler.o healer.o interp.o note.o lookup.o magic.o magic2.o \
 	  music.o recycle.o save.o scan.o skills.o special.o tables.o \
-	  update.o
+ 	  update.o mob_cmds.o mob_prog.o olc.o olc_act.o olc_save.o bit.o \
+	  mem.o string.o pedit.o hedit.o cmdedit.o raedit.o skedit.o \
+	  sedit.o gedit.o tablesave.o screen.o
 
 rom: $(O_FILES)
 	rm -f rom
@@ -16,3 +18,6 @@
 
 .c.o: merc.h
 	$(CC) -c $(C_FLAGS) $<
+
+clean:
+	rm *.o
diff -ur src/Makefile.linux new/Makefile.linux
--- src/Makefile.linux	Mon May 25 07:24:59 1998
+++ new/Makefile.linux	Wed Mar 15 22:57:16 2000
@@ -1,7 +1,7 @@
 CC      = gcc
 PROF    = -O -g
 NOCRYPT =
-C_FLAGS =  -Wall $(PROF) $(NOCRYPT)
+C_FLAGS =  -Wall $(PROF) $(NOCRYPT) -DFIRST_BOOT
 L_FLAGS =  $(PROF)
 LIBS	= -lcrypt
 
@@ -9,7 +9,9 @@
           alias.o ban.o comm.o const.o db.o db2.o effects.o fight.o flags.o \
 	  handler.o healer.o interp.o note.o lookup.o magic.o magic2.o \
 	  music.o recycle.o save.o scan.o skills.o special.o tables.o \
-	  update.o
+ 	  update.o mob_cmds.o mob_prog.o olc.o olc_act.o olc_save.o bit.o \
+	  mem.o string.o pedit.o hedit.o cmdedit.o raedit.o skedit.o \
+	  sedit.o gedit.o tablesave.o screen.o
 
 rom: $(O_FILES)
 	rm -f rom
diff -ur src/Makefile.normal new/Makefile.normal
--- src/Makefile.normal	Tue Apr 14 02:52:21 1998
+++ new/Makefile.normal	Wed Mar 15 22:57:16 2000
@@ -1,14 +1,16 @@
 CC      = gcc
 PROF    = -O -g
 NOCRYPT =
-C_FLAGS =  -Wall $(PROF) $(NOCRYPT)
+C_FLAGS =  -Wall $(PROF) $(NOCRYPT) -DFIRST_BOOT
 L_FLAGS =  $(PROF)
 
 O_FILES = act_comm.o act_enter.o act_info.o act_move.o act_obj.o act_wiz.o \
           alias.o ban.o comm.o const.o db.o db2.o effects.o fight.o flags.o \
 	  handler.o healer.o interp.o note.o lookup.o magic.o magic2.o \
 	  music.o recycle.o save.o scan.o skills.o special.o tables.o \
-	  update.o
+ 	  update.o mob_cmds.o mob_prog.o olc.o olc_act.o olc_save.o bit.o \
+	  mem.o string.o pedit.o hedit.o cmdedit.o raedit.o skedit.o \
+	  sedit.o gedit.o tablesave.o screen.o
 
 rom: $(O_FILES)
 	rm -f rom
diff -ur src/Makefile.solaris new/Makefile.solaris
--- src/Makefile.solaris	Tue Apr 14 03:36:40 1998
+++ new/Makefile.solaris	Wed Mar 15 22:57:16 2000
@@ -1,7 +1,7 @@
 CC      = gcc
 PROF    = -O -g
 NOCRYPT =
-C_FLAGS = -Wall $(PROF) $(NOCRYPT)
+C_FLAGS = -Wall $(PROF) $(NOCRYPT) -DFIRST_BOOT
 L_FLAGS = $(PROF)
 LIBS    = -lsocket -lresolv -lnsl
 
@@ -9,7 +9,9 @@
           alias.o ban.o comm.o const.o db.o db2.o effects.o fight.o flags.o \
 	  handler.o healer.o interp.o note.o lookup.o magic.o magic2.o \
 	  music.o recycle.o save.o scan.o skills.o special.o tables.o \
-	  update.o
+ 	  update.o mob_cmds.o mob_prog.o olc.o olc_act.o olc_save.o bit.o \
+	  mem.o string.o pedit.o hedit.o cmdedit.o raedit.o skedit.o \
+	  sedit.o gedit.o tablesave.o screen.o
 
 rom: $(O_FILES)
 	rm -f rom
diff -ur src/act_comm.c new/act_comm.c
--- src/act_comm.c	Wed May 27 23:23:48 1998
+++ new/act_comm.c	Wed Mar 15 22:57:16 2000
@@ -39,6 +39,8 @@
 #include "interp.h"
 #include "recycle.h"
 #include "tables.h"
+#include "vt.h"
+#include "screen.h"
 
 /* RT code to delete yourself */
 
@@ -753,6 +755,18 @@
 
     act( "$n says '$T'", ch, NULL, argument, TO_ROOM );
     act( "You say '$T'", ch, NULL, argument, TO_CHAR );
+
+    if ( !IS_NPC(ch) )
+    {
+	CHAR_DATA *mob, *mob_next;
+	for ( mob = ch->in_room->people; mob != NULL; mob = mob_next )
+	{
+	    mob_next = mob->next_in_room;
+	    if ( IS_NPC(mob) && HAS_TRIGGER( mob, TRIG_SPEECH )
+	    &&   mob->position == mob->pIndexData->default_pos )
+		mp_act_trigger( argument, mob, ch, NULL, NULL, TRIG_SPEECH );
+	}
+    }
     return;
 }
 
@@ -893,6 +907,9 @@
     act_new("$n tells you '$t'",ch,argument,victim,TO_VICT,POS_DEAD);
     victim->reply	= ch;
 
+    if ( !IS_NPC(ch) && IS_NPC(victim) && HAS_TRIGGER(victim,TRIG_SPEECH) )
+	mp_act_trigger( argument, victim, ch, NULL, NULL, TRIG_SPEECH );
+
     return;
 }
 
@@ -1018,8 +1035,10 @@
         return;
     }
  
+    MOBtrigger = FALSE;
     act( "$n $T", ch, NULL, argument, TO_ROOM );
     act( "$n $T", ch, NULL, argument, TO_CHAR );
+    MOBtrigger = TRUE;
     return;
 }
 
@@ -1052,7 +1071,9 @@
 
 	if ((letter = strstr(argument,vch->name)) == NULL)
 	{
+	    MOBtrigger = FALSE;
 	    act("$N $t",vch,argument,ch,TO_CHAR);
+	    MOBtrigger = TRUE;
 	    continue;
 	}
 
@@ -1102,7 +1123,9 @@
 	    name = vch->name;
 	}
 
+	MOBtrigger = FALSE;
 	act("$N $t",vch,temp,ch,TO_CHAR);
+	MOBtrigger = TRUE;
     }
 	
     return;
@@ -1619,7 +1642,7 @@
     argument = one_argument( argument, arg );
     one_argument(argument,arg2);
 
-    if (!str_cmp(arg2,"delete"))
+    if (!str_cmp(arg2,"delete") || !str_cmp(arg2,"mob"))
     {
         send_to_char("That will NOT be done.\n\r",ch);
         return;
@@ -1947,3 +1970,26 @@
     if ( bch->leader != NULL ) bch = bch->leader;
     return ach == bch;
 }
+
+void do_clear(CHAR_DATA *ch, char *argument)
+{
+	if ( !str_cmp( argument, "reset" ) )
+//		send_to_char(VT_SETWIN_CLEAR VT_HOMECLR, ch);
+		send_to_char(VT_CLENSEQ, ch);
+	else
+		send_to_char(VT_CLEAR_SCREEN, ch);
+
+	if (ch->desc && ch->desc->screenmap)
+		InitScreenMap(ch->desc);
+
+	return;
+}
+
+void do_olcx(CHAR_DATA *ch, char *argument)
+{
+	TOGGLE_BIT(ch->comm, COMM_OLCX);
+	if (IS_SET(ch->comm, COMM_OLCX))
+		send_to_char("Activated extensions VT100/OLC.\n\r", ch );
+	else
+		send_to_char("Dectivated extensions VT100/OLC\n\r", ch );
+}
diff -ur src/act_enter.c new/act_enter.c
--- src/act_enter.c	Thu May 28 00:37:33 1998
+++ new/act_enter.c	Wed Mar 15 22:57:16 2000
@@ -206,6 +206,16 @@
 	    }
 	    extract_obj(portal);
 	}
+
+	/* 
+	 * If someone is following the char, these triggers get activated
+	 * for the followers before the char, but it's safer this way...
+	 */
+	if ( IS_NPC( ch ) && HAS_TRIGGER( ch, TRIG_ENTRY ) )
+	    mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_ENTRY );
+	if ( !IS_NPC( ch ) )
+	    mp_greet_trigger( ch );
+
 	return;
     }
 
diff -ur src/act_info.c new/act_info.c
--- src/act_info.c	Thu May 28 00:37:17 1998
+++ new/act_info.c	Wed Mar 15 22:57:16 2000
@@ -591,7 +591,7 @@
      
     col = 0;
    
-    for (iSocial = 0; social_table[iSocial].name[0] != '\0'; iSocial++)
+    for (iSocial = 0; !IS_NULLSTR(social_table[iSocial].name); iSocial++)
     {
 	sprintf(buf,"%-12s",social_table[iSocial].name);
 	send_to_char(buf,ch);
@@ -1027,7 +1027,8 @@
 	/* 'look' or 'look auto' */
 	send_to_char( ch->in_room->name, ch );
 
-	if (IS_IMMORTAL(ch) && (IS_NPC(ch) || IS_SET(ch->act,PLR_HOLYLIGHT)))
+	if ( (IS_IMMORTAL(ch) && (IS_NPC(ch) || IS_SET(ch->act,PLR_HOLYLIGHT)))
+	||   IS_BUILDER(ch, ch->in_room->area) )
 	{
 	    sprintf(buf," [Room %d]",ch->in_room->vnum);
 	    send_to_char(buf,ch);
@@ -1861,8 +1862,12 @@
 	    /* a little formatting */
 	    sprintf(buf, "[%2d %6s %s] %s%s%s%s%s%s%s%s\n\r",
 		wch->level,
+#if defined(FIRST_BOOT)
 		wch->race < MAX_PC_RACE ? pc_race_table[wch->race].who_name
 					: "     ",
+#else
+		race_table[wch->race].who_name,
+#endif
 		class,
 	     wch->incog_level >= LEVEL_HERO ? "(Incog) ": "",
  	     wch->invis_level >= LEVEL_HERO ? "(Wizi) " : "",
@@ -2058,8 +2063,12 @@
 	 */
 	sprintf( buf, "[%2d %6s %s] %s%s%s%s%s%s%s%s\n\r",
 	    wch->level,
+#if defined(FIRST_BOOT)
 	    wch->race < MAX_PC_RACE ? pc_race_table[wch->race].who_name 
 				    : "     ",
+#else
+	    race_table[wch->race].who_name,
+#endif
 	    class,
 	    wch->incog_level >= LEVEL_HERO ? "(Incog) " : "",
 	    wch->invis_level >= LEVEL_HERO ? "(Wizi) " : "",
diff -ur src/act_move.c new/act_move.c
--- src/act_move.c	Thu May 28 00:40:32 1998
+++ new/act_move.c	Wed Mar 15 22:57:16 2000
@@ -76,6 +76,12 @@
 	return;
     }
 
+    /*
+     * Exit trigger, if activated, bail out. Only PCs are triggered.
+     */
+    if ( !IS_NPC(ch) && mp_exit_trigger( ch, door ) )
+	return;
+
     in_room = ch->in_room;
     if ( ( pexit   = in_room->exit[door] ) == NULL
     ||   ( to_room = pexit->u1.to_room   ) == NULL 
@@ -231,6 +237,15 @@
 	}
     }
 
+    /* 
+     * If someone is following the char, these triggers get activated
+     * for the followers before the char, but it's safer this way...
+     */
+    if ( IS_NPC( ch ) && HAS_TRIGGER( ch, TRIG_ENTRY ) )
+	mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_ENTRY );
+    if ( !IS_NPC( ch ) )
+    	mp_greet_trigger( ch );
+
     return;
 }
 
diff -ur src/act_obj.c new/act_obj.c
--- src/act_obj.c	Thu May 28 00:11:12 1998
+++ new/act_obj.c	Wed Mar 15 22:57:16 2000
@@ -720,6 +720,12 @@
 	sprintf(buf,"You give $N %d %s.",amount, silver ? "silver" : "gold");
 	act( buf, ch, NULL, victim, TO_CHAR    );
 
+	/*
+	 * Bribe trigger
+	 */
+	if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_BRIBE ) )
+	    mp_bribe_trigger( victim, ch, silver ? amount : amount * 100 );
+
 	if (IS_NPC(victim) && IS_SET(victim->act,ACT_IS_CHANGER))
 	{
 	    int change;
@@ -815,9 +821,18 @@
 
     obj_from_char( obj );
     obj_to_char( obj, victim );
+    MOBtrigger = FALSE;
     act( "$n gives $p to $N.", ch, obj, victim, TO_NOTVICT );
     act( "$n gives you $p.",   ch, obj, victim, TO_VICT    );
     act( "You give $p to $N.", ch, obj, victim, TO_CHAR    );
+    MOBtrigger = TRUE;
+
+    /*
+     * Give trigger
+     */
+    if ( IS_NPC(victim) && HAS_TRIGGER( victim, TRIG_GIVE ) )
+	mp_give_trigger( victim, ch, obj );
+
     return;
 }
 
diff -ur src/act_wiz.c new/act_wiz.c
--- src/act_wiz.c	Thu May 28 20:14:17 1998
+++ new/act_wiz.c	Wed Mar 15 22:57:16 2000
@@ -1692,6 +1692,12 @@
 	victim->pet 	    ? victim->pet->name	     : "(none)");
     send_to_char( buf, ch );
 
+    if (!IS_NPC(victim))
+    {
+	sprintf( buf, "Security: %d.\n\r", victim->pcdata->security );	/* OLC */
+	send_to_char( buf, ch );					/* OLC */
+    }
+
     sprintf( buf, "Short description: %s\n\rLong  description: %s",
 	victim->short_descr,
 	victim->long_descr[0] != '\0' ? victim->long_descr : "(none)\n\r" );
@@ -3343,6 +3349,7 @@
 	send_to_char( "    str int wis dex con sex class level\n\r",	ch );
 	send_to_char( "    race group gold silver hp mana move prac\n\r",ch);
 	send_to_char( "    align train thirst hunger drunk full\n\r",	ch );
+	send_to_char( "    security\n\r",				ch );
 	return;
     }
 
@@ -3378,6 +3385,38 @@
 	return;
     }
 
+    if ( !str_cmp( arg2, "security" ) )	/* OLC */
+    {
+	if ( IS_NPC(ch) )
+	{
+		send_to_char( "if, clear.\n\r", ch );
+		return;
+	}
+
+        if ( IS_NPC( victim ) )
+        {
+            send_to_char( "Not on NPC's.\n\r", ch );
+            return;
+        }
+
+	if ( value > ch->pcdata->security || value < 0 )
+	{
+	    if ( ch->pcdata->security != 0 )
+	    {
+		sprintf( buf, "Valid security is 0-%d.\n\r",
+		    ch->pcdata->security );
+		send_to_char( buf, ch );
+	    }
+	    else
+	    {
+		send_to_char( "Valid security is 0 only.\n\r", ch );
+	    }
+	    return;
+	}
+	victim->pcdata->security = value;
+	return;
+    }
+
     if ( !str_cmp( arg2, "int" ) )
     {
         if ( value < 3 || value > get_max_train(victim,STAT_INT) )
@@ -4103,7 +4142,7 @@
 
     one_argument(argument,arg2);
   
-    if (!str_cmp(arg2,"delete"))
+    if (!str_cmp(arg2,"delete") || !str_prefix(arg2,"mob"))
     {
 	send_to_char("That will NOT be done.\n\r",ch);
 	return;
diff -ur src/alias.c new/alias.c
--- src/alias.c	Mon May 25 06:04:43 1998
+++ new/alias.c	Wed Mar 15 22:57:16 2000
@@ -49,7 +49,7 @@
     if (ch->prefix[0] != '\0' && str_prefix("prefix",argument))
     {
 	if (strlen(ch->prefix) + strlen(argument) > MAX_INPUT_LENGTH)
-	    send_to_char("Line to long, prefix not processed.\r\n",ch);
+	    send_to_char("Line too long, prefix not processed.\r\n",ch);
 	else
 	{
 	    sprintf(prefix,"%s %s",ch->prefix,argument);
@@ -61,7 +61,8 @@
     ||	!str_prefix("alias",argument) || !str_prefix("una",argument) 
     ||  !str_prefix("prefix",argument)) 
     {
-	interpret(d->character,argument);
+	if (!run_olc_editor(d,argument))
+		interpret(d->character,argument);
 	return;
     }
 
@@ -92,7 +93,8 @@
 	    }
 	}
     }
-    interpret(d->character,buf);
+    if (!run_olc_editor(d, buf))
+	interpret(d->character,buf);
 }
 
 void do_alia(CHAR_DATA *ch, char *argument)
diff -ur src/comm.c new/comm.c
--- src/comm.c	Thu May 28 00:25:22 1998
+++ new/comm.c	Wed Mar 15 22:57:16 2000
@@ -56,11 +56,15 @@
 #include <string.h>
 #include <stdlib.h>
 #include <time.h>
+#include <unistd.h> /* OLC -- for close read write etc */
+#include <stdarg.h> /* printf_to_char */
 
 #include "merc.h"
+#include "olc.h"
 #include "interp.h"
 #include "recycle.h"
 #include "tables.h"
+#include "screen.h"
 
 /*
  * Malloc debugging stuff.
@@ -173,11 +177,11 @@
 
 int	close		args( ( int fd ) );
 int	gettimeofday	args( ( struct timeval *tp, struct timezone *tzp ) );
-int	read		args( ( int fd, char *buf, int nbyte ) );
+/* int	read		args( ( int fd, char *buf, int nbyte ) ); */
 int	select		args( ( int width, fd_set *readfds, fd_set *writefds,
 			    fd_set *exceptfds, struct timeval *timeout ) );
 int	socket		args( ( int domain, int type, int protocol ) );
-int	write		args( ( int fd, char *buf, int nbyte ) );
+/* int	write		args( ( int fd, char *buf, int nbyte ) ); */ /* read,write in unistd.h */
 #endif
 
 #if	defined(macintosh)
@@ -305,7 +309,7 @@
 bool		    newlock;		/* Game is newlocked		*/
 char		    str_boot_time[MAX_INPUT_LENGTH];
 time_t		    current_time;	/* time of this pulse */	
-
+bool		    MOBtrigger = TRUE;  /* act() switch                 */
 
 
 /*
@@ -516,6 +520,9 @@
     dcon.next		= descriptor_list;
     dcon.showstr_head	= NULL;
     dcon.showstr_point	= NULL;
+    dcon.pEdit		= NULL;			/* OLC */
+    dcon.pString	= NULL;			/* OLC */
+    dcon.editor		= 0;			/* OLC */
     descriptor_list	= &dcon;
 
     /*
@@ -573,10 +580,22 @@
 		d->fcommand	= TRUE;
 		stop_idling( d->character );
 
-		if ( d->connected == CON_PLAYING )
-		    substitute_alias( d, d->incomm );
-		else
-		    nanny( d, d->incomm );
+	        /* OLC */
+	        if ( d->showstr_point )
+	            show_string( d, d->incomm );
+	        else
+	        if ( d->pString )
+	            string_add( d->character, d->incomm );
+	        else
+	            switch ( d->connected )
+	            {
+	                case CON_PLAYING:
+			    substitute_alias( d, d->incomm );
+			    break;
+	                default:
+			    nanny( d, d->incomm );
+			    break;
+	            }
 
 		d->incomm[0]	= '\0';
 	    }
@@ -762,12 +781,22 @@
 		d->fcommand	= TRUE;
 		stop_idling( d->character );
 
-		if (d->showstr_point)
-		    show_string(d,d->incomm);
-		else if ( d->connected == CON_PLAYING )
+	/* OLC */
+	if ( d->showstr_point )
+	    show_string( d, d->incomm );
+	else
+	if ( d->pString )
+	    string_add( d->character, d->incomm );
+	else
+	    switch ( d->connected )
+	    {
+	        case CON_PLAYING:
 		    substitute_alias( d, d->incomm );
-		else
+		    break;
+	        default:
 		    nanny( d, d->incomm );
+		    break;
+	    }
 
 		d->incomm[0]	= '\0';
 	    }
@@ -892,6 +921,9 @@
     dnew->showstr_head	= NULL;
     dnew->showstr_point = NULL;
     dnew->outsize	= 2000;
+    dnew->pEdit		= NULL;			/* OLC */
+    dnew->pString	= NULL;			/* OLC */
+    dnew->editor	= 0;			/* OLC */
     dnew->outbuf	= alloc_mem( dnew->outsize );
 
     size = sizeof(sock);
@@ -1221,11 +1253,14 @@
     /*
      * Bust a prompt.
      */
-    if (!merc_down && d->showstr_point)
-	write_to_buffer(d,"[Hit Return to continue]\n\r",0);
-    else if (fPrompt && !merc_down && d->connected == CON_PLAYING)
-    {
-   	CHAR_DATA *ch;
+    if ( !merc_down )
+	if ( d->showstr_point )
+	    write_to_buffer( d, "[Hit Return to continue]\n\r", 0 );
+	else if ( fPrompt && d->pString && d->connected == CON_PLAYING )
+	    write_to_buffer( d, "> ", 2 );
+	else if ( fPrompt && d->connected == CON_PLAYING )
+	{
+	    CHAR_DATA *ch;
 	CHAR_DATA *victim;
 
 	ch = d->character;
@@ -1270,12 +1305,16 @@
 	if (!IS_SET(ch->comm, COMM_COMPACT) )
 	    write_to_buffer( d, "\n\r", 2 );
 
-
         if ( IS_SET(ch->comm, COMM_PROMPT) )
             bust_a_prompt( d->character );
 
 	if (IS_SET(ch->comm,COMM_TELNET_GA))
 	    write_to_buffer(d,go_ahead_str,0);
+
+	if (IS_SET(ch->comm,COMM_OLCX)
+	&&  d->editor != ED_NONE
+	&&  d->pString == NULL)
+		UpdateOLCScreen(d);
     }
 
     /*
@@ -1440,6 +1479,12 @@
          case '%' :
             sprintf( buf2, "%%" );
             i = buf2; break;
+         case 'o' :
+            sprintf( buf2, "%s", olc_ed_name(ch) );
+            i = buf2; break;
+	 case 'O' :
+	    sprintf( buf2, "%s", olc_ed_vnum(ch) );
+	    i = buf2; break;
       }
       ++str;
       while( (*point = *i) != '\0' )
@@ -1843,7 +1888,11 @@
         ch->race = race;
 	/* initialize stats */
 	for (i = 0; i < MAX_STATS; i++)
+#if defined(FIRST_BOOT)
 	    ch->perm_stat[i] = pc_race_table[race].stats[i];
+#else
+	    ch->perm_stat[i] = race_table[race].stats[i];
+#endif
 	ch->affected_by = ch->affected_by|race_table[race].aff;
 	ch->imm_flags	= ch->imm_flags|race_table[race].imm;
 	ch->res_flags	= ch->res_flags|race_table[race].res;
@@ -1854,6 +1903,7 @@
 	/* add skills */
 	for (i = 0; i < 5; i++)
 	{
+#if defined(FIRST_BOOT)
 	    if (pc_race_table[race].skills[i] == NULL)
 	 	break;
 	    group_add(ch,pc_race_table[race].skills[i],FALSE);
@@ -1861,6 +1911,15 @@
 	/* add cost */
 	ch->pcdata->points = pc_race_table[race].points;
 	ch->size = pc_race_table[race].size;
+#else
+	    if (race_table[race].skills[i] == NULL)
+	    	break;
+	    group_add(ch,race_table[race].skills[i],FALSE);
+	}
+	/* add cost */
+	ch->pcdata->points = race_table[race].points;
+	ch->size = race_table[race].size;
+#endif
 
         write_to_buffer( d, "What is your sex (M/F)? ", 0 );
         d->connected = CON_GET_NEW_SEX;
@@ -2005,17 +2064,29 @@
 
        	if (!str_cmp(argument,"done"))
        	{
+#if defined(FIRST_BOOT)
 	    if (ch->pcdata->points == pc_race_table[ch->race].points)
+#else
+	    if (ch->pcdata->points == race_table[ch->race].points)
+#endif
 	    {
 	        send_to_char("You didn't pick anything.\n\r",ch);
 		break;
 	    }
 
+#if defined(FIRST_BOOT)
 	    if (ch->pcdata->points <= 40 + pc_race_table[ch->race].points)
+#else
+	    if (ch->pcdata->points <= 40 + race_table[ch->race].points)
+#endif
 	    {
 		sprintf(buf,
 		    "You must take at least %d points of skills and groups",
+#if defined(FIRST_BOOT)
 		    40 + pc_race_table[ch->race].points);
+#else
+		    40 + race_table[ch->race].points);
+#endif
 		send_to_char(buf, ch);
 		break;
 	    }
@@ -2146,7 +2217,7 @@
      * Reserved words.
      */
     if (is_exact_name(name,
-	"all auto immortal self someone something the you loner"))
+	"all auto immortal self someone something the you loner none"))
     {
 	return FALSE;
     }
@@ -2472,7 +2543,9 @@
  
     for ( ; to != NULL; to = to->next_in_room )
     {
-        if ( to->desc == NULL || to->position < min_pos )
+	if ( (!IS_NPC(to) && to->desc == NULL )
+	||   ( IS_NPC(to) && !HAS_TRIGGER(to, TRIG_ACT) )
+	||    to->position < min_pos )
             continue;
  
         if ( (type == TO_CHAR) && to != ch )
@@ -2551,10 +2624,14 @@
  
         *point++ = '\n';
         *point++ = '\r';
+	*point   = '\0';
         buf[0]   = UPPER(buf[0]);
+	if ( to->desc != NULL )
         write_to_buffer( to->desc, buf, point - buf );
+	else
+	if ( MOBtrigger )
+	    mp_act_trigger( buf, to, ch, arg1, arg2, TRIG_ACT );
     }
- 
     return;
 }
 
@@ -2570,3 +2647,38 @@
     tp->tv_usec = 0;
 }
 #endif
+
+/* source: EOD, by John Booth <???> */
+
+void printf_to_char (CHAR_DATA *ch, char *fmt, ...)
+{
+	char buf [MAX_STRING_LENGTH];
+	va_list args;
+	va_start (args, fmt);
+	vsprintf (buf, fmt, args);
+	va_end (args);
+	
+	send_to_char (buf, ch);
+}
+
+void bugf (char * fmt, ...)
+{
+	char buf [2*MSL];
+	va_list args;
+	va_start (args, fmt);
+	vsprintf (buf, fmt, args);
+	va_end (args);
+
+	bug (buf, 0);
+}
+
+void flog (char * fmt, ...)
+{
+	char buf [2*MSL];
+	va_list args;
+	va_start (args, fmt);
+	vsprintf (buf, fmt, args);
+	va_end (args);
+
+	log_string (buf);
+}
diff -ur src/const.c new/const.c
--- src/const.c	Sat May 23 22:27:14 1998
+++ new/const.c	Wed Mar 15 22:57:16 2000
@@ -161,6 +161,7 @@
     {   NULL,		NULL,		0		}
 };
 
+#if defined(FIRST_BOOT)
 /* race table */
 const 	struct	race_type	race_table	[]		=
 {
@@ -424,7 +425,7 @@
 	{ 16, 11, 13, 11, 14 },	{ 22, 15, 18, 15, 20 }, SIZE_LARGE
     }
 };
-
+#endif
 	
       	
 
@@ -991,6 +992,7 @@
  */
 #define SLOT(n)	n
 
+#if defined(FIRST_BOOT)
 const	struct	skill_type	skill_table	[MAX_SKILL]	=
 {
 
@@ -2123,3 +2125,4 @@
    
 
 };
+#endif
diff -ur src/db.c new/db.c
--- src/db.c	Fri May 29 22:22:58 1998
+++ new/db.c	Wed Mar 15 22:57:16 2000
@@ -42,8 +42,12 @@
 #include "db.h"
 #include "recycle.h"
 #include "music.h"
+#include "tables.h"
 #include "lookup.h"
+#include "olc.h"
 
+COMMAND(do_asave)
+MPROG_CODE * pedir_prog(int);
 
 #if !defined(macintosh)
 extern	int	_filbuf		args( (FILE *) );
@@ -72,11 +76,15 @@
 HELP_DATA *		help_first;
 HELP_DATA *		help_last;
 
+HELP_AREA *		had_list;
+
 SHOP_DATA *		shop_first;
 SHOP_DATA *		shop_last;
 
 NOTE_DATA *		note_free;
 
+MPROG_CODE *		mprog_list;
+
 char			bug_buf		[2*MAX_INPUT_LENGTH];
 CHAR_DATA *		char_list;
 char *			help_greeting;
@@ -154,6 +162,7 @@
 
 AREA_DATA *		area_first;
 AREA_DATA *		area_last;
+AREA_DATA *		current_area;
 
 char *			string_space;
 char *			top_string;
@@ -169,6 +178,10 @@
 int			top_reset;
 int			top_room;
 int			top_shop;
+int                     top_vnum_room;		/* OLC */
+int                     top_vnum_mob;		/* OLC */
+int                     top_vnum_obj;		/* OLC */
+int			top_mprog_index;	/* OLC */
 int 			mobile_count = 0;
 int			newmobs = 0;
 int			newobjs = 0;
@@ -210,7 +223,8 @@
 */
 void    init_mm         args( ( void ) );
 void	load_area	args( ( FILE *fp ) );
-void	load_helps	args( ( FILE *fp ) );
+void    new_load_area   args( ( FILE *fp ) );   /* OLC */
+void	load_helps	args( ( FILE *fp, char *fname ) );
 void	load_old_mob	args( ( FILE *fp ) );
 void 	load_mobiles	args( ( FILE *fp ) );
 void	load_old_obj	args( ( FILE *fp ) );
@@ -222,8 +236,11 @@
 void	load_specials	args( ( FILE *fp ) );
 void	load_notes	args( ( void ) );
 void	load_bans	args( ( void ) );
+void	load_mobprogs	args( ( FILE *fp ) );
+void	load_groups	( void );
 
 void	fix_exits	args( ( void ) );
+void    fix_mobprogs	args( ( void ) );
 
 void	reset_area	args( ( AREA_DATA * pArea ) );
 
@@ -253,6 +270,14 @@
         init_mm( );
     }
 
+#if !defined(FIRST_BOOT)
+    cargar_skills();
+    cargar_razas();
+    cargar_comandos();
+    cargar_socials();
+    load_groups();
+#endif
+
     /*
      * Set time and weather.
      */
@@ -332,6 +357,8 @@
 		}
 	    }
 
+	    current_area = NULL;
+
 	    for ( ; ; )
 	    {
 		char *word;
@@ -346,9 +373,11 @@
 
 		     if ( word[0] == '$'               )                 break;
 		else if ( !str_cmp( word, "AREA"     ) ) load_area    (fpArea);
-		else if ( !str_cmp( word, "HELPS"    ) ) load_helps   (fpArea);
+  /* OLC */     else if ( !str_cmp( word, "AREADATA" ) ) new_load_area(fpArea);
+		else if ( !str_cmp( word, "HELPS"    ) ) load_helps   (fpArea, strArea);
 		else if ( !str_cmp( word, "MOBOLD"   ) ) load_old_mob (fpArea);
 		else if ( !str_cmp( word, "MOBILES"  ) ) load_mobiles (fpArea);
+		else if ( !str_cmp( word, "MOBPROGS" ) ) load_mobprogs(fpArea);
 		else if ( !str_cmp( word, "OBJOLD"   ) ) load_old_obj (fpArea);
 	  	else if ( !str_cmp( word, "OBJECTS"  ) ) load_objects (fpArea);
 		else if ( !str_cmp( word, "RESETS"   ) ) load_resets  (fpArea);
@@ -378,13 +407,26 @@
      */
     {
 	fix_exits( );
+	fix_mobprogs( );
 	fBootDb	= FALSE;
+        convert_objects( );           /* ROM OLC */
 	area_update( );
 	load_notes( );
 	load_bans();
 	load_songs();
     }
 
+#if defined(FIRST_BOOT)
+    grabar_skills();
+    grabar_razas();
+    grabar_tabla_comandos();
+    grabar_socials();
+    save_groups();
+    do_asave(NULL,"");
+    flog("Now recompile without -DFIRST_BOOT.");
+    exit(0);
+#endif
+
     return;
 }
 
@@ -398,9 +440,13 @@
     AREA_DATA *pArea;
 
     pArea		= alloc_perm( sizeof(*pArea) );
-    pArea->reset_first	= NULL;
-    pArea->reset_last	= NULL;
     pArea->file_name	= fread_string(fp);
+
+    pArea->area_flags   = AREA_LOADING;         /* OLC */
+    pArea->security     = 9;                    /* OLC */ /* 9 -- Hugin */
+    pArea->builders     = str_dup( "None" );    /* OLC */
+    pArea->vnum         = top_area;             /* OLC */
+
     pArea->name		= fread_string( fp );
     pArea->credits	= fread_string( fp );
     pArea->min_vnum	= fread_number(fp);
@@ -409,33 +455,185 @@
     pArea->nplayer	= 0;
     pArea->empty	= FALSE;
 
-    if ( area_first == NULL )
+    if ( !area_first )
 	area_first = pArea;
-    if ( area_last  != NULL )
+    if ( area_last )
+    {
 	area_last->next = pArea;
-    area_last	= pArea;
-    pArea->next	= NULL;
+        REMOVE_BIT(area_last->area_flags, AREA_LOADING);        /* OLC */
+    }
+    area_last		= pArea;
+    pArea->next		= NULL;
+    current_area	= pArea;
 
     top_area++;
     return;
 }
 
+/*
+ * OLC
+ * Use these macros to load any new area formats that you choose to
+ * support on your MUD.  See the new_load_area format below for
+ * a short example.
+ */
+#if defined(KEY)
+#undef KEY
+#endif
+
+#define KEY( literal, field, value )                \
+                if ( !str_cmp( word, literal ) )    \
+                {                                   \
+                    field  = value;                 \
+                    fMatch = TRUE;                  \
+                    break;                          \
+                                }
+
+#define SKEY( string, field )                       \
+                if ( !str_cmp( word, string ) )     \
+                {                                   \
+                    free_string( field );           \
+                    field = fread_string( fp );     \
+                    fMatch = TRUE;                  \
+                    break;                          \
+                                }
+
+
+
+/* OLC
+ * Snarf an 'area' header line.   Check this format.  MUCH better.  Add fields
+ * too.
+ *
+ * #AREAFILE
+ * Name   { All } Locke    Newbie School~
+ * Repop  A teacher pops in the room and says, 'Repop coming!'~
+ * Recall 3001
+ * End
+ */
+void new_load_area( FILE *fp )
+{
+    AREA_DATA *pArea;
+    char      *word;
+    bool      fMatch;
 
+    pArea               = alloc_perm( sizeof(*pArea) );
+    pArea->age          = 15;
+    pArea->nplayer      = 0;
+    pArea->file_name     = str_dup( strArea );
+    pArea->vnum         = top_area;
+    pArea->name         = str_dup( "New Area" );
+    pArea->builders     = str_dup( "" );
+    pArea->security     = 9;                    /* 9 -- Hugin */
+    pArea->min_vnum        = 0;
+    pArea->max_vnum        = 0;
+    pArea->area_flags   = 0;
+/*  pArea->recall       = ROOM_VNUM_TEMPLE;        ROM OLC */
+
+    for ( ; ; )
+    {
+       word   = feof( fp ) ? "End" : fread_word( fp );
+       fMatch = FALSE;
+
+       switch ( UPPER(word[0]) )
+       {
+           case 'N':
+            SKEY( "Name", pArea->name );
+            break;
+           case 'S':
+             KEY( "Security", pArea->security, fread_number( fp ) );
+            break;
+           case 'V':
+            if ( !str_cmp( word, "VNUMs" ) )
+            {
+                pArea->min_vnum = fread_number( fp );
+                pArea->max_vnum = fread_number( fp );
+            }
+            break;
+           case 'E':
+             if ( !str_cmp( word, "End" ) )
+             {
+                 fMatch = TRUE;
+                 if ( area_first == NULL )
+                    area_first = pArea;
+                 if ( area_last  != NULL )
+                    area_last->next = pArea;
+                 area_last	= pArea;
+                 pArea->next	= NULL;
+		 current_area	= pArea;
+                 top_area++;
+
+                 return;
+            }
+            break;
+           case 'B':
+            SKEY( "Builders", pArea->builders );
+            break;
+	   case 'C':
+	    SKEY( "Credits", pArea->credits );
+	    break;
+        }
+    }
+}
+
+/*
+ * Sets vnum range for area using OLC protection features.
+ */
+void assign_area_vnum( int vnum )
+{
+    if ( area_last->min_vnum == 0 || area_last->max_vnum == 0 )
+        area_last->min_vnum = area_last->max_vnum = vnum;
+    if ( vnum != URANGE( area_last->min_vnum, vnum, area_last->max_vnum ) )
+        if ( vnum < area_last->min_vnum )
+            area_last->min_vnum = vnum;
+        else
+            area_last->max_vnum = vnum;
+    return;
+}
 
 /*
  * Snarf a help section.
  */
-void load_helps( FILE *fp )
+void load_helps( FILE *fp, char *fname )
 {
     HELP_DATA *pHelp;
+    int level;
+    char *keyword;
 
     for ( ; ; )
     {
-	pHelp		= alloc_perm( sizeof(*pHelp) );
-	pHelp->level	= fread_number( fp );
-	pHelp->keyword	= fread_string( fp );
-	if ( pHelp->keyword[0] == '$' )
-	    break;
+	HELP_AREA * had;
+
+	level		= fread_number( fp );
+	keyword		= fread_string( fp );
+
+	if ( keyword[0] == '$' )
+		break;
+
+	if ( !had_list )
+	{
+		had			= new_had ();
+		had->filename		= str_dup( fname );
+		had->area		= current_area;
+		if ( current_area )
+			current_area->helps	= had;
+		had_list		= had;
+	}
+	else
+	if ( str_cmp( fname, had_list->filename ) )
+	{
+		had			= new_had ();
+		had->filename		= str_dup( fname );
+		had->area		= current_area;
+		if ( current_area )
+			current_area->helps	= had;
+		had->next		= had_list;
+		had_list		= had;
+	}
+	else
+		had			= had_list;
+
+	pHelp		= new_help( );
+	pHelp->level	= level;
+	pHelp->keyword	= keyword;
 	pHelp->text	= fread_string( fp );
 
 	if ( !str_cmp( pHelp->keyword, "greeting" ) )
@@ -446,8 +644,18 @@
 	if ( help_last  != NULL )
 	    help_last->next = pHelp;
 
-	help_last	= pHelp;
-	pHelp->next	= NULL;
+	help_last		= pHelp;
+	pHelp->next		= NULL;
+
+	if ( !had->first )
+		had->first	= pHelp;
+	if ( !had->last )
+		had->last	= pHelp;
+
+	had->last->next_area	= pHelp;
+	had->last		= pHelp;
+	pHelp->next_area	= NULL;
+
 	top_help++;
     }
 
@@ -466,6 +674,12 @@
     int race;
     char name[MAX_STRING_LENGTH];
 
+    if ( !area_last )   /* OLC */
+    {
+        bug( "Load_mobiles: no #AREA seen yet.", 0 );
+        exit( 1 );
+    }
+
     for ( ; ; )
     {
 	sh_int vnum;
@@ -493,6 +707,7 @@
 
 	pMobIndex			= alloc_perm( sizeof(*pMobIndex) );
 	pMobIndex->vnum			= vnum;
+        pMobIndex->area                 = area_last;               /* OLC */
 	pMobIndex->new_format		= FALSE;
 	pMobIndex->player_name		= fread_string( fp );
 	pMobIndex->short_descr		= fread_string( fp );
@@ -573,10 +788,14 @@
 	    exit( 1 );
 	}
 
+	convert_mobile( pMobIndex );                           /* ROM OLC */
+
 	iHash			= vnum % MAX_KEY_HASH;
 	pMobIndex->next		= mob_index_hash[iHash];
 	mob_index_hash[iHash]	= pMobIndex;
 	top_mob_index++;
+        top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob;  /* OLC */
+        assign_area_vnum( vnum );                                  /* OLC */
 	kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++;
     }
 
@@ -590,6 +809,12 @@
 {
     OBJ_INDEX_DATA *pObjIndex;
 
+    if ( !area_last )   /* OLC */
+    {
+        bug( "Load_objects: no #AREA seen yet.", 0 );
+        exit( 1 );
+    }
+
     for ( ; ; )
     {
 	sh_int vnum;
@@ -617,6 +842,7 @@
 
 	pObjIndex			= alloc_perm( sizeof(*pObjIndex) );
 	pObjIndex->vnum			= vnum;
+        pObjIndex->area                 = area_last;            /* OLC */
 	pObjIndex->new_format		= FALSE;
 	pObjIndex->reset_num	 	= 0;
 	pObjIndex->name			= fread_string( fp );
@@ -724,14 +950,42 @@
 	pObjIndex->next		= obj_index_hash[iHash];
 	obj_index_hash[iHash]	= pObjIndex;
 	top_obj_index++;
+        top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj;   /* OLC */
+        assign_area_vnum( vnum );                                   /* OLC */
     }
 
     return;
 }
 
+/*
+ * Adds a reset to a room.  OLC
+ * Similar to add_reset in olc.c
+ */
+void new_reset( ROOM_INDEX_DATA *pR, RESET_DATA *pReset )
+{
+    RESET_DATA *pr;
+
+    if ( !pR )
+       return;
 
+    pr = pR->reset_last;
+
+    if ( !pr )
+    {
+        pR->reset_first = pReset;
+        pR->reset_last  = pReset;
+    }
+    else
+    {
+        pR->reset_last->next = pReset;
+        pR->reset_last       = pReset;
+        pR->reset_last->next = NULL;
+    }
 
+/*    top_reset++; no estamos asignando memoria!!!! */
 
+    return;
+}
 
 /*
  * Snarf a reset section.
@@ -739,8 +993,11 @@
 void load_resets( FILE *fp )
 {
     RESET_DATA *pReset;
+    EXIT_DATA *pexit;
+    ROOM_INDEX_DATA *pRoomIndex;
+    int rVnum = -1;
 
-    if ( area_last == NULL )
+    if ( !area_last )
     {
 	bug( "Load_resets: no #AREA seen yet.", 0 );
 	exit( 1 );
@@ -748,10 +1005,7 @@
 
     for ( ; ; )
     {
-	ROOM_INDEX_DATA *pRoomIndex;
-	EXIT_DATA *pexit;
 	char letter;
-	OBJ_INDEX_DATA *temp_index;
 
 	if ( ( letter = fread_letter( fp ) ) == 'S' )
 	    break;
@@ -762,7 +1016,7 @@
 	    continue;
 	}
 
-	pReset		= alloc_perm( sizeof(*pReset) );
+	pReset		= new_reset_data();
 	pReset->command	= letter;
 	/* if_flag */	  fread_number( fp );
 	pReset->arg1	= fread_number( fp );
@@ -773,87 +1027,61 @@
 			    ? fread_number(fp) : 0;
 			  fread_to_eol( fp );
 
-	/*
-	 * Validate parameters.
-	 * We're calling the index functions for the side effect.
-	 */
-	switch ( letter )
+	switch( pReset->command )
 	{
-	default:
-	    bug( "Load_resets: bad command '%c'.", letter );
-	    exit( 1 );
-	    break;
-
-	case 'M':
-	    get_mob_index  ( pReset->arg1 );
-	    get_room_index ( pReset->arg3 );
-	    break;
-
-	case 'O':
-	    temp_index = get_obj_index  ( pReset->arg1 );
-	    temp_index->reset_num++;
-	    get_room_index ( pReset->arg3 );
-	    break;
-
-	case 'P':
-	    temp_index = get_obj_index  ( pReset->arg1 );
-	    temp_index->reset_num++;
-	    get_obj_index  ( pReset->arg3 );
-	    break;
-
-	case 'G':
-	case 'E':
-	    temp_index = get_obj_index  ( pReset->arg1 );
-	    temp_index->reset_num++;
-	    break;
-
-	case 'D':
-	    pRoomIndex = get_room_index( pReset->arg1 );
-
-	    if ( pReset->arg2 < 0
-	    ||   pReset->arg2 > 5
-	    || ( pexit = pRoomIndex->exit[pReset->arg2] ) == NULL
-	    || !IS_SET( pexit->exit_info, EX_ISDOOR ) )
-	    {
-		bug( "Load_resets: 'D': exit %d not door.", pReset->arg2 );
-		exit( 1 );
-	    }
-
-	    if ( pReset->arg3 < 0 || pReset->arg3 > 2 )
-	    {
-		bug( "Load_resets: 'D': bad 'locks': %d.", pReset->arg3 );
-		exit( 1 );
-	    }
+		case 'M':
+		case 'O':
+		rVnum = pReset->arg3;
+		break;
 
-	    break;
+		case 'P':
+		case 'G':
+		case 'E':
+		break;
 
-	case 'R':
-	    pRoomIndex		= get_room_index( pReset->arg1 );
+		case 'D':
+		pRoomIndex = get_room_index( (rVnum = pReset->arg1) );
+		if ( pReset->arg2 < 0
+		||   pReset->arg2 >= MAX_DIR
+		|| !pRoomIndex
+		|| !( pexit = pRoomIndex->exit[pReset->arg2] )
+		|| !IS_SET( pexit->rs_flags, EX_ISDOOR ) )
+		{
+			bugf( "Load_resets: 'D': exit %d, room %d not door.", pReset->arg2, pReset->arg1 );
+			exit( 1 );
+		}
 
-	    if ( pReset->arg2 < 0 || pReset->arg2 > 6 )
-	    {
-		bug( "Load_resets: 'R': bad exit %d.", pReset->arg2 );
-		exit( 1 );
-	    }
+		switch ( pReset->arg3 )
+		{
+			default: bug( "Load_resets: 'D': bad 'locks': %d." , pReset->arg3); break;
+			case 0: break;
+			case 1: SET_BIT( pexit->rs_flags, EX_CLOSED );
+				SET_BIT( pexit->exit_info, EX_CLOSED ); break;
+			case 2: SET_BIT( pexit->rs_flags, EX_CLOSED | EX_LOCKED );
+				SET_BIT( pexit->exit_info, EX_CLOSED | EX_LOCKED ); break;
+		}
+		break;
 
-	    break;
+		case 'R':
+		rVnum = pReset->arg1;
+		break;
 	}
 
-	if ( area_last->reset_first == NULL )
-	    area_last->reset_first	= pReset;
-	if ( area_last->reset_last  != NULL )
-	    area_last->reset_last->next	= pReset;
-	    
-	area_last->reset_last	= pReset;
-	pReset->next		= NULL;
-	top_reset++;
+	if ( rVnum == -1 )
+	{
+ 		bugf( "load_resets : rVnum == -1" );
+ 		exit(1);
+ 	}
+
+	if ( pReset->command != 'D' )
+		new_reset( get_room_index(rVnum), pReset );
+	else
+		free_reset_data( pReset );
     }
 
     return;
 }
 
-
-
 /*
  * Snarf a room section.
  */
@@ -956,21 +1184,26 @@
 		pexit->description	= fread_string( fp );
 		pexit->keyword		= fread_string( fp );
 		pexit->exit_info	= 0;
-		locks			= fread_number( fp );
+                pexit->rs_flags         = 0;                    /* OLC */
+		locks			= fread_number(fp);
 		pexit->key		= fread_number( fp );
 		pexit->u1.vnum		= fread_number( fp );
+		pexit->orig_door	= door;			/* OLC */
 
 		switch ( locks )
 		{
-		case 1: pexit->exit_info = EX_ISDOOR;                break;
-		case 2: pexit->exit_info = EX_ISDOOR | EX_PICKPROOF; break;
-		case 3: pexit->exit_info = EX_ISDOOR | EX_NOPASS;    break;
+		case 1: pexit->exit_info = EX_ISDOOR;               
+			pexit->rs_flags  = EX_ISDOOR;		     break;
+		case 2: pexit->exit_info = EX_ISDOOR | EX_PICKPROOF;
+			pexit->rs_flags  = EX_ISDOOR | EX_PICKPROOF; break;
+		case 3: pexit->exit_info = EX_ISDOOR | EX_NOPASS;    
+			pexit->rs_flags  = EX_ISDOOR | EX_NOPASS;    break;
 		case 4: pexit->exit_info = EX_ISDOOR|EX_NOPASS|EX_PICKPROOF;
+			pexit->rs_flags  = EX_ISDOOR|EX_NOPASS|EX_PICKPROOF;
 			break;
 		}
 
 		pRoomIndex->exit[door]	= pexit;
-		pRoomIndex->old_exit[door] = pexit;
 		top_exit++;
 	    }
 	    else if ( letter == 'E' )
@@ -1007,6 +1240,8 @@
 	pRoomIndex->next	= room_index_hash[iHash];
 	room_index_hash[iHash]	= pRoomIndex;
 	top_room++;
+        top_vnum_room = top_vnum_room < vnum ? vnum : top_vnum_room; /* OLC */
+        assign_area_vnum( vnum );                                    /* OLC */
     }
 
     return;
@@ -1105,6 +1340,8 @@
     ROOM_INDEX_DATA *to_room;
     EXIT_DATA *pexit;
     EXIT_DATA *pexit_rev;
+    RESET_DATA *pReset;
+    ROOM_INDEX_DATA *iLastRoom, *iLastObj;
     int iHash;
     int door;
 
@@ -1116,6 +1353,64 @@
 	{
 	    bool fexit;
 
+	    iLastRoom = iLastObj = NULL;
+
+	    /* OLC : nuevo chequeo de resets */
+	    for ( pReset = pRoomIndex->reset_first; pReset; pReset = pReset->next )
+	    {
+	    	switch( pReset->command )
+	    	{
+	    		default:
+	    		bugf( "fix_exits : Room %d with reset cmd %c", pRoomIndex->vnum, pReset->command );
+	    		exit(1);
+	    		break;
+
+			case 'M':
+			get_mob_index( pReset->arg1 );
+			iLastRoom = get_room_index( pReset->arg3 );
+			break;
+
+			case 'O':
+			get_obj_index( pReset->arg1 );
+			iLastObj = get_room_index( pReset->arg3 );
+			break;
+
+			case 'P':
+			get_obj_index( pReset->arg1 );
+			if (iLastObj == NULL)
+			{
+				bugf( "fix_exits : reset en cuarto %d con iLastObj NULL", pRoomIndex->vnum );
+				exit(1);
+			}
+			break;
+
+			case 'G':
+			case 'E':
+			get_obj_index( pReset->arg1 );
+			if (iLastRoom == NULL)
+			{
+				bugf( "fix_exits : reset en cuarto %d con iLastRoom NULL", pRoomIndex->vnum );
+				exit(1);
+			}
+			iLastObj = iLastRoom;
+			break;
+
+			case 'D':
+			bugf( "???" );
+			break;
+
+			case 'R':
+			get_room_index( pReset->arg1 );
+			if ( pReset->arg2 < 0 || pReset->arg2 > MAX_DIR )
+			{
+				bugf( "fix_exits : reset en cuarto %d con arg2 %d >= MAX_DIR",
+					pRoomIndex->vnum, pReset->arg2 );
+				exit(1);
+			}
+			break;
+		} /* switch */
+	    } /* for */
+
 	    fexit = FALSE;
 	    for ( door = 0; door <= 5; door++ )
 	    {
@@ -1164,6 +1459,87 @@
     return;
 }
 
+/*
+ * Load mobprogs section
+ */
+void load_mobprogs( FILE *fp )
+{
+    MPROG_CODE *pMprog;
+
+    if ( area_last == NULL )
+    {
+	bug( "Load_mobprogs: no #AREA seen yet.", 0 );
+	exit( 1 );
+    }
+
+    for ( ; ; )
+    {
+	sh_int vnum;
+	char letter;
+
+	letter		  = fread_letter( fp );
+	if ( letter != '#' )
+	{
+	    bug( "Load_mobprogs: # not found.", 0 );
+	    exit( 1 );
+	}
+
+	vnum		 = fread_number( fp );
+	if ( vnum == 0 )
+	    break;
+
+	fBootDb = FALSE;
+	if ( get_mprog_index( vnum ) != NULL )
+	{
+	    bug( "Load_mobprogs: vnum %d duplicated.", vnum );
+	    exit( 1 );
+	}
+	fBootDb = TRUE;
+
+	pMprog		= alloc_perm( sizeof(*pMprog) );
+	pMprog->vnum  	= vnum;
+	pMprog->code  	= fread_string( fp );
+	if ( mprog_list == NULL )
+	    mprog_list = pMprog;
+	else
+	{
+	    pMprog->next = mprog_list;
+	    mprog_list 	= pMprog;
+	}
+	top_mprog_index++;
+    }
+    return;
+}
+
+/*
+ *  Translate mobprog vnums pointers to real code
+ */
+void fix_mobprogs( void )
+{
+    MOB_INDEX_DATA *pMobIndex;
+    MPROG_LIST        *list;
+    MPROG_CODE        *prog;
+    int iHash;
+
+    for ( iHash = 0; iHash < MAX_KEY_HASH; iHash++ )
+    {
+	for ( pMobIndex   = mob_index_hash[iHash];
+	      pMobIndex   != NULL;
+	      pMobIndex   = pMobIndex->next )
+	{
+	    for( list = pMobIndex->mprogs; list != NULL; list = list->next )
+	    {
+		if ( ( prog = pedir_prog( list->vnum ) ) != NULL )
+		    list->code = prog->code;
+		else
+		{
+		    bug( "Fix_mobprogs: code vnum %d not found.", list->vnum );
+		    exit( 1 );
+		}
+	    }
+	}
+    }
+}
 
 
 /*
@@ -1205,57 +1581,76 @@
     return;
 }
 
-
-
-/*
- * Reset one area.
+/* OLC
+ * Reset one room.  Called by reset_area and olc.
  */
-void reset_area( AREA_DATA *pArea )
+void reset_room( ROOM_INDEX_DATA *pRoom )
 {
-    RESET_DATA *pReset;
-    CHAR_DATA *mob;
+    RESET_DATA  *pReset;
+    CHAR_DATA   *pMob;
+    CHAR_DATA	*mob;
+    OBJ_DATA    *pObj;
+    CHAR_DATA   *LastMob = NULL;
+    OBJ_DATA    *LastObj = NULL;
+    int iExit;
+    int level = 0;
     bool last;
-    int level;
 
-    mob 	= NULL;
-    last	= TRUE;
-    level	= 0;
-    for ( pReset = pArea->reset_first; pReset != NULL; pReset = pReset->next )
+    if ( !pRoom )
+        return;
+
+    pMob        = NULL;
+    last        = FALSE;
+    
+    for ( iExit = 0;  iExit < MAX_DIR;  iExit++ )
     {
-	ROOM_INDEX_DATA *pRoomIndex;
-	MOB_INDEX_DATA *pMobIndex;
-	OBJ_INDEX_DATA *pObjIndex;
-	OBJ_INDEX_DATA *pObjToIndex;
-	EXIT_DATA *pexit;
-	OBJ_DATA *obj;
-	OBJ_DATA *obj_to;
-	int count, limit;
+        EXIT_DATA *pExit;
+        if ( ( pExit = pRoom->exit[iExit] )
+	  /*  && !IS_SET( pExit->exit_info, EX_BASHED )   ROM OLC */ )  
+        {
+            pExit->exit_info = pExit->rs_flags;
+            if ( ( pExit->u1.to_room != NULL )
+              && ( ( pExit = pExit->u1.to_room->exit[rev_dir[iExit]] ) ) )
+            {
+                /* nail the other side */
+                pExit->exit_info = pExit->rs_flags;
+            }
+        }
+    }
 
-	switch ( pReset->command )
-	{
-	default:
-	    bug( "Reset_area: bad command %c.", pReset->command );
-	    break;
+    for ( pReset = pRoom->reset_first; pReset != NULL; pReset = pReset->next )
+    {
+        MOB_INDEX_DATA  *pMobIndex;
+        OBJ_INDEX_DATA  *pObjIndex;
+        OBJ_INDEX_DATA  *pObjToIndex;
+        ROOM_INDEX_DATA *pRoomIndex;
+	char buf[MAX_STRING_LENGTH];
+	int count,limit=0;
 
-	case 'M':
-	    if ( ( pMobIndex = get_mob_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'M': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
+        switch ( pReset->command )
+        {
+        default:
+                bug( "Reset_room: bad command %c.", pReset->command );
+                break;
+
+        case 'M':
+            if ( !( pMobIndex = get_mob_index( pReset->arg1 ) ) )
+            {
+                bug( "Reset_room: 'M': bad vnum %d.", pReset->arg1 );
+                continue;
+            }
 
 	    if ( ( pRoomIndex = get_room_index( pReset->arg3 ) ) == NULL )
 	    {
 		bug( "Reset_area: 'R': bad vnum %d.", pReset->arg3 );
 		continue;
 	    }
-
-	    if ( pMobIndex->count >= pReset->arg2 )
-	    {
-		last = FALSE;
-		break;
-	    }
-
+            if ( pMobIndex->count >= pReset->arg2 )
+            {
+                last = FALSE;
+                break;
+            }
+/* */
 	    count = 0;
 	    for (mob = pRoomIndex->people; mob != NULL; mob = mob->next_in_room)
 		if (mob->pIndexData == pMobIndex)
@@ -1271,66 +1666,80 @@
 	    if (count >= pReset->arg4)
 		break;
 
-	    mob = create_mobile( pMobIndex );
+/* */
 
-	    /*
-	     * Check for pet shop.
-	     */
-	    {
-		ROOM_INDEX_DATA *pRoomIndexPrev;
-		pRoomIndexPrev = get_room_index( pRoomIndex->vnum - 1 );
-		if ( pRoomIndexPrev != NULL
-		&&   IS_SET(pRoomIndexPrev->room_flags, ROOM_PET_SHOP) )
-		    SET_BIT(mob->act, ACT_PET);
-	    }
+            pMob = create_mobile( pMobIndex );
 
-	    /* set area */
-	    mob->zone = pRoomIndex->area;
+            /*
+             * Some more hard coding.
+             */
+            if ( room_is_dark( pRoom ) )
+                SET_BIT(pMob->affected_by, AFF_INFRARED);
+
+            /*
+             * Pet shop mobiles get ACT_PET set.
+             */
+            {
+                ROOM_INDEX_DATA *pRoomIndexPrev;
 
-	    char_to_room( mob, pRoomIndex );
-	    level = URANGE( 0, mob->level - 2, LEVEL_HERO - 1 );
-	    last  = TRUE;
-	    break;
+                pRoomIndexPrev = get_room_index( pRoom->vnum - 1 );
+                if ( pRoomIndexPrev
+                    && IS_SET( pRoomIndexPrev->room_flags, ROOM_PET_SHOP ) )
+                    SET_BIT( pMob->act, ACT_PET);
+            }
 
-	case 'O':
-	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'O': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
+            char_to_room( pMob, pRoom );
 
-	    if ( ( pRoomIndex = get_room_index( pReset->arg3 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'R': bad vnum %d.", pReset->arg3 );
-		continue;
-	    }
+            LastMob = pMob;
+            level  = URANGE( 0, pMob->level - 2, LEVEL_HERO - 1 ); /* -1 ROM */
+            last = TRUE;
+            break;
 
-	    if ( pArea->nplayer > 0
-	    ||   count_obj_list( pObjIndex, pRoomIndex->contents ) > 0 )
+        case 'O':
+            if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
+            {
+                bug( "Reset_room: 'O' 1 : bad vnum %d", pReset->arg1 );
+                sprintf (buf,"%d %d %d %d",pReset->arg1, pReset->arg2, pReset->arg3,
+                pReset->arg4 );
+		bug(buf,1);
+                continue;
+            }
+
+            if ( !( pRoomIndex = get_room_index( pReset->arg3 ) ) )
+            {
+                bug( "Reset_room: 'O' 2 : bad vnum %d.", pReset->arg3 );
+                sprintf (buf,"%d %d %d %d",pReset->arg1, pReset->arg2, pReset->arg3,
+                pReset->arg4 );
+		bug(buf,1);
+                continue;
+            }
+
+            if ( pRoom->area->nplayer > 0
+              || count_obj_list( pObjIndex, pRoom->contents ) > 0 )
 	    {
 		last = FALSE;
 		break;
 	    }
 
-	    obj       = create_object( pObjIndex, UMIN(number_fuzzy(level),
-						       LEVEL_HERO - 1) );
-	    obj->cost = 0;
-	    obj_to_room( obj, pRoomIndex );
+            pObj = create_object( pObjIndex,              /* UMIN - ROM OLC */
+				  UMIN(number_fuzzy( level ), LEVEL_HERO -1) );
+            pObj->cost = 0;
+            obj_to_room( pObj, pRoom );
 	    last = TRUE;
-	    break;
+            break;
 
-	case 'P':
-	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'P': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
+        case 'P':
+            if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
+            {
+                bug( "Reset_room: 'P': bad vnum %d.", pReset->arg1 );
+                continue;
+            }
 
-	    if ( ( pObjToIndex = get_obj_index( pReset->arg3 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'P': bad vnum %d.", pReset->arg3 );
-		continue;
-	    }
+            if ( !( pObjToIndex = get_obj_index( pReset->arg3 ) ) )
+            {
+                bug( "Reset_room: 'P': bad vnum %d.", pReset->arg3 );
+                continue;
+            }
 
             if (pReset->arg2 > 50) /* old format */
                 limit = 6;
@@ -1339,60 +1748,62 @@
             else
                 limit = pReset->arg2;
 
-	    if (pArea->nplayer > 0
-	    || (obj_to = get_obj_type( pObjToIndex ) ) == NULL
-	    || (obj_to->in_room == NULL && !last)
-	    || ( pObjIndex->count >= limit && number_range(0,4) != 0)
-	    || (count = count_obj_list(pObjIndex,obj_to->contains)) 
-		> pReset->arg4 )
+            if ( pRoom->area->nplayer > 0
+              || ( LastObj = get_obj_type( pObjToIndex ) ) == NULL
+              || ( LastObj->in_room == NULL && !last)
+              || ( pObjIndex->count >= limit /* && number_range(0,4) != 0 */ )
+              || ( count = count_obj_list( pObjIndex, LastObj->contains ) ) > pReset->arg4  )
 	    {
 		last = FALSE;
 		break;
 	    }
+				                /* lastObj->level  -  ROM */
 
 	    while (count < pReset->arg4)
 	    {
-	        obj = create_object( pObjIndex, number_fuzzy(obj_to->level) );
-	    	obj_to_obj( obj, obj_to );
+            pObj = create_object( pObjIndex, number_fuzzy( LastObj->level ) );
+            obj_to_obj( pObj, LastObj );
 		count++;
 		if (pObjIndex->count >= limit)
 		    break;
 	    }
+
 	    /* fix object lock state! */
-	    obj_to->value[1] = obj_to->pIndexData->value[1];
+	    LastObj->value[1] = LastObj->pIndexData->value[1];
 	    last = TRUE;
-	    break;
+            break;
 
-	case 'G':
-	case 'E':
-	    if ( ( pObjIndex = get_obj_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'E' or 'G': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
+        case 'G':
+        case 'E':
+            if ( !( pObjIndex = get_obj_index( pReset->arg1 ) ) )
+            {
+                bug( "Reset_room: 'E' or 'G': bad vnum %d.", pReset->arg1 );
+                continue;
+            }
 
-	    if ( !last )
-		break;
+            if ( !last )
+                break;
 
-	    if ( mob == NULL )
-	    {
-		bug( "Reset_area: 'E' or 'G': null mob for vnum %d.",
-		    pReset->arg1 );
-		last = FALSE;
-		break;
-	    }
+            if ( !LastMob )
+            {
+                bug( "Reset_room: 'E' or 'G': null mob for vnum %d.",
+                    pReset->arg1 );
+                last = FALSE;
+                break;
+            }
 
-	    if ( mob->pIndexData->pShop != NULL )
-	    {
-		int olevel = 0,i,j;
+            if ( LastMob->pIndexData->pShop )   /* Shop-keeper? */
+            {
+                int olevel=0,i,j;
 
 		if (!pObjIndex->new_format)
-		    switch ( pObjIndex->item_type )
-		{
-		case ITEM_PILL:
-		case ITEM_POTION:
-		case ITEM_SCROLL:
-		    olevel = 53;
+                 switch ( pObjIndex->item_type )
+                {
+                default:                olevel = 0;                      break;
+                case ITEM_PILL:
+                case ITEM_POTION:
+                case ITEM_SCROLL:
+ 		    olevel = 53;
 		    for (i = 1; i < 5; i++)
 		    {
 			if (pObjIndex->value[i] > 0)
@@ -1408,108 +1819,121 @@
 		   
 		    olevel = UMAX(0,(olevel * 3 / 4) - 2);
 		    break;
-		case ITEM_WAND:		olevel = number_range( 10, 20 ); break;
-		case ITEM_STAFF:	olevel = number_range( 15, 25 ); break;
-		case ITEM_ARMOR:	olevel = number_range(  5, 15 ); break;
-		case ITEM_WEAPON:	olevel = number_range(  5, 15 ); break;
-		case ITEM_TREASURE:	olevel = number_range( 10, 20 ); break;
-		}
-
-		obj = create_object( pObjIndex, olevel );
-		SET_BIT( obj->extra_flags, ITEM_INVENTORY );
-	    }
+		    
+               case ITEM_WAND:         olevel = number_range( 10, 20 ); break;
+                case ITEM_STAFF:        olevel = number_range( 15, 25 ); break;
+                case ITEM_ARMOR:        olevel = number_range(  5, 15 ); break;
+                /* ROM patch weapon, treasure */
+		case ITEM_WEAPON:       olevel = number_range(  5, 15 ); break;
+		case ITEM_TREASURE:     olevel = number_range( 10, 20 ); break;
+
+#if 0 /* envy version */
+                case ITEM_WEAPON:       if ( pReset->command == 'G' )
+                                            olevel = number_range( 5, 15 );
+                                        else
+                                            olevel = number_fuzzy( level );
+#endif /* envy version */
+
+                  break;
+                }
+
+                pObj = create_object( pObjIndex, olevel );
+		SET_BIT( pObj->extra_flags, ITEM_INVENTORY );  /* ROM OLC */
+
+#if 0 /* envy version */
+                if ( pReset->command == 'G' )
+                    SET_BIT( pObj->extra_flags, ITEM_INVENTORY );
+#endif /* envy version */
 
-	    else
+            }
+	    else   /* ROM OLC else version */
 	    {
-		if (pReset->arg2 > 50) /* old format */
+		int limit;
+		if (pReset->arg2 > 50 )  /* old format */
 		    limit = 6;
-		else if (pReset->arg2 == -1) /* no limit */
+		else if ( pReset->arg2 == -1 || pReset->arg2 == 0 )  /* no limit */
 		    limit = 999;
 		else
 		    limit = pReset->arg2;
 
-		if (pObjIndex->count < limit || number_range(0,4) == 0)
+		if ( pObjIndex->count < limit || number_range(0,4) == 0 )
 		{
-		    obj=create_object(pObjIndex,UMIN(number_fuzzy(level),
-		    LEVEL_HERO - 1));
+		    pObj = create_object( pObjIndex, 
+			   UMIN( number_fuzzy( level ), LEVEL_HERO - 1 ) );
 		    /* error message if it is too high */
-		    if (obj->level > mob->level + 3
-		    ||  (obj->item_type == ITEM_WEAPON 
+		    if (pObj->level > LastMob->level + 3
+		    ||  (pObj->item_type == ITEM_WEAPON 
 		    &&   pReset->command == 'E' 
-		    &&   obj->level < mob->level -5 && obj->level < 45))
+		    &&   pObj->level < LastMob->level -5 && pObj->level < 45))
 			fprintf(stderr,
 			    "Err: obj %s (%d) -- %d, mob %s (%d) -- %d\n",
-			    obj->short_descr,obj->pIndexData->vnum,obj->level,
-			    mob->short_descr,mob->pIndexData->vnum,mob->level);
+			    pObj->short_descr,pObj->pIndexData->vnum,pObj->level,
+			    LastMob->short_descr,LastMob->pIndexData->vnum,LastMob->level);
 		}
 		else
 		    break;
 	    }
-	    obj_to_char( obj, mob );
-	    if ( pReset->command == 'E' )
-		equip_char( mob, obj, pReset->arg3 );
-	    last = TRUE;
-	    break;
-
-	case 'D':
-	    if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'D': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
-
-	    if ( ( pexit = pRoomIndex->exit[pReset->arg2] ) == NULL )
-		break;
+									 
+#if 0 /* envy else version */
+            else
+            {
+                pObj = create_object( pObjIndex, number_fuzzy( level ) );
+            }
+#endif /* envy else version */
 
-	    switch ( pReset->arg3 )
-	    {
-	    case 0:
-		REMOVE_BIT( pexit->exit_info, EX_CLOSED );
-		REMOVE_BIT( pexit->exit_info, EX_LOCKED );
-		break;
+            obj_to_char( pObj, LastMob );
+            if ( pReset->command == 'E' )
+                equip_char( LastMob, pObj, pReset->arg3 );
+            last = TRUE;
+            break;
 
-	    case 1:
-		SET_BIT(    pexit->exit_info, EX_CLOSED );
-		REMOVE_BIT( pexit->exit_info, EX_LOCKED );
-		break;
+        case 'D':
+            break;
 
-	    case 2:
-		SET_BIT(    pexit->exit_info, EX_CLOSED );
-		SET_BIT(    pexit->exit_info, EX_LOCKED );
-		break;
-	    }
+        case 'R':
+            if ( !( pRoomIndex = get_room_index( pReset->arg1 ) ) )
+            {
+                bug( "Reset_room: 'R': bad vnum %d.", pReset->arg1 );
+                continue;
+            }
 
-	    last = TRUE;
-	    break;
+            {
+                EXIT_DATA *pExit;
+                int d0;
+                int d1;
+
+                for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ )
+                {
+                    d1                   = number_range( d0, pReset->arg2-1 );
+                    pExit                = pRoomIndex->exit[d0];
+                    pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
+                    pRoomIndex->exit[d1] = pExit;
+                }
+            }
+            break;
+        }
+    }
 
-	case 'R':
-	    if ( ( pRoomIndex = get_room_index( pReset->arg1 ) ) == NULL )
-	    {
-		bug( "Reset_area: 'R': bad vnum %d.", pReset->arg1 );
-		continue;
-	    }
+    return;
+}
 
-	    {
-		int d0;
-		int d1;
+/* OLC
+ * Reset one area.
+ */
+void reset_area( AREA_DATA *pArea )
+{
+    ROOM_INDEX_DATA *pRoom;
+    int  vnum;
 
-		for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ )
-		{
-		    d1                   = number_range( d0, pReset->arg2-1 );
-		    pexit                = pRoomIndex->exit[d0];
-		    pRoomIndex->exit[d0] = pRoomIndex->exit[d1];
-		    pRoomIndex->exit[d1] = pexit;
-		}
-	    }
-	    break;
-	}
+    for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
+    {
+        if ( ( pRoom = get_room_index(vnum) ) )
+            reset_room(pRoom);
     }
 
     return;
 }
 
-
-
 /*
  * Create an instance of a mobile.
  */
@@ -1531,13 +1955,14 @@
 
     mob->pIndexData	= pMobIndex;
 
-    mob->name		= pMobIndex->player_name;
+    mob->name		= str_dup( pMobIndex->player_name );    /* OLC */
+    mob->short_descr	= str_dup( pMobIndex->short_descr );    /* OLC */
+    mob->long_descr	= str_dup( pMobIndex->long_descr );     /* OLC */
+    mob->description	= str_dup( pMobIndex->description );    /* OLC */
     mob->id		= get_mob_id();
-    mob->short_descr	= pMobIndex->short_descr;
-    mob->long_descr	= pMobIndex->long_descr;
-    mob->description	= pMobIndex->description;
     mob->spec_fun	= pMobIndex->spec_fun;
     mob->prompt		= NULL;
+    mob->mprog_target   = NULL;
 
     if (pMobIndex->wealth == 0)
     {
@@ -1845,9 +2270,9 @@
 	obj->level		= UMAX(0,level);
     obj->wear_loc	= -1;
 
-    obj->name		= pObjIndex->name;
-    obj->short_descr	= pObjIndex->short_descr;
-    obj->description	= pObjIndex->description;
+    obj->name		= str_dup( pObjIndex->name );           /* OLC */
+    obj->short_descr	= str_dup( pObjIndex->short_descr );    /* OLC */
+    obj->description	= str_dup( pObjIndex->description );    /* OLC */
     obj->material	= str_dup(pObjIndex->material);
     obj->item_type	= pObjIndex->item_type;
     obj->extra_flags	= pObjIndex->extra_flags;
@@ -2140,6 +2565,17 @@
     return NULL;
 }
 
+MPROG_CODE *get_mprog_index( int vnum )
+{
+    MPROG_CODE *prg;
+    for( prg = mprog_list; prg; prg = prg->next )
+    {
+    	if ( prg->vnum == vnum )
+            return( prg );
+    }
+    return NULL;
+}    
+
 
 
 /*
diff -ur src/db.h new/db.h
--- src/db.h	Sat May 23 22:27:21 1998
+++ new/db.h	Wed Mar 15 22:57:16 2000
@@ -50,3 +50,12 @@
 
 /* Magic number for memory allocation */
 #define MAGIC_NUM 52571214
+
+/* func from db.c */
+extern void assign_area_vnum( int vnum );                    /* OLC */
+
+/* from db2.c */
+ 
+void convert_mobile( MOB_INDEX_DATA *pMobIndex );            /* OLC ROM */
+void convert_objects( void );                                /* OLC ROM */
+void convert_object( OBJ_INDEX_DATA *pObjIndex );            /* OLC ROM */
diff -ur src/db2.c new/db2.c
--- src/db2.c	Sat May 23 22:27:26 1998
+++ new/db2.c	Wed Mar 15 22:57:16 2000
@@ -39,16 +39,24 @@
 
 #include "merc.h"
 #include "db.h"
+#include "tables.h"
 #include "lookup.h"
 
+extern int flag_lookup args((const char *name, const struct flag_type *flag_table));
 
 /* values for db2.c */
+#if defined(FIRST_BOOT)
 struct		social_type	social_table		[MAX_SOCIALS];
+#else
+struct		social_type *	social_table;
+#endif
 int		social_count;
 
 /* snarf a socials file */
 void load_socials( FILE *fp)
 {
+    extern int maxSocial;
+
     for ( ; ; ) 
     {
     	struct social_type social;
@@ -71,8 +79,8 @@
 	    fprintf(stderr,"%s\n\r",temp);
 #endif
 
-    	strcpy(social.name,temp);
-    	fread_to_eol(fp);
+    	social.name = str_dup(temp);
+	fread_to_eol(fp);
 
 	temp = fread_string_eol(fp);
 	if (!strcmp(temp,"$"))
@@ -172,6 +180,7 @@
 	
 	social_table[social_count] = social;
     	social_count++;
+    	maxSocial++;
    }
    return;
 }
@@ -188,6 +197,12 @@
 {
     MOB_INDEX_DATA *pMobIndex;
  
+    if ( !area_last )   /* OLC */
+    {
+        bug( "Load_mobiles: no #AREA seen yet.", 0 );
+        exit( 1 );
+    }
+
     for ( ; ; )
     {
         sh_int vnum;
@@ -215,6 +230,7 @@
  
         pMobIndex                       = alloc_perm( sizeof(*pMobIndex) );
         pMobIndex->vnum                 = vnum;
+        pMobIndex->area                 = area_last;               /* OLC */
 	pMobIndex->new_format		= TRUE;
 	newmobs++;
         pMobIndex->player_name          = fread_string( fp );
@@ -287,7 +303,8 @@
 	pMobIndex->parts		= fread_flag( fp )
 					| race_table[pMobIndex->race].parts;
 	/* size */
-	pMobIndex->size			= size_lookup(fread_word(fp));
+	CHECK_POS( pMobIndex->size, size_lookup(fread_word(fp)), "size" );
+/*	pMobIndex->size			= size_lookup(fread_word(fp)); */
 	pMobIndex->material		= str_dup(fread_word( fp ));
  
 	for ( ; ; )
@@ -324,6 +341,26 @@
 		    exit(1);
 		}
 	     }
+	     else if ( letter == 'M' )
+	     {
+		MPROG_LIST *pMprog;
+		char *word;
+		int trigger = 0;
+		
+		pMprog              = alloc_perm(sizeof(*pMprog));
+		word   		    = fread_word( fp );
+		if ( (trigger = flag_lookup( word, mprog_flags )) == NO_FLAG )
+		{
+		    bug("MOBprogs: invalid trigger.",0);
+		    exit(1);
+		}
+		SET_BIT( pMobIndex->mprog_flags, trigger );
+		pMprog->trig_type   = trigger;
+		pMprog->vnum        = fread_number( fp );
+		pMprog->trig_phrase = fread_string( fp );
+		pMprog->next        = pMobIndex->mprogs;
+		pMobIndex->mprogs   = pMprog;
+	     }
 	     else
 	     {
 		ungetc(letter,fp);
@@ -335,6 +372,8 @@
         pMobIndex->next         = mob_index_hash[iHash];
         mob_index_hash[iHash]   = pMobIndex;
         top_mob_index++;
+        top_vnum_mob = top_vnum_mob < vnum ? vnum : top_vnum_mob;  /* OLC */
+        assign_area_vnum( vnum );                                  /* OLC */
         kill_table[URANGE(0, pMobIndex->level, MAX_LEVEL-1)].number++;
     }
  
@@ -348,6 +387,12 @@
 {
     OBJ_INDEX_DATA *pObjIndex;
  
+    if ( !area_last )   /* OLC */
+    {
+        bug( "Load_objects: no #AREA seen yet.", 0 );
+        exit( 1 );
+    }
+
     for ( ; ; )
     {
         sh_int vnum;
@@ -375,6 +420,7 @@
  
         pObjIndex                       = alloc_perm( sizeof(*pObjIndex) );
         pObjIndex->vnum                 = vnum;
+        pObjIndex->area                 = area_last;            /* OLC */
         pObjIndex->new_format           = TRUE;
 	pObjIndex->reset_num		= 0;
 	newobjs++;
@@ -382,8 +428,8 @@
         pObjIndex->short_descr          = fread_string( fp );
         pObjIndex->description          = fread_string( fp );
         pObjIndex->material		= fread_string( fp );
- 
-        pObjIndex->item_type            = item_lookup(fread_word( fp ));
+
+	CHECK_POS(pObjIndex->item_type, item_lookup(fread_word( fp )), "item_type" );
         pObjIndex->extra_flags          = fread_flag( fp );
         pObjIndex->wear_flags           = fread_flag( fp );
 	switch(pObjIndex->item_type)
@@ -406,7 +452,7 @@
 	case ITEM_FOUNTAIN:
             pObjIndex->value[0]         = fread_number(fp);
             pObjIndex->value[1]         = fread_number(fp);
-            pObjIndex->value[2]         = liq_lookup(fread_word(fp));
+	    CHECK_POS(pObjIndex->value[2], liq_lookup(fread_word(fp)), "liq_lookup" );
             pObjIndex->value[3]         = fread_number(fp);
             pObjIndex->value[4]         = fread_number(fp);
             break;
@@ -534,8 +580,445 @@
         pObjIndex->next         = obj_index_hash[iHash];
         obj_index_hash[iHash]   = pObjIndex;
         top_obj_index++;
+        top_vnum_obj = top_vnum_obj < vnum ? vnum : top_vnum_obj;   /* OLC */
+        assign_area_vnum( vnum );                                   /* OLC */
     }
  
     return;
 }
 
+/*****************************************************************************
+ Name:	        convert_objects
+ Purpose:	Converts all old format objects to new format
+ Called by:	boot_db (db.c).
+ Note:          Loops over all resets to find the level of the mob
+                loaded before the object to determine the level of
+                the object.
+		It might be better to update the levels in load_resets().
+		This function is not pretty.. Sorry about that :)
+ Author:        Hugin
+ ****************************************************************************/
+void convert_objects( void )
+{
+    int vnum;
+    AREA_DATA  *pArea;
+    RESET_DATA *pReset;
+    MOB_INDEX_DATA *pMob = NULL;
+    OBJ_INDEX_DATA *pObj;
+    ROOM_INDEX_DATA *pRoom;
+
+    if ( newobjs == top_obj_index ) return; /* all objects in new format */
+
+    for ( pArea = area_first; pArea; pArea = pArea->next )
+    {
+        for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
+	{
+	    if ( !( pRoom = get_room_index( vnum ) ) ) continue;
+
+	    for ( pReset = pRoom->reset_first; pReset; pReset = pReset->next )
+	    {
+		switch ( pReset->command )
+		{
+		case 'M':
+		    if ( !( pMob = get_mob_index( pReset->arg1 ) ) )
+			bug( "Convert_objects: 'M': bad vnum %d.", pReset->arg1 );
+		    break;
+
+		case 'O':
+		    if ( !( pObj = get_obj_index( pReset->arg1 ) ) )
+		    {
+			bug( "Convert_objects: 'O': bad vnum %d.", pReset->arg1 );
+			break;
+		    }
+
+		    if ( pObj->new_format )
+			continue;
+
+		    if ( !pMob )
+		    {
+			bug( "Convert_objects: 'O': No mob reset yet.", 0 );
+			break;
+		    }
+
+		    pObj->level = pObj->level < 1 ? pMob->level - 2
+			: UMIN(pObj->level, pMob->level - 2);
+		    break;
+
+		case 'P':
+		    {
+			OBJ_INDEX_DATA *pObj, *pObjTo;
+
+			if ( !( pObj = get_obj_index( pReset->arg1 ) ) )
+			{
+			    bug( "Convert_objects: 'P': bad vnum %d.", pReset->arg1 );
+			    break;
+			}
+
+			if ( pObj->new_format )
+			    continue;
+
+			if ( !( pObjTo = get_obj_index( pReset->arg3 ) ) )
+			{
+			    bug( "Convert_objects: 'P': bad vnum %d.", pReset->arg3 );
+			    break;
+			}
+
+			pObj->level = pObj->level < 1 ? pObjTo->level
+			    : UMIN(pObj->level, pObjTo->level);
+		    }
+		    break;
+
+		case 'G':
+		case 'E':
+		    if ( !( pObj = get_obj_index( pReset->arg1 ) ) )
+		    {
+			bug( "Convert_objects: 'E' or 'G': bad vnum %d.", pReset->arg1 );
+			break;
+		    }
+
+		    if ( !pMob )
+		    {
+			bug( "Convert_objects: 'E' or 'G': null mob for vnum %d.",
+			     pReset->arg1 );
+			break;
+		    }
+
+		    if ( pObj->new_format )
+			continue;
+
+		    if ( pMob->pShop )
+		    {
+			switch ( pObj->item_type )
+			{
+			default:
+			    pObj->level = UMAX(0, pObj->level);
+			    break;
+			case ITEM_PILL:
+			case ITEM_POTION:
+			    pObj->level = UMAX(5, pObj->level);
+			    break;
+			case ITEM_SCROLL:
+			case ITEM_ARMOR:
+			case ITEM_WEAPON:
+			    pObj->level = UMAX(10, pObj->level);
+			    break;
+			case ITEM_WAND:
+			case ITEM_TREASURE:
+			    pObj->level = UMAX(15, pObj->level);
+			    break;
+			case ITEM_STAFF:
+			    pObj->level = UMAX(20, pObj->level);
+			    break;
+			}
+		    }
+		    else
+			pObj->level = pObj->level < 1 ? pMob->level
+			    : UMIN( pObj->level, pMob->level );
+		    break;
+		} /* switch ( pReset->command ) */
+	    }
+	}
+    }
+
+    /* do the conversion: */
+
+    for ( pArea = area_first; pArea ; pArea = pArea->next )
+	for ( vnum = pArea->min_vnum; vnum <= pArea->max_vnum; vnum++ )
+	    if ( (pObj = get_obj_index( vnum )) )
+ 		if ( !pObj->new_format )
+		    convert_object( pObj );
+
+    return;
+}
+
+
+
+/*****************************************************************************
+ Name:		convert_object
+ Purpose:	Converts an old_format obj to new_format
+ Called by:	convert_objects (db2.c).
+ Note:          Dug out of create_obj (db.c)
+ Author:        Hugin
+ ****************************************************************************/
+void convert_object( OBJ_INDEX_DATA *pObjIndex )
+{
+    int level;
+    int number, type;  /* for dice-conversion */
+
+    if ( !pObjIndex || pObjIndex->new_format ) return;
+
+    level = pObjIndex->level;
+
+    pObjIndex->level    = UMAX( 0, pObjIndex->level ); /* just to be sure */
+    pObjIndex->cost     = 10*level;
+
+    switch ( pObjIndex->item_type )
+    {
+        default:
+            bug( "Obj_convert: vnum %d bad type.", pObjIndex->item_type );
+            break;
+
+        case ITEM_LIGHT:
+        case ITEM_TREASURE:
+        case ITEM_FURNITURE:
+        case ITEM_TRASH:
+        case ITEM_CONTAINER:
+        case ITEM_DRINK_CON:
+        case ITEM_KEY:
+        case ITEM_FOOD:
+        case ITEM_BOAT:
+        case ITEM_CORPSE_NPC:
+        case ITEM_CORPSE_PC:
+        case ITEM_FOUNTAIN:
+        case ITEM_MAP:
+        case ITEM_CLOTHING:
+        case ITEM_SCROLL:
+	    break;
+
+        case ITEM_WAND:
+        case ITEM_STAFF:
+            pObjIndex->value[2] = pObjIndex->value[1];
+	    break;
+
+        case ITEM_WEAPON:
+
+	    /*
+	     * The conversion below is based on the values generated
+	     * in one_hit() (fight.c).  Since I don't want a lvl 50 
+	     * weapon to do 15d3 damage, the min value will be below
+	     * the one in one_hit, and to make up for it, I've made 
+	     * the max value higher.
+	     * (I don't want 15d2 because this will hardly ever roll
+	     * 15 or 30, it will only roll damage close to 23.
+	     * I can't do 4d8+11, because one_hit there is no dice-
+	     * bounus value to set...)
+	     *
+	     * The conversion below gives:
+
+	     level:   dice      min      max      mean
+	       1:     1d8      1( 2)    8( 7)     5( 5)
+	       2:     2d5      2( 3)   10( 8)     6( 6)
+	       3:     2d5      2( 3)   10( 8)     6( 6)
+	       5:     2d6      2( 3)   12(10)     7( 7)
+	      10:     4d5      4( 5)   20(14)    12(10)
+	      20:     5d5      5( 7)   25(21)    15(14)
+	      30:     5d7      5(10)   35(29)    20(20)
+	      50:     5d11     5(15)   55(44)    30(30)
+
+	     */
+
+	    number = UMIN(level/4 + 1, 5);
+	    type   = (level + 7)/number;
+
+            pObjIndex->value[1] = number;
+            pObjIndex->value[2] = type;
+	    break;
+
+        case ITEM_ARMOR:
+            pObjIndex->value[0] = level / 5 + 3;
+            pObjIndex->value[1] = pObjIndex->value[0];
+            pObjIndex->value[2] = pObjIndex->value[0];
+	    break;
+
+        case ITEM_POTION:
+        case ITEM_PILL:
+            break;
+
+        case ITEM_MONEY:
+	    pObjIndex->value[0] = pObjIndex->cost;
+	    break;
+    }
+
+    pObjIndex->new_format = TRUE;
+    ++newobjs;
+
+    return;
+}
+
+
+
+
+/*****************************************************************************
+ Name:		convert_mobile
+ Purpose:	Converts an old_format mob into new_format
+ Called by:	load_old_mob (db.c).
+ Note:          Dug out of create_mobile (db.c)
+ Author:        Hugin
+ ****************************************************************************/
+void convert_mobile( MOB_INDEX_DATA *pMobIndex )
+{
+    int i;
+    int type, number, bonus;
+    int level;
+
+    if ( !pMobIndex || pMobIndex->new_format ) return;
+
+    level = pMobIndex->level;
+
+    pMobIndex->act              |= ACT_WARRIOR;
+
+    /*
+     * Calculate hit dice.  Gives close to the hitpoints
+     * of old format mobs created with create_mobile()  (db.c)
+     * A high number of dice makes for less variance in mobiles
+     * hitpoints.
+     * (might be a good idea to reduce the max number of dice)
+     *
+     * The conversion below gives:
+
+       level:     dice         min         max        diff       mean
+         1:       1d2+6       7(  7)     8(   8)     1(   1)     8(   8)
+	 2:       1d3+15     16( 15)    18(  18)     2(   3)    17(  17)
+	 3:       1d6+24     25( 24)    30(  30)     5(   6)    27(  27)
+	 5:      1d17+42     43( 42)    59(  59)    16(  17)    51(  51)
+	10:      3d22+96     99( 95)   162( 162)    63(  67)   131(    )
+	15:     5d30+161    166(159)   311( 311)   145( 150)   239(    )
+	30:    10d61+416    426(419)  1026(1026)   600( 607)   726(    )
+	50:    10d169+920   930(923)  2610(2610)  1680(1688)  1770(    )
+
+	The values in parenthesis give the values generated in create_mobile.
+        Diff = max - min.  Mean is the arithmetic mean.
+	(hmm.. must be some roundoff error in my calculations.. smurfette got
+	 1d6+23 hp at level 3 ? -- anyway.. the values above should be
+	 approximately right..)
+     */
+    type   = level*level*27/40;
+    number = UMIN(type/40 + 1, 10); /* how do they get 11 ??? */
+    type   = UMAX(2, type/number);
+    bonus  = UMAX(0, level*(8 + level)*.9 - number*type);
+
+    pMobIndex->hit[DICE_NUMBER]    = number;
+    pMobIndex->hit[DICE_TYPE]      = type;
+    pMobIndex->hit[DICE_BONUS]     = bonus;
+
+    pMobIndex->mana[DICE_NUMBER]   = level;
+    pMobIndex->mana[DICE_TYPE]     = 10;
+    pMobIndex->mana[DICE_BONUS]    = 100;
+
+    /*
+     * Calculate dam dice.  Gives close to the damage
+     * of old format mobs in damage()  (fight.c)
+     */
+    type   = level*7/4;
+    number = UMIN(type/8 + 1, 5);
+    type   = UMAX(2, type/number);
+    bonus  = UMAX(0, level*9/4 - number*type);
+
+    pMobIndex->damage[DICE_NUMBER] = number;
+    pMobIndex->damage[DICE_TYPE]   = type;
+    pMobIndex->damage[DICE_BONUS]  = bonus;
+
+    switch ( number_range( 1, 3 ) )
+    {
+        case (1): pMobIndex->dam_type =  3;       break;  /* slash  */
+        case (2): pMobIndex->dam_type =  7;       break;  /* pound  */
+        case (3): pMobIndex->dam_type = 11;       break;  /* pierce */
+    }
+
+    for (i = 0; i < 3; i++)
+        pMobIndex->ac[i]         = interpolate( level, 100, -100);
+    pMobIndex->ac[3]             = interpolate( level, 100, 0);    /* exotic */
+
+    pMobIndex->wealth           /= 100;
+    pMobIndex->size              = SIZE_MEDIUM;
+    pMobIndex->material          = str_dup("none");
+
+    pMobIndex->new_format        = TRUE;
+    ++newmobs;
+
+    return;
+}
+
+void recalc( MOB_INDEX_DATA *pMob )
+{
+	int hplev, aclev, damlev, hitbonus;
+	int i, cnt = 0, clase[10];
+	float n;
+
+	if ( pMob->level == 0 )
+		return;
+
+	hplev = 0; aclev = 0; damlev = 0; hitbonus = 0;
+
+	if ( IS_SET(pMob->act, ACT_WARRIOR) )
+	{
+		hplev += 1;
+		clase[cnt++] = ACT_WARRIOR;
+	}
+
+	if ( IS_SET(pMob->act, ACT_THIEF) )
+	{
+		hplev -= 1; aclev -= 1; damlev -= 1;
+		clase[cnt++] = ACT_THIEF;
+	}
+
+	if ( IS_SET(pMob->act, ACT_CLERIC) )
+	{
+		damlev -= 2;
+		clase[cnt++] = ACT_CLERIC;
+	}
+
+	if ( IS_SET(pMob->act, ACT_MAGE) )
+	{
+//		hplev -= 1; aclev -= 1; damlev -= 3;
+		hplev -= 2; aclev -= 1; damlev -= 3;
+		clase[cnt++] = ACT_MAGE;
+	}
+
+	hplev	+= pMob->level;
+	aclev	+= pMob->level;
+	damlev	+= pMob->level;
+
+	hplev	= URANGE( 1, hplev, 60 ) - 1;
+	aclev	= URANGE( 1, aclev, 60 ) - 1;
+	damlev	= URANGE( 1, damlev, 60 ) - 1;
+
+	pMob->hit[DICE_NUMBER]		= recval_table[hplev].numhit;
+	pMob->hit[DICE_TYPE]		= recval_table[hplev].typhit;
+	pMob->hit[DICE_BONUS]		= recval_table[hplev].bonhit;
+
+	pMob->damage[DICE_NUMBER]	= recval_table[damlev].numdam;
+	pMob->damage[DICE_TYPE]		= recval_table[damlev].typdam;
+	pMob->damage[DICE_BONUS]	= recval_table[damlev].bondam;
+
+	pMob->mana[DICE_NUMBER]		= pMob->level;
+	pMob->mana[DICE_TYPE]		= 10 + (pMob->level / 8);
+	pMob->mana[DICE_BONUS]		= 100;
+
+	if ( IS_SET(pMob->act, ACT_CLERIC) || IS_SET(pMob->act, ACT_MAGE) )
+		pMob->mana[DICE_BONUS]	*= (1 + pMob->level / 3);
+
+	for ( i = 0; i < 3; i++ )
+		pMob->ac[i]	= recval_table[aclev].ac * 10;
+
+	if ( IS_SET(pMob->act, ACT_UNDEAD)
+	||   IS_SET(pMob->form, FORM_UNDEAD)
+	||   IS_SET(pMob->form, FORM_MAGICAL) )
+		n	= 0;
+	else
+	if ( IS_SET(pMob->act, ACT_MAGE) )
+		n	= 1;
+	else
+	if ( IS_SET(pMob->act,ACT_THIEF)
+	||   IS_SET(pMob->act,ACT_CLERIC) )
+		n	= 2;
+	else
+		n	= 3;
+
+	aclev = UMAX(0, aclev - n);
+
+	pMob->ac[3]	= recval_table[aclev].ac * 10;
+
+	if ( IS_SET(pMob->act, ACT_WARRIOR) )
+		hitbonus = pMob->level * 3 / 2;
+	else
+	if ( IS_SET(pMob->act, ACT_THIEF) )
+		hitbonus = pMob->level * 2 / 3;
+	else
+	if ( IS_SET(pMob->act, ACT_CLERIC) || IS_SET(pMob->act, ACT_MAGE) )
+		hitbonus = pMob->level / 2;
+
+	pMob->hitroll	= hitbonus;
+
+	return;
+}
diff -ur src/fight.c new/fight.c
--- src/fight.c	Thu May 28 00:39:30 1998
+++ new/fight.c	Wed Mar 15 22:57:16 2000
@@ -70,7 +70,7 @@
     CHAR_DATA *ch_next;
     CHAR_DATA *victim;
 
-    for ( ch = char_list; ch != NULL; ch = ch->next )
+    for ( ch = char_list; ch != NULL; ch = ch_next )
     {
 	ch_next	= ch->next;
 
@@ -89,6 +89,14 @@
 	 * Fun for the whole family!
 	 */
 	check_assist(ch,victim);
+
+	if ( IS_NPC( ch ) )
+	{
+	    if ( HAS_TRIGGER( ch, TRIG_FIGHT ) )
+		mp_percent_trigger( ch, victim, NULL, NULL, TRIG_FIGHT );
+	    if ( HAS_TRIGGER( ch, TRIG_HPCNT ) )
+		mp_hprct_trigger( ch, victim );
+	}
     }
 
     return;
@@ -722,7 +730,11 @@
 	if ( victim->position > POS_STUNNED )
 	{
 	    if ( victim->fighting == NULL )
+	    {
 		set_fighting( victim, ch );
+		if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_KILL ) )
+		    mp_percent_trigger( victim, ch, NULL, NULL, TRIG_KILL );
+	    }
 	    if (victim->timer <= 4)
 	    	victim->position = POS_FIGHTING;
 	}
@@ -893,6 +905,15 @@
         else
             wiznet(log_buf,NULL,NULL,WIZ_DEATHS,0,0);
 
+	/*
+	 * Death trigger
+	 */
+	if ( IS_NPC( victim ) && HAS_TRIGGER( victim, TRIG_DEATH) )
+	{
+	    victim->position = POS_STANDING;
+	    mp_percent_trigger( victim, ch, NULL, NULL, TRIG_DEATH );
+	}
+
 	raw_kill( victim );
         /* dump the flags */
         if (ch != victim && !IS_NPC(ch) && !is_same_clan(ch,victim))
@@ -3047,7 +3068,27 @@
     return;
 }
 
+void do_surrender( CHAR_DATA *ch, char *argument )
+{
+    CHAR_DATA *mob;
+    if ( (mob = ch->fighting) == NULL )
+    {
+	send_to_char( "But you're not fighting!\n\r", ch );
+	return;
+    }
+    act( "You surrender to $N!", ch, NULL, mob, TO_CHAR );
+    act( "$n surrenders to you!", ch, NULL, mob, TO_VICT );
+    act( "$n tries to surrender to $N!", ch, NULL, mob, TO_NOTVICT );
+    stop_fighting( ch, TRUE );
 
+    if ( !IS_NPC( ch ) && IS_NPC( mob ) 
+    &&   ( !HAS_TRIGGER( mob, TRIG_SURR ) 
+        || !mp_percent_trigger( mob, ch, NULL, NULL, TRIG_SURR ) ) )
+    {
+	act( "$N seems to ignore your cowardly act!", ch, NULL, mob, TO_CHAR );
+	multi_hit( mob, ch, TYPE_UNDEFINED );
+    }
+}
 
 void do_sla( CHAR_DATA *ch, char *argument )
 {
diff -ur src/flags.c new/flags.c
--- src/flags.c	Sat May 23 22:27:35 1998
+++ new/flags.c	Wed Mar 15 22:57:16 2000
@@ -203,7 +203,8 @@
 		break;
 
 	    pos = flag_lookup(word,flag_table);
-	    if (pos == 0)
+
+	    if (pos == NO_FLAG)
 	    {
 		send_to_char("That flag doesn't exist!\n\r",ch);
 		return;
diff -ur src/handler.c new/handler.c
--- src/handler.c	Thu May 28 00:30:47 1998
+++ new/handler.c	Wed Mar 15 22:57:16 2000
@@ -112,35 +112,6 @@
     return 0;
 }
 
-/* returns race number */
-int race_lookup (const char *name)
-{
-   int race;
-
-   for ( race = 0; race_table[race].name != NULL; race++)
-   {
-	if (LOWER(name[0]) == LOWER(race_table[race].name[0])
-	&&  !str_prefix( name,race_table[race].name))
-	    return race;
-   }
-
-   return 0;
-} 
-
-int liq_lookup (const char *name)
-{
-    int liq;
-
-    for ( liq = 0; liq_table[liq].liq_name != NULL; liq++)
-    {
-	if (LOWER(name[0]) == LOWER(liq_table[liq].liq_name[0])
-	&& !str_prefix(name,liq_table[liq].liq_name))
-	    return liq;
-    }
-
-    return -1;
-}
-
 int weapon_lookup (const char *name)
 {
     int type;
@@ -169,21 +140,6 @@
     return WEAPON_EXOTIC;
 }
 
-
-int item_lookup(const char *name)
-{
-    int type;
-
-    for (type = 0; item_table[type].name != NULL; type++)
-    {
-        if (LOWER(name[0]) == LOWER(item_table[type].name[0])
-        &&  !str_prefix(name,item_table[type].name))
-            return item_table[type].type;
-    }
- 
-    return -1;
-}
-
 char *item_name(int item_type)
 {
     int type;
@@ -735,7 +691,11 @@
 
     else
     {
+#if defined(FIRST_BOOT)
 	max = pc_race_table[ch->race].max_stats[stat] + 4;
+#else
+	max = race_table[ch->race].max_stats[stat] + 4;
+#endif
 
 	if (class_table[ch->class].attr_prime == stat)
 	    max += 2;
@@ -757,7 +717,11 @@
     if (IS_NPC(ch) || ch->level > LEVEL_IMMORTAL)
 	return 25;
 
+#if defined(FIRST_BOOT)
     max = pc_race_table[ch->race].max_stats[stat];
+#else
+    max = race_table[ch->race].max_stats[stat];
+#endif
     if (class_table[ch->class].attr_prime == stat)
 	if (ch->race == race_lookup("human"))
 	   max += 3;
@@ -1972,6 +1936,8 @@
     {
 	if ( wch->reply == ch )
 	    wch->reply = NULL;
+	if ( ch->mprog_target == wch )
+	    wch->mprog_target = NULL;
     }
 
     if ( ch == char_list )
@@ -2908,3 +2874,70 @@
 
     return ( buf[0] != '\0' ) ? buf+1 : "none";
 }
+
+bool emptystring( const char * str )
+{
+	int i = 0;
+
+	for ( ; str[i]; i++ )
+		if ( str[i] != ' ' )
+			return FALSE;
+
+	return TRUE;
+}
+
+char *itos( int temp )
+{
+	static char buf[64];
+
+	sprintf( buf, "%d", temp );
+
+	return buf;
+}
+
+int get_vnum_mob_name_area( char * name, AREA_DATA * pArea )
+{
+	int hash;
+	MOB_INDEX_DATA * mob;
+
+	for ( hash = 0; hash < MAX_KEY_HASH; hash++ )
+		for ( mob = mob_index_hash[hash]; mob; mob = mob->next )
+			if ( mob->area == pArea
+			&&  !str_prefix(name, mob->player_name) )
+				return mob->vnum;
+
+	return 0;
+}
+
+int get_vnum_obj_name_area( char * name, AREA_DATA * pArea )
+{
+	int hash;
+	OBJ_INDEX_DATA * obj;
+
+	for ( hash = 0; hash < MAX_KEY_HASH; hash++ )
+		for ( obj = obj_index_hash[hash]; obj; obj = obj->next )
+			if ( obj->area == pArea
+			&&  !str_prefix(name, obj->name) )
+				return obj->vnum;
+
+	return 0;
+}
+
+#if !defined(FIRST_BOOT)
+int get_points( int race, int class )
+{
+	int x;
+
+	x = group_lookup(class_table[class].default_group);
+
+	if ( x == -1 )
+	{
+		bugf( "get_points : group %s doesn't exist, create %d, clase %d",
+			class_table[class].default_group,
+			race, class );
+		return -1;
+	}
+
+	return group_table[x].rating[class] + race_table[race].points;
+}
+#endif
diff -ur src/interp.c new/interp.c
--- src/interp.c	Mon May 25 07:12:59 1998
+++ new/interp.c	Wed Mar 15 22:57:16 2000
@@ -61,6 +61,7 @@
 /*
  * Command table.
  */
+#if defined(FIRST_BOOT)
 const	struct	cmd_type	cmd_table	[] =
 {
     /*
@@ -246,9 +247,15 @@
     { "murde",		do_murde,	POS_FIGHTING,	 0,  LOG_NORMAL, 0 },
     { "murder",		do_murder,	POS_FIGHTING,	 5,  LOG_ALWAYS, 1 },
     { "rescue",		do_rescue,	POS_FIGHTING,	 0,  LOG_NORMAL, 0 },
+    { "surrender",	do_surrender,	POS_FIGHTING,    0,  LOG_NORMAL, 1 },
     { "trip",		do_trip,	POS_FIGHTING,    0,  LOG_NORMAL, 1 },
 
     /*
+     * Mob command interpreter (placed here for faster scan...)
+     */
+    { "mob",		do_mob,		POS_DEAD,	 0,  LOG_NEVER,  0 },
+
+    /*
      * Miscellaneous commands.
      */
     { "enter", 		do_enter, 	POS_STANDING,	 0,  LOG_NORMAL, 1 },
@@ -350,15 +357,121 @@
     { "smote",		do_smote,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
     { "prefi",		do_prefi,	POS_DEAD,	IM,  LOG_NORMAL, 0 },
     { "prefix",		do_prefix,	POS_DEAD,	IM,  LOG_NORMAL, 1 },
+    { "mpdump",		do_mpdump,	POS_DEAD,	IM,  LOG_NEVER,  1 },
+    { "mpstat",		do_mpstat,	POS_DEAD,	IM,  LOG_NEVER,  1 },
+
+    /*
+     * OLC
+     */
+    { "edit",		do_olc,		POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "asave",          do_asave,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "alist",		do_alist,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "resets",		do_resets,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "redit",		do_redit,	POS_DEAD,    0,	 LOG_NORMAL, 1 },
+    { "medit",		do_medit,	POS_DEAD,    0,	 LOG_NORMAL, 1 },
+    { "aedit",		do_aedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "oedit",		do_oedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "mpedit",		do_pedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "hedit",		do_hedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "skedit",		do_skedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "raedit",		do_raedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "sedit",		do_sedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "gedit",		do_gedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "cmdedit",	do_cmdedit,	POS_DEAD,    0,  LOG_NORMAL, 1 },
+    { "olcx",		do_olcx,	POS_DEAD,    0,  LOG_NORMAL, 1 },
 
     /*
      * End of list.
      */
     { "",		0,		POS_DEAD,	 0,  LOG_NORMAL, 0 }
 };
+#else
+void ordenar_tabla_com( void )
+{
+	int i, j, cnt, maxcnt = 0, cntl[27], ilet, calc;
+	char letra;
+	struct cmd_type *new_cmd_table;
+	struct cmd_type **temptabla;
+
+	for ( i = 0; i < 27; ++i )
+		cntl[i] = 0;
+
+	for ( i = 0; i < 26; i++ )
+	{
+		cnt = 0;
+
+		for ( j = 0; j < MAX_CMD; ++j )
+		{
+			letra = LOWER(cmd_table[j].name[0]) - 'a';
+			if ( i == (int) letra )
+				cnt++;
+		}
+
+		if ( cnt > maxcnt )
+			maxcnt = cnt;
+	}
+
+	temptabla = calloc( (maxcnt*27), sizeof(struct cmd_type *) );
+
+	for ( i = 0; i < (maxcnt*27); ++i )
+		temptabla[i] = NULL;
 
+	for ( i = 0; i < MAX_CMD; ++i )
+	{
+		if ( !isalpha(cmd_table[i].name[0]) )
+			temptabla[cntl[0]++] = &cmd_table[i];
+		else
+		{
+			letra = LOWER(cmd_table[i].name[0]);
+			ilet = (int) letra;
+			ilet -= 'a';
+			ilet++;
+			cntl[ilet]++;
+			calc = (maxcnt * ilet) + cntl[ilet];
+			temptabla[calc] = &cmd_table[i];
+		}
+	}
+
+	new_cmd_table = malloc (sizeof(struct cmd_type) * (MAX_CMD + 1));
+
+	i = cnt = 0;
+	while ( i < (maxcnt*27) )
+	{
+		if ( temptabla[i] )
+			new_cmd_table[cnt++] = *temptabla[i];
+		i++;
+	}
 
+	new_cmd_table[MAX_CMD].name = str_dup( "" );
+
+	free(temptabla);
+	free(cmd_table);
+	cmd_table = new_cmd_table;
+}
 
+int	num_letra[26];
+
+void crear_tabla_com( void )
+{
+	int cmd;
+	char letra;
+
+	/* Ordenar tabla e inicializar vector */
+	ordenar_tabla_com();
+	for ( cmd = 0; cmd < 26; cmd++ )
+		num_letra[cmd] = -1;
+
+	for ( cmd = 0; cmd_table[cmd].name[0] != '\0'; ++cmd )
+	{
+		letra = LOWER(cmd_table[cmd].name[0]);
+		if ( !isalpha(letra) )
+			continue;
+		letra -= 'a'; /* rango 0...26-1 */
+		if ( num_letra[(int) letra] == -1 )
+			num_letra[(int) letra] = cmd;
+	}
+}
+#endif
 
 /*
  * The main entry point for executing commands.
@@ -533,7 +646,7 @@
     bool found;
 
     found  = FALSE;
-    for ( cmd = 0; social_table[cmd].name[0] != '\0'; cmd++ )
+    for ( cmd = 0; !IS_NULLSTR(social_table[cmd].name); cmd++ )
     {
 	if ( command[0] == social_table[cmd].name[0]
 	&&   !str_prefix( command, social_table[cmd].name ) )
diff -ur src/interp.h new/interp.h
--- src/interp.h	Thu May 28 00:44:20 1998
+++ new/interp.h	Wed Mar 15 22:57:16 2000
@@ -51,7 +51,7 @@
  */
 struct	cmd_type
 {
-    char * const	name;
+    char *		name;
     DO_FUN *		do_fun;
     sh_int		position;
     sh_int		level;
@@ -60,239 +60,12 @@
 };
 
 /* the command table itself */
+#if defined(FIRST_BOOT)
 extern	const	struct	cmd_type	cmd_table	[];
+#else
+extern		struct	cmd_type *	cmd_table;
+#endif
 
-/*
- * Command functions.
- * Defined in act_*.c (mostly).
- */
-DECLARE_DO_FUN(	do_advance	);
-DECLARE_DO_FUN( do_affects	);
-DECLARE_DO_FUN( do_afk		);
-DECLARE_DO_FUN( do_alia		);
-DECLARE_DO_FUN( do_alias	);
-DECLARE_DO_FUN(	do_allow	);
-DECLARE_DO_FUN( do_answer	);
-DECLARE_DO_FUN(	do_areas	);
-DECLARE_DO_FUN(	do_at		);
-DECLARE_DO_FUN(	do_auction	);
-DECLARE_DO_FUN( do_autoassist	);
-DECLARE_DO_FUN( do_autoexit	);
-DECLARE_DO_FUN( do_autogold	);
-DECLARE_DO_FUN( do_autolist	);
-DECLARE_DO_FUN( do_autoloot	);
-DECLARE_DO_FUN( do_autosac	);
-DECLARE_DO_FUN( do_autosplit	);
-DECLARE_DO_FUN(	do_backstab	);
-DECLARE_DO_FUN(	do_bamfin	);
-DECLARE_DO_FUN(	do_bamfout	);
-DECLARE_DO_FUN(	do_ban		);
-DECLARE_DO_FUN( do_bash		);
-DECLARE_DO_FUN( do_berserk	);
-DECLARE_DO_FUN(	do_brandish	);
-DECLARE_DO_FUN( do_brief	);
-DECLARE_DO_FUN(	do_bug		);
-DECLARE_DO_FUN(	do_buy		);
-DECLARE_DO_FUN(	do_cast		);
-DECLARE_DO_FUN( do_changes	);
-DECLARE_DO_FUN( do_channels	);
-DECLARE_DO_FUN( do_clone	);
-DECLARE_DO_FUN(	do_close	);
-DECLARE_DO_FUN(	do_commands	);
-DECLARE_DO_FUN( do_combine	);
-DECLARE_DO_FUN( do_compact	);
-DECLARE_DO_FUN(	do_compare	);
-DECLARE_DO_FUN(	do_consider	);
-DECLARE_DO_FUN( do_count	);
-DECLARE_DO_FUN(	do_credits	);
-DECLARE_DO_FUN( do_deaf		);
-DECLARE_DO_FUN( do_delet	);
-DECLARE_DO_FUN( do_delete	);
-DECLARE_DO_FUN(	do_deny		);
-DECLARE_DO_FUN(	do_description	);
-DECLARE_DO_FUN( do_dirt		);
-DECLARE_DO_FUN(	do_disarm	);
-DECLARE_DO_FUN(	do_disconnect	);
-DECLARE_DO_FUN(	do_down		);
-DECLARE_DO_FUN(	do_drink	);
-DECLARE_DO_FUN(	do_drop		);
-DECLARE_DO_FUN( do_dump		);
-DECLARE_DO_FUN(	do_east		);
-DECLARE_DO_FUN(	do_eat		);
-DECLARE_DO_FUN(	do_echo		);
-DECLARE_DO_FUN(	do_emote	);
-DECLARE_DO_FUN( do_enter	);
-DECLARE_DO_FUN( do_envenom	);
-DECLARE_DO_FUN(	do_equipment	);
-DECLARE_DO_FUN(	do_examine	);
-DECLARE_DO_FUN(	do_exits	);
-DECLARE_DO_FUN(	do_fill		);
-DECLARE_DO_FUN( do_flag		);
-DECLARE_DO_FUN(	do_flee		);
-DECLARE_DO_FUN(	do_follow	);
-DECLARE_DO_FUN(	do_force	);
-DECLARE_DO_FUN(	do_freeze	);
-DECLARE_DO_FUN( do_gain		);
-DECLARE_DO_FUN(	do_get		);
-DECLARE_DO_FUN(	do_give		);
-DECLARE_DO_FUN( do_gossip	);
-DECLARE_DO_FUN(	do_goto		);
-DECLARE_DO_FUN( do_grats	);
-DECLARE_DO_FUN(	do_group	);
-DECLARE_DO_FUN( do_groups	);
-DECLARE_DO_FUN(	do_gtell	);
-DECLARE_DO_FUN( do_guild    	);
-DECLARE_DO_FUN( do_heal		);
-DECLARE_DO_FUN(	do_help		);
-DECLARE_DO_FUN(	do_hide		);
-DECLARE_DO_FUN(	do_holylight	);
-DECLARE_DO_FUN(	do_idea		);
-DECLARE_DO_FUN(	do_immtalk	);
-DECLARE_DO_FUN( do_incognito	);
-DECLARE_DO_FUN( do_clantalk	);
-DECLARE_DO_FUN( do_imotd	);
-DECLARE_DO_FUN(	do_inventory	);
-DECLARE_DO_FUN(	do_invis	);
-DECLARE_DO_FUN(	do_kick		);
-DECLARE_DO_FUN(	do_kill		);
-DECLARE_DO_FUN(	do_list		);
-DECLARE_DO_FUN( do_load		);
-DECLARE_DO_FUN(	do_lock		);
-DECLARE_DO_FUN(	do_log		);
-DECLARE_DO_FUN(	do_look		);
-DECLARE_DO_FUN(	do_memory	);
-DECLARE_DO_FUN(	do_mfind	);
-DECLARE_DO_FUN(	do_mload	);
-DECLARE_DO_FUN(	do_mset		);
-DECLARE_DO_FUN(	do_mstat	);
-DECLARE_DO_FUN(	do_mwhere	);
-DECLARE_DO_FUN( do_motd		);
-DECLARE_DO_FUN(	do_murde	);
-DECLARE_DO_FUN(	do_murder	);
-DECLARE_DO_FUN( do_music	);
-DECLARE_DO_FUN( do_newlock	);
-DECLARE_DO_FUN( do_news		);
-DECLARE_DO_FUN( do_nochannels	);
-DECLARE_DO_FUN(	do_noemote	);
-DECLARE_DO_FUN( do_nofollow	);
-DECLARE_DO_FUN( do_noloot	);
-DECLARE_DO_FUN(	do_north	);
-DECLARE_DO_FUN(	do_noshout	);
-DECLARE_DO_FUN( do_nosummon	);
-DECLARE_DO_FUN(	do_note		);
-DECLARE_DO_FUN(	do_notell	);
-DECLARE_DO_FUN(	do_ofind	);
-DECLARE_DO_FUN(	do_oload	);
-DECLARE_DO_FUN(	do_open		);
-DECLARE_DO_FUN(	do_order	);
-DECLARE_DO_FUN(	do_oset		);
-DECLARE_DO_FUN(	do_ostat	);
-DECLARE_DO_FUN( do_outfit	);
-DECLARE_DO_FUN( do_owhere	);
-DECLARE_DO_FUN(	do_pardon	);
-DECLARE_DO_FUN(	do_password	);
-DECLARE_DO_FUN(	do_peace	);
-DECLARE_DO_FUN( do_pecho	);
-DECLARE_DO_FUN( do_penalty	);
-DECLARE_DO_FUN( do_permban	);
-DECLARE_DO_FUN(	do_pick		);
-DECLARE_DO_FUN( do_play		);
-DECLARE_DO_FUN( do_pmote	);
-DECLARE_DO_FUN(	do_pose		);
-DECLARE_DO_FUN( do_pour		);
-DECLARE_DO_FUN(	do_practice	);
-DECLARE_DO_FUN( do_prefi	);
-DECLARE_DO_FUN( do_prefix	);
-DECLARE_DO_FUN( do_prompt	);
-DECLARE_DO_FUN( do_protect	);
-DECLARE_DO_FUN(	do_purge	);
-DECLARE_DO_FUN(	do_put		);
-DECLARE_DO_FUN(	do_quaff	);
-DECLARE_DO_FUN( do_question	);
-DECLARE_DO_FUN(	do_qui		);
-DECLARE_DO_FUN( do_quiet	);
-DECLARE_DO_FUN(	do_quit		);
-DECLARE_DO_FUN( do_quote	);
-DECLARE_DO_FUN( do_read		);
-DECLARE_DO_FUN(	do_reboo	);
-DECLARE_DO_FUN(	do_reboot	);
-DECLARE_DO_FUN(	do_recall	);
-DECLARE_DO_FUN(	do_recho	);
-DECLARE_DO_FUN(	do_recite	);
-DECLARE_DO_FUN(	do_remove	);
-DECLARE_DO_FUN(	do_rent		);
-DECLARE_DO_FUN( do_replay	);
-DECLARE_DO_FUN(	do_reply	);
-DECLARE_DO_FUN(	do_report	);
-DECLARE_DO_FUN(	do_rescue	);
-DECLARE_DO_FUN(	do_rest		);
-DECLARE_DO_FUN(	do_restore	);
-DECLARE_DO_FUN(	do_return	);
-DECLARE_DO_FUN(	do_rset		);
-DECLARE_DO_FUN(	do_rstat	);
-DECLARE_DO_FUN( do_rules	);
-DECLARE_DO_FUN(	do_sacrifice	);
-DECLARE_DO_FUN(	do_save		);
-DECLARE_DO_FUN(	do_say		);
-DECLARE_DO_FUN(	do_scan		);
-DECLARE_DO_FUN(	do_score	);
-DECLARE_DO_FUN( do_scroll	);
-DECLARE_DO_FUN(	do_sell		);
-DECLARE_DO_FUN( do_set		);
-DECLARE_DO_FUN(	do_shout	);
-DECLARE_DO_FUN( do_show		);
-DECLARE_DO_FUN(	do_shutdow	);
-DECLARE_DO_FUN(	do_shutdown	);
-DECLARE_DO_FUN( do_sit		);
-DECLARE_DO_FUN( do_skills	);
-DECLARE_DO_FUN(	do_sla		);
-DECLARE_DO_FUN(	do_slay		);
-DECLARE_DO_FUN(	do_sleep	);
-DECLARE_DO_FUN(	do_slookup	);
-DECLARE_DO_FUN( do_smote	);
-DECLARE_DO_FUN(	do_sneak	);
-DECLARE_DO_FUN(	do_snoop	);
-DECLARE_DO_FUN( do_socials	);
-DECLARE_DO_FUN(	do_south	);
-DECLARE_DO_FUN( do_sockets	);
-DECLARE_DO_FUN( do_spells	);
-DECLARE_DO_FUN(	do_split	);
-DECLARE_DO_FUN(	do_sset		);
-DECLARE_DO_FUN(	do_stand	);
-DECLARE_DO_FUN( do_stat		);
-DECLARE_DO_FUN(	do_steal	);
-DECLARE_DO_FUN( do_story	);
-DECLARE_DO_FUN( do_string	);
-DECLARE_DO_FUN(	do_switch	);
-DECLARE_DO_FUN(	do_tell		);
-DECLARE_DO_FUN(	do_time		);
-DECLARE_DO_FUN(	do_title	);
-DECLARE_DO_FUN(	do_train	);
-DECLARE_DO_FUN(	do_transfer	);
-DECLARE_DO_FUN( do_trip		);
-DECLARE_DO_FUN(	do_trust	);
-DECLARE_DO_FUN(	do_typo		);
-DECLARE_DO_FUN( do_unalias	);
-DECLARE_DO_FUN(	do_unlock	);
-DECLARE_DO_FUN( do_unread	);
-DECLARE_DO_FUN(	do_up		);
-DECLARE_DO_FUN(	do_value	);
-DECLARE_DO_FUN(	do_visible	);
-DECLARE_DO_FUN( do_violate	);
-DECLARE_DO_FUN( do_vnum		);
-DECLARE_DO_FUN(	do_wake		);
-DECLARE_DO_FUN(	do_wear		);
-DECLARE_DO_FUN(	do_weather	);
-DECLARE_DO_FUN(	do_west		);
-DECLARE_DO_FUN(	do_where	);
-DECLARE_DO_FUN(	do_who		);
-DECLARE_DO_FUN( do_whois	);
-DECLARE_DO_FUN(	do_wimpy	);
-DECLARE_DO_FUN(	do_wizhelp	);
-DECLARE_DO_FUN(	do_wizlock	);
-DECLARE_DO_FUN( do_wizlist	);
-DECLARE_DO_FUN( do_wiznet	);
-DECLARE_DO_FUN( do_worth	);
-DECLARE_DO_FUN(	do_yell		);
-DECLARE_DO_FUN(	do_zap		);
-DECLARE_DO_FUN( do_zecho	);
+extern int MAX_CMD;
+
+#include "command.h"
diff -ur src/lookup.c new/lookup.c
--- src/lookup.c	Sat May 23 22:27:42 1998
+++ new/lookup.c	Wed Mar 15 22:57:16 2000
@@ -32,6 +32,7 @@
 #endif
 #include <stdio.h>
 #include <time.h>
+#include <string.h>
 #include "merc.h"
 #include "tables.h"
 
@@ -46,7 +47,7 @@
 	    return flag_table[flag].bit;
     }
 
-    return 0;
+    return NO_FLAG;
 }
 
 int clan_lookup(const char *name)
@@ -104,3 +105,80 @@
  
    return -1;
 }
+
+/* returns race number */
+int race_lookup (const char *name)
+{
+   int race;
+
+   for ( race = 0; race_table[race].name != NULL; race++)
+   {
+	if (LOWER(name[0]) == LOWER(race_table[race].name[0])
+	&&  !str_prefix( name,race_table[race].name))
+	    return race;
+   }
+
+   return 0;
+} 
+
+int item_lookup(const char *name)
+{
+    int type;
+
+    for (type = 0; item_table[type].name != NULL; type++)
+    {
+        if (LOWER(name[0]) == LOWER(item_table[type].name[0])
+        &&  !str_prefix(name,item_table[type].name))
+            return item_table[type].type;
+    }
+ 
+    return -1;
+}
+
+int liq_lookup (const char *name)
+{
+    int liq;
+
+    for ( liq = 0; liq_table[liq].liq_name != NULL; liq++)
+    {
+	if (LOWER(name[0]) == LOWER(liq_table[liq].liq_name[0])
+	&& !str_prefix(name,liq_table[liq].liq_name))
+	    return liq;
+    }
+
+    return -1;
+}
+
+HELP_DATA * help_lookup( char *keyword )
+{
+	HELP_DATA *pHelp;
+	char temp[MIL], argall[MIL];
+
+	argall[0] = '\0';
+
+	while (keyword[0] != '\0' )
+	{
+		keyword = one_argument(keyword, temp);
+		if (argall[0] != '\0')
+			strcat(argall," ");
+		strcat(argall, temp);
+	}
+
+	for ( pHelp = help_first; pHelp != NULL; pHelp = pHelp->next )
+		if ( is_name( argall, pHelp->keyword ) )
+			return pHelp;
+
+	return NULL;
+}
+
+HELP_AREA * had_lookup( char *arg )
+{
+	HELP_AREA * temp;
+	extern HELP_AREA * had_list;
+
+	for ( temp = had_list; temp; temp = temp->next )
+		if ( !str_cmp( arg, temp->filename ) )
+			return temp;
+
+	return NULL;
+}
diff -ur src/lookup.h new/lookup.h
--- src/lookup.h	Sat May 23 22:27:43 1998
+++ new/lookup.h	Wed Mar 15 22:57:16 2000
@@ -25,8 +25,16 @@
 *	ROM license, in the file Rom24/doc/rom.license			   *
 ***************************************************************************/
 
+#if !defined(_LOOKUP_H)
+#define _LOOKUP_H
+
+#include "tables.h"
 
 int	clan_lookup	args( (const char *name) );
 int	position_lookup	args( (const char *name) );
 int 	sex_lookup	args( (const char *name) );
 int 	size_lookup	args( (const char *name) );
+int	flag_lookup	args( (const char *, const struct flag_type *) );
+HELP_DATA * help_lookup	args( (char *) );
+HELP_AREA * had_lookup	args( (char *) );
+#endif
diff -ur src/magic.h new/magic.h
--- src/magic.h	Sat May 23 22:27:47 1998
+++ new/magic.h	Wed Mar 15 22:57:16 2000
@@ -30,101 +30,101 @@
  * Spell functions.
  * Defined in magic.c.
  */
-DECLARE_SPELL_FUN(	spell_null		);
-DECLARE_SPELL_FUN(	spell_acid_blast	);
-DECLARE_SPELL_FUN(	spell_armor		);
-DECLARE_SPELL_FUN(	spell_bless		);
-DECLARE_SPELL_FUN(	spell_blindness		);
-DECLARE_SPELL_FUN(	spell_burning_hands	);
-DECLARE_SPELL_FUN(	spell_call_lightning	);
-DECLARE_SPELL_FUN(      spell_calm		);
-DECLARE_SPELL_FUN(      spell_cancellation	);
-DECLARE_SPELL_FUN(	spell_cause_critical	);
-DECLARE_SPELL_FUN(	spell_cause_light	);
-DECLARE_SPELL_FUN(	spell_cause_serious	);
-DECLARE_SPELL_FUN(	spell_change_sex	);
-DECLARE_SPELL_FUN(      spell_chain_lightning   );
-DECLARE_SPELL_FUN(	spell_charm_person	);
-DECLARE_SPELL_FUN(	spell_chill_touch	);
-DECLARE_SPELL_FUN(	spell_colour_spray	);
-DECLARE_SPELL_FUN(	spell_continual_light	);
-DECLARE_SPELL_FUN(	spell_control_weather	);
-DECLARE_SPELL_FUN(	spell_create_food	);
-DECLARE_SPELL_FUN(	spell_create_rose	);
-DECLARE_SPELL_FUN(	spell_create_spring	);
-DECLARE_SPELL_FUN(	spell_create_water	);
-DECLARE_SPELL_FUN(	spell_cure_blindness	);
-DECLARE_SPELL_FUN(	spell_cure_critical	);
-DECLARE_SPELL_FUN(      spell_cure_disease	);
-DECLARE_SPELL_FUN(	spell_cure_light	);
-DECLARE_SPELL_FUN(	spell_cure_poison	);
-DECLARE_SPELL_FUN(	spell_cure_serious	);
-DECLARE_SPELL_FUN(	spell_curse		);
-DECLARE_SPELL_FUN(      spell_demonfire		);
-DECLARE_SPELL_FUN(	spell_detect_evil	);
-DECLARE_SPELL_FUN(	spell_detect_good	);
-DECLARE_SPELL_FUN(	spell_detect_hidden	);
-DECLARE_SPELL_FUN(	spell_detect_invis	);
-DECLARE_SPELL_FUN(	spell_detect_magic	);
-DECLARE_SPELL_FUN(	spell_detect_poison	);
-DECLARE_SPELL_FUN(	spell_dispel_evil	);
-DECLARE_SPELL_FUN(      spell_dispel_good       );
-DECLARE_SPELL_FUN(	spell_dispel_magic	);
-DECLARE_SPELL_FUN(	spell_earthquake	);
-DECLARE_SPELL_FUN(	spell_enchant_armor	);
-DECLARE_SPELL_FUN(	spell_enchant_weapon	);
-DECLARE_SPELL_FUN(	spell_energy_drain	);
-DECLARE_SPELL_FUN(	spell_faerie_fire	);
-DECLARE_SPELL_FUN(	spell_faerie_fog	);
-DECLARE_SPELL_FUN(	spell_farsight		);
-DECLARE_SPELL_FUN(	spell_fireball		);
-DECLARE_SPELL_FUN(	spell_fireproof		);
-DECLARE_SPELL_FUN(	spell_flamestrike	);
-DECLARE_SPELL_FUN(	spell_floating_disc	);
-DECLARE_SPELL_FUN(	spell_fly		);
-DECLARE_SPELL_FUN(      spell_frenzy		);
-DECLARE_SPELL_FUN(	spell_gate		);
-DECLARE_SPELL_FUN(	spell_giant_strength	);
-DECLARE_SPELL_FUN(	spell_harm		);
-DECLARE_SPELL_FUN(      spell_haste		);
-DECLARE_SPELL_FUN(	spell_heal		);
-DECLARE_SPELL_FUN(	spell_heat_metal	);
-DECLARE_SPELL_FUN(      spell_holy_word		);
-DECLARE_SPELL_FUN(	spell_identify		);
-DECLARE_SPELL_FUN(	spell_infravision	);
-DECLARE_SPELL_FUN(	spell_invis		);
-DECLARE_SPELL_FUN(	spell_know_alignment	);
-DECLARE_SPELL_FUN(	spell_lightning_bolt	);
-DECLARE_SPELL_FUN(	spell_locate_object	);
-DECLARE_SPELL_FUN(	spell_magic_missile	);
-DECLARE_SPELL_FUN(      spell_mass_healing	);
-DECLARE_SPELL_FUN(	spell_mass_invis	);
-DECLARE_SPELL_FUN(	spell_nexus		);
-DECLARE_SPELL_FUN(	spell_pass_door		);
-DECLARE_SPELL_FUN(      spell_plague		);
-DECLARE_SPELL_FUN(	spell_poison		);
-DECLARE_SPELL_FUN(	spell_portal		);
-DECLARE_SPELL_FUN(	spell_protection_evil	);
-DECLARE_SPELL_FUN(	spell_protection_good	);
-DECLARE_SPELL_FUN(	spell_ray_of_truth	);
-DECLARE_SPELL_FUN(	spell_recharge		);
-DECLARE_SPELL_FUN(	spell_refresh		);
-DECLARE_SPELL_FUN(	spell_remove_curse	);
-DECLARE_SPELL_FUN(	spell_sanctuary		);
-DECLARE_SPELL_FUN(	spell_shocking_grasp	);
-DECLARE_SPELL_FUN(	spell_shield		);
-DECLARE_SPELL_FUN(	spell_sleep		);
-DECLARE_SPELL_FUN(	spell_slow		);
-DECLARE_SPELL_FUN(	spell_stone_skin	);
-DECLARE_SPELL_FUN(	spell_summon		);
-DECLARE_SPELL_FUN(	spell_teleport		);
-DECLARE_SPELL_FUN(	spell_ventriloquate	);
-DECLARE_SPELL_FUN(	spell_weaken		);
-DECLARE_SPELL_FUN(	spell_word_of_recall	);
-DECLARE_SPELL_FUN(	spell_acid_breath	);
-DECLARE_SPELL_FUN(	spell_fire_breath	);
-DECLARE_SPELL_FUN(	spell_frost_breath	);
-DECLARE_SPELL_FUN(	spell_gas_breath	);
-DECLARE_SPELL_FUN(	spell_lightning_breath	);
-DECLARE_SPELL_FUN(	spell_general_purpose	);
-DECLARE_SPELL_FUN(	spell_high_explosive	);
+SPELL(	spell_null		)
+SPELL(	spell_acid_blast	)
+SPELL(	spell_armor		)
+SPELL(	spell_bless		)
+SPELL(	spell_blindness		)
+SPELL(	spell_burning_hands	)
+SPELL(	spell_call_lightning	)
+SPELL(      spell_calm		)
+SPELL(      spell_cancellation	)
+SPELL(	spell_cause_critical	)
+SPELL(	spell_cause_light	)
+SPELL(	spell_cause_serious	)
+SPELL(	spell_change_sex	)
+SPELL(      spell_chain_lightning   )
+SPELL(	spell_charm_person	)
+SPELL(	spell_chill_touch	)
+SPELL(	spell_colour_spray	)
+SPELL(	spell_continual_light	)
+SPELL(	spell_control_weather	)
+SPELL(	spell_create_food	)
+SPELL(	spell_create_rose	)
+SPELL(	spell_create_spring	)
+SPELL(	spell_create_water	)
+SPELL(	spell_cure_blindness	)
+SPELL(	spell_cure_critical	)
+SPELL(      spell_cure_disease	)
+SPELL(	spell_cure_light	)
+SPELL(	spell_cure_poison	)
+SPELL(	spell_cure_serious	)
+SPELL(	spell_curse		)
+SPELL(      spell_demonfire		)
+SPELL(	spell_detect_evil	)
+SPELL(	spell_detect_good	)
+SPELL(	spell_detect_hidden	)
+SPELL(	spell_detect_invis	)
+SPELL(	spell_detect_magic	)
+SPELL(	spell_detect_poison	)
+SPELL(	spell_dispel_evil	)
+SPELL(      spell_dispel_good       )
+SPELL(	spell_dispel_magic	)
+SPELL(	spell_earthquake	)
+SPELL(	spell_enchant_armor	)
+SPELL(	spell_enchant_weapon	)
+SPELL(	spell_energy_drain	)
+SPELL(	spell_faerie_fire	)
+SPELL(	spell_faerie_fog	)
+SPELL(	spell_farsight		)
+SPELL(	spell_fireball		)
+SPELL(	spell_fireproof		)
+SPELL(	spell_flamestrike	)
+SPELL(	spell_floating_disc	)
+SPELL(	spell_fly		)
+SPELL(      spell_frenzy		)
+SPELL(	spell_gate		)
+SPELL(	spell_giant_strength	)
+SPELL(	spell_harm		)
+SPELL(      spell_haste		)
+SPELL(	spell_heal		)
+SPELL(	spell_heat_metal	)
+SPELL(      spell_holy_word		)
+SPELL(	spell_identify		)
+SPELL(	spell_infravision	)
+SPELL(	spell_invis		)
+SPELL(	spell_know_alignment	)
+SPELL(	spell_lightning_bolt	)
+SPELL(	spell_locate_object	)
+SPELL(	spell_magic_missile	)
+SPELL(      spell_mass_healing	)
+SPELL(	spell_mass_invis	)
+SPELL(	spell_nexus		)
+SPELL(	spell_pass_door		)
+SPELL(      spell_plague		)
+SPELL(	spell_poison		)
+SPELL(	spell_portal		)
+SPELL(	spell_protection_evil	)
+SPELL(	spell_protection_good	)
+SPELL(	spell_ray_of_truth	)
+SPELL(	spell_recharge		)
+SPELL(	spell_refresh		)
+SPELL(	spell_remove_curse	)
+SPELL(	spell_sanctuary		)
+SPELL(	spell_shocking_grasp	)
+SPELL(	spell_shield		)
+SPELL(	spell_sleep		)
+SPELL(	spell_slow		)
+SPELL(	spell_stone_skin	)
+SPELL(	spell_summon		)
+SPELL(	spell_teleport		)
+SPELL(	spell_ventriloquate	)
+SPELL(	spell_weaken		)
+SPELL(	spell_word_of_recall	)
+SPELL(	spell_acid_breath	)
+SPELL(	spell_fire_breath	)
+SPELL(	spell_frost_breath	)
+SPELL(	spell_gas_breath	)
+SPELL(	spell_lightning_breath	)
+SPELL(	spell_general_purpose	)
+SPELL(	spell_high_explosive	)
diff -ur src/merc.h new/merc.h
--- src/merc.h	Mon May 25 20:48:53 1998
+++ new/merc.h	Wed Mar 15 22:57:16 2000
@@ -35,13 +35,23 @@
 #define DECLARE_DO_FUN( fun )		void fun( )
 #define DECLARE_SPEC_FUN( fun )		bool fun( )
 #define DECLARE_SPELL_FUN( fun )	void fun( )
+#define DECLARE_LOOKUP_FUN( fun )	int fun ( )
 #else
 #define args( list )			list
 #define DECLARE_DO_FUN( fun )		DO_FUN    fun
 #define DECLARE_SPEC_FUN( fun )		SPEC_FUN  fun
 #define DECLARE_SPELL_FUN( fun )	SPELL_FUN fun
+#define DECLARE_LOOKUP_FUN( fun )	LOOKUP_F  fun
 #endif
 
+// OLC2
+#define SPELL(spell)		DECLARE_SPELL_FUN(spell);
+#define SPELL_FUN_DEC(spell)	FRetVal spell (int sn, int level, Entity *caster, Entity * ent, int target)
+#define COMMAND(cmd)		DECLARE_DO_FUN(cmd);
+#define DO_FUN_DEC(x)		void x (CHAR_DATA *ch, char *argument)
+#define NEW_DO_FUN_DEC(x)	FRetVal x (Entity *ent, char *argument)
+#define DECLARE_SPELL_CB(x)	FRetVal x (Entity *ent)
+
 /* system calls */
 int unlink();
 int system();
@@ -72,7 +82,9 @@
 typedef unsigned char			bool;
 #endif
 
-
+/* ea */
+#define MSL MAX_STRING_LENGTH
+#define MIL MAX_INPUT_LENGTH
 
 /*
  * Structure types.
@@ -86,6 +98,7 @@
 typedef struct	exit_data		EXIT_DATA;
 typedef struct	extra_descr_data	EXTRA_DESCR_DATA;
 typedef struct	help_data		HELP_DATA;
+typedef struct	help_area_data		HELP_AREA;
 typedef struct	kill_data		KILL_DATA;
 typedef struct	mem_data		MEM_DATA;
 typedef struct	mob_index_data		MOB_INDEX_DATA;
@@ -99,7 +112,8 @@
 typedef struct	shop_data		SHOP_DATA;
 typedef struct	time_info_data		TIME_INFO_DATA;
 typedef struct	weather_data		WEATHER_DATA;
-
+typedef struct  mprog_list		MPROG_LIST;
+typedef struct  mprog_code		MPROG_CODE;
 
 
 /*
@@ -109,7 +123,7 @@
 typedef bool SPEC_FUN	args( ( CHAR_DATA *ch ) );
 typedef void SPELL_FUN	args( ( int sn, int level, CHAR_DATA *ch, void *vo,
 				int target ) );
-
+typedef int	LOOKUP_F	args( ( const char * ) );
 
 
 /*
@@ -128,8 +142,13 @@
  * Adjust the pulse numbers to suit yourself.
  */
 #define MAX_SOCIALS		  256
+#if defined(FIRST_BOOT)
 #define MAX_SKILL		  150
 #define MAX_GROUP		   30
+#else
+extern int MAX_SKILL;
+extern int MAX_GROUP;
+#endif
 #define MAX_IN_GROUP		   15
 #define MAX_ALIAS		    5
 #define MAX_CLASS		    4
@@ -139,6 +158,7 @@
 #define MAX_LEVEL		   60
 #define LEVEL_HERO		   (MAX_LEVEL - 9)
 #define LEVEL_IMMORTAL		   (MAX_LEVEL - 8)
+#define MAX_VNUM		32767
 
 #define PULSE_PER_SECOND	    4
 #define PULSE_VIOLENCE		  ( 3 * PULSE_PER_SECOND)
@@ -189,7 +209,11 @@
     char *      string; /* buffer's string */
 };
 
-
+struct skhash
+{
+	struct skhash *	next;
+	int		sn;
+};
 
 /*
  * Time and weather stuff.
@@ -267,6 +291,12 @@
     int			outtop;
     char *		showstr_head;
     char *		showstr_point;
+    void *              pEdit;		/* OLC */
+    char **             pString;	/* OLC */
+    sh_int		editor;		/* OLC */
+    sh_int		pagina;
+    char *		screenmap;
+    char *		oldscreenmap;
 };
 
 
@@ -322,11 +352,21 @@
 struct	help_data
 {
     HELP_DATA *	next;
+    HELP_DATA * next_area;
     sh_int	level;
     char *	keyword;
     char *	text;
 };
 
+struct help_area_data
+{
+	HELP_AREA *	next;
+	HELP_DATA *	first;
+	HELP_DATA *	last;
+	AREA_DATA *	area;
+	char *		filename;
+	bool		changed;
+};
 
 
 /*
@@ -416,13 +456,23 @@
     long	vuln;			/* vuln bits for the race */
     long	form;			/* default form flag for the race */
     long	parts;			/* default parts for the race */
+    sh_int	race_id;
+#if !defined(FIRST_BOOT)
+    char *	who_name;
+    sh_int	points;			/* cost in points of the race */
+    sh_int	class_mult[MAX_CLASS];	/* exp multiplier for class, * 100 */
+    char *	skills[5];		/* bonus skills for the race */
+    sh_int 	stats[MAX_STATS];	/* starting stats */
+    sh_int	max_stats[MAX_STATS];	/* maximum stats */
+    sh_int	size;			/* aff bits for the race */
+#endif
 };
 
-
+#if defined(FIRST_BOOT)
 struct pc_race_type  /* additional data for pc races */
 {
     char *	name;			/* MUST be in race_type */
-    char 	who_name[6];
+    char *	who_name;
     sh_int	points;			/* cost in points of the race */
     sh_int	class_mult[MAX_CLASS];	/* exp multiplier for class, * 100 */
     char *	skills[5];		/* bonus skills for the race */
@@ -430,7 +480,7 @@
     sh_int	max_stats[MAX_STATS];	/* maximum stats */
     sh_int	size;			/* aff bits for the race */
 };
-
+#endif
 
 struct spec_type
 {
@@ -1177,6 +1227,30 @@
 #define WEAR_FLOAT		     18
 #define MAX_WEAR		     19
 
+/*
+ * Command logging types.
+ */
+#define LOG_NORMAL	0
+#define LOG_ALWAYS	1
+#define LOG_NEVER	2
+
+/*
+ * Command types.
+ */
+#define TYP_NUL 0
+#define TYP_UNDEF 1
+#define TYP_CMM	10
+#define TYP_CBT	2
+#define TYP_ESP 3
+#define TYP_GRP 4
+#define TYP_OBJ 5
+#define TYP_INF 6
+#define TYP_OTH 7
+#define TYP_MVT 8
+#define TYP_CNF 9
+#define TYP_LNG 11
+#define TYP_PLR 12
+#define TYP_OLC 13
 
 
 /***************************************************************************
@@ -1251,6 +1325,7 @@
 #define COMM_NOCLAN		(H)
 #define COMM_NOQUOTE		(I)
 #define COMM_SHOUTSOFF		(J)
+#define COMM_OLCX		(K)
 
 /* display flags */
 #define COMM_COMPACT		(L)
@@ -1300,6 +1375,8 @@
     MOB_INDEX_DATA *	next;
     SPEC_FUN *		spec_fun;
     SHOP_DATA *		pShop;
+    MPROG_LIST *        mprogs;
+    AREA_DATA *		area;		/* OLC */
     sh_int		vnum;
     sh_int		group;
     bool		new_format;
@@ -1331,7 +1408,9 @@
     long		form;
     long		parts;
     sh_int		size;
+    sh_int		reset_num;
     char *		material;
+    long		mprog_flags;
 };
 
 
@@ -1365,6 +1444,7 @@
     CHAR_DATA *		fighting;
     CHAR_DATA *		reply;
     CHAR_DATA *		pet;
+    CHAR_DATA *		mprog_target;
     MEM_DATA *		memory;
     SPEC_FUN *		spec_fun;
     MOB_INDEX_DATA *	pIndexData;
@@ -1443,6 +1523,8 @@
     sh_int		dam_type;
     sh_int		start_pos;
     sh_int		default_pos;
+
+    sh_int		mprog_delay;
 };
 
 
@@ -1470,12 +1552,18 @@
     sh_int		true_sex;
     int			last_level;
     sh_int		condition	[4];
+#if defined(FIRST_BOOT)
     sh_int		learned		[MAX_SKILL];
     bool		group_known	[MAX_GROUP];
+#else
+    sh_int *		learned;
+    bool *		group_known;
+#endif
     sh_int		points;
     bool              	confirm_delete;
     char *		alias[MAX_ALIAS];
     char * 		alias_sub[MAX_ALIAS];
+    int 		security;	/* OLC */ /* Builder security */
 };
 
 /* Data for generating characters -- only used during generation */
@@ -1483,8 +1571,13 @@
 {
     GEN_DATA	*next;
     bool	valid;
+#if defined(FIRST_BOOT)
     bool	skill_chosen[MAX_SKILL];
     bool	group_chosen[MAX_GROUP];
+#else
+    bool *	skill_chosen;
+    bool *	group_chosen;
+#endif
     int		points_chosen;
 };
 
@@ -1525,6 +1618,7 @@
     OBJ_INDEX_DATA *	next;
     EXTRA_DESCR_DATA *	extra_descr;
     AFFECT_DATA *	affected;
+    AREA_DATA *		area;		/* OLC */
     bool		new_format;
     char *		name;
     char *		short_descr;
@@ -1595,6 +1689,9 @@
     sh_int		key;
     char *		keyword;
     char *		description;
+    EXIT_DATA *		next;		/* OLC */
+    int			rs_flags;	/* OLC */
+    int			orig_door;	/* OLC */
 };
 
 
@@ -1633,8 +1730,7 @@
 struct	area_data
 {
     AREA_DATA *		next;
-    RESET_DATA *	reset_first;
-    RESET_DATA *	reset_last;
+    HELP_AREA *		helps;
     char *		file_name;
     char *		name;
     char *		credits;
@@ -1645,6 +1741,10 @@
     sh_int 		min_vnum;
     sh_int		max_vnum;
     bool		empty;
+    char *		builders;	/* OLC */ /* Listing of */
+    int			vnum;		/* OLC */ /* Area vnum  */
+    int			area_flags;	/* OLC */
+    int			security;	/* OLC */ /* Value 1-9  */
 };
 
 
@@ -1660,7 +1760,8 @@
     EXTRA_DESCR_DATA *	extra_descr;
     AREA_DATA *		area;
     EXIT_DATA *		exit	[6];
-    EXIT_DATA * 	old_exit[6];
+    RESET_DATA *	reset_first;	/* OLC */
+    RESET_DATA *	reset_last;	/* OLC */
     char *		name;
     char *		description;
     char *		owner;
@@ -1671,6 +1772,7 @@
     sh_int		heal_rate;
     sh_int 		mana_rate;
     sh_int		clan;
+    sh_int		reset_num;
 };
 
 
@@ -1730,67 +1832,48 @@
     char *	spells[MAX_IN_GROUP];
 };
 
-
-
 /*
- * These are skill_lookup return values for common skills and spells.
- */
-extern	sh_int	gsn_backstab;
-extern	sh_int	gsn_dodge;
-extern  sh_int  gsn_envenom;
-extern	sh_int	gsn_hide;
-extern	sh_int	gsn_peek;
-extern	sh_int	gsn_pick_lock;
-extern	sh_int	gsn_sneak;
-extern	sh_int	gsn_steal;
-
-extern	sh_int	gsn_disarm;
-extern	sh_int	gsn_enhanced_damage;
-extern	sh_int	gsn_kick;
-extern	sh_int	gsn_parry;
-extern	sh_int	gsn_rescue;
-extern	sh_int	gsn_second_attack;
-extern	sh_int	gsn_third_attack;
-
-extern	sh_int	gsn_blindness;
-extern	sh_int	gsn_charm_person;
-extern	sh_int	gsn_curse;
-extern	sh_int	gsn_invis;
-extern	sh_int	gsn_mass_invis;
-extern  sh_int  gsn_plague;
-extern	sh_int	gsn_poison;
-extern	sh_int	gsn_sleep;
-extern  sh_int  gsn_fly;
-extern  sh_int  gsn_sanctuary;
-
-/* new gsns */
-extern sh_int  gsn_axe;
-extern sh_int  gsn_dagger;
-extern sh_int  gsn_flail;
-extern sh_int  gsn_mace;
-extern sh_int  gsn_polearm;
-extern sh_int  gsn_shield_block;
-extern sh_int  gsn_spear;
-extern sh_int  gsn_sword;
-extern sh_int  gsn_whip;
- 
-extern sh_int  gsn_bash;
-extern sh_int  gsn_berserk;
-extern sh_int  gsn_dirt;
-extern sh_int  gsn_hand_to_hand;
-extern sh_int  gsn_trip;
- 
-extern sh_int  gsn_fast_healing;
-extern sh_int  gsn_haggle;
-extern sh_int  gsn_lore;
-extern sh_int  gsn_meditation;
- 
-extern sh_int  gsn_scrolls;
-extern sh_int  gsn_staves;
-extern sh_int  gsn_wands;
-extern sh_int  gsn_recall;
+ * MOBprog definitions
+ */                   
+#define TRIG_ACT	(A)
+#define TRIG_BRIBE	(B)
+#define TRIG_DEATH	(C)
+#define TRIG_ENTRY	(D)
+#define TRIG_FIGHT	(E)
+#define TRIG_GIVE	(F)
+#define TRIG_GREET	(G)
+#define TRIG_GRALL	(H)
+#define TRIG_KILL	(I)
+#define TRIG_HPCNT	(J)
+#define TRIG_RANDOM	(K)
+#define TRIG_SPEECH	(L)
+#define TRIG_EXIT	(M)
+#define TRIG_EXALL	(N)
+#define TRIG_DELAY	(O)
+#define TRIG_SURR	(P)
+
+struct mprog_list
+{
+    int			trig_type;
+    char *		trig_phrase;
+    sh_int		vnum;
+    char *  		code;
+    MPROG_LIST * 	next;
+    bool		valid;
+};
 
+struct mprog_code
+{
+    sh_int		vnum;
+    bool		changed;
+    char *		code;
+    MPROG_CODE *	next;
+};
 
+// gsn
+#define GSN(x)	extern sh_int x;
+#include "gsn.h"
+#undef GSN
 
 /*
  * Utility macros.
@@ -1806,8 +1889,24 @@
 #define IS_SET(flag, bit)	((flag) & (bit))
 #define SET_BIT(var, bit)	((var) |= (bit))
 #define REMOVE_BIT(var, bit)	((var) &= ~(bit))
-
-
+#define TOGGLE_BIT(var, bit)    ((var) ^= (bit))
+#define IS_NULLSTR(str)		((str) == NULL || (str)[0] == '\0')
+#define CHECKNULLSTR(str) ( (str) == NULL ? "" : (str) )
+#define CH(d)		((d)->original ? (d)->original : (d)->character )
+#define ENTRE(min,num,max)	( ((min) < (num)) && ((num) < (max)) )
+#define ENTRE_I(x,y,z)	(((x) <= (y)) && ((y) <= (z)))
+#define CHECK_POS(a, b, c)	{							\
+					(a) = (b);					\
+					if ( (a) < 0 )					\
+					bug( "CHECK_POS : " c " == %d < 0", a );	\
+				}
+
+#define ARRAY_COPY( array1, array2, largo )				\
+		{							\
+			int _xxx_;					\
+			for ( _xxx_ = 0; _xxx_ < largo; _xxx_++ )	\
+				array1[_xxx_] = array2[_xxx_];		\
+		}
 
 /*
  * Character macros.
@@ -1846,6 +1945,13 @@
 #define act(format,ch,arg1,arg2,type)\
 	act_new((format),(ch),(arg1),(arg2),(type),POS_RESTING)
 
+#define HAS_TRIGGER(ch,trig)	(IS_SET((ch)->pIndexData->mprog_flags,(trig)))
+#define IS_SWITCHED( ch )       ( ch->desc && ch->desc->original )
+#define IS_BUILDER(ch, Area)	( !IS_NPC(ch) && !IS_SWITCHED( ch ) &&	  \
+				( ch->pcdata->security >= Area->security  \
+				|| strstr( Area->builders, ch->name )	  \
+				|| strstr( Area->builders, "All" ) ) )
+
 /*
  * Object macros.
  */
@@ -1869,7 +1975,7 @@
  */
 struct	social_type
 {
-    char      name[20];
+    char *	name;
     char *    char_no_arg;
     char *    others_no_arg;
     char *    char_found;
@@ -1896,13 +2002,20 @@
 extern  const   struct  item_type	item_table	[];
 extern	const	struct	wiznet_type	wiznet_table	[];
 extern	const	struct	attack_type	attack_table	[];
+#if defined(FIRST_BOOT)
 extern  const	struct  race_type	race_table	[];
+extern	const	struct	skill_type	skill_table	[MAX_SKILL];
+extern          struct social_type      social_table	[MAX_SOCIALS];
+extern  const   struct  group_type      group_table	[MAX_GROUP];
 extern	const	struct	pc_race_type	pc_race_table	[];
+#else
+extern		struct	race_type *	race_table;
+extern		struct	skill_type *	skill_table;
+extern		struct	social_type *	social_table;
+extern		struct	group_type *	group_table;
+#endif
 extern  const	struct	spec_type	spec_table	[];
 extern	const	struct	liq_type	liq_table	[];
-extern	const	struct	skill_type	skill_table	[MAX_SKILL];
-extern  const   struct  group_type      group_table	[MAX_GROUP];
-extern          struct social_type      social_table	[MAX_SOCIALS];
 extern	char *	const			title_table	[MAX_CLASS]
 							[MAX_LEVEL+1]
 							[2];
@@ -1919,6 +2032,8 @@
 extern		DESCRIPTOR_DATA   *	descriptor_list;
 extern		OBJ_DATA	  *	object_list;
 
+extern		MPROG_CODE	  *	mprog_list;
+
 extern		char			bug_buf		[];
 extern		time_t			current_time;
 extern		bool			fLogAll;
@@ -1927,6 +2042,7 @@
 extern		char			log_buf		[];
 extern		TIME_INFO_DATA		time_info;
 extern		WEATHER_DATA		weather_info;
+extern		bool			MOBtrigger;
 
 /*
  * OS-dependent declarations.
@@ -2047,6 +2163,9 @@
 #endif
 
 #define AREA_LIST       "area.lst"  /* List of areas*/
+#define AREA_DIR	"../area/"
+#define DATA_DIR	"../data/"
+#define PROG_DIR	"../data/progs/"
 #define BUG_FILE        "bugs.txt" /* For 'bug' and bug()*/
 #define TYPO_FILE       "typos.txt" /* For 'typo'*/
 #define NOTE_FILE       "notes.not"/* For 'notes'*/
@@ -2071,6 +2190,7 @@
 #define RID	ROOM_INDEX_DATA
 #define SF	SPEC_FUN
 #define AD	AFFECT_DATA
+#define MPC	MPROG_CODE
 
 /* act_comm.c */
 void  	check_sex	args( ( CHAR_DATA *ch) );
@@ -2091,6 +2211,7 @@
 
 /* act_obj.c */
 bool can_loot		args( (CHAR_DATA *ch, OBJ_DATA *obj) );
+void	wear_obj	args( (CHAR_DATA *ch, OBJ_DATA *obj, bool fReplace) );
 void    get_obj         args( ( CHAR_DATA *ch, OBJ_DATA *obj,
                             OBJ_DATA *container ) );
 
@@ -2116,8 +2237,13 @@
 void	act_new		args( ( const char *format, CHAR_DATA *ch, 
 			    const void *arg1, const void *arg2, int type,
 			    int min_pos) );
+void	printf_to_char	args( ( CHAR_DATA *, char *, ... ) );
+void	bugf		args( ( char *, ... ) );
+void	flog		args( ( char *, ... ) );
 
 /* db.c */
+void	reset_area      args( ( AREA_DATA * pArea ) );		/* OLC */
+void	reset_room	args( ( ROOM_INDEX_DATA *pRoom ) );	/* OLC */
 char *	print_flags	args( ( int flag ));
 void	boot_db		args( ( void ) );
 void	area_update	args( ( void ) );
@@ -2130,6 +2256,7 @@
 MID *	get_mob_index	args( ( int vnum ) );
 OID *	get_obj_index	args( ( int vnum ) );
 RID *	get_room_index	args( ( int vnum ) );
+MPC *	get_mprog_index args( ( int vnum ) );
 char	fread_letter	args( ( FILE *fp ) );
 int	fread_number	args( ( FILE *fp ) );
 long 	fread_flag	args( ( FILE *fp ) );
@@ -2190,15 +2317,12 @@
 void 	deduct_cost	args( (CHAR_DATA *ch, int cost) );
 void	affect_enchant	args( (OBJ_DATA *obj) );
 int 	check_immune	args( (CHAR_DATA *ch, int dam_type) );
-int	liq_lookup	args( ( const char *name) );
 int 	material_lookup args( ( const char *name) );
 int	weapon_lookup	args( ( const char *name) );
 int	weapon_type	args( ( const char *name) );
 char 	*weapon_name	args( ( int weapon_Type) );
-int	item_lookup	args( ( const char *name) );
 char	*item_name	args( ( int item_type) ); 
 int	attack_lookup	args( ( const char *name) );
-int	race_lookup	args( ( const char *name) );
 long	wiznet_lookup	args( ( const char *name) );
 int	class_lookup	args( ( const char *name) );
 bool	is_clan		args( (CHAR_DATA *ch) );
@@ -2271,7 +2395,11 @@
 char *	weapon_bit_name	args( ( int weapon_flags ) );
 char *  comm_bit_name	args( ( int comm_flags ) );
 char *	cont_bit_name	args( ( int cont_flags) );
-
+bool	emptystring	args( ( const char * ) );
+char *	itos		args( ( int ) );
+int	get_vnum_mob_name_area	args( ( char *, AREA_DATA * ) );
+int	get_vnum_obj_name_area	args( ( char *, AREA_DATA * ) );
+int	get_points	( int race, int args );
 
 /* interp.c */
 void	interpret	args( ( CHAR_DATA *ch, char *argument ) );
@@ -2288,6 +2416,24 @@
 bool	saves_spell	args( ( int level, CHAR_DATA *victim, int dam_type ) );
 void	obj_cast_spell	args( ( int sn, int level, CHAR_DATA *ch,
 				    CHAR_DATA *victim, OBJ_DATA *obj ) );
+
+/* mob_prog.c */
+void	program_flow	args( ( sh_int vnum, char *source, CHAR_DATA *mob, CHAR_DATA *ch,
+				const void *arg1, const void *arg2 ) );
+void	mp_act_trigger	args( ( char *argument, CHAR_DATA *mob, CHAR_DATA *ch,
+				const void *arg1, const void *arg2, int type ) );
+bool	mp_percent_trigger args( ( CHAR_DATA *mob, CHAR_DATA *ch, 				
+				const void *arg1, const void *arg2, int type ) );
+void	mp_bribe_trigger  args( ( CHAR_DATA *mob, CHAR_DATA *ch, int amount ) );
+bool	mp_exit_trigger   args( ( CHAR_DATA *ch, int dir ) );
+void	mp_give_trigger   args( ( CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj ) );
+void 	mp_greet_trigger  args( ( CHAR_DATA *ch ) );
+void	mp_hprct_trigger  args( ( CHAR_DATA *mob, CHAR_DATA *ch ) );
+
+/* mob_cmds.c */
+void	mob_interpret	args( ( CHAR_DATA *ch, char *argument ) );
+char *	mprog_type_to_name	args( ( int ) );
+
 /* save.c */
 void	save_char_obj	args( ( CHAR_DATA *ch ) );
 bool	load_char_obj	args( ( DESCRIPTOR_DATA *d, char *name ) );
@@ -2304,6 +2450,7 @@
 void 	gn_remove	args( ( CHAR_DATA *ch, int gn) );
 void 	group_add	args( ( CHAR_DATA *ch, const char *name, bool deduct) );
 void	group_remove	args( ( CHAR_DATA *ch, const char *name) );
+int	race_exp_per_level	( int race, int class, int points );
 
 /* special.c */
 SF *	spec_lookup	args( ( const char *name ) );
@@ -2318,6 +2465,26 @@
 void	gain_condition	args( ( CHAR_DATA *ch, int iCond, int value ) );
 void	update_handler	args( ( void ) );
 
+/* string.c */
+void	string_edit	args( ( CHAR_DATA *ch, char **pString ) );
+void    string_append   args( ( CHAR_DATA *ch, char **pString ) );
+char *	string_replace	args( ( char * orig, char * old, char * new ) );
+void    string_add      args( ( CHAR_DATA *ch, char *argument ) );
+char *  format_string   args( ( char *oldstring /*, bool fSpace */ ) );
+char *  first_arg       args( ( char *argument, char *arg_first, bool fCase ) );
+char *	string_unpad	args( ( char * argument ) );
+char *	string_proper	args( ( char * argument ) );
+
+/* olc.c */
+bool	run_olc_editor	args( ( DESCRIPTOR_DATA *d, char *incomm ) );
+char	*olc_ed_name	args( ( CHAR_DATA *ch ) );
+char	*olc_ed_vnum	args( ( CHAR_DATA *ch ) );
+
+/* lookup.c */
+int	race_lookup	args( ( const char *name) );
+int	item_lookup	args( ( const char *name) );
+int	liq_lookup	args( ( const char *name) );
+
 #undef	CD
 #undef	MID
 #undef	OD
@@ -2325,3 +2492,59 @@
 #undef	RID
 #undef	SF
 #undef AD
+
+/*****************************************************************************
+ *                                    OLC                                    *
+ *****************************************************************************/
+
+/*
+ * Object defined in limbo.are
+ * Used in save.c to load objects that don't exist.
+ */
+#define OBJ_VNUM_DUMMY	30
+
+/*
+ * Area flags.
+ */
+#define         AREA_NONE       0
+#define         AREA_CHANGED    1	/* Area has been modified. */
+#define         AREA_ADDED      2	/* Area has been added to. */
+#define         AREA_LOADING    4	/* Used for counting in db.c */
+
+#define MAX_DIR	6
+#define NO_FLAG -99	/* Must not be used in flags or stats. */
+
+/*
+ * Global Constants
+ */
+extern	char *	const	dir_name        [];
+extern	const	sh_int	rev_dir         [];          /* sh_int - ROM OLC */
+extern	const	struct	spec_type	spec_table	[];
+
+/*
+ * Global variables
+ */
+extern		AREA_DATA *		area_first;
+extern		AREA_DATA *		area_last;
+extern		SHOP_DATA *		shop_last;
+
+extern		int			top_affect;
+extern		int			top_area;
+extern		int			top_ed;
+extern		int			top_exit;
+extern		int			top_help;
+extern		int			top_mob_index;
+extern		int			top_obj_index;
+extern		int			top_reset;
+extern		int			top_room;
+extern		int			top_shop;
+
+extern		int			top_vnum_mob;
+extern		int			top_vnum_obj;
+extern		int			top_vnum_room;
+
+extern		char			str_empty       [1];
+
+extern		MOB_INDEX_DATA *	mob_index_hash  [MAX_KEY_HASH];
+extern		OBJ_INDEX_DATA *	obj_index_hash  [MAX_KEY_HASH];
+extern		ROOM_INDEX_DATA *	room_index_hash [MAX_KEY_HASH];
diff -ur src/recycle.c new/recycle.c
--- src/recycle.c	Sat May 23 22:27:55 1998
+++ new/recycle.c	Wed Mar 15 23:42:31 2000
@@ -38,6 +38,101 @@
 #include "merc.h"
 #include "recycle.h"
 
+#define STANDARD_ALLOCMEM(type, name)			\
+type * name ## _free;					\
+int name ## _created;					\
+int name ## _allocated;					\
+							\
+type * new_ ## name( void )				\
+{							\
+	type * temp;					\
+static	type   tZero;					\
+							\
+	if ( name ## _free )				\
+	{						\
+		temp = name ## _free;			\
+		name ## _free = name ## _free->next;	\
+	}						\
+	else						\
+	{						\
+		temp = alloc_mem( sizeof(*temp) );	\
+		name ## _allocated++;			\
+	}						\
+							\
+	*temp = tZero;					\
+							\
+	name ## _created++;				\
+							\
+	return temp;					\
+}
+
+#define STANDARD_FREEMEM(type, name)			\
+int name ## _freed;					\
+							\
+void free_ ## name( type * temp )			\
+{							\
+	temp->next = name ## _free;			\
+	name ## _free = temp;				\
+	name ## _freed++;				\
+}
+
+#define VAL_ALLOCMEM(type, name)			\
+type * name ## _free;					\
+int name ## _created;					\
+int name ## _allocated;					\
+							\
+type * new_ ## name( void )				\
+{							\
+	type * temp;					\
+static	type   tZero;					\
+							\
+	if ( name ## _free )				\
+	{						\
+		temp = name ## _free;			\
+		name ## _free = name ## _free->next;	\
+	}						\
+	else						\
+	{						\
+		temp = alloc_mem( sizeof(*temp) );	\
+		name ## _allocated++;			\
+	}						\
+							\
+	*temp = tZero;					\
+							\
+	VALIDATE(temp);					\
+							\
+	name ## _created++;				\
+							\
+	return temp;					\
+}
+
+#define VAL_FREEMEM(type, name)				\
+int name ## _freed;					\
+							\
+void free_ ## name( type * temp )			\
+{							\
+	if (!IS_VALID(temp))				\
+		return;					\
+							\
+	INVALIDATE(temp);				\
+	temp->next = name ## _free;			\
+	name ## _free = temp;				\
+	name ## _freed++;				\
+}
+
+#define allocfunc(a,b)		\
+STANDARD_ALLOCMEM(a,b)		\
+STANDARD_FREEMEM(a,b)
+
+#define allocfunc_val(a,b)	\
+VAL_ALLOCMEM(a,b)		\
+VAL_FREEMEM(a,b)
+
+#include "allocfunc.h"
+
+#undef allocfunc
+#undef allocfunc_val
+
 /* stuff for recyling notes */
 NOTE_DATA *note_free;
 
@@ -156,7 +251,14 @@
 	gen_data_free = gen_data_free->next;
     }
     *gen = gen_zero;
+
+#if !defined(FIRST_BOOT)
+    gen->skill_chosen = new_boolarray(MAX_SKILL);
+    gen->group_chosen = new_boolarray(MAX_GROUP);
+#endif
+
     VALIDATE(gen);
+
     return gen;
 }
 
@@ -167,6 +269,11 @@
 
     INVALIDATE(gen);
 
+#if !defined(FIRST_BOOT)
+    free_boolarray(gen->skill_chosen);
+    free_boolarray(gen->group_chosen);
+#endif
+
     gen->next = gen_data_free;
     gen_data_free = gen;
 } 
@@ -406,6 +513,11 @@
     }
 
     pcdata->buffer = new_buf();
+
+#if !defined(FIRST_BOOT)
+    pcdata->learned = new_learned();
+    pcdata->group_known = new_boolarray(MAX_GROUP);
+#endif
     
     VALIDATE(pcdata);
     return pcdata;
@@ -419,6 +531,11 @@
     if (!IS_VALID(pcdata))
 	return;
 
+#if !defined(FIRST_BOOT)
+    free_learned(pcdata->learned);
+    free_boolarray(pcdata->group_known);
+#endif
+
     free_string(pcdata->pwd);
     free_string(pcdata->bamfin);
     free_string(pcdata->bamfout);
@@ -639,14 +756,120 @@
     return buffer->string;
 }
 
-    
+/* stuff for recycling mobprograms */
+MPROG_LIST *mprog_free;
 
-	
+MPROG_LIST *new_mprog(void)
+{
+   static MPROG_LIST mp_zero;
+   MPROG_LIST *mp;
+
+   if (mprog_free == NULL)
+       mp = alloc_perm(sizeof(*mp));
+   else
+   {
+       mp = mprog_free;
+       mprog_free=mprog_free->next;
+   }
+
+   *mp = mp_zero;
+   mp->vnum             = 0;
+   mp->trig_type        = 0;
+   mp->code             = str_dup("");
+   VALIDATE(mp);
+   return mp;
+}
+
+void free_mprog(MPROG_LIST *mp)
+{
+   if (!IS_VALID(mp))
+      return;
+
+   INVALIDATE(mp);
+   mp->next = mprog_free;
+   mprog_free = mp;
+}
+
+HELP_AREA * had_free;
+
+HELP_AREA * new_had ( void )
+{
+	HELP_AREA * had;
+static	HELP_AREA   zHad;
+
+	if ( had_free )
+	{
+		had		= had_free;
+		had_free	= had_free->next;
+	}
+	else
+		had		= alloc_perm( sizeof( *had ) );
 
+	*had = zHad;
 
+	return had;
+}
 
+HELP_DATA * help_free;
 
+HELP_DATA * new_help ( void )
+{
+	HELP_DATA * help;
 
+	if ( help_free )
+	{
+		help		= help_free;
+		help_free	= help_free->next;
+	}
+	else
+		help		= alloc_perm( sizeof( *help ) );
 
+	return help;
+}
 
+void free_help(HELP_DATA *help)
+{
+	free_string(help->keyword);
+	free_string(help->text);
+	help->next = help_free;
+	help_free = help;
+}
+
+sh_int *new_learned( void ) // retorna un arreglo de MAX_SKILL sh_int's
+{
+	sh_int *temp;
+	int i;
+
+	temp = malloc( sizeof( sh_int ) * MAX_SKILL );
+
+	for ( i = 0; i < MAX_SKILL; ++i )
+		temp[i] = 0;
+
+	return temp;
+}
 
+void	free_learned( sh_int *temp )
+{
+	free(temp);
+	temp = NULL;
+	return;
+}
+
+bool	*new_boolarray( int largo ) // retorna un arreglo de 'largo' booleanos
+{
+	bool *temp;
+	int i;
+	
+	temp = malloc( sizeof( bool ) * largo );
+	for ( i = 0; i < largo; ++i )
+		temp[i] = FALSE;
+
+	return temp;
+}
+
+void	free_boolarray( bool *temp )
+{
+	free(temp);
+	temp = NULL;
+	return;
+}
diff -ur src/recycle.h new/recycle.h
--- src/recycle.h	Sat May 23 22:27:56 1998
+++ new/recycle.h	Wed Mar 15 23:42:52 2000
@@ -103,10 +103,29 @@
 #undef MD
 
 /* buffer procedures */
-
 BUFFER	*new_buf args( (void) );
 BUFFER  *new_buf_size args( (int size) );
 void	free_buf args( (BUFFER *buffer) );
 bool	add_buf args( (BUFFER *buffer, char *string) );
 void	clear_buf args( (BUFFER *buffer) );
 char	*buf_string args( (BUFFER *buffer) );
+
+HELP_AREA *	new_had		args( ( void ) );
+HELP_DATA *	new_help	args( ( void ) );
+void		free_help	args( ( HELP_DATA * ) );
+
+sh_int *	new_learned	args( ( void ) );
+void		free_learned	args( ( sh_int * ) );
+
+bool *		new_boolarray	args( ( int ) );
+void		free_boolarray	args( ( bool * ) );
+
+#define allocfunc_val allocfunc
+#define allocfunc(a,b)						\
+a *		new_ ## b	args( ( void ) );		\
+void		free_ ## b	args( ( a * ) );
+
+#include "allocfunc.h"
+
+#undef allocfunc
+#undef allocfunc_val
diff -ur src/save.c new/save.c
--- src/save.c	Mon May 25 06:25:25 1998
+++ new/save.c	Wed Mar 15 22:57:16 2000
@@ -37,15 +37,15 @@
 #include <malloc.h>
 #include "merc.h"
 #include "recycle.h"
-#include "lookup.h"
 #include "tables.h"
+#include "lookup.h"
  
 #if !defined(macintosh)
 extern  int     _filbuf         args( (FILE *) );
 #endif
 
 
-int rename(const char *oldfname, const char *newfname);
+/* int rename(const char *oldfname, const char *newfname); viene en stdio.h */
 
 char *print_flags(int flag)
 {
@@ -180,7 +180,11 @@
     	fprintf( fp, "Desc %s~\n",	ch->description	);
     if (ch->prompt != NULL || !str_cmp(ch->prompt,"<%hhp %mm %vmv> "))
         fprintf( fp, "Prom %s~\n",      ch->prompt  	);
+#if defined(FIRST_BOOT)
     fprintf( fp, "Race %s~\n", pc_race_table[ch->race].name );
+#else
+    fprintf( fp, "Race %s~\n", race_table[ch->race].name );
+#endif
     if (ch->clan)
     	fprintf( fp, "Clan %s~\n",clan_table[ch->clan].name);
     fprintf( fp, "Sex  %d\n",	ch->sex			);
@@ -188,6 +192,7 @@
     fprintf( fp, "Levl %d\n",	ch->level		);
     if (ch->trust != 0)
 	fprintf( fp, "Tru  %d\n",	ch->trust	);
+    fprintf( fp, "Sec  %d\n",    ch->pcdata->security	);	/* OLC */
     fprintf( fp, "Plyd %d\n",
 	ch->played + (int) (current_time - ch->logon)	);
     fprintf( fp, "Not  %ld %ld %ld %ld %ld\n",		
@@ -567,6 +572,7 @@
     ch->pcdata->condition[COND_THIRST]	= 48; 
     ch->pcdata->condition[COND_FULL]	= 48;
     ch->pcdata->condition[COND_HUNGER]	= 48;
+    ch->pcdata->security		= 0;	/* OLC */
 
     found = FALSE;
     fclose( fpReserve );
@@ -635,14 +641,24 @@
 	if (ch->race == 0)
 	    ch->race = race_lookup("human");
 
+#if defined(FIRST_BOOT)
 	ch->size = pc_race_table[ch->race].size;
+#else
+	ch->size = race_table[ch->race].size;
+#endif
 	ch->dam_type = 17; /*punch */
 
 	for (i = 0; i < 5; i++)
 	{
+#if defined(FIRST_BOOT)
 	    if (pc_race_table[ch->race].skills[i] == NULL)
 		break;
 	    group_add(ch,pc_race_table[ch->race].skills[i],FALSE);
+#else
+	    if (race_table[ch->race].skills[i] == NULL)
+	    	break;
+	    group_add(ch,race_table[ch->race].skills[i],FALSE);
+#endif
 	}
 	ch->affected_by = ch->affected_by|race_table[ch->race].aff;
 	ch->imm_flags	= ch->imm_flags | race_table[ch->race].imm;
@@ -1051,6 +1067,7 @@
 	    KEY( "Sex",		ch->sex,		fread_number( fp ) );
 	    KEY( "ShortDescr",	ch->short_descr,	fread_string( fp ) );
 	    KEY( "ShD",		ch->short_descr,	fread_string( fp ) );
+	    KEY( "Sec",         ch->pcdata->security,	fread_number( fp ) );	/* OLC */
             KEY( "Silv",        ch->silver,             fread_number( fp ) );
 
 
@@ -1339,7 +1356,7 @@
     }
 }
 
-
+extern	OBJ_DATA	*obj_free;
 
 void fread_obj( CHAR_DATA *ch, FILE *fp )
 {
@@ -1492,14 +1509,20 @@
 
 	    if ( !str_cmp( word, "End" ) )
 	    {
-		if ( !fNest || !fVnum || obj->pIndexData == NULL)
+		if ( !fNest || ( fVnum && obj->pIndexData == NULL ) )
 		{
 		    bug( "Fread_obj: incomplete object.", 0 );
 		    free_obj(obj);
 		    return;
 		}
 		else
-		{
+	        {
+		    if ( !fVnum )
+		    {
+			free_obj( obj );
+			obj = create_object( get_obj_index( OBJ_VNUM_DUMMY ), 0 );
+		    }
+
 		    if (!new_format)
 		    {
 		    	obj->next	= object_list;
diff -ur src/skills.c new/skills.c
--- src/skills.c	Thu May 28 00:32:11 1998
+++ new/skills.c	Wed Mar 15 22:57:16 2000
@@ -633,8 +633,13 @@
     inc = 500;
 
     if (points < 40)
+#if defined(FIRST_BOOT)
 	return 1000 * (pc_race_table[ch->race].class_mult[ch->class] ?
 		       pc_race_table[ch->race].class_mult[ch->class]/100 : 1);
+#else
+	return 1000 * (race_table[ch->race].class_mult[ch->class] ?
+		       race_table[ch->race].class_mult[ch->class]/100 : 1);
+#endif
 
     /* processing */
     points -= 40;
@@ -653,7 +658,11 @@
 
     expl += points * inc / 10;  
 
+#if defined(FIRST_BOOT)
     return expl * pc_race_table[ch->race].class_mult[ch->class]/100;
+#else
+    return expl * race_table[ch->race].class_mult[ch->class]/100;
+#endif
 }
 
 /* this procedure handles the input parsing for the skill generator */
@@ -1067,3 +1076,36 @@
 	gn_remove(ch,gn);  /* be sure to call gn_add on all remaining groups */
     }
 }
+
+#if !defined(FIRST_BOOT)
+int race_exp_per_level( int race, int class, int points )
+{
+    int expl,inc;
+
+    expl = 1000;
+    inc = 500;
+
+    if (points < 40)
+	return 1000 * (race_table[race].class_mult[class] ?
+		       race_table[race].class_mult[class]/100 : 1);
+
+    /* processing */
+    points -= 40;
+
+    while (points > 9)
+    {
+	expl += inc;
+        points -= 10;
+        if (points > 9)
+	{
+	    expl += inc;
+	    inc *= 2;
+	    points -= 10;
+	}
+    }
+
+    expl += points * inc / 10;  
+
+    return expl * race_table[race].class_mult[class]/100;
+}
+#endif
diff -ur src/tables.c new/tables.c
--- src/tables.c	Sat May 23 22:28:04 1998
+++ new/tables.c	Wed Mar 15 22:57:16 2000
@@ -306,17 +306,618 @@
     {	NULL,			0,			0	}
 };
 
+const struct flag_type mprog_flags[] =
+{
+    {	"act",			TRIG_ACT,		TRUE	},
+    {	"bribe",		TRIG_BRIBE,		TRUE 	},
+    {	"death",		TRIG_DEATH,		TRUE    },
+    {	"entry",		TRIG_ENTRY,		TRUE	},
+    {	"fight",		TRIG_FIGHT,		TRUE	},
+    {	"give",			TRIG_GIVE,		TRUE	},
+    {	"greet",		TRIG_GREET,		TRUE    },
+    {	"grall",		TRIG_GRALL,		TRUE	},
+    {	"kill",			TRIG_KILL,		TRUE	},
+    {	"hpcnt",		TRIG_HPCNT,		TRUE    },
+    {	"random",		TRIG_RANDOM,		TRUE	},
+    {	"speech",		TRIG_SPEECH,		TRUE	},
+    {	"exit",			TRIG_EXIT,		TRUE    },
+    {	"exall",		TRIG_EXALL,		TRUE    },
+    {	"delay",		TRIG_DELAY,		TRUE    },
+    {	"surr",			TRIG_SURR,		TRUE    },
+    {	NULL,			0,			TRUE	}
+};
 
+const struct flag_type area_flags[] =
+{
+    {	"none",			AREA_NONE,		FALSE	},
+    {	"changed",		AREA_CHANGED,		TRUE	},
+    {	"added",		AREA_ADDED,		TRUE	},
+    {	"loading",		AREA_LOADING,		FALSE	},
+    {	NULL,			0,			0	}
+};
 
 
 
+const struct flag_type sex_flags[] =
+{
+    {	"male",			SEX_MALE,		TRUE	},
+    {	"female",		SEX_FEMALE,		TRUE	},
+    {	"neutral",		SEX_NEUTRAL,		TRUE	},
+    {   "random",               3,                      TRUE    },   /* ROM */
+    {	"none",			SEX_NEUTRAL,		TRUE	},
+    {	NULL,			0,			0	}
+};
 
 
 
+const struct flag_type exit_flags[] =
+{
+    {   "door",			EX_ISDOOR,		TRUE    },
+    {	"closed",		EX_CLOSED,		TRUE	},
+    {	"locked",		EX_LOCKED,		TRUE	},
+    {	"pickproof",		EX_PICKPROOF,		TRUE	},
+    {   "nopass",		EX_NOPASS,		TRUE	},
+    {   "easy",			EX_EASY,		TRUE	},
+    {   "hard",			EX_HARD,		TRUE	},
+    {	"infuriating",		EX_INFURIATING,		TRUE	},
+    {	"noclose",		EX_NOCLOSE,		TRUE	},
+    {	"nolock",		EX_NOLOCK,		TRUE	},
+    {	NULL,			0,			0	}
+};
+
 
 
+const struct flag_type door_resets[] =
+{
+    {	"open and unlocked",	0,		TRUE	},
+    {	"closed and unlocked",	1,		TRUE	},
+    {	"closed and locked",	2,		TRUE	},
+    {	NULL,			0,		0	}
+};
 
 
 
+const struct flag_type room_flags[] =
+{
+    {	"dark",			ROOM_DARK,		TRUE	},
+    {	"no_mob",		ROOM_NO_MOB,		TRUE	},
+    {	"indoors",		ROOM_INDOORS,		TRUE	},
+    {	"private",		ROOM_PRIVATE,		TRUE    },
+    {	"safe",			ROOM_SAFE,		TRUE	},
+    {	"solitary",		ROOM_SOLITARY,		TRUE	},
+    {	"pet_shop",		ROOM_PET_SHOP,		TRUE	},
+    {	"no_recall",		ROOM_NO_RECALL,		TRUE	},
+    {	"imp_only",		ROOM_IMP_ONLY,		TRUE    },
+    {	"gods_only",	        ROOM_GODS_ONLY,		TRUE    },
+    {	"heroes_only",		ROOM_HEROES_ONLY,	TRUE	},
+    {	"newbies_only",		ROOM_NEWBIES_ONLY,	TRUE	},
+    {	"law",			ROOM_LAW,		TRUE	},
+    {   "nowhere",		ROOM_NOWHERE,		TRUE	},
+    {	NULL,			0,			0	}
+};
+
+
+
+const struct flag_type sector_flags[] =
+{
+    {	"inside",	SECT_INSIDE,		TRUE	},
+    {	"city",		SECT_CITY,		TRUE	},
+    {	"field",	SECT_FIELD,		TRUE	},
+    {	"forest",	SECT_FOREST,		TRUE	},
+    {	"hills",	SECT_HILLS,		TRUE	},
+    {	"mountain",	SECT_MOUNTAIN,		TRUE	},
+    {	"swim",		SECT_WATER_SWIM,	TRUE	},
+    {	"noswim",	SECT_WATER_NOSWIM,	TRUE	},
+    {   "unused",	SECT_UNUSED,		TRUE	},
+    {	"air",		SECT_AIR,		TRUE	},
+    {	"desert",	SECT_DESERT,		TRUE	},
+    {	NULL,		0,			0	}
+};
+
+
+
+const struct flag_type type_flags[] =
+{
+    {	"light",		ITEM_LIGHT,		TRUE	},
+    {	"scroll",		ITEM_SCROLL,		TRUE	},
+    {	"wand",			ITEM_WAND,		TRUE	},
+    {	"staff",		ITEM_STAFF,		TRUE	},
+    {	"weapon",		ITEM_WEAPON,		TRUE	},
+    {	"treasure",		ITEM_TREASURE,		TRUE	},
+    {	"armor",		ITEM_ARMOR,		TRUE	},
+    {	"potion",		ITEM_POTION,		TRUE	},
+    {	"furniture",		ITEM_FURNITURE,		TRUE	},
+    {	"trash",		ITEM_TRASH,		TRUE	},
+    {	"container",		ITEM_CONTAINER,		TRUE	},
+    {	"drinkcontainer",	ITEM_DRINK_CON,		TRUE	},
+    {	"key",			ITEM_KEY,		TRUE	},
+    {	"food",			ITEM_FOOD,		TRUE	},
+    {	"money",		ITEM_MONEY,		TRUE	},
+    {	"boat",			ITEM_BOAT,		TRUE	},
+    {	"npccorpse",		ITEM_CORPSE_NPC,	TRUE	},
+    {	"pc corpse",		ITEM_CORPSE_PC,		FALSE	},
+    {	"fountain",		ITEM_FOUNTAIN,		TRUE	},
+    {	"pill",			ITEM_PILL,		TRUE	},
+    {	"protect",		ITEM_PROTECT,		TRUE	},
+    {	"map",			ITEM_MAP,		TRUE	},
+    {   "portal",		ITEM_PORTAL,		TRUE	},
+    {   "warpstone",		ITEM_WARP_STONE,	TRUE	},
+    {	"roomkey",		ITEM_ROOM_KEY,		TRUE	},
+    { 	"gem",			ITEM_GEM,		TRUE	},
+    {	"jewelry",		ITEM_JEWELRY,		TRUE	},
+    {	"jukebox",		ITEM_JUKEBOX,		TRUE	},
+    {	NULL,			0,			0	}
+};
+
+
+const struct flag_type extra_flags[] =
+{
+    {	"glow",			ITEM_GLOW,		TRUE	},
+    {	"hum",			ITEM_HUM,		TRUE	},
+    {	"dark",			ITEM_DARK,		TRUE	},
+    {	"lock",			ITEM_LOCK,		TRUE	},
+    {	"evil",			ITEM_EVIL,		TRUE	},
+    {	"invis",		ITEM_INVIS,		TRUE	},
+    {	"magic",		ITEM_MAGIC,		TRUE	},
+    {	"nodrop",		ITEM_NODROP,		TRUE	},
+    {	"bless",		ITEM_BLESS,		TRUE	},
+    {	"antigood",		ITEM_ANTI_GOOD,		TRUE	},
+    {	"antievil",		ITEM_ANTI_EVIL,		TRUE	},
+    {	"antineutral",		ITEM_ANTI_NEUTRAL,	TRUE	},
+    {	"noremove",		ITEM_NOREMOVE,		TRUE	},
+    {	"inventory",		ITEM_INVENTORY,		TRUE	},
+    {	"nopurge",		ITEM_NOPURGE,		TRUE	},
+    {	"rotdeath",		ITEM_ROT_DEATH,		TRUE	},
+    {	"visdeath",		ITEM_VIS_DEATH,		TRUE	},
+    {   "nonmetal",		ITEM_NONMETAL,		TRUE	},
+    {	"meltdrop",		ITEM_MELT_DROP,		TRUE	},
+    {	"hadtimer",		ITEM_HAD_TIMER,		TRUE	},
+    {	"sellextract",		ITEM_SELL_EXTRACT,	TRUE	},
+    {	"burnproof",		ITEM_BURN_PROOF,	TRUE	},
+    {	"nouncurse",		ITEM_NOUNCURSE,		TRUE	},
+    {	NULL,			0,			0	}
+};
+
+
+
+const struct flag_type wear_flags[] =
+{
+    {	"take",			ITEM_TAKE,		TRUE	},
+    {	"finger",		ITEM_WEAR_FINGER,	TRUE	},
+    {	"neck",			ITEM_WEAR_NECK,		TRUE	},
+    {	"body",			ITEM_WEAR_BODY,		TRUE	},
+    {	"head",			ITEM_WEAR_HEAD,		TRUE	},
+    {	"legs",			ITEM_WEAR_LEGS,		TRUE	},
+    {	"feet",			ITEM_WEAR_FEET,		TRUE	},
+    {	"hands",		ITEM_WEAR_HANDS,	TRUE	},
+    {	"arms",			ITEM_WEAR_ARMS,		TRUE	},
+    {	"shield",		ITEM_WEAR_SHIELD,	TRUE	},
+    {	"about",		ITEM_WEAR_ABOUT,	TRUE	},
+    {	"waist",		ITEM_WEAR_WAIST,	TRUE	},
+    {	"wrist",		ITEM_WEAR_WRIST,	TRUE	},
+    {	"wield",		ITEM_WIELD,		TRUE	},
+    {	"hold",			ITEM_HOLD,		TRUE	},
+    {   "nosac",		ITEM_NO_SAC,		TRUE	},
+    {	"wearfloat",		ITEM_WEAR_FLOAT,	TRUE	},
+/*    {   "twohands",            ITEM_TWO_HANDS,         TRUE    }, */
+    {	NULL,			0,			0	}
+};
+
+/*
+ * Used when adding an affect to tell where it goes.
+ * See addaffect and delaffect in act_olc.c
+ */
+const struct flag_type apply_flags[] =
+{
+    {	"none",			APPLY_NONE,		TRUE	},
+    {	"strength",		APPLY_STR,		TRUE	},
+    {	"dexterity",		APPLY_DEX,		TRUE	},
+    {	"intelligence",		APPLY_INT,		TRUE	},
+    {	"wisdom",		APPLY_WIS,		TRUE	},
+    {	"constitution",		APPLY_CON,		TRUE	},
+    {	"sex",			APPLY_SEX,		TRUE	},
+    {	"class",		APPLY_CLASS,		TRUE	},
+    {	"level",		APPLY_LEVEL,		TRUE	},
+    {	"age",			APPLY_AGE,		TRUE	},
+    {	"height",		APPLY_HEIGHT,		TRUE	},
+    {	"weight",		APPLY_WEIGHT,		TRUE	},
+    {	"mana",			APPLY_MANA,		TRUE	},
+    {	"hp",			APPLY_HIT,		TRUE	},
+    {	"move",			APPLY_MOVE,		TRUE	},
+    {	"gold",			APPLY_GOLD,		TRUE	},
+    {	"experience",		APPLY_EXP,		TRUE	},
+    {	"ac",			APPLY_AC,		TRUE	},
+    {	"hitroll",		APPLY_HITROLL,		TRUE	},
+    {	"damroll",		APPLY_DAMROLL,		TRUE	},
+    {	"saves",		APPLY_SAVES,		TRUE	},
+    {	"savingpara",		APPLY_SAVING_PARA,	TRUE	},
+    {	"savingrod",		APPLY_SAVING_ROD,	TRUE	},
+    {	"savingpetri",		APPLY_SAVING_PETRI,	TRUE	},
+    {	"savingbreath",		APPLY_SAVING_BREATH,	TRUE	},
+    {	"savingspell",		APPLY_SAVING_SPELL,	TRUE	},
+    {	"spellaffect",		APPLY_SPELL_AFFECT,	FALSE	},
+    {	NULL,			0,			0	}
+};
+
+
+
+/*
+ * What is seen.
+ */
+const struct flag_type wear_loc_strings[] =
+{
+    {	"in the inventory",	WEAR_NONE,	TRUE	},
+    {	"as a light",		WEAR_LIGHT,	TRUE	},
+    {	"on the left finger",	WEAR_FINGER_L,	TRUE	},
+    {	"on the right finger",	WEAR_FINGER_R,	TRUE	},
+    {	"around the neck (1)",	WEAR_NECK_1,	TRUE	},
+    {	"around the neck (2)",	WEAR_NECK_2,	TRUE	},
+    {	"on the body",		WEAR_BODY,	TRUE	},
+    {	"over the head",	WEAR_HEAD,	TRUE	},
+    {	"on the legs",		WEAR_LEGS,	TRUE	},
+    {	"on the feet",		WEAR_FEET,	TRUE	},
+    {	"on the hands",		WEAR_HANDS,	TRUE	},
+    {	"on the arms",		WEAR_ARMS,	TRUE	},
+    {	"as a shield",		WEAR_SHIELD,	TRUE	},
+    {	"about the shoulders",	WEAR_ABOUT,	TRUE	},
+    {	"around the waist",	WEAR_WAIST,	TRUE	},
+    {	"on the left wrist",	WEAR_WRIST_L,	TRUE	},
+    {	"on the right wrist",	WEAR_WRIST_R,	TRUE	},
+    {	"wielded",		WEAR_WIELD,	TRUE	},
+    {	"held in the hands",	WEAR_HOLD,	TRUE	},
+    {	"floating nearby",	WEAR_FLOAT,	TRUE	},
+    {	NULL,			0	      , 0	}
+};
+
+
+const struct flag_type wear_loc_flags[] =
+{
+    {	"none",		WEAR_NONE,	TRUE	},
+    {	"light",	WEAR_LIGHT,	TRUE	},
+    {	"lfinger",	WEAR_FINGER_L,	TRUE	},
+    {	"rfinger",	WEAR_FINGER_R,	TRUE	},
+    {	"neck1",	WEAR_NECK_1,	TRUE	},
+    {	"neck2",	WEAR_NECK_2,	TRUE	},
+    {	"body",		WEAR_BODY,	TRUE	},
+    {	"head",		WEAR_HEAD,	TRUE	},
+    {	"legs",		WEAR_LEGS,	TRUE	},
+    {	"feet",		WEAR_FEET,	TRUE	},
+    {	"hands",	WEAR_HANDS,	TRUE	},
+    {	"arms",		WEAR_ARMS,	TRUE	},
+    {	"shield",	WEAR_SHIELD,	TRUE	},
+    {	"about",	WEAR_ABOUT,	TRUE	},
+    {	"waist",	WEAR_WAIST,	TRUE	},
+    {	"lwrist",	WEAR_WRIST_L,	TRUE	},
+    {	"rwrist",	WEAR_WRIST_R,	TRUE	},
+    {	"wielded",	WEAR_WIELD,	TRUE	},
+    {	"hold",		WEAR_HOLD,	TRUE	},
+    {	"floating",	WEAR_FLOAT,	TRUE	},
+    {	NULL,		0,		0	}
+};
+
+const struct flag_type container_flags[] =
+{
+    {	"closeable",		1,		TRUE	},
+    {	"pickproof",		2,		TRUE	},
+    {	"closed",		4,		TRUE	},
+    {	"locked",		8,		TRUE	},
+    {	"puton",		16,		TRUE	},
+    {	NULL,			0,		0	}
+};
 
+/*****************************************************************************
+                      ROM - specific tables:
+ ****************************************************************************/
 
+
+
+
+const struct flag_type ac_type[] =
+{
+    {   "pierce",        AC_PIERCE,            TRUE    },
+    {   "bash",          AC_BASH,              TRUE    },
+    {   "slash",         AC_SLASH,             TRUE    },
+    {   "exotic",        AC_EXOTIC,            TRUE    },
+    {   NULL,              0,                    0       }
+};
+
+
+const struct flag_type size_flags[] =
+{
+    {   "tiny",          SIZE_TINY,            TRUE    },
+    {   "small",         SIZE_SMALL,           TRUE    },
+    {   "medium",        SIZE_MEDIUM,          TRUE    },
+    {   "large",         SIZE_LARGE,           TRUE    },
+    {   "huge",          SIZE_HUGE,            TRUE    },
+    {   "giant",         SIZE_GIANT,           TRUE    },
+    {   NULL,              0,                    0       },
+};
+
+
+const struct flag_type weapon_class[] =
+{
+    {   "exotic",	WEAPON_EXOTIC,		TRUE    },
+    {   "sword",	WEAPON_SWORD,		TRUE    },
+    {   "dagger",	WEAPON_DAGGER,		TRUE    },
+    {   "spear",	WEAPON_SPEAR,		TRUE    },
+    {   "mace",		WEAPON_MACE,		TRUE    },
+    {   "axe",		WEAPON_AXE,		TRUE    },
+    {   "flail",	WEAPON_FLAIL,		TRUE    },
+    {   "whip",		WEAPON_WHIP,		TRUE    },
+    {   "polearm",	WEAPON_POLEARM,		TRUE    },
+    {   NULL,		0,			0       }
+};
+
+
+const struct flag_type weapon_type2[] =
+{
+    {   "flaming",       WEAPON_FLAMING,       TRUE    },
+    {   "frost",         WEAPON_FROST,         TRUE    },
+    {   "vampiric",      WEAPON_VAMPIRIC,      TRUE    },
+    {   "sharp",         WEAPON_SHARP,         TRUE    },
+    {   "vorpal",        WEAPON_VORPAL,        TRUE    },
+    {   "twohands",     WEAPON_TWO_HANDS,     TRUE    },
+    {	"shocking",	 WEAPON_SHOCKING,      TRUE    },
+    {	"poison",	WEAPON_POISON,		TRUE	},
+    {   NULL,              0,                    0       }
+};
+
+const struct flag_type res_flags[] =
+{
+    {	"summon",	 RES_SUMMON,		TRUE	},
+    {   "charm",         RES_CHARM,            TRUE    },
+    {   "magic",         RES_MAGIC,            TRUE    },
+    {   "weapon",        RES_WEAPON,           TRUE    },
+    {   "bash",          RES_BASH,             TRUE    },
+    {   "pierce",        RES_PIERCE,           TRUE    },
+    {   "slash",         RES_SLASH,            TRUE    },
+    {   "fire",          RES_FIRE,             TRUE    },
+    {   "cold",          RES_COLD,             TRUE    },
+    {   "lightning",     RES_LIGHTNING,        TRUE    },
+    {   "acid",          RES_ACID,             TRUE    },
+    {   "poison",        RES_POISON,           TRUE    },
+    {   "negative",      RES_NEGATIVE,         TRUE    },
+    {   "holy",          RES_HOLY,             TRUE    },
+    {   "energy",        RES_ENERGY,           TRUE    },
+    {   "mental",        RES_MENTAL,           TRUE    },
+    {   "disease",       RES_DISEASE,          TRUE    },
+    {   "drowning",      RES_DROWNING,         TRUE    },
+    {   "light",         RES_LIGHT,            TRUE    },
+    {	"sound",	RES_SOUND,		TRUE	},
+    {	"wood",		RES_WOOD,		TRUE	},
+    {	"silver",	RES_SILVER,		TRUE	},
+    {	"iron",		RES_IRON,		TRUE	},
+    {   NULL,          0,            0    }
+};
+
+
+const struct flag_type vuln_flags[] =
+{
+    {	"summon",	 VULN_SUMMON,		TRUE	},
+    {	"charm",	VULN_CHARM,		TRUE	},
+    {   "magic",         VULN_MAGIC,           TRUE    },
+    {   "weapon",        VULN_WEAPON,          TRUE    },
+    {   "bash",          VULN_BASH,            TRUE    },
+    {   "pierce",        VULN_PIERCE,          TRUE    },
+    {   "slash",         VULN_SLASH,           TRUE    },
+    {   "fire",          VULN_FIRE,            TRUE    },
+    {   "cold",          VULN_COLD,            TRUE    },
+    {   "lightning",     VULN_LIGHTNING,       TRUE    },
+    {   "acid",          VULN_ACID,            TRUE    },
+    {   "poison",        VULN_POISON,          TRUE    },
+    {   "negative",      VULN_NEGATIVE,        TRUE    },
+    {   "holy",          VULN_HOLY,            TRUE    },
+    {   "energy",        VULN_ENERGY,          TRUE    },
+    {   "mental",        VULN_MENTAL,          TRUE    },
+    {   "disease",       VULN_DISEASE,         TRUE    },
+    {   "drowning",      VULN_DROWNING,        TRUE    },
+    {   "light",         VULN_LIGHT,           TRUE    },
+    {	"sound",	 VULN_SOUND,		TRUE	},
+    {   "wood",          VULN_WOOD,            TRUE    },
+    {   "silver",        VULN_SILVER,          TRUE    },
+    {   "iron",          VULN_IRON,            TRUE    },
+    {   NULL,              0,                    0       }
+};
+
+const struct flag_type position_flags[] =
+{
+    {   "dead",           POS_DEAD,            FALSE   },
+    {   "mortal",         POS_MORTAL,          FALSE   },
+    {   "incap",          POS_INCAP,           FALSE   },
+    {   "stunned",        POS_STUNNED,         FALSE   },
+    {   "sleeping",       POS_SLEEPING,        TRUE    },
+    {   "resting",        POS_RESTING,         TRUE    },
+    {   "sitting",        POS_SITTING,         TRUE    },
+    {   "fighting",       POS_FIGHTING,        FALSE   },
+    {   "standing",       POS_STANDING,        TRUE    },
+    {   NULL,              0,                    0       }
+};
+
+const struct flag_type portal_flags[]=
+{
+    {   "normal_exit",	  GATE_NORMAL_EXIT,	TRUE	},
+    {	"no_curse",	  GATE_NOCURSE,		TRUE	},
+    {   "go_with",	  GATE_GOWITH,		TRUE	},
+    {   "buggy",	  GATE_BUGGY,		TRUE	},
+    {	"random",	  GATE_RANDOM,		TRUE	},
+    {   NULL,		  0,			0	}
+};
+
+const struct flag_type furniture_flags[]=
+{
+    {   "stand_at",	  STAND_AT,		TRUE	},
+    {	"stand_on",	  STAND_ON,		TRUE	},
+    {	"stand_in",	  STAND_IN,		TRUE	},
+    {	"sit_at",	  SIT_AT,		TRUE	},
+    {	"sit_on",	  SIT_ON,		TRUE	},
+    {	"sit_in",	  SIT_IN,		TRUE	},
+    {	"rest_at",	  REST_AT,		TRUE	},
+    {	"rest_on",	  REST_ON,		TRUE	},
+    {	"rest_in",	  REST_IN,		TRUE	},
+    {	"sleep_at",	  SLEEP_AT,		TRUE	},
+    {	"sleep_on",	  SLEEP_ON,		TRUE	},
+    {	"sleep_in",	  SLEEP_IN,		TRUE	},
+    {	"put_at",	  PUT_AT,		TRUE	},
+    {	"put_on",	  PUT_ON,		TRUE	},
+    {	"put_in",	  PUT_IN,		TRUE	},
+    {	"put_inside",	  PUT_INSIDE,		TRUE	},
+    {	NULL,		  0,			0	}
+};
+
+const	struct	flag_type	apply_types	[]	=
+{
+	{	"affects",	TO_AFFECTS,	TRUE	},
+	{	"object",	TO_OBJECT,	TRUE	},
+	{	"immune",	TO_IMMUNE,	TRUE	},
+	{	"resist",	TO_RESIST,	TRUE	},
+	{	"vuln",		TO_VULN,	TRUE	},
+	{	"weapon",	TO_WEAPON,	TRUE	},
+	{	NULL,		0,		TRUE	}
+};
+
+const	struct	bit_type	bitvector_type	[]	=
+{
+	{	affect_flags,	"affect"	},
+	{	apply_flags,	"apply"		},
+	{	imm_flags,	"imm"		},
+	{	res_flags,	"res"		},
+	{	vuln_flags,	"vuln"		},
+	{	weapon_type2,	"weapon"	}
+};
+
+const	struct	flag_type	target_table	[]	=
+{
+	{	"tar_ignore",		TAR_IGNORE,		TRUE	},
+	{	"tar_char_offensive",	TAR_CHAR_OFFENSIVE,	TRUE	},
+	{	"tar_char_defensive",	TAR_CHAR_DEFENSIVE,	TRUE	},
+	{	"tar_char_self",	TAR_CHAR_SELF,		TRUE	},
+	{	"tar_obj_inv",		TAR_OBJ_INV,		TRUE	},
+	{	"tar_obj_char_def",	TAR_OBJ_CHAR_DEF,	TRUE	},
+	{	"tar_obj_char_off",	TAR_OBJ_CHAR_OFF,	TRUE	},
+	{	NULL,			0,			TRUE	}
+};
+
+const	struct	recval_type	recval_table	[]	=
+{
+	/*      2d6	    +   10,     AC,     dam			}, */
+	{	2,	6,	10,	9,	1,	4,	0	},
+	{	2,	7,	21,	8,	1,	5,	0	},
+	{	2,	6,	35,	7,	1,	6,	0	},
+	{	2,	7,	46,	6,	1,	5,	1	},
+	{	2,	6,	60,	5,	1,	6,	1	},
+	{	2,	7,	71,	4,	1,	7,	1	},
+	{	2,	6,	85,	4,	1,	8,	1	},
+	{	2,	7,	96,	3,	1,	7,	2	},
+	{	2,	6,	110,	2,	1,	8,	2	},
+	{	2,	7,	121,	1,	2,	4,	2	}, /* 10 */
+	{	2,	8,	134,	1,	1,	10,	2	},
+	{	2,	10,	150,	0,	1,	10,	3	},
+	{	2,	10,	170,	-1,	2,	5,	3	},
+	{	2,	10,	190,	-1,	1,	12,	3	},
+	{	3,	9,	208,	-2,	2,	6,	3	},
+	{	3,	9,	233,	-2,	2,	6,	4	},
+	{	3,	9,	258,	-3,	3,	4,	4	},
+	{	3,	9,	283,	-3,	2,	7,	4	},
+	{	3,	9,	308,	-4,	2,	7,	5	},
+	{	3,	9,	333,	-4,	2,	8,	5	}, /* 20 */
+	{	4,	10,	360,	-5,	4,	4,	5	},
+	{	5,	10,	400,	-5,	4,	4,	6	},
+	{	5,	10,	450,	-6,	3,	6,	6	},
+	{	5,	10,	500,	-6,	2,	10,	6	},
+	{	5,	10,	550,	-7,	2,	10,	7	},
+	{	5,	10,	600,	-7,	3,	7,	7	},
+	{	5,	10,	650,	-8,	5,	4,	7	},
+	{	6,	12,	703,	-8,	2,	12,	8	},
+	{	6,	12,	778,	-9,	2,	12,	8	},
+	{	6,	12,	853,	-9,	4,	6,	8	}, /* 30 */
+	{	6,	12,	928,	-10,	6,	4,	9	},
+	{	10,	10,	1000,	-10,	4,	7,	9	},
+	{	10,	10,	1100,	-11,	7,	4,	10	},
+	{	10,	10,	1200,	-11,	5,	6,	10	},
+	{	10,	10,	1300,	-11,	6,	5,	11	},
+	{	10,	10,	1400,	-12,	4,	8,	11	},
+	{	10,	10,	1500,	-12,	8,	4,	12	},
+	{	10,	10,	1600,	-13,	16,	2,	12	},
+	{	15,	10,	1700,	-13,	17,	2,	13	},
+	{	15,	10,	1850,	-13,	6,	6,	13	}, /* 40 */
+	{	25,	10,	2000,	-14,	12,	3,	14	},
+	{	25,	10,	2250,	-14,	5,	8,	14	},
+	{	25,	10,	2500,	-15,	10,	4,	15	},
+	{	25,	10,	2750,	-15,	5,	9,	15	},
+	{	25,	10,	3000,	-15,	9,	5,	16	},
+	{	25,	10,	3250,	-16,	7,	7,	16	},
+	{	25,	10,	3500,	-17,	13,	4,	17	},
+	{	25,	10,	3750,	-18,	5,	11,	18	},
+	{	50,	10,	4000,	-19,	11,	5,	18	},
+	{	50,	10,	4500,	-20,	10,	6,	19	}, /* 50 */
+	{	50,	10,	5000,	-21,	5,	13,	20	},
+	{	50,	10,	5500,	-22,	15,	5,	20	},
+	{	50,	10,	6000,	-23,	15,	6,	21	},
+	{	50,	10,	6500,	-24,	15,	7,	22	},
+	{	50,	10,	7000,	-25,	15,	8,	23	},
+	{	50,	10,	7500,	-26,	15,	9,	24	},
+	{	50,	10,	8000,	-27,	15,	10,	24	},
+	{	50,	10,	8500,	-28,	20,	10,	25	},
+	{	50,	10,	9000,	-29,	30,	10,	26	},
+	{	50,	10,	9500,	-30,	50,	10,	28	}  /* 60 */
+};
+
+const	struct	flag_type	dam_classes	[]	=
+{
+	{	"dam_bash",	DAM_BASH,	TRUE	},
+	{	"dam_pierce",	DAM_PIERCE,	TRUE	},
+	{	"dam_slash",	DAM_SLASH,	TRUE	},
+	{	"dam_fire",	DAM_FIRE,	TRUE	},
+	{	"dam_cold",	DAM_COLD,	TRUE	},
+	{	"dam_lightning",DAM_LIGHTNING,	TRUE	},
+	{	"dam_acid",	DAM_ACID,	TRUE	},
+	{	"dam_poison",	DAM_POISON,	TRUE	},
+	{	"dam_negative",	DAM_NEGATIVE,	TRUE	},
+	{	"dam_holy",	DAM_HOLY,	TRUE	},
+	{	"dam_energy",	DAM_ENERGY,	TRUE	},
+	{	"dam_mental",	DAM_MENTAL,	TRUE	},
+	{	"dam_disease",	DAM_DISEASE,	TRUE	},
+	{	"dam_drowning",	DAM_DROWNING,	TRUE	},
+	{	"dam_light",	DAM_LIGHT,	TRUE	},
+	{	"dam_other",	DAM_OTHER,	TRUE	},
+	{	"dam_harm",	DAM_HARM,	TRUE	},
+	{	"dam_charm",	DAM_CHARM,	TRUE	},
+	{	"dam_sound",	DAM_SOUND,	TRUE	},
+	{	NULL,		0,		TRUE	}
+};
+
+const	struct	flag_type	log_flags	[]	=
+{
+	{	"log_normal",	LOG_NORMAL,	TRUE	},
+	{	"log_always",	LOG_ALWAYS,	TRUE	},
+	{	"log_never",	LOG_NEVER,	TRUE	},
+	{	NULL,		0,		TRUE	}
+};
+
+const	struct	flag_type	show_flags	[]	=
+{
+	{	"undef",	TYP_UNDEF,	TRUE	},
+	{	"comunicacion",	TYP_CMM,	TRUE	},
+	{	"combate",	TYP_CBT,	TRUE	},
+	{	"especiales",	TYP_ESP,	TRUE	},
+	{	"grupo",	TYP_GRP,	TRUE	},
+	{	"objetos",	TYP_OBJ,	TRUE	},
+	{	"informacion",	TYP_INF,	TRUE	},
+	{	"otros",	TYP_OTH,	TRUE	},
+	{	"movimiento",	TYP_MVT,	TRUE	},
+	{	"configuracion",TYP_CNF,	TRUE	},
+	{	"lenguajes",	TYP_LNG,	TRUE	},
+	{	"manejo",	TYP_PLR,	TRUE	},
+	{	"olc",		TYP_OLC,	TRUE	},
+	{	NULL,		0,		TRUE	}
+};
+
+const struct flag_type stat_table[] =
+{
+	{	"str",		STAT_STR,	TRUE	},
+	{	"int",		STAT_INT,	TRUE	},
+	{	"wis",		STAT_WIS,	TRUE	},
+	{	"dex",		STAT_DEX,	TRUE	},
+	{	"con",		STAT_CON,	TRUE	},
+	{	NULL,		0,		TRUE	}
+};
diff -ur src/tables.h new/tables.h
--- src/tables.h	Sat May 23 22:28:05 1998
+++ new/tables.h	Wed Mar 15 22:57:16 2000
@@ -25,6 +25,9 @@
 *	ROM license, in the file Rom24/doc/rom.license			   *
 ***************************************************************************/
 
+#if !defined(_TABLES_H)
+#define _TABLES_H
+
 /* game tables */
 extern	const	struct	clan_type	clan_table[MAX_CLAN];
 extern	const	struct	position_type	position_table[];
@@ -47,6 +50,33 @@
 extern	const	struct	flag_type	portal_flags[];
 extern	const	struct	flag_type	room_flags[];
 extern	const	struct	flag_type	exit_flags[];
+extern 	const	struct  flag_type	mprog_flags[];
+extern	const	struct	flag_type	area_flags[];
+extern	const	struct	flag_type	sector_flags[];
+extern	const	struct	flag_type	door_resets[];
+extern	const	struct	flag_type	wear_loc_strings[];
+extern	const	struct	flag_type	wear_loc_flags[];
+extern	const	struct	flag_type	res_flags[];
+extern	const	struct	flag_type	imm_flags[];
+extern	const	struct	flag_type	vuln_flags[];
+extern	const	struct	flag_type	type_flags[];
+extern	const	struct	flag_type	apply_flags[];
+extern	const	struct	flag_type	sex_flags[];
+extern	const	struct	flag_type	furniture_flags[];
+extern	const	struct	flag_type	weapon_class[];
+extern	const	struct	flag_type	apply_types[];
+extern	const	struct	flag_type	weapon_type2[];
+extern	const	struct	flag_type	apply_types[];
+extern	const	struct	flag_type	size_flags[];
+extern	const	struct	flag_type	position_flags[];
+extern	const	struct	flag_type	ac_type[];
+extern	const	struct	bit_type	bitvector_type[];
+extern	const	struct	recval_type	recval_table[];
+extern	const	struct	flag_type	target_table[];
+extern	const	struct	flag_type	dam_classes[];
+extern	const	struct	flag_type	log_flags[];
+extern	const	struct	flag_type	show_flags[];
+extern	const	struct	flag_type	stat_table[];
 
 struct flag_type
 {
@@ -79,3 +109,20 @@
     char *name;
 };
 
+struct	bit_type
+{
+	const	struct	flag_type *	table;
+	char *				help;
+};
+
+struct recval_type
+{
+	int numhit;
+	int typhit;
+	int bonhit;
+	int ac;
+	int numdam;
+	int typdam;
+	int bondam;
+};
+#endif // _TABLES_H
diff -ur src/update.c new/update.c
--- src/update.c	Thu May 28 00:35:35 1998
+++ new/update.c	Wed Mar 15 22:57:16 2000
@@ -403,6 +403,27 @@
 		ch->silver += ch->pIndexData->wealth * number_range(1,20)/50000;
 	    }
 	 
+	/*
+	 * Check triggers only if mobile still in default position
+	 */
+	if ( ch->position == ch->pIndexData->default_pos )
+	{
+	    /* Delay */
+	    if ( HAS_TRIGGER( ch, TRIG_DELAY) 
+	    &&   ch->mprog_delay > 0 )
+	    {
+		if ( --ch->mprog_delay <= 0 )
+		{
+		    mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_DELAY );
+		    continue;
+		}
+	    } 
+	    if ( HAS_TRIGGER( ch, TRIG_RANDOM) )
+	    {
+		if( mp_percent_trigger( ch, NULL, NULL, NULL, TRIG_RANDOM ) )
+		continue;
+	    }
+	}
 
 	/* That's all for sleeping / busy monster, and empty zones */
 	if ( ch->position != POS_STANDING )