diff -BENbdpru old/doc/OasisOLC.Changes new/doc/OasisOLC.Changes
--- old/doc/OasisOLC.Changes	2003-07-28 19:37:24.000000000 +0000
+++ new/doc/OasisOLC.Changes	2003-07-28 19:38:00.000000000 +0000
@@ -1,12 +1,27 @@
-        --==** OasisOLC Version 2.0.4 For CircleMUD Version 3.1 **==-
-
-[Current Additions]
-* RLIST command.  Lists all rooms in a given zone.
-* (D) command in redit.  Allows the builder to delete the room from memory.
-* Added a builders list for zones.
+        --==** OasisOLC Version 2.0.5 For CircleMUD Version 3.1 **==-
 
-[Current Modifications]
-* Maintenance Release:
+* Maintenance Release 2.0.5:
+  Upped version number to 2.0.5
+  Now can_edit_zone() works as advertised--reversed TRUE/FALSE
+  Rlist no longer displays exits to rooms that don't exist
+  Rlist shows exits even if low/high arguments aren't provided
+  Merged in some can_edit_zone() checks from DG Scripts
+  Combined ACMD(do_oasis_[morsz]list) into ACMD(do_oasis_list)
+  Made unaffect work when an object has been edited then removed
+  Added a links command for displaying exits from a zone
+  Added checks for CONFIG_AUTO_SAVE in [morsz]edit_parse()
+  Turn on smash_tilde() by default
+  Added smash_tilde() calls in MEDIT_(ALIAS|S_DESC|L_DESC) cases
+  REMOVE_BIT AFF_(CHARM|POISON|GROUP|SLEEP) in MEDIT_AFF_FLAGS case
+  Added an abort option to oedit
+  Fixed bounds checking in the OEDIT_TYPE case
+  Limit oedit weapon modifiers to +/-50 and dice to 50
+  Check more out of range oedit values for scrolls and potions
+  Don't allow assigning shop_keeper specproc in sedit_parse()
+  Call zedit_save_to_disk() from zedit_new_zone()
+  Various int to rnum fixes throughout gen(mob|obj|wld).c
+  Cedit no longer accumulates MENU WELC_MESSG START_MESSG newlines
+* Maintenance Release 2.0.4:
   Upped version number to 2.0.4
   Added empty builder field to lib/world/zon/*.zon
   Moved Oasis docfiles into doc/
@@ -17,31 +32,34 @@
   Repaired a bunch of potential format string exploits
   Added missing can_edit check to zedit
   Fixed free_strings() crash for rooms with multiple ex_description
-  Now can_edit_zone() works as advertised--reversed TRUE/FALSE
 * Alterations by Welcor:
   Upped version number to 2.0.3 (I think the new additions warrant it)
-  oasis-ified tedit (a bit) and made d->olc a struct oasis_olc_data * instead of void *
+  oasis-ified tedit (a bit) and made d->olc a struct oasis_olc_data *
+    instead of void *
   All olc files: Dependency on global buffers removed.
   All olc files: ->in_room -> IN_ROOM() change.
   All files (olc files + comm.c): update to circle 3.1
-  All olc files: removed some buffers, changed to write_to_output and send_to_char
-  db.c, db.h: Changed config_info to a static variable (to save some malloc/free'ing)
-  structs.h: Embedded substructs in config_data struct instead of using pointers (same reason)
+  All olc files: removed some buffers, changed to write_to_output and
+    send_to_char
+  db.c, db.h: Changed config_info to a static variable (to save some
+    malloc/free'ing)
+  structs.h: Embedded substructs in config_data struct instead of using
+    pointers (same reason)
   utils.h: Added macros to configure options.
   All olc files: Removed some outdated comments.
-  oasis_copy.c: Fixed serious buffer size error in do_dig and cleaned the code up.
-  All olc files: Added support for unsigned IDXTYPE by removing checks for <0 and ==-1
+  oasis_copy.c: Fixed serious buffer size error in do_dig and cleaned the
+    code up.
+  All olc files: Added support for unsigned IDXTYPE by removing checks for
+    <0 and ==-1
   comm.c: Added support for auto prompt. (hey, the bit was there...)
-* BugFix
-  zedit.
+* BugFix zedit.
     Modified the message to the user from "Zone create successfully\r\n" to
     "Zone created successfully.\r\n".
-* BugFix (Not really)
-  save
+* BugFix (Not really) save
     Added a check to make sure the zone is in the save_list before calling
     remove_from_save_list.  This was a problem because everytime a builder
     saved his/her zone, but it wasn't in the save list, an error was sent
     to the log file, erraneous.
-
-[Old Additions and Modifications]
-* None to date.
+* RLIST command.  Lists all rooms in a given zone.
+* (D) command in redit.  Allows the builder to delete the room from memory.
+* Added a builders list for zones.
diff -BENbdpru old/doc/OasisOLC.html new/doc/OasisOLC.html
--- old/doc/OasisOLC.html	2003-07-28 19:37:24.000000000 +0000
+++ new/doc/OasisOLC.html	2003-07-28 19:38:00.000000000 +0000
@@ -1,6 +1,6 @@
 <HTML>
 <HEAD>
-  <TITLE>OasisOLC v2.0.4</TITLE>
+  <TITLE>OasisOLC v2.0.5</TITLE>
 </HEAD>
 <BODY>
 
diff -BENbdpru old/src/Makefile.in new/src/Makefile.in
--- old/src/Makefile.in	2003-07-28 19:37:24.000000000 +0000
+++ new/src/Makefile.in	2003-07-28 19:38:00.000000000 +0000
@@ -25,23 +25,23 @@ LIBS = @LIBS@ @CRYPTLIB@ @NETLIB@
 
 OBJFILES = act.comm.o act.informative.o act.item.o act.movement.o \
 	act.offensive.o act.other.o act.social.o act.wizard.o alias.o ban.o \
-	boards.o castle.o cedit.o class.o comm.o config.o constants.o db.o \
-	fight.o genmob.o genobj.o genolc.o genshp.o genwld.o genzon.o graph.o \
-	handler.o house.o improved-edit.o interpreter.o limits.o magic.o mail.o \
-	medit.o mobact.o modify.o oasis.o oasis_copy.o oasis_delete.o \
-	oasis_list.o objsave.o oedit.o olc.o random.o redit.o sedit.o \
-	shop.o spec_assign.o spec_procs.o spell_parser.o spells.o tedit.o \
-	utils.o weather.o zedit.o bsd-snprintf.o
+	boards.o castle.o class.o comm.o config.o constants.o db.o fight.o \
+	graph.o handler.o house.o interpreter.o limits.o magic.o mail.o \
+	mobact.o modify.o objsave.o olc.o random.o shop.o spec_assign.o \
+	spec_procs.o spell_parser.o spells.o utils.o weather.o \
+	bsd-snprintf.o cedit.o genmob.o genobj.o genolc.o genshp.o genwld.o \
+	genzon.o improved-edit.o medit.o oasis.o oasis_copy.o oasis_delete.o \
+	oasis_list.o oedit.o redit.o sedit.o tedit.o zedit.o
 
 CXREF_FILES = act.comm.c act.informative.c act.item.c act.movement.c \
 	act.offensive.c act.other.c act.social.c act.wizard.c alias.c ban.c \
-	boards.c castle.c cedit.c class.c comm.c config.c constants.c db.c \
-	fight.c genmob.c genobj.c genolc.c genshp.c genwld.c genzon.c graph.c \
-	handler.c house.c improved-edit.c interpreter.c limits.c magic.c mail.c \
-	medit.c mobact.c modify.c oasis.c oasis_copy.o oasis_delete.c \
-	oasis_list.o objsave.c oedit.c olc.c random.c redit.c sedit.c \
-	shop.c spec_assign.c spec_procs.c spell_parser.c spells.c tedit.c \
-	utils.c weather.c zedit.c bsd-snprintf.c
+	boards.c castle.c class.c comm.c config.c constants.c db.c fight.c \
+	graph.c handler.c house.c interpreter.c limits.c magic.c mail.c \
+	mobact.c modify.c objsave.c olc.c random.c shop.c spec_assign.c \
+	spec_procs.c spell_parser.c spells.c utils.c weather.c \
+	bsd-snprintf.c cedit.c genmob.c genobj.c genolc.c genshp.c genwld.c \
+	genzon.c improved-edit.c medit.c oasis.c oasis_copy.c oasis_delete.c \
+	oasis_list.c oedit.c redit.c sedit.c tedit.c zedit.c
 
 default: all
 
diff -BENbdpru old/src/act.wizard.c new/src/act.wizard.c
--- old/src/act.wizard.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/act.wizard.c	2003-07-28 19:38:00.000000000 +0000
@@ -1852,9 +1852,10 @@ ACMD(do_wizutil)
       act("A sudden fireball conjured from nowhere thaws $n!", FALSE, vict, 0, 0, TO_ROOM);
       break;
     case SCMD_UNAFFECT:
-      if (vict->affected) {
+      if (vict->affected || AFF_FLAGS(vict)) {
 	while (vict->affected)
 	  affect_remove(vict, vict->affected);
+	AFF_FLAGS(vict) = 0;
 	send_to_char(vict, "There is a brief flash of light!\r\nYou feel slightly different.\r\n");
 	send_to_char(ch, "All spells removed.\r\n");
       } else {
diff -BENbdpru old/src/cedit.c new/src/cedit.c
--- old/src/cedit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/cedit.c	2003-07-28 19:38:00.000000000 +0000
@@ -519,14 +519,15 @@ int save_config( sh_int nowhere )
     strip_cr(buf);
     
     fprintf(fl, "* The entrance/exit menu.\n"
-                "MENU = \n%s\n~\n\n", buf);
+      "MENU = \n%s~\n\n", buf);
   }
   
   if (CONFIG_WELC_MESSG) {
     strcpy(buf, CONFIG_WELC_MESSG);
     strip_cr(buf);
     
-    fprintf(fl, "* The welcome message.\nWELC_MESSG = \n%s\n~\n\n", buf);
+    fprintf(fl, "* The welcome message.\n"
+      "WELC_MESSG = \n%s~\n\n", buf);
   }
   
   if (CONFIG_START_MESSG) {
@@ -534,7 +535,7 @@ int save_config( sh_int nowhere )
     strip_cr(buf);
     
     fprintf(fl, "* NEWBIE start message.\n"
-                "START_MESSG = \n%s\n~\n\n", buf);
+      "START_MESSG = \n%s~\n\n", buf);
   }
   
   fprintf(fl, "\n\n\n* [ Autowiz Options ]\n");
@@ -789,6 +790,10 @@ void cedit_parse(struct descriptor_data 
           mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, 
                  "OLC: %s modifies the game configuration.", GET_NAME(d->character));
           cleanup_olc(d, CLEANUP_CONFIG);
+	  if (CONFIG_AUTO_SAVE) {
+	    cedit_save_to_disk();
+	    write_to_output(d, "Game configuration saved to disk.\r\n");
+	  } else
           write_to_output(d, "Game configuration saved to memory.\r\n");
           return;
         case 'n':
@@ -798,7 +803,7 @@ void cedit_parse(struct descriptor_data 
           return;
         default :
           write_to_output(d, "\r\nThat is an invalid choice!\r\n");
-          write_to_output(d, "Do you wish to save the configuration internally? (y/n) : ");
+          write_to_output(d, "Do you wish to save the configuration? (y/n) : ");
           return;
       }
       
@@ -838,7 +843,7 @@ void cedit_parse(struct descriptor_data 
         
         case 'q':
         case 'Q':
-          write_to_output(d, "Do you wish to save the configuration internally? (y/n) : ");
+          write_to_output(d, "Do you wish to save the configuration? (y/n) : ");
           OLC_MODE(d) = CEDIT_CONFIRM_SAVESTRING;
           break;
           
diff -BENbdpru old/src/constants.c new/src/constants.c
--- old/src/constants.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/constants.c	2003-07-28 19:38:00.000000000 +0000
@@ -18,7 +18,7 @@ cpp_extern const char *circlemud_version
 	"CircleMUD, version 3.1";
 
 cpp_extern const char *oasisolc_version =
-	"OasisOLC 2.0.4";
+	"OasisOLC 2.0.5";
 
 /* strings corresponding to ordinals/bitvectors in structs.h ***********/
 
