diff -uprN -x *.o ../../xapobj/src/.cvsignore ./.cvsignore
--- ../../xapobj/src/.cvsignore	Wed Dec 31 18:00:00 1969
+++ ./.cvsignore	Fri Mar 26 06:53:06 1999
@@ -0,0 +1,3 @@
+conf.h
+.accepted
+Makefile
diff -uprN -x *.o ../../xapobj/src/db.c ./db.c
--- ../../xapobj/src/db.c	Sun Mar 28 07:03:59 1999
+++ ./db.c	Sun Mar 28 05:01:15 1999
@@ -23,6 +23,7 @@
 #include "mail.h"
 #include "interpreter.h"
 #include "house.h"
+#include "olc.h"
 
 /**************************************************************************
 *  declarations of most of the 'global' variables                         *
@@ -2722,6 +2723,12 @@ int read_xap_objects(FILE *fl,struct cha
           temp->affected[j].modifier = 0;
         }
 
+       /* You have to null out the extradescs when you're parsing a xap_obj.
+           This is done right before the extradescs are read. */
+
+        if (temp->ex_description) {
+          temp->ex_description = NULL;
+        }
 
         for (k=j=zwei=0;!zwei && !feof(fl);) {
           switch (*line) {
diff -uprN -x *.o ../../xapobj/src/db.h ./db.h
--- ../../xapobj/src/db.h	Sun Mar 28 07:04:12 1999
+++ ./db.h	Sun Mar 28 03:15:08 1999
@@ -234,6 +234,5 @@ extern char	*NOPERSON;
 extern char	*NOEFFECT;
 #endif
 
-void strip_string(char *buffer);
 int read_xap_objects(FILE *fl,struct char_data *ch);
 
diff -uprN -x *.o ../../xapobj/src/interpreter.c ./interpreter.c
--- ../../xapobj/src/interpreter.c	Sun Mar 28 07:00:18 1999
+++ ./interpreter.c	Sun Mar 28 05:52:37 1999
@@ -55,6 +55,7 @@ int parse_class(char arg);
 int special(struct char_data *ch, int cmd, char *arg);
 int isbanned(char *hostname);
 int Valid_Name(char *newname);
+void iedit_parse(struct descriptor_data *d, char *arg);
 void oedit_parse(struct descriptor_data *d, char *arg);
 void redit_parse(struct descriptor_data *d, char *arg);
 void zedit_parse(struct descriptor_data *d, char *arg);
@@ -119,6 +120,7 @@ ACMD(do_help);
 ACMD(do_hide);
 ACMD(do_hit);
 ACMD(do_house);
+ACMD(do_iedit);
 ACMD(do_info);
 ACMD(do_insult);
 ACMD(do_inventory);
@@ -342,6 +344,7 @@ cpp_extern const struct command_info cmd
   { "hug"      , POS_RESTING , do_action   , 0, 0 },
 
   { "inventory", POS_DEAD    , do_inventory, 0, 0 },
+  { "iedit"    , POS_DEAD   , do_iedit    , LVL_IMMORT, 0 },
   { "idea"     , POS_DEAD    , do_gen_write, 0, SCMD_IDEA },
   { "imotd"    , POS_DEAD    , do_gen_ps   , LVL_IMMORT, SCMD_IMOTD },
   { "immlist"  , POS_DEAD    , do_gen_ps   , 0, SCMD_IMMLIST },
@@ -393,6 +396,7 @@ cpp_extern const struct command_info cmd
   { "objconv"  , POS_DEAD    , do_objconv  , LVL_IMPL, 0 },
   { "olc"      , POS_DEAD    , do_olc      , LVL_GOD, SCMD_OLC_SAVEINFO },
   { "oedit"    , POS_DEAD    , do_olc      , LVL_BUILDER, SCMD_OLC_OEDIT},
+
   { "order"    , POS_RESTING , do_order    , 1, 0 },
   { "offer"    , POS_STANDING, do_not_here , 1, 0 },
   { "open"     , POS_SITTING , do_gen_door , 0, SCMD_OPEN },
@@ -1322,6 +1326,11 @@ void nanny(struct descriptor_data *d, ch
     break;
   case CON_SEDIT: 
     sedit_parse(d, arg);
+    break;
+  case CON_IEDIT:
+/*
+    iedit_parse(d,arg);*/
+    oedit_parse(d,arg);
     break;
   /*. End of OLC states .*/
 
diff -uprN -x *.o ../../xapobj/src/objsave.c ./objsave.c
--- ../../xapobj/src/objsave.c	Fri Mar 12 19:35:00 1999
+++ ./objsave.c	Sun Mar 28 06:13:27 1999
@@ -1470,6 +1470,10 @@ int Crash_load_xapobjs(struct char_data 
           temp->affected[j].modifier = 0;
         }
 
+        if (temp->ex_description) {
+          temp->ex_description = NULL;
+        }
+
         get_line(fl,line);
         for (k=j=zwei=0;!zwei && !feof(fl);) {
           switch (*line) {
diff -uprN -x *.o ../../xapobj/src/oedit.c ./oedit.c
--- ../../xapobj/src/oedit.c	Sun Mar 28 06:58:34 1999
+++ ./oedit.c	Sun Mar 28 06:56:42 1999
@@ -14,6 +14,8 @@
 #include "boards.h"
 #include "shop.h"
 #include "olc.h"
+#include "interpreter.h"
+#include "handler.h"
 
 /*------------------------------------------------------------------------*/
 
@@ -68,6 +70,10 @@ void oedit_setup_new(struct descriptor_d
 void oedit_setup_existing(struct descriptor_data *d, int real_num);
 void oedit_save_to_disk(int zone);
 void oedit_save_internally(struct descriptor_data *d);
+void iedit_setup_existing(struct descriptor_data *d, struct obj_data *real_num);
+void iedit_parse(struct descriptor_data *d, char *arg);
+struct obj_data *copy_object(struct obj_data *obj);
+
 
 /*------------------------------------------------------------------------*\
   Utility and exported functions
@@ -885,18 +891,43 @@ void oedit_parse(struct descriptor_data 
     switch (*arg) {
     case 'y':
     case 'Y':
-      send_to_char("Saving object to memory.\r\n", d->character);
-      oedit_save_internally(d);
-      sprintf(buf, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d));
-      mudlog(buf, CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE);
-      cleanup_olc(d, CLEANUP_STRUCTS);
+      if(STATE(d) == CON_OEDIT) {
+        send_to_char("Saving object to memory.\r\n", d->character);
+        oedit_save_internally(d);
+        sprintf(buf, "OLC: %s edits obj %d", GET_NAME(d->character), OLC_NUM(d));
+        mudlog(buf, CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE);
+        cleanup_olc(d, CLEANUP_STRUCTS);
+      } else {  /* case is iedit */
+        send_to_char("Commiting iedit changes.\r\n", d->character);
+        *(OLC_IEDIT(d)) = *(OLC_OBJ(d));
+  /* Xap - ought to save the old pointer, free after assignment I suppose */
+
+        sprintf(buf, "OLC: %s uses iedit", GET_NAME(d->character));
+        mudlog(buf, CMP, MAX(LVL_BUILDER, GET_INVIS_LEV(d->character)), TRUE);
+        if (d->character) {
+          REMOVE_BIT(PLR_FLAGS(d->character), PLR_WRITING);
+          STATE(d) = CON_PLAYING;
+          act("$n stops using OLC.", TRUE, d->character, 0, 0, TO_ROOM);
+        }
+        free(d->olc);
+      }
+
       return;
     case 'n':
     case 'N':
       /*
        * Cleanup all.
        */
-      cleanup_olc(d, CLEANUP_ALL);
+      if(STATE(d) == CON_OEDIT) {
+        cleanup_olc(d, CLEANUP_ALL);
+      } else {
+        if (d->character) {
+          REMOVE_BIT(PLR_FLAGS(d->character), PLR_WRITING);
+          STATE(d) = CON_PLAYING;
+          act("$n stops using OLC.", TRUE, d->character, 0, 0, TO_ROOM);
+        }
+        free(d->olc);
+      }
       return;
     default:
       send_to_char("Invalid choice!\r\n", d->character);
@@ -1298,3 +1329,185 @@ void oedit_parse(struct descriptor_data 
   OLC_VAL(d) = 1;
   oedit_disp_menu(d);
 }
+
+/* this is all iedit stuff */
+void iedit_setup_existing(struct descriptor_data *d,
+  struct obj_data *real_num) {
+  struct obj_data *obj;
+
+  OLC_IEDIT(d) = real_num;
+
+  obj=copy_object(real_num);
+
+  OLC_OBJ(d) = obj;
+  OLC_IEDIT(d) = real_num;
+  OLC_VAL(d) = 0;
+  oedit_disp_menu(d);
+}
+
+/* Iedit is just a stripped down interface to oedit.  Basically, it lets
+   you edit individual instantiations of an object.  I'd recommend using
+   it with the xapobjs patch, else you may notice that your individual
+   objects do crazy things when you save/return */
+
+/* You know what? I can put anything in a comment!  That's right!
+   So, the other day, I was listening to the radio, and they give
+   this funny situation:
+       This 19 year-old kid went out and had his 17-year old girl
+     friend get breast enlargement surgery.  He stole his mothers
+     credit card to pay for the 2500$ operation.  Ouch.
+       Now, his mother presses credit fraud charges, and he ends up
+     paying the full 2500$ + 1500$ for a fine.  Then his 'enhanced'
+     girlfriend ditches him for someone with money, and no criminal
+     record.... Now, what is the moral of the story?
+       If you're going to pay for your girlfriends cosmetic surgery,
+     at least steal your _dad's_ card! At least then you can justify
+     it.  I mean.. what's he going to say?
+	"YOUNG MAN! YOU WILL NEVER DO IT AGAIN! .. unless you can get your
+	 girlfriend to bring your mother?"
+      or.. why wait for him to bring it up?
+        "Dad.. c'mon!  22b.. 38d.. You do the math!"
+     .... or you can wait for the opening comment that you know is coming..
+	   "YOUNG MAN! WHAT WERE YOU THINKING!?!?"
+		"Now that's a really silly question isn't it?"
+    I suppose that will do for inane for now. */
+
+ACMD(do_iedit) {
+  struct obj_data *k;
+  int found=0;
+  int tmp;
+  extern struct room_data *world;
+
+  one_argument(argument, arg);
+
+  if(!*arg || !*argument) {
+    send_to_char("You must supply an object name.\r\n",ch);
+  }
+
+  if ((k = get_object_in_equip_vis(ch, arg, ch->equipment, &tmp))) {
+    found=1;
+  } else if ((k = get_obj_in_list_vis(ch, arg, ch->carrying))) {
+    found=1;
+  } else if ((k = get_obj_in_list_vis(ch, arg,
+        world[ch->in_room].contents))) {
+    found =1;
+  } else if ((k = get_obj_vis(ch, arg))) {
+    found=1;
+  }
+
+  if (!found) {
+    send_to_char("Couldn't find that object. Sorry.\r\n",ch);
+    return;
+  }
+
+                /* set up here */
+  CREATE(ch->desc->olc, struct olc_data, 1);
+  SET_BIT(GET_OBJ_EXTRA(k), ITEM_UNIQUE_SAVE);
+
+  SET_BIT(PLR_FLAGS(ch), PLR_WRITING);
+  iedit_setup_existing(ch->desc,k);
+  OLC_VAL(ch->desc) = 0;
+
+  act("$n starts using OLC.", TRUE, ch, 0, 0, TO_ROOM);
+
+  STATE(ch->desc) = CON_IEDIT;
+
+  return;
+}
+
+/* make a complete copy of an object */
+struct obj_data *copy_object(struct obj_data *obj) {
+  struct extra_descr_data *this, *temp, *temp2;
+  struct obj_affected_type *affs;
+  struct obj_data *returno;
+  int i;
+
+  /* allocate object */
+  CREATE(returno, struct obj_data, 1);
+
+  clear_object(returno);
+
+  /* create the interal seperate structs */
+
+
+  /* copy all strings over */
+  if (obj->name)
+    returno->name = str_dup(obj->name);
+
+  if (obj->short_description)
+    returno->short_description = str_dup(obj->short_description);
+
+  if (obj->description)
+    returno->description = str_dup(obj->description);
+
+  if (obj->action_description)
+    returno->action_description = str_dup(obj->action_description);
+  /*. Extra descriptions if necessary . */
+  if (obj->ex_description) {    /* temp is for obj being edited */
+    CREATE(temp, struct extra_descr_data, 1);
+
+    returno->ex_description = temp;
+
+    for (this = obj->ex_description; this; this = this->next) {
+      if (this->keyword && *(this->keyword))
+        temp->keyword = str_dup(this->keyword);
+      if (this->description && *(this->description))
+        temp->description = str_dup(this->description);
+      if (this->next) {
+        CREATE(temp2, struct extra_descr_data, 1);
+
+        temp->next = temp2;
+        temp = temp2;
+      } else
+        temp->next = NULL;
+    }
+  }
+  /* now some hard data */
+  GET_OBJ_VAL(returno,0)=GET_OBJ_VAL(obj,0);
+  GET_OBJ_VAL(returno,1)=GET_OBJ_VAL(obj,1);
+  GET_OBJ_VAL(returno,2)=GET_OBJ_VAL(obj,2);
+  GET_OBJ_VAL(returno,3)=GET_OBJ_VAL(obj,3);
+
+  GET_OBJ_TYPE(returno) = GET_OBJ_TYPE(obj);
+
+  GET_OBJ_WEAR(returno)=GET_OBJ_WEAR(obj);
+
+  GET_OBJ_EXTRA(returno)=GET_OBJ_EXTRA(obj);
+
+  GET_OBJ_WEIGHT(returno)=GET_OBJ_WEIGHT(obj);
+
+  GET_OBJ_COST(returno)=GET_OBJ_COST(obj);
+  GET_OBJ_RENT(returno)=GET_OBJ_RENT(obj);
+
+  GET_OBJ_TIMER(returno)=GET_OBJ_TIMER(obj);
+
+  GET_OBJ_RNUM(returno)=GET_OBJ_RNUM(obj);
+
+  returno->obj_flags.bitvector=obj->obj_flags.bitvector;
+
+  for(i = 0;i < MAX_OBJ_AFFECT;i++) {
+    if(obj->affected[i].location) {
+      CREATE(affs,struct obj_affected_type,1);
+      affs->location = obj->affected[i].location;
+      affs->modifier = obj->affected[i].modifier;
+    } else {
+      CREATE(affs,struct obj_affected_type,1);
+      affs->location = APPLY_NONE;
+      affs->modifier = 0;
+
+    }
+      returno->affected[i]=*affs;
+  }
+
+  returno->in_room = obj->in_room;
+  returno->carried_by = obj->carried_by;
+  returno->worn_by = obj->worn_by;
+  returno->worn_on = obj->worn_on;
+  returno->in_obj = obj->in_obj;
+  returno->contains = obj->contains;
+  returno->next_content = obj->next_content;
+  returno->next = obj->next;
+
+  return (returno);
+}
+
diff -uprN -x *.o ../../xapobj/src/olc.h ./olc.h
--- ../../xapobj/src/olc.h	Sun Mar 28 06:58:34 1999
+++ ./olc.h	Sun Mar 28 06:25:29 1999
@@ -59,7 +59,7 @@
 /*
  * Utilities exported from olc.c.
  */
-void strip_string(char *);
+void strip_string(char *buffer);
 void cleanup_olc(struct descriptor_data *d, byte cleanup_type);
 void get_char_cols(struct char_data *ch);
 void olc_add_to_save_list(int zone, byte type);
@@ -81,6 +81,9 @@ struct olc_data {
   struct zone_data *zone;
   struct shop_data *shop;
   struct extra_descr_data *desc;
+ /* why a seperate object for iedit? Because we have to have the ability
+    to confirm/deny changes, as well as replace the original */
+  struct obj_data *iobj;
 #if defined(OASIS_MPROG)
   struct mob_prog_data *mprog;
   struct mob_prog_data *mprogl;
@@ -113,6 +116,8 @@ extern struct olc_save_info *olc_save_li
 #define OLC_ZNUM(d) 	((d)->olc->zone_num)	/* Real zone number.	*/
 #define OLC_ROOM(d) 	((d)->olc->room)	/* Room structure.	*/
 #define OLC_OBJ(d) 	((d)->olc->obj)		/* Object structure.	*/
+#define OLC_IEDIT(d)    ((d)->olc->iobj)        /*. iObject structure.  */
+
 #define OLC_ZONE(d)     ((d)->olc->zone)	/* Zone structure.	*/
 #define OLC_MOB(d)	((d)->olc->mob)		/* Mob structure.	*/
 #define OLC_SHOP(d) 	((d)->olc->shop)	/* Shop structure.	*/
diff -uprN -x *.o ../../xapobj/src/structs.h ./structs.h
--- ../../xapobj/src/structs.h	Sun Mar 28 06:58:34 1999
+++ ./structs.h	Sun Mar 28 02:24:02 1999
@@ -240,6 +240,7 @@
 #define CON_ZEDIT	 20		/*. OLC mode - zone info edit	*/
 #define CON_MEDIT	 21		/*. OLC mode - mobile edit	*/
 #define CON_SEDIT	 22		/*. OLC mode - shop edit	*/
+#define CON_IEDIT	 23		/*  OLC mode - individual edit  */
 
 /* Character equipment positions: used as index for char_data.equipment[] */
 /* NOTE: Don't confuse these constants with the ITEM_ bitvectors