diff -BENbdpru old/src/genmob.c new/src/genmob.c
--- old/src/genmob.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/genmob.c	2003-07-28 19:38:00.000000000 +0000
@@ -36,6 +36,8 @@ extern struct char_data *character_list;
 extern struct char_data *mob_proto;
 extern struct index_data *mob_index;
 
+extern void smash_tilde(char *str);
+
 int add_mobile(struct char_data *mob, mob_vnum vnum)
 {
   int rnum, i, found = FALSE, shop, cmd_no;
@@ -53,7 +55,7 @@ int add_mobile(struct char_data *mob, mo
 
     add_to_save_list(zone_table[real_zone_by_thing(vnum)].number, SL_MOB);
     log("GenOLC: add_mobile: Updated existing mobile #%d.", vnum);
-    return TRUE;
+    return rnum;
   }
 
   RECREATE(mob_proto, struct char_data, top_of_mobt + 2);
@@ -246,7 +248,7 @@ int free_mobile_strings(struct char_data
  */
 int free_mobile(struct char_data *mob)
 {
-  int i;
+  mob_rnum i;
 
   if (mob == NULL)
     return FALSE;
@@ -261,11 +263,14 @@ int free_mobile(struct char_data *mob)
       free(mob->player.name);
     if (mob->player.title && mob->player.title != mob_proto[i].player.title)
       free(mob->player.title);
-    if (mob->player.short_descr && mob->player.short_descr != mob_proto[i].player.short_descr)
+    if (mob->player.short_descr &&
+      mob->player.short_descr != mob_proto[i].player.short_descr)
       free(mob->player.short_descr);
-    if (mob->player.long_descr && mob->player.long_descr != mob_proto[i].player.long_descr)
+    if (mob->player.long_descr &&
+      mob->player.long_descr != mob_proto[i].player.long_descr)
       free(mob->player.long_descr);
-    if (mob->player.description && mob->player.description != mob_proto[i].player.description)
+    if (mob->player.description &&
+      mob->player.description != mob_proto[i].player.description)
       free(mob->player.description);
   }
   while (mob->affected)
@@ -289,14 +294,16 @@ int save_mobiles(zone_rnum rznum)
 #else
   if (rznum < 0 || rznum > top_of_zone_table) {
 #endif
-    log("SYSERR: GenOLC: save_mobiles: Invalid real zone number %d. (0-%d)", rznum, top_of_zone_table);
+    log("SYSERR: GenOLC: save_mobiles: Invalid real zone number %d. (0-%d)",
+      rznum, top_of_zone_table);
     return FALSE;
   }
 
   vznum = zone_table[rznum].number;
   snprintf(mobfname, sizeof(mobfname), "%s%d.new", MOB_PREFIX, vznum);
   if ((mobfd = fopen(mobfname, "w")) == NULL) {
-    mudlog(BRF, LVL_GOD, TRUE, "SYSERR: GenOLC: Cannot open mob file for writing.");
+    mudlog(BRF, LVL_GOD, TRUE,
+      "SYSERR: GenOLC: Cannot open mob file for writing.");
     return FALSE;
   }
 
diff -BENbdpru old/src/genobj.c new/src/genobj.c
--- old/src/genobj.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/genobj.c	2003-07-28 19:38:00.000000000 +0000
@@ -156,9 +156,9 @@ int adjust_objects(obj_rnum refpt)
  * Function handle the insertion of an object within the prototype framework.  Note that this does not adjust internal values
  * of other objects, use add_object() for that.
  */
-int insert_object(struct obj_data *obj, obj_vnum ovnum)
+obj_rnum insert_object(struct obj_data *obj, obj_vnum ovnum)
 {
-  int i;
+  obj_rnum i;
 
   top_of_objt++;
   RECREATE(obj_index, struct index_data, top_of_objt + 1);
@@ -186,7 +186,7 @@ int insert_object(struct obj_data *obj, 
 
 /* ------------------------------------------------------------------------------------------------------------------------------ */
 
-int index_object(struct obj_data *obj, obj_vnum ovnum, obj_rnum ornum)
+obj_rnum index_object(struct obj_data *obj, obj_vnum ovnum, obj_rnum ornum)
 {
 #if CIRCLE_UNSIGNED_INDEX
   if (obj == NULL || ovnum < 0 || ornum == NOTHING || ornum > top_of_objt)
diff -BENbdpru old/src/genobj.h new/src/genobj.h
--- old/src/genobj.h	2003-07-28 19:37:24.000000000 +0000
+++ new/src/genobj.h	2003-07-28 19:38:00.000000000 +0000
@@ -11,9 +11,9 @@ void free_object_strings_proto(struct ob
 int copy_object(struct obj_data *to, struct obj_data *from);
 int copy_object_preserve(struct obj_data *to, struct obj_data *from);
 int save_objects(zone_rnum vznum);
-int insert_object(struct obj_data *obj, obj_vnum ovnum);
+obj_rnum insert_object(struct obj_data *obj, obj_vnum ovnum);
 int adjust_objects(obj_rnum refpt);
-int index_object(struct obj_data *obj, obj_vnum ovnum, obj_rnum ornum);
+obj_rnum index_object(struct obj_data *obj, obj_vnum ovnum, obj_rnum ornum);
 int update_objects(struct obj_data *refobj);
 obj_rnum add_object(struct obj_data *, obj_vnum ovnum);
 
diff -BENbdpru old/src/genwld.c new/src/genwld.c
--- old/src/genwld.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/genwld.c	2003-07-28 19:38:00.000000000 +0000
@@ -33,7 +33,8 @@ room_rnum add_room(struct room_data *roo
 {
   struct char_data *tch;
   struct obj_data *tobj;
-  int i, j, found = FALSE;
+  int j, found = FALSE;
+  room_rnum i;
 
   if (room == NULL)
     return NOWHERE;
@@ -126,7 +127,8 @@ room_rnum add_room(struct room_data *roo
 
 int delete_room(room_rnum rnum)
 {
-  int i, j;
+  room_rnum i;
+  int j;
   struct char_data *ppl, *next_ppl;
   struct obj_data *obj, *next_obj;
   struct room_data *room;
diff -BENbdpru old/src/interpreter.c new/src/interpreter.c
--- old/src/interpreter.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/interpreter.c	2003-07-28 19:38:00.000000000 +0000
@@ -354,6 +354,7 @@ cpp_extern const struct command_info cmd
   { "levels"   , POS_DEAD    , do_levels   , 0, 0 },
   { "list"     , POS_STANDING, do_not_here , 0, 0 },
   { "lick"     , POS_RESTING , do_action   , 0, 0 },
+  { "links"    , POS_DEAD    , do_oasis    , LVL_BUILDER, SCMD_OASIS_LINKS },
   { "lock"     , POS_SITTING , do_gen_door , 0, SCMD_LOCK },
   { "load"     , POS_DEAD    , do_load     , LVL_GOD, 0 },
   { "love"     , POS_RESTING , do_action   , 0, 0 },
diff -BENbdpru old/src/interpreter.h new/src/interpreter.h
--- old/src/interpreter.h	2003-07-28 19:37:24.000000000 +0000
+++ new/src/interpreter.h	2003-07-28 19:38:00.000000000 +0000
@@ -222,3 +222,4 @@ struct alias_data {
 #define SCMD_OASIS_OLIST	10
 #define SCMD_OASIS_SLIST	11
 #define SCMD_OASIS_ZLIST        12
+#define SCMD_OASIS_LINKS        13
diff -BENbdpru old/src/medit.c new/src/medit.c
--- old/src/medit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/medit.c	2003-07-28 19:38:00.000000000 +0000
@@ -39,6 +39,11 @@ extern struct descriptor_data *descripto
 extern const char *mobprog_types[];
 #endif
 
+/*
+ * External function prototypes/
+ */
+extern void smash_tilde(char *str);
+
 /*-------------------------------------------------------------------*/
 
 /*
@@ -640,9 +645,14 @@ void medit_parse(struct descriptor_data 
       /*
        * Save the mob in memory and to disk.
        */
-      write_to_output(d, "Saving mobile to memory.\r\n");
       medit_save_internally(d);
-      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits mob %d", GET_NAME(d->character), OLC_NUM(d));
+      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE,
+	"OLC: %s edits mob %d", GET_NAME(d->character), OLC_NUM(d));
+      if (CONFIG_AUTO_SAVE) {
+	medit_save_to_disk(zone_table[real_zone_by_thing(OLC_NUM(d))].number);
+	write_to_output(d, "Mobile saved to disk.\r\n");
+      } else
+        write_to_output(d, "Mobile saved to memory.\r\n");
       /* FALL THROUGH */
     case 'n':
     case 'N':
@@ -797,18 +807,21 @@ void medit_parse(struct descriptor_data 
     return;
 /*-------------------------------------------------------------------*/
   case MEDIT_ALIAS:
+    smash_tilde(arg);
     if (GET_ALIAS(OLC_MOB(d)))
       free(GET_ALIAS(OLC_MOB(d)));
     GET_ALIAS(OLC_MOB(d)) = str_udup(arg);
     break;
 /*-------------------------------------------------------------------*/
   case MEDIT_S_DESC:
+    smash_tilde(arg);
     if (GET_SDESC(OLC_MOB(d)))
       free(GET_SDESC(OLC_MOB(d)));
     GET_SDESC(OLC_MOB(d)) = str_udup(arg);
     break;
 /*-------------------------------------------------------------------*/
   case MEDIT_L_DESC:
+    smash_tilde(arg);
     if (GET_LDESC(OLC_MOB(d)))
       free(GET_LDESC(OLC_MOB(d)));
     if (arg && *arg) {
@@ -852,6 +865,9 @@ void medit_parse(struct descriptor_data 
       break;
     else if (i <= NUM_AFF_FLAGS)
       TOGGLE_BIT(AFF_FLAGS(OLC_MOB(d)), 1 << (i - 1));
+    /* Remove unwanted bits right away. */
+    REMOVE_BIT(AFF_FLAGS(OLC_MOB(d)),
+      AFF_CHARM | AFF_POISON | AFF_GROUP | AFF_SLEEP);
     medit_disp_aff_flags(d);
     return;
 /*-------------------------------------------------------------------*/
diff -BENbdpru old/src/modify.c new/src/modify.c
--- old/src/modify.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/modify.c	2003-07-28 19:38:00.000000000 +0000
@@ -75,7 +75,7 @@ int length[] =
  */
 void smash_tilde(char *str)
 {
-#if 0
+#if 1
   /*
    * Erase any ~'s inserted by people in the editor.  This prevents anyone
    * using online creation from causing parse errors in the world files.
diff -BENbdpru old/src/oasis.c new/src/oasis.c
--- old/src/oasis.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/oasis.c	2003-07-28 19:38:00.000000000 +0000
@@ -129,27 +129,20 @@ ACMD(do_oasis)
       break;
       
     case SCMD_OASIS_RLIST:
-      do_oasis_rlist(ch, argument, cmd, subcmd);
-      break;
-      
     case SCMD_OASIS_MLIST:
-      do_oasis_mlist(ch, argument, cmd, subcmd);
-      break;
-      
     case SCMD_OASIS_OLIST:
-      do_oasis_olist(ch, argument, cmd, subcmd);
-      break;
-    
     case SCMD_OASIS_SLIST:
-      do_oasis_slist(ch, argument, cmd, subcmd);
+    case SCMD_OASIS_ZLIST:
+      do_oasis_list(ch, argument, cmd, subcmd);
       break;
     
-    case SCMD_OASIS_ZLIST:
-      do_oasis_zlist(ch, argument, cmd, subcmd);
+    case SCMD_OASIS_LINKS:
+      do_oasis_links(ch, argument, cmd, subcmd);
       break;
       
     default:
-      log("SYSERR: (OLC) Invalid subcmd passed to do_oasis, subcmd - (%d)", subcmd);
+      log("SYSERR: (OLC) Invalid subcmd passed to do_oasis, subcmd - (%d)",
+	subcmd);
       return;
   }
   
@@ -335,11 +328,29 @@ void free_config(struct config_data *dat
 /******************************************************************************/
 int can_edit_zone(struct char_data *ch, zone_rnum rnum)
 {
+  /* no access if called with bad arguments */
+  if (!ch->desc || IS_NPC(ch) || rnum == NOWHERE)
+    return FALSE;
+
+  /* always access if ch is high enough level */
   if (GET_LEVEL(ch) >= LVL_IMPL)
     return (TRUE);
   
+  /* always access if a player have helped build the zone in the first place */
   if (is_name(GET_NAME(ch), zone_table[rnum].builders))
     return (TRUE);
   
+  /* no access if you haven't been assigned a zone */
+  if (GET_OLC_ZONE(ch) == NOWHERE)
+    return FALSE;
+ 
+  /* no access if you're not at least LVL_BUILDER */
+  if (GET_LEVEL(ch) < LVL_BUILDER)
+    return FALSE;
+ 
+  /* always access if you're assigned to this zone */
+  if (real_zone(GET_OLC_ZONE(ch)) == rnum)
+    return TRUE;
+ 
   return (FALSE);
 }
diff -BENbdpru old/src/oasis.h new/src/oasis.h
--- old/src/oasis.h	2003-07-28 19:37:24.000000000 +0000
+++ new/src/oasis.h	2003-07-28 19:38:00.000000000 +0000
@@ -383,6 +383,8 @@ extern const char *nrm, *grn, *cyn, *yel
  */
 void clear_screen(struct descriptor_data *);
 ACMD(do_oasis);
+ACMD(do_oasis_list);
+ACMD(do_oasis_links);
 
 /*
  * Prototypes, to be moved later.
@@ -405,7 +407,6 @@ void medit_disp_menu(struct descriptor_d
 void medit_parse(struct descriptor_data *d, char *arg);
 void medit_string_cleanup(struct descriptor_data *d, int terminator);
 ACMD(do_oasis_medit);
-ACMD(do_oasis_mlist);
 
 void oedit_setup_new(struct descriptor_data *d);
 void oedit_setup_existing(struct descriptor_data *d, int real_num);
@@ -430,7 +431,6 @@ void oedit_parse(struct descriptor_data 
 void oedit_disp_perm_menu(struct descriptor_data *d);
 void oedit_string_cleanup(struct descriptor_data *d, int terminator);
 ACMD(do_oasis_oedit);
-ACMD(do_oasis_olist);
 
 void redit_string_cleanup(struct descriptor_data *d, int terminator);
 void redit_setup_new(struct descriptor_data *d);
@@ -446,7 +446,6 @@ void redit_disp_menu(struct descriptor_d
 void redit_parse(struct descriptor_data *d, char *arg);
 void free_room(struct room_data *room);
 ACMD(do_oasis_redit);
-ACMD(do_oasis_rlist);
 
 void sedit_setup_new(struct descriptor_data *d);
 void sedit_setup_existing(struct descriptor_data *d, int rshop_num);
@@ -462,7 +461,6 @@ void sedit_types_menu(struct descriptor_
 void sedit_disp_menu(struct descriptor_data *d);
 void sedit_parse(struct descriptor_data *d, char *arg);
 ACMD(do_oasis_sedit);
-ACMD(do_oasis_slist);
 
 void zedit_setup(struct descriptor_data *d, int room_num);
 void zedit_new_zone(struct char_data *ch, zone_vnum vzone_num, room_vnum bottom, room_vnum top);
@@ -476,7 +474,6 @@ void zedit_disp_arg2(struct descriptor_d
 void zedit_disp_arg3(struct descriptor_data *d);
 void zedit_parse(struct descriptor_data *d, char *arg);
 ACMD(do_oasis_zedit);
-ACMD(do_oasis_zlist);
 
 void cedit_setup(struct descriptor_data *d);
 void cedit_parse(struct descriptor_data *d, char *arg);
diff -BENbdpru old/src/oasis_list.c new/src/oasis_list.c
--- old/src/oasis_list.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/oasis_list.c	2003-07-28 19:38:00.000000000 +0000
@@ -42,63 +42,26 @@ void print_zone(struct char_data *ch, zo
 /******************************************************************************/
 /** Ingame Commands                                                          **/
 /******************************************************************************/
-ACMD(do_oasis_rlist)
+ACMD(do_oasis_list)
 {
-  zone_rnum rzone;
+  zone_rnum rzone = NOWHERE;
   room_rnum vmin = NOWHERE;
   room_rnum vmax = NOWHERE;
   char smin[MAX_INPUT_LENGTH];
   char smax[MAX_INPUT_LENGTH];
   
-  /****************************************************************************/
-  /** Split the arguments into smin and smax.                                **/
-  /****************************************************************************/
   two_arguments(argument, smin, smax);
   
-  if (!*smin || *smin == '.') {
-    rzone = world[IN_ROOM(ch)].zone;
-    
-    list_rooms(ch, rzone, NOWHERE, NOWHERE);
-
-  } else if (!*smax) {
-    rzone = real_zone(atoi(smin));
-    
-    if (rzone == NOWHERE) {
-      send_to_char(ch, "Sorry, there's no zone with that number\r\n");
+  if (subcmd == SCMD_OASIS_ZLIST) { /* special case */
+    if (smin && *smin && is_number(smin))
+      print_zone(ch, atoi(smin));
+    else
+      list_zones(ch);
       return;
     }
     
-    list_rooms(ch, rzone, NOWHERE, NOWHERE);
-    
-  } else {
-    /****************************************************************************/
-    /** Listing by min vnum / max vnum.  Retrieve the numeric values.          **/
-    /****************************************************************************/
-    vmin = atoi(smin);
-    vmax = atoi(smax);
-    
-    list_rooms(ch, NOWHERE, vmin, vmax);
-  }
-}
-
-ACMD(do_oasis_mlist)
-{
-  zone_rnum rzone;
-  room_rnum vmin = NOWHERE;
-  room_rnum vmax = NOWHERE;
-  char smin[MAX_INPUT_LENGTH];
-  char smax[MAX_INPUT_LENGTH];
-  
-  /****************************************************************************/
-  /** Split the arguments into smin and smax.                                **/
-  /****************************************************************************/
-  two_arguments(argument, smin, smax);
-  
   if (!*smin || *smin == '.') {
     rzone = world[IN_ROOM(ch)].zone;
-    
-    list_mobiles(ch, rzone, NOWHERE, NOWHERE);
-
   } else if (!*smax) {
     rzone = real_zone(atoi(smin));
     
@@ -106,109 +69,78 @@ ACMD(do_oasis_mlist)
       send_to_char(ch, "Sorry, there's no zone with that number\r\n");
       return;
     }
-    
-    list_mobiles(ch, rzone, NOWHERE, NOWHERE);
-    
   } else {
-    /****************************************************************************/
     /** Listing by min vnum / max vnum.  Retrieve the numeric values.          **/
-    /****************************************************************************/
     vmin = atoi(smin);
     vmax = atoi(smax);
     
-    list_mobiles(ch, NOWHERE, vmin, vmax);
-  }
-}
-
-ACMD(do_oasis_olist)
-{
-  zone_rnum rzone;
-  room_rnum vmin = NOWHERE;
-  room_rnum vmax = NOWHERE;
-  char smin[MAX_INPUT_LENGTH];
-  char smax[MAX_INPUT_LENGTH];
-  
-  /****************************************************************************/
-  /** Split the arguments into smin and smax.                                **/
-  /****************************************************************************/
-  two_arguments(argument, smin, smax);
-  
-  if (!*smin || *smin == '.') {
-    rzone = world[IN_ROOM(ch)].zone;
-    
-    list_objects(ch, rzone, NOWHERE, NOWHERE);
-
-  } else if (!*smax) {
-    rzone = real_zone(atoi(smin));
-    
-    if (rzone == NOWHERE) {
-      send_to_char(ch, "Sorry, there's no zone with that number\r\n");
+    if (vmin > vmax) {
+      send_to_char(ch, "List from %d to %d - Aren't we funny today!\r\n",
+	vmin, vmax);
       return;
     }
+  }
     
-    list_objects(ch, rzone, NOWHERE, NOWHERE);
-    
-  } else {
-    /****************************************************************************/
-    /** Listing by min vnum / max vnum.  Retrieve the numeric values.          **/
-    /****************************************************************************/
-    vmin = atoi(smin);
-    vmax = atoi(smax);
-    
-    list_objects(ch, NOWHERE, vmin, vmax);
+  switch (subcmd) {
+    case SCMD_OASIS_MLIST: list_mobiles(ch, rzone, vmin, vmax); break;
+    case SCMD_OASIS_OLIST: list_objects(ch, rzone, vmin, vmax); break;
+    case SCMD_OASIS_RLIST: list_rooms(ch, rzone, vmin, vmax); break;
+    case SCMD_OASIS_SLIST: list_shops(ch, rzone, vmin, vmax); break;
+    default:
+      send_to_char(ch, "You can't list that!\r\n");
+      mudlog(BRF, LVL_IMMORT, TRUE,
+        "SYSERR: do_oasis_list: Unknown list option: %d", subcmd);
   }
 }
 
-ACMD(do_oasis_slist)
+ACMD(do_oasis_links)
 {
-  zone_rnum rzone;
-  room_rnum vmin = NOWHERE;
-  room_rnum vmax = NOWHERE;
-  char smin[MAX_INPUT_LENGTH];
-  char smax[MAX_INPUT_LENGTH];
-  
-  /****************************************************************************/
-  /** Split the arguments into smin and smax.                                **/
-  /****************************************************************************/
-  two_arguments(argument, smin, smax);
-  
-  if (!*smin || *smin == '.') {
-    rzone = world[IN_ROOM(ch)].zone;
-    
-    list_shops(ch, rzone, NOWHERE, NOWHERE);
+  zone_rnum zrnum;
+  zone_vnum zvnum;
+  room_rnum nr, to_room;
+  int first, last, j;
+  char arg[MAX_INPUT_LENGTH];
 
-  } else if (!*smax) {
-    rzone = real_zone(atoi(smin));
+  skip_spaces(&argument);
+  one_argument(argument, arg);
     
-    /**************************************************************************/
-    /** Make sure the zone exists.                                           **/
-    /**************************************************************************/
-    if (rzone == NOWHERE) {
-      send_to_char(ch, "Sorry, there's no zone with that number\r\n");
+  if (!arg || !*arg) {
+    send_to_char(ch,
+      "Syntax: links <zone_vnum> ('.' for zone you are standing in)\r\n");
       return;
     }
     
-    list_shops(ch, rzone, NOWHERE, NOWHERE);
-    
+  if (!strcmp(arg, ".")) {
+    zrnum = world[IN_ROOM(ch)].zone;
+    zvnum = zone_table[zrnum].number;
   } else {
-    /****************************************************************************/
-    /** Listing by min vnum / max vnum.  Retrieve the numeric values.          **/
-    /****************************************************************************/
-    vmin = atoi(smin);
-    vmax = atoi(smax);
+    zvnum = atoi(arg);
+    zrnum = real_zone(zvnum);
+  }
     
-    list_shops(ch, NOWHERE, vmin, vmax);
+  if (zrnum == NOWHERE || zvnum == NOWHERE) {
+    send_to_char(ch, "No zone was found with that number.\n\r");
+    return;
   }
-}
 
+  last  = zone_table[zrnum].top;
+  first = zone_table[zrnum].bot;
 
-ACMD(do_oasis_zlist)
-{
-  skip_spaces(&argument);
-  if (argument && *argument && is_number(argument)) 
-    print_zone(ch, atoi(argument));
-  else
-    list_zones(ch);  
+  send_to_char(ch, "Zone %d is linked to the following zones:\r\n", zvnum);
+  for (nr = 0; nr <= top_of_world && (GET_ROOM_VNUM(nr) <= last); nr++) {
+    if (GET_ROOM_VNUM(nr) >= first) {
+      for (j = 0; j < NUM_OF_DIRS; j++) {
+	if (world[nr].dir_option[j]) {
+	  to_room = world[nr].dir_option[j]->to_room;
+	  if (to_room != NOWHERE && (zrnum != world[to_room].zone))
+	    send_to_char(ch, "%3d %-30s at %5d (%-5s) ---> %5d\r\n",
+	      zone_table[world[to_room].zone].number,
+	      zone_table[world[to_room].zone].name,
+	      GET_ROOM_VNUM(nr), dirs[j], world[to_room].number);
+	}
+      }
+    }
+  }
 }
 
 
@@ -272,11 +204,10 @@ void list_rooms(struct char_data *ch, zo
         counter, QGRN, world[i].number, QNRM, QCYN, world[i].name, QNRM);
 
       for (j = 0; j < NUM_OF_DIRS; j++) {
-        if (W_EXIT(i, j) == NULL)
-          continue;
-        
-        if (world[W_EXIT(i, j)->to_room].zone != rnum) 
-          send_to_char(ch, "(%s%d%s)", QYEL, world[W_EXIT(i, j)->to_room].number, QNRM);
+        if (W_EXIT(i, j) != NULL &&
+	  W_EXIT(i, j)->to_room != NOWHERE)
+          send_to_char(ch, "(%s%d%s)",
+	    QYEL, world[W_EXIT(i, j)->to_room].number, QNRM);
      
       }
     
diff -BENbdpru old/src/oedit.c new/src/oedit.c
--- old/src/oedit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/oedit.c	2003-07-28 19:38:00.000000000 +0000
@@ -762,17 +762,26 @@ void oedit_parse(struct descriptor_data 
     switch (*arg) {
     case 'y':
     case 'Y':
-      write_to_output(d, "Saving object to memory.\r\n");
       oedit_save_internally(d);
-      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d));
+      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE,
+	"OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d));
+      if (CONFIG_AUTO_SAVE) {
+	oedit_save_to_disk(real_zone_by_thing(OLC_NUM(d)));
+	write_to_output(d, "Object saved to disk.\r\n");
+      } else
+        write_to_output(d, "Object saved to memory.\r\n");
       /* Fall through. */
     case 'n':
     case 'N':
       cleanup_olc(d, CLEANUP_ALL);
       return;
+    case 'a': /* abort quit */
+    case 'A':
+      oedit_disp_menu(d);
+      return;
     default:
       write_to_output(d, "Invalid choice!\r\n");
-      write_to_output(d, "Do you wish to save this object internally?\r\n");
+      write_to_output(d, "Do you wish to save this object?\r\n");
       return;
     }
 
@@ -784,7 +793,7 @@ void oedit_parse(struct descriptor_data 
     case 'q':
     case 'Q':
       if (OLC_VAL(d)) {	/* Something has been modified. */
-	write_to_output(d, "Do you wish to save this object internally? : ");
+	write_to_output(d, "Do you wish to save this object? : ");
 	OLC_MODE(d) = OEDIT_CONFIRM_SAVESTRING;
       } else
 	cleanup_olc(d, CLEANUP_ALL);
@@ -851,6 +860,7 @@ void oedit_parse(struct descriptor_data 
       GET_OBJ_VAL(OLC_OBJ(d), 1) = 0;
       GET_OBJ_VAL(OLC_OBJ(d), 2) = 0;
       GET_OBJ_VAL(OLC_OBJ(d), 3) = 0;
+      OLC_VAL(d) = 1;
       oedit_disp_val1_menu(d);
       break;
     case 'd':
@@ -918,6 +928,9 @@ void oedit_parse(struct descriptor_data 
       return;
     } else
       GET_OBJ_TYPE(OLC_OBJ(d)) = number;
+    /* what's the boundschecking worth if we don't do this ? -- Welcor */
+    GET_OBJ_VAL(OLC_OBJ(d), 0) = GET_OBJ_VAL(OLC_OBJ(d), 1) =
+      GET_OBJ_VAL(OLC_OBJ(d), 2) = GET_OBJ_VAL(OLC_OBJ(d), 3) = 0;
     break;
 
   case OEDIT_EXTRAS:
@@ -980,7 +993,13 @@ void oedit_parse(struct descriptor_data 
      * Lucky, I don't need to check any of these for out of range values.
      * Hmm, I'm not so sure - Rv  
      */
+    switch (GET_OBJ_TYPE(OLC_OBJ(d))) {
+      case ITEM_WEAPON:
+	GET_OBJ_VAL(OLC_OBJ(d), 0) = MIN(MAX(atoi(arg), -50), 50);
+	break;
+      default:
     GET_OBJ_VAL(OLC_OBJ(d), 0) = atoi(arg);
+    }
     /*
      * proceed to menu 2 
      */
@@ -996,10 +1015,11 @@ void oedit_parse(struct descriptor_data 
     case ITEM_POTION:
       if (number < 0 || number >= NUM_SPELLS)
 	oedit_disp_val2_menu(d);
-      else {
+      else if (number == 0)
+	GET_OBJ_VAL(OLC_OBJ(d), 1) = -1;
+      else
 	GET_OBJ_VAL(OLC_OBJ(d), 1) = number;
 	oedit_disp_val3_menu(d);
-      }
       break;
     case ITEM_CONTAINER:
       /*
@@ -1015,6 +1035,11 @@ void oedit_parse(struct descriptor_data 
       } else
 	oedit_disp_val3_menu(d);
       break;
+    case ITEM_WEAPON:
+      /* 50 dice must be enough -- Welcor */
+      GET_OBJ_VAL(OLC_OBJ(d), 1) = MIN(MAX(number, 1), 50);
+      oedit_disp_val3_menu(d);
+      break;
 
     default:
       GET_OBJ_VAL(OLC_OBJ(d), 1) = number;
@@ -1030,6 +1055,11 @@ void oedit_parse(struct descriptor_data 
     switch (GET_OBJ_TYPE(OLC_OBJ(d))) {
     case ITEM_SCROLL:
     case ITEM_POTION:
+      if (number == 0) {
+	GET_OBJ_VAL(OLC_OBJ(d), 2) = -1;
+	oedit_disp_val3_menu(d);
+	return;
+      }
       min_val = -1;
       max_val = NUM_SPELLS - 1;
       break;
@@ -1064,6 +1094,10 @@ void oedit_parse(struct descriptor_data 
     switch (GET_OBJ_TYPE(OLC_OBJ(d))) {
     case ITEM_SCROLL:
     case ITEM_POTION:
+      if (number == 0) {
+	GET_OBJ_VAL(OLC_OBJ(d), 3) = -1;
+	return;
+      }
       min_val = -1;
       max_val = NUM_SPELLS - 1;
       break;
diff -BENbdpru old/src/redit.c new/src/redit.c
--- old/src/redit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/redit.c	2003-07-28 19:38:00.000000000 +0000
@@ -501,12 +501,17 @@ void redit_parse(struct descriptor_data 
     case 'y':
     case 'Y':
       redit_save_internally(d);
-      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits room %d.", GET_NAME(d->character), OLC_NUM(d));
+      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE,
+	"OLC: %s edits room %d.", GET_NAME(d->character), OLC_NUM(d));
+      if (CONFIG_AUTO_SAVE) {
+	redit_save_to_disk(real_zone_by_thing(OLC_NUM(d)));
+	write_to_output(d, "Room saved to disk.\r\n");
+      } else
+        write_to_output(d, "Room saved to memory.\r\n");
       /*
        * Do NOT free strings! Just the room structure. 
        */
       cleanup_olc(d, CLEANUP_STRUCTS);
-      write_to_output(d, "Room saved to memory.\r\n");
       break;
     case 'n':
     case 'N':
@@ -516,7 +521,8 @@ void redit_parse(struct descriptor_data 
       cleanup_olc(d, CLEANUP_ALL);
       break;
     default:
-      write_to_output(d, "Invalid choice!\r\nDo you wish to save this room internally? : ");
+      write_to_output(d,
+	"Invalid choice!\r\nDo you wish to save this room? : ");
       break;
     }
     return;
@@ -526,7 +532,7 @@ void redit_parse(struct descriptor_data 
     case 'q':
     case 'Q':
       if (OLC_VAL(d)) { /* Something has been modified. */
-        write_to_output(d, "Do you wish to save this room internally? : ");
+        write_to_output(d, "Do you wish to save this room? : ");
         OLC_MODE(d) = REDIT_CONFIRM_SAVESTRING;
       } else
         cleanup_olc(d, CLEANUP_ALL);
diff -BENbdpru old/src/sedit.c new/src/sedit.c
--- old/src/sedit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/sedit.c	2003-07-28 19:38:00.000000000 +0000
@@ -498,11 +498,14 @@ void sedit_parse(struct descriptor_data 
     switch (*arg) {
     case 'y':
     case 'Y':
-      write_to_output(d, "Saving shop to memory.\r\n");
       sedit_save_internally(d);
       mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE,
-             "OLC: %s edits shop %d", GET_NAME(d->character),
-             OLC_NUM(d));
+        "OLC: %s edits shop %d", GET_NAME(d->character), OLC_NUM(d));
+      if (CONFIG_AUTO_SAVE) {
+	sedit_save_to_disk(real_zone_by_thing(OLC_NUM(d)));
+	write_to_output(d, "Shop saved to disk.\r\n");
+      } else
+        write_to_output(d, "Shop saved to memory.\r\n");
       cleanup_olc(d, CLEANUP_STRUCTS);
       return;
     case 'n':
@@ -742,7 +745,8 @@ void sedit_parse(struct descriptor_data 
     /*
      * Fiddle with special procs.
      */
-    S_FUNC(OLC_SHOP(d)) = mob_index[i].func;
+    S_FUNC(OLC_SHOP(d)) =
+      mob_index[i].func != shop_keeper ? mob_index[i].func : NULL;
     mob_index[i].func = shop_keeper;
     break;
   case SEDIT_OPEN1:
diff -BENbdpru old/src/zedit.c new/src/zedit.c
--- old/src/zedit.c	2003-07-28 19:37:24.000000000 +0000
+++ new/src/zedit.c	2003-07-28 19:38:00.000000000 +0000
@@ -312,7 +312,10 @@ void zedit_new_zone(struct char_data *ch
     }
   }
 
-  mudlog(BRF, MAX(LVL_BUILDER, GET_INVIS_LEV(ch)), TRUE, "OLC: %s creates new zone #%d", GET_NAME(ch), vzone_num);
+  zedit_save_to_disk(result); /* save to disk .. */
+
+  mudlog(BRF, MAX(LVL_BUILDER, GET_INVIS_LEV(ch)), TRUE,
+    "OLC: %s creates new zone #%d", GET_NAME(ch), vzone_num);
   write_to_output(ch->desc, "Zone created successfully.\r\n");
 }
 
@@ -721,10 +724,15 @@ void zedit_parse(struct descriptor_data 
       /*
        * Save the zone in memory, hiding invisible people.
        */
-      write_to_output(d, "Saving zone info in memory.\r\n");
       zedit_save_internally(d);
+      if (CONFIG_AUTO_SAVE) {
+	write_to_output(d, "Saving zone info to disk.\r\n");
+	zedit_save_to_disk(OLC_ZNUM(d));
+      } else
+        write_to_output(d, "Saving zone info in memory.\r\n");
 
-      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE, "OLC: %s edits zone info for room %d.", GET_NAME(d->character), OLC_NUM(d));
+      mudlog(CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE,
+	"OLC: %s edits zone info for room %d.", GET_NAME(d->character), OLC_NUM(d));
       /* FALL THROUGH */
     case 'n':
     case 'N':
