diff -u c:\mud\src/act.wizard.c c:\mwan\src/act.wizard.c
--- c:\mud\src/act.wizard.c	Sun Mar 26 21:53:04 2000
+++ c:\mwan\src/act.wizard.c	Fri Nov 17 09:58:08 2000
@@ -835,7 +835,6 @@
 {
   struct char_data *victim;
   struct obj_data *object;
-  struct char_file_u tmp_store;
   int tmp;
 
   half_chop(argument, buf1, buf2);
@@ -869,9 +868,8 @@
     } else {
       CREATE(victim, struct char_data, 1);
       clear_char(victim);
-      if (load_char(buf2, &tmp_store) > -1) {
-	store_to_char(&tmp_store, victim);
-	victim->player.time.logon = tmp_store.last_logon;
+      if (load_char(buf2, victim) > -1) {
+//	victim->player.time.logon = tmp_store.last_logon;
 	char_to_room(victim, 0);
 	if (GET_LEVEL(victim) > GET_LEVEL(ch))
 	  send_to_char("Sorry, you can't do that.\r\n", ch);
@@ -1598,25 +1596,29 @@
 
 ACMD(do_last)
 {
-  struct char_file_u chdata;
+  struct char_data *vict = NULL;
+  extern char *class_abbrevs[];
 
   one_argument(argument, arg);
   if (!*arg) {
     send_to_char("For whom do you wish to search?\r\n", ch);
     return;
   }
-  if (load_char(arg, &chdata) < 0) {
+  CREATE(vict, struct char_data, 1);
+  clear_char(vict);
+  CREATE(vict->player_specials, struct player_special_data, 1);
+  if (load_char(arg, vict) < 0) {
     send_to_char("There is no such player.\r\n", ch);
     return;
   }
-  if ((chdata.level > GET_LEVEL(ch)) && (GET_LEVEL(ch) < LVL_IMPL)) {
+  if ((GET_LEVEL(vict) > GET_LEVEL(ch)) && (GET_LEVEL(ch) < LVL_IMPL)) {
     send_to_char("You are not sufficiently godly for that!\r\n", ch);
     return;
   }
-  sprintf(buf, "[%5ld] [%2d %s] %-12s : %-18s : %-20s\r\n",
-	  chdata.char_specials_saved.idnum, (int) chdata.level,
-	  class_abbrevs[(int) chdata.chclass], chdata.name, chdata.host,
-	  ctime(&chdata.last_logon));
+  sprintf(buf, "[%5ld] [%2d %s] %-12s : %-20s\r\n",
+	  GET_IDNUM(vict), (int) GET_LEVEL(vict),
+	  class_abbrevs[(int) GET_CLASS(vict)], GET_NAME(vict),
+	  ctime(&vict->player.time.logon));
   send_to_char(buf, ch);
 }
 
@@ -1950,7 +1952,6 @@
 
 ACMD(do_show)
 {
-  struct char_file_u vbuf;
   int i, j, k, l, con;		/* i, j, k to specifics? */
   zone_rnum zrn;
   zone_vnum zvn;
@@ -2026,24 +2027,28 @@
       send_to_char("A name would help.\r\n", ch);
       return;
     }
-
-    if (load_char(value, &vbuf) < 0) {
+    CREATE(vict, struct char_data, 1);
+    clear_char(vict);
+    CREATE(vict->player_specials, struct player_special_data, 1);
+    if (load_char(value, vict) < 0) {
       send_to_char("There is no such player.\r\n", ch);
       return;
     }
-    sprintf(buf, "Player: %-12s (%s) [%2d %s]\r\n", vbuf.name,
-      genders[(int) vbuf.sex], vbuf.level, class_abbrevs[(int) vbuf.chclass]);
-    sprintf(buf + strlen(buf),
-	 "Au: %-8d  Bal: %-8d  Exp: %-8d  Align: %-5d  Lessons: %-3d\r\n",
-	    vbuf.points.gold, vbuf.points.bank_gold, vbuf.points.exp,
-	    vbuf.char_specials_saved.alignment,
-	    vbuf.player_specials_saved.spells_to_learn);
-    strcpy(birth, ctime(&vbuf.birth));
-    sprintf(buf + strlen(buf),
-	    "Started: %-20.16s  Last: %-20.16s  Played: %3dh %2dm\r\n",
-	    birth, ctime(&vbuf.last_logon), (int) (vbuf.played / 3600),
-	    (int) (vbuf.played / 60 % 60));
+    sprintf(buf + strlen(buf), "Player: %-12s (%s) [%2d %s]\r\n", GET_NAME(vict),
+      genders[(int) GET_SEX(vict)], GET_LEVEL(vict), class_abbrevs[(int)
+        GET_CLASS(vict)]);
+    sprintf(buf,
+         "Au: %-8d  Bal: %-8d  Exp: %-8d  Align: %-5d  Lessons: %-3d\r\n",
+          GET_GOLD(vict), GET_BANK_GOLD(vict), GET_EXP(vict),
+          GET_ALIGNMENT(vict), GET_PRACTICES(vict));
+    strcpy(birth, ctime(&vict->player.time.birth));
+    sprintf(buf,
+            "Started: %-20.16s  Last: %-20.16s  Played: %3dh %2dm\r\n",
+          birth, ctime(&vict->player.time.logon), (int)
+          (vict->player.time.played / 3600),
+          (int) (vict->player.time.played / 60 % 60));
     send_to_char(buf, ch);
+    free_char(vict);
     break;
   case 3:
     if (!*value) {
@@ -2565,7 +2570,6 @@
 ACMD(do_set)
 {
   struct char_data *vict = NULL, *cbuf = NULL;
-  struct char_file_u tmp_store;
   char field[MAX_INPUT_LENGTH], name[MAX_INPUT_LENGTH],
 	val_arg[MAX_INPUT_LENGTH];
   int mode, len, player_i = 0, retval;
@@ -2607,8 +2611,8 @@
     /* try to load the player off disk */
     CREATE(cbuf, struct char_data, 1);
     clear_char(cbuf);
-    if ((player_i = load_char(name, &tmp_store)) > -1) {
-      store_to_char(&tmp_store, cbuf);
+    CREATE(cbuf->player_specials, struct player_special_data, 1);
+    if ((player_i = load_char(name, cbuf)) > -1) {
       if (GET_LEVEL(cbuf) >= GET_LEVEL(ch)) {
 	free_char(cbuf);
 	send_to_char("Sorry, you can't do that.\r\n", ch);
@@ -2636,9 +2640,8 @@
     if (!is_file && !IS_NPC(vict))
       save_char(vict, NOWHERE);
     if (is_file) {
-      char_to_store(vict, &tmp_store);
-      fseek(player_fl, (player_i) * sizeof(struct char_file_u), SEEK_SET);
-      fwrite(&tmp_store, sizeof(struct char_file_u), 1, player_fl);
+    GET_PFILEPOS(cbuf) = player_i;
+    save_char(cbuf, GET_LOADROOM(cbuf));
       send_to_char("Saved in file.\r\n", ch);
     }
   }
diff -u c:\mud\src/comm.c c:\mwan\src/comm.c
--- c:\mud\src/comm.c	Sun Mar 26 22:01:22 2000
+++ c:\mwan\src/comm.c	Thu Nov 16 16:11:22 2000
@@ -76,7 +76,6 @@
 extern int circle_restrict;
 extern int mini_mud;
 extern int no_rent_check;
-extern FILE *player_fl;
 extern ush_int DFLT_PORT;
 extern const char *DFLT_DIR;
 extern const char *DFLT_IP;
@@ -361,7 +360,6 @@
     close_socket(descriptor_list);
 
   CLOSE_SOCKET(mother_desc);
-  fclose(player_fl);
 
   if (circle_reboot != 2)
     save_all();
@@ -810,7 +808,6 @@
     weather_and_time(1);
     affect_update();
     point_update();
-    fflush(player_fl);
   }
   if (auto_save && !(pulse % (60 * PASSES_PER_SEC))) {	/* 1 minute */
     if (++mins_since_crashsave >= autosave_time) {
Only in c:\mwan\src: conf.h
Only in c:\mud\src: conf.h.win
diff -u c:\mud\src/config.c c:\mwan\src/config.c
--- c:\mud\src/config.c	Sun Mar 26 22:01:38 2000
+++ c:\mwan\src/config.c	Fri Nov 17 11:24:10 2000
@@ -143,6 +143,63 @@
 /* Lifetime of normal rent files in days */
 int rent_file_timeout = 30;
 
+/* Do you want to automatically wipe players who've been gone too long? */
+int auto_pwipe = NO;
+
+/* Autowipe deletion criteria
+   This struct holds information used to determine which players to wipe
+   then the mud boots.  The levels must be in ascending order, with a
+   descending level marking the end of the array.  A level -1 entry in the
+   beginning is the case for players with the PLR_DELETED flag.  The
+   values below match the stock purgeplay.c criteria.
+
+   Detailed explanation by array element:
+   * Element 0, level -1, days 0: Players with PLR_DELETED flag are always
+	wiped.
+   * Element 1, level 0, days 0: Players at level 0 have created a
+	character, but have never actually entered the game, so always
+	wipe them.
+   * Element 2, level 1, days 4: Players at level 1 are wiped if they
+	haven't logged on in the past 4 days.
+   * Element 3, level 4, days 7: Players level 2 through 4 are wiped if
+	they haven't logged on in the past 7 days.
+   * Element 4, level 10, days 30: Players level 5-10 get 30 days.
+   * Element 5, level LVL_IMMORT - 1, days 60: All other mortals get
+	60 days.
+   * Element 6, level LVL_IMPL, days 90: Immortals get 90 days.
+   * Element 7: Because -2 is less than LVL_IMPL, this is assumed to
+	be the end of the criteria.  The days entry is not used in this
+	case.
+*/
+struct pclean_criteria_data pclean_criteria[] = {
+/*	LEVEL		DAYS	*/
+  {	-1		,0	}, /* players with PLR_DELETE flag */
+  {	0		,0	}, /* level 0 */
+  {	1		,4	},
+  {	4		,7	},
+  {	10		,30	},
+  {	LVL_IMMORT - 1	,60	}, /* highest mortal */
+  {	LVL_IMPL	,90	}, /* all immortals */
+  {	-2		,0	}  /* no more level checks */
+};
+
+/* Do you want to save backups of players and their objects and mail when
+   they are deleted by the pfile autocleaner?
+*/
+int backup_wiped_pfiles = YES;
+
+/* Do you want players who self-delete to be wiped immediately with no
+   backup?
+*/
+int selfdelete_fastwipe = YES;
+
+/* Minimum level for pfile backup to occur when wiping players.
+   Note:  If you set selfdelete_fastwipe to NO, you'll need this to
+   prevent your backup directory from being filled with level 0 and
+   1 deletions.
+*/
+int pfile_backup_minlevel = 5;
+
 
 /****************************************************************************/
 /****************************************************************************/
@@ -206,8 +263,8 @@
  * versions of Circle.  If you specify a file, you don't get messages to
  * the screen. (Hint: Try 'tail -f' if you have a UNIX machine.)
  */
-const char *LOGNAME = NULL;
-/* const char *LOGNAME = "log/syslog";  -- useful for Windows users */
+//const char *LOGNAME = NULL;
+const char *LOGNAME = "log/syslog.txt";//  -- useful for Windows users
 
 /* maximum number of players allowed before game starts to turn people away */
 int max_playing = 300;
@@ -247,7 +304,7 @@
  * the SLOWNS command from within the MUD.
  */
 
-int nameserver_is_slow = NO;
+int nameserver_is_slow = YES;
 
 
 const char *MENU =
diff -u c:\mud\src/db.c c:\mwan\src/db.c
--- c:\mud\src/db.c	Sun Mar 26 22:04:22 2000
+++ c:\mwan\src/db.c	Sun Dec  3 23:29:16 2000
@@ -122,6 +122,9 @@
 void log_zone_error(zone_rnum zone, int cmd_no, const char *message);
 void reset_time(void);
 long get_ptable_by_name(char *name);
+void sprintbits(long vektor,char *outstring);
+void tag_argument(char *argument, char *tag);
+void clean_pfiles(void);
 
 /* external functions */
 struct time_info_data *mud_time_passed(time_t t2, time_t t1);
@@ -141,6 +144,7 @@
 void prune_crlf(char *txt);
 void free_object_strings(struct obj_data *obj);
 void free_object_strings_proto(struct obj_data *obj);
+void strip_cr(char *);
 
 /* external vars */
 extern int no_specials;
@@ -152,8 +156,39 @@
 extern struct spell_info_type spell_info[];
 extern const char *unused_spellname;
 
+/* external ascii pfile vars */
+extern int pfile_backup_minlevel;
+extern int backup_wiped_pfiles;
+extern struct pclean_criteria_data pclean_criteria[];
+extern int selfdelete_fastwipe;
+extern int auto_pwipe;
+
+
 #define READ_SIZE 256
 
+/* make these TRUE if you want aliases and poofs saved in the pfiles
+   or FALSE to leave them out
+*/
+#define ASCII_SAVE_POOFS	TRUE
+#define ASCII_SAVE_ALIASES	TRUE
+
+/* this is necessary for description handling.
+   It was taken from GenOLC (OLC 2.0) */
+void genolc_strip_cr(char *buffer)
+{  
+  int rpos, wpos;
+ 
+  if (buffer == NULL)
+    return;
+  
+  for (rpos = 0, wpos = 0; buffer[rpos]; rpos++) {
+    buffer[wpos] = buffer[rpos];
+    wpos += (buffer[rpos] != '\r');
+  }
+  buffer[wpos] = '\0';
+}
+
+
 /*************************************************************************
 *  routines for booting the system                                       *
 *************************************************************************/
@@ -305,6 +340,11 @@
   log("Generating player index.");
   build_player_index();
 
+  if(auto_pwipe) {
+    log("Cleaning out the pfiles.");
+    clean_pfiles();
+  }
+
   log("Loading fight messages.");
   load_messages();
 
@@ -409,57 +449,154 @@
     weather_info.sky = SKY_CLOUDLESS;
 }
 
+/* new version to build the player index for the ascii pfiles */
+ /* generate index table for the player file */
+void build_player_index(void)
+ {
+  int rec_count = 0, i;
+  FILE *plr_index;
+  char index_name[40], line[256], bits[64];
+  char arg2[80];
+
+  sprintf(index_name, "%s", PLR_INDEX_FILE);
+  if(!(plr_index = fopen(index_name, "r"))) {
+    top_of_p_table = -1;
+    log("No player index file!  First new char will be IMP!");
+    return;
+   }
 
+  /* count the number of players in the index */
+  while(get_line(plr_index, line))
+    if(*line != '~')
+      rec_count++;
+  rewind(plr_index);
+
+  if(rec_count == 0) {
+     player_table = NULL;
+     top_of_p_file = top_of_p_table = -1;
+     return;
+   }
+
+  CREATE(player_table, struct player_index_element, rec_count);
+  for(i = 0; i < rec_count; i++) {
+    get_line(plr_index, line);
+    sscanf(line, "%ld %s %d %s %d", &player_table[i].id, arg2,
+	&player_table[i].level, bits, (int *)&player_table[i].last);
+    CREATE(player_table[i].name, char, strlen(arg2) + 1);
+    strcpy(player_table[i].name, arg2);
+    player_table[i].flags = asciiflag_conv(bits);
+    top_idnum = MAX(top_idnum, player_table[i].id);
+  }
+  fclose(plr_index);
+  top_of_p_file = top_of_p_table = i - 1;
+}
 
-/* generate index table for the player file */
-void build_player_index(void)
+void save_player_index(void)
 {
-  int nr = -1, i;
-  long size, recs;
-  struct char_file_u dummy;
-
-  if (!(player_fl = fopen(PLAYER_FILE, "r+b"))) {
-    if (errno != ENOENT) {
-      perror("SYSERR: fatal error opening playerfile");
-      exit(1);
-    } else {
-      log("No playerfile.  Creating a new one.");
-      touch(PLAYER_FILE);
-      if (!(player_fl = fopen(PLAYER_FILE, "r+b"))) {
-	perror("SYSERR: fatal error opening playerfile");
-	exit(1);
-      }
-    }
-  }
+  int i;
+  char bits[64];
+  FILE *index_file;
 
-  fseek(player_fl, 0L, SEEK_END);
-  size = ftell(player_fl);
-  rewind(player_fl);
-  if (size % sizeof(struct char_file_u))
-    log("\aWARNING:  PLAYERFILE IS PROBABLY CORRUPT!");
-  recs = size / sizeof(struct char_file_u);
-  if (recs) {
-    log("   %ld players in database.", recs);
-    CREATE(player_table, struct player_index_element, recs);
-  } else {
-    player_table = NULL;
-    top_of_p_file = top_of_p_table = -1;
+  if(!(index_file = fopen(PLR_INDEX_FILE, "w"))) {
+    log("SYSERR:  Could not write player index file");
     return;
   }
 
-  for (; !feof(player_fl);) {
-    fread(&dummy, sizeof(struct char_file_u), 1, player_fl);
-    if (!feof(player_fl)) {	/* new record */
-      nr++;
-      CREATE(player_table[nr].name, char, strlen(dummy.name) + 1);
-      for (i = 0;
-	   (*(player_table[nr].name + i) = LOWER(*(dummy.name + i))); i++);
-      player_table[nr].id = dummy.char_specials_saved.idnum;
-      top_idnum = MAX(top_idnum, dummy.char_specials_saved.idnum);
+  for(i = 0; i <= top_of_p_table; i++)
+    if(*player_table[i].name) {
+      sprintbits(player_table[i].flags, bits);
+      fprintf(index_file, "%d %s %d %s %d\n", player_table[i].id,
+	player_table[i].name, player_table[i].level, *bits ? bits : "0",
+	player_table[i].last);
     }
-  }
+  fprintf(index_file, "~\n");
 
-  top_of_p_file = top_of_p_table = nr;
+  fclose(index_file);
+}
+
+void remove_player(int pfilepos)
+{
+  char backup_name[128], pfile_name[128]/*, rent_name[128]*/;
+  FILE *backup_file;
+
+  if(!*player_table[pfilepos].name)
+    return;
+
+  if(player_table[pfilepos].level >= pfile_backup_minlevel
+	&& backup_wiped_pfiles && (!selfdelete_fastwipe ||
+	!IS_SET(player_table[pfilepos].flags, PINDEX_SELFDELETE))) {
+    sprintf(backup_name, "%s/%s.%d", BACKUP_PREFIX,
+	player_table[pfilepos].name, (int)time(0));
+    if(!(backup_file = fopen(backup_name, "w"))) {
+      sprintf(buf, "PCLEAN: Unable to open backup file %s.",
+	backup_name);
+      log(buf);
+      return;
+    }
+
+    /* pfile */
+    fprintf(backup_file, "**\n** PFILE: %s\n**\n",
+	player_table[pfilepos].name);
+    sprintf(pfile_name, "%s/%c/%s%s", PLR_PREFIX,
+	*player_table[pfilepos].name, player_table[pfilepos].name,
+	PLR_SUFFIX);
+//    if(!fcat(pfile_name, backup_file))
+//      fprintf(backup_file, "** (NO FILE)\n");
+
+    /* rent file */
+/*    fbprintf(backup_file, "**\n** RENT FILE: %s\n**\n",
+	player_table[pfilepos].name);
+    sprintf(rent_name, "%s/%c/%s", RENT_PREFIX,
+	*player_table[pfilepos].name,
+	player_table[pfilepos].name);
+    if(!fbcat(rent_name, backup_file))
+      fbprintf(backup_file, "** (NO FILE)\n");*/
+
+    /* mail file */
+/*    fbprintf(backup_file, "**\n** MAIL FILE: %s\n**\n",
+	player_table[pfilepos].name);
+    sprintf(mail_name, "%s/%c/%s", MAIL_PREFIX,
+	*player_table[pfilepos].name,
+	player_table[pfilepos].name);
+    if(!fbcat(mail_name, backup_file))
+      fbprintf(backup_file, "** (NO FILE)\n");*/
+    fclose(backup_file);
+  }
+  unlink(pfile_name);
+  /*unlink(rent_name);
+  unlink(mail_name);*/
+  sprintf(buf, "PCLEAN: %s Lev: %d Last: %s",
+	player_table[pfilepos].name, player_table[pfilepos].level,
+	asctime(localtime(&player_table[pfilepos].last)));
+  log(buf);
+  player_table[pfilepos].name[0] = '\0';
+  save_player_index();
+}
+
+
+void clean_pfiles(void)
+{
+  int i, ci, timeout;
+
+  for(i = 0; i <= top_of_p_table; i++) {
+    if(IS_SET(player_table[i].flags, PINDEX_NODELETE))
+      continue;
+    timeout = -1;
+    for(ci = 0; ci == 0 || (pclean_criteria[ci].level > 
+	pclean_criteria[ci - 1].level); ci++) {
+      if((pclean_criteria[ci].level == -1 && IS_SET(player_table[i].flags,
+		PINDEX_DELETED)) || player_table[i].level <=
+		pclean_criteria[ci].level) {
+	timeout = pclean_criteria[ci].days;
+	break;
+      }
+    }
+    if(timeout >= 0) {
+      timeout *= SECS_PER_REAL_DAY;
+      if((time(0) - player_table[i].last) > timeout)
+	remove_player(i);
+    }
+  }  
 }
 
 /*
@@ -1951,217 +2088,527 @@
 }
 
 
-/* Load a char, TRUE if loaded, FALSE if not */
-int load_char(char *name, struct char_file_u * char_element)
+int load_char(char *name, struct char_data * ch)
 {
-  int player_i;
+  int rec_count = 0, i, idnum;
+  FILE *plr_index;
+  char line[256];
+  char arg2[80];
 
-  if ((player_i = find_name(name)) >= 0) {
-    fseek(player_fl, (long) (player_i * sizeof(struct char_file_u)), SEEK_SET);
-    fread(char_element, sizeof(struct char_file_u), 1, player_fl);
-    return (player_i);
-  } else
-    return (-1);
-}
+  if(!(plr_index = fopen(PLR_INDEX_FILE, "r"))) {
+	return -1;
+  }
 
+  while(get_line(plr_index, line))
+    if(*line != '~')
+      rec_count++;
+  rewind(plr_index);
 
+  if(rec_count == 0) {
+    return -1;
+   }
 
+  for(i = 0; i < rec_count; i++) {
+    get_line(plr_index, line);
+    sscanf(line, "%d %s", &idnum, arg2);
+	for (i = 0;(*(name + i) = LOWER(*(name + i))); i++);
 
-/*
- * write the vital data of a player to the player file
- *
- * NOTE: load_room should be an *RNUM* now.  It is converted to a vnum here.
- */
-void save_char(struct char_data * ch, room_rnum load_room)
+    if (!strcmp(arg2, name)) {
+	  fclose(plr_index);
+	  store_to_char(name, ch);
+	  return idnum; }
+  }
+
+  return -1;
+  fclose(plr_index);
+}
+
+void save_char(struct char_data * ch, sh_int load_room)
 {
-  struct char_file_u st;
 
   if (IS_NPC(ch) || !ch->desc || GET_PFILEPOS(ch) < 0)
     return;
 
-  char_to_store(ch, &st);
-
-  strncpy(st.host, ch->desc->host, HOST_LENGTH);
-  st.host[HOST_LENGTH] = '\0';
-
-  if (!PLR_FLAGGED(ch, PLR_LOADROOM)) {
-    if (load_room == NOWHERE)
-      st.player_specials_saved.load_room = NOWHERE;
-    else
-      st.player_specials_saved.load_room = GET_ROOM_VNUM(load_room);
-  }
-
-  fseek(player_fl, GET_PFILEPOS(ch) * sizeof(struct char_file_u), SEEK_SET);
-  fwrite(&st, sizeof(struct char_file_u), 1, player_fl);
+  char_to_store(ch);
 }
 
 
 
-/* copy data from the file structure to a char struct */
-void store_to_char(struct char_file_u * st, struct char_data * ch)
+void store_to_char(char *name, struct char_data * ch)
 {
-  int i;
-
-  /* to save memory, only PC's -- not MOB's -- have player_specials */
-  if (ch->player_specials == NULL)
-    CREATE(ch->player_specials, struct player_special_data, 1);
-
-  GET_SEX(ch) = st->sex;
-  GET_CLASS(ch) = st->chclass;
-  GET_LEVEL(ch) = st->level;
-
-  ch->player.short_descr = NULL;
-  ch->player.long_descr = NULL;
-  ch->player.title = str_dup(st->title);
-  ch->player.description = str_dup(st->description);
+  int id, num = 0, num2 = 0, num3 = 0, num4 = 0, num5 = 0, i;
+  FILE *fl;
+  char filename[40];
+  char buf[128], line[MAX_INPUT_LENGTH+1], tag[6];
+  struct affected_type tmp_aff[MAX_AFFECT];
+ 
 
-  ch->player.hometown = st->hometown;
-  ch->player.time.birth = st->birth;
-  ch->player.time.played = st->played;
-  ch->player.time.logon = time(0);
+  if((id = find_name(name)) < 0) {
+     return;
+  } else {
+    sprintf(filename, "%s/%c/%s%s", PLR_PREFIX, *player_table[id].name,
+      player_table[id].name, PLR_SUFFIX);
+    if(!(fl = fopen(filename, "r"))) {
+      sprintf(buf, "SYSERR: Couldn't open player file %s", filename);
+      mudlog(buf, NRM, LVL_GOD, TRUE);
+      return;
+    }
+  
+    /* initializations necessary to keep some things straight */
+    if (ch->player_specials == NULL) 
+     CREATE(ch->player_specials, struct player_special_data, 1);
+    init_char(ch);
+  }
+    
+
+     while(get_line(fl, line)) {
+      tag_argument(line, tag);
+      num = atoi(line);
+
+      switch (*tag) {
+      case 'A':
+	if(!strcmp(tag, "Ac  "))
+	  GET_AC(ch) = num;
+	else if(!strcmp(tag, "Act "))
+	  PLR_FLAGS(ch) = num;
+	else if(!strcmp(tag, "Aff "))
+	  AFF_FLAGS(ch) = asciiflag_conv(line);
+	else if(!strcmp(tag, "Affs")) {
+	  i = 0;
+	  do {
+	    get_line(fl, line);
+	    sscanf(line, "%d %d %d %d %d", &num, &num2, &num3, &num4, &num5);
+	    tmp_aff[i].type = num;
+	    tmp_aff[i].duration = num2;
+	    tmp_aff[i].modifier = num3;
+	    tmp_aff[i].location = num4;
+	    tmp_aff[i].bitvector = num5;
+	    i++;
+	  } while (num != 0);
+	} else if(!strcmp(tag, "Alin"))
+	  GET_ALIGNMENT(ch) = num;
+	break;
+ 
+      case 'B':
+	if(!strcmp(tag, "Badp"))
+	  GET_BAD_PWS(ch) = num;
+	else if(!strcmp(tag, "Bank"))
+	  GET_BANK_GOLD(ch) = num;
+	else if(!strcmp(tag, "Brth"))
+	  ch->player.time.birth = num;
+	break;
+ 
+      case 'C':
+	if(!strcmp(tag, "Cha "))
+	  GET_CHA(ch) = num;
+	else if(!strcmp(tag, "Clas"))
+	  GET_CLASS(ch) = num;
+	else if(!strcmp(tag, "Con "))
+	  GET_CON(ch) = num;
+	break;
+  
+      case 'D':
+	if(!strcmp(tag, "Desc")) {
+	  ch->player.description = str_dup(line);
+	} else if(!strcmp(tag, "Dex "))
+	  GET_DEX(ch) = num;
+	else if(!strcmp(tag, "Drnk"))
+	  GET_COND(ch, DRUNK) = num;
+	else if(!strcmp(tag, "Drol"))
+	  GET_DAMROLL(ch) = num;
+	break;
+  
+      case 'E':
+	if(!strcmp(tag, "Exp "))
+	  GET_EXP(ch) = num;
+	break;
+ 
+      case 'F':
+	if(!strcmp(tag, "Frez"))
+	  GET_FREEZE_LEV(ch) = num;
+	break;
+  
+      case 'G':
+	if(!strcmp(tag, "Gold"))
+	  GET_GOLD(ch) = num;
+	break;
+  
+      case 'H':
+	if(!strcmp(tag, "Hit ")) {
+	  sscanf(line, "%d/%d", &num, &num2);
+	  GET_HIT(ch) = num;
+	  GET_MAX_HIT(ch) = num2;
+	} else if(!strcmp(tag, "Hite"))
+	  GET_HEIGHT(ch) = num;
+	else if(!strcmp(tag, "Home"))
+	  GET_HOME(ch) = num;
+	else if(!strcmp(tag, "Host"))
+	  strcpy(ch->desc->host,str_dup(line));
+	else if(!strcmp(tag, "Hrol"))
+	  GET_HITROLL(ch) = num;
+	else if(!strcmp(tag, "Hung"))
+	 GET_COND(ch, FULL) = num;
+	break;
 
-  ch->player.weight = st->weight;
-  ch->player.height = st->height;
+      case 'I':
+	if(!strcmp(tag, "Id  "))
+	  GET_IDNUM(ch) = num;
+	else if(!strcmp(tag, "Int "))
+	  GET_INT(ch) = num;
+	else if(!strcmp(tag, "Invs"))
+	  GET_INVIS_LEV(ch) = num;
+	break;
 
-  ch->real_abils = st->abilities;
-  ch->aff_abils = st->abilities;
-  ch->points = st->points;
-  ch->char_specials.saved = st->char_specials_saved;
-  ch->player_specials->saved = st->player_specials_saved;
-  POOFIN(ch) = NULL;
-  POOFOUT(ch) = NULL;
-  GET_LAST_TELL(ch) = NOBODY;
+      case 'L':
+	if(!strcmp(tag, "Last"))
+	  ch->player.time.logon = num;
+	else if(!strcmp(tag, "Lern"))
+	  GET_PRACTICES(ch) = num;
+	else if(!strcmp(tag, "Levl"))
+	  GET_LEVEL(ch) = num;
+	break;
+  
+      case 'M':
+	if(!strcmp(tag, "Mana")) {
+	  sscanf(line, "%d/%d", &num, &num2);
+	  GET_MANA(ch) = num;
+	  GET_MAX_MANA(ch) = num2;
+	} else if(!strcmp(tag, "Move")) {
+	  sscanf(line, "%d/%d", &num, &num2);
+	  GET_MOVE(ch) = num;
+	  GET_MAX_MOVE(ch) = num2;
+	}
+	break;
 
-  if (ch->points.max_mana < 100)
-    ch->points.max_mana = 100;
+      case 'N':
+	if(!strcmp(tag, "Name"))
+	  ch->player.name = str_dup(line);
+	break;
 
-  ch->char_specials.carry_weight = 0;
-  ch->char_specials.carry_items = 0;
-  ch->points.armor = 100;
-  ch->points.hitroll = 0;
-  ch->points.damroll = 0;
+      case 'P':
+	if(!strcmp(tag, "Pass"))
+	  strcpy(GET_PASSWD(ch), line);
+	else if(!strcmp(tag, "Plyd"))
+	  ch->player.time.played = num;
+	else if(!strcmp(tag, "PfIn"))
+	  POOFIN(ch) = str_dup(line);
+	else if(!strcmp(tag, "PfOt"))
+	  POOFOUT(ch) = str_dup(line);
+	else if(!strcmp(tag, "Pref"))
+	  PRF_FLAGS(ch) = asciiflag_conv(line);
+	break;
+  
+      case 'R':
+	if(!strcmp(tag, "Room"))
+	  GET_LOADROOM(ch) = num;
+	break;
+  
+      case 'S':
+	if(!strcmp(tag, "Sex "))
+	  GET_SEX(ch) = num;
+	else if(!strcmp(tag, "Skil")) {
+	  do {
+	    get_line(fl, line);
+	    sscanf(line, "%d %d", &num, &num2);
+	      if(num != 0)
+		GET_SKILL(ch, num) = num2;
+	  } while (num != 0);
+	} else if(!strcmp(tag, "Str ")) {
+	  sscanf(line, "%d/%d", &num, &num2);
+	  GET_STR(ch) = num;
+	  GET_ADD(ch) = num2;
+	}
+	break;
 
-  if (ch->player.name == NULL)
-    CREATE(ch->player.name, char, strlen(st->name) + 1);
-  strcpy(ch->player.name, st->name);
-  strcpy(ch->player.passwd, st->pwd);
-
-  /* Add all spell effects */
-  for (i = 0; i < MAX_AFFECT; i++) {
-    if (st->affected[i].type)
-      affect_to_char(ch, &st->affected[i]);
-  }
+      case 'T':
+	if(!strcmp(tag, "Thir"))
+	  GET_COND(ch, THIRST) = num;
+	else if(!strcmp(tag, "Thr1"))
+	  GET_SAVE(ch, 0) = num;
+	else if(!strcmp(tag, "Thr2"))
+	  GET_SAVE(ch, 1) = num;
+	else if(!strcmp(tag, "Thr3"))
+	  GET_SAVE(ch, 2) = num;
+	else if(!strcmp(tag, "Thr4"))
+	  GET_SAVE(ch, 3) = num;
+	else if(!strcmp(tag, "Thr5"))
+	  GET_SAVE(ch, 4) = num;
+	else if(!strcmp(tag, "Titl"))
+	  GET_TITLE(ch) = str_dup(line);
+	break;
+  
+      case 'W':
+	if(!strcmp(tag, "Wate"))
+	  GET_WEIGHT(ch) = num;
+	else if(!strcmp(tag, "Wimp"))
+	  GET_WIMP_LEV(ch) = num;
+	else if(!strcmp(tag, "Wis "))
+	  GET_WIS(ch) = num;
+	break;
+  
+      default:
+	sprintf(buf, "SYSERR: Unknown tag %s in pfile %s", tag, name);
+      }
+    }
+   
 
-  /*
-   * If you're not poisioned and you've been away for more than an hour of
-   * real time, we'll set your HMV back to full
-   */
+  
+  /* set real_abils = aff_abils */
+  ch->real_abils = ch->aff_abils;
+  
+   for (i = 0; i < MAX_AFFECT, tmp_aff[i].type!=0; i++) {
+    if (tmp_aff[i].type)
+      affect_to_char(ch, &tmp_aff[i]);
+   }
+ 
+
+  /* initialization for imms */
+  if(GET_LEVEL(ch) >= LVL_IMMORT) {
+/*    for(i = 1; i <= MAX_SKILLS; i++)
+      GET_SKILL(ch, i) = 100;*/
+    GET_COND(ch, FULL) = -1;
+    GET_COND(ch, THIRST) = -1;
+    GET_COND(ch, DRUNK) = -1;
+   }
 
-  if (!AFF_FLAGGED(ch, AFF_POISON) &&
-      (((long) (time(0) - st->last_logon)) >= SECS_PER_REAL_HOUR)) {
-    GET_HIT(ch) = GET_MAX_HIT(ch);
-    GET_MOVE(ch) = GET_MAX_MOVE(ch);
-    GET_MANA(ch) = GET_MAX_MANA(ch);
-  }
+  fclose(fl);
+  return;
 }				/* store_to_char */
 
 
 
 
-/* copy vital data from a players char-structure to the file structure */
-void char_to_store(struct char_data * ch, struct char_file_u * st)
+void char_to_store(struct char_data * ch)
 {
-  int i;
-  struct affected_type *af;
+  FILE *fl;
+  char outname[40], bits[127], buf[MAX_STRING_LENGTH];
+  int i, id, save_index = FALSE;
+  struct affected_type *aff, tmp_aff[MAX_AFFECT];
   struct obj_data *char_eq[NUM_WEARS];
 
-  /* Unaffect everything a character can be affected by */
-
-  for (i = 0; i < NUM_WEARS; i++) {
-    if (GET_EQ(ch, i))
-      char_eq[i] = unequip_char(ch, i);
+  if (IS_NPC(ch) || GET_PFILEPOS(ch) < 0)
+    return;
+  
+  /* If ch->desc doesn't exist, it's because we're doing a set file.
+     Last host will disappear in that case.  No biggie, eh?
+  */
+  
+  if (!PLR_FLAGGED(ch, PLR_LOADROOM)) {
+    if (GET_LOADROOM(ch) == NOWHERE)
+      GET_LOADROOM(ch) = NOWHERE;
     else
-      char_eq[i] = NULL;
+      GET_LOADROOM(ch) = world[GET_LOADROOM(ch)].number;
   }
 
-  for (af = ch->affected, i = 0; i < MAX_AFFECT; i++) {
-    if (af) {
-      st->affected[i] = *af;
-      st->affected[i].next = 0;
-      af = af->next;
-    } else {
-      st->affected[i].type = 0;	/* Zero signifies not used */
-      st->affected[i].duration = 0;
-      st->affected[i].modifier = 0;
-      st->affected[i].location = 0;
-      st->affected[i].bitvector = 0;
-      st->affected[i].next = 0;
+  /*strcpy(player.pwd, GET_PASSWD(ch));*/
+ 
+  {
+    for (i = 0;
+      (*(bits + i) = LOWER(*(GET_NAME(ch) + i))); i++);
+    sprintf(outname, "%s/%c/%s%s", PLR_PREFIX, *bits, bits, PLR_SUFFIX);
+    if (!(fl = fopen(outname, "w"))) {
+      sprintf(buf, "SYSERR: Couldn't open player file %s for write",
+		outname);
+      mudlog(buf, NRM, LVL_GOD, TRUE);
+      return;
+    }
+  
+    /* remove affects from eq and spells (from char_to_store) */
+    /* Unaffect everything a character can be affected by */
+  
+    for (i = 0; i < NUM_WEARS; i++) {
+      if (GET_EQ(ch, i))
+        char_eq[i] = unequip_char(ch, i);
+      else
+        char_eq[i] = NULL;
     }
-  }
-
-
-  /*
-   * remove the affections so that the raw values are stored; otherwise the
-   * effects are doubled when the char logs back in.
-   */
 
-  while (ch->affected)
-    affect_remove(ch, ch->affected);
+    for (aff = ch->affected, i = 0; i < MAX_AFFECT; i++) {
+      if (aff) {
+        tmp_aff[i] = *aff;
+        tmp_aff[i].next = 0;
+        aff = aff->next;
+      } else {
+        tmp_aff[i].type = 0;	/* Zero signifies not used */
+        tmp_aff[i].duration = 0;
+        tmp_aff[i].modifier = 0;
+        tmp_aff[i].location = 0;
+        tmp_aff[i].bitvector = 0;
+        tmp_aff[i].next = 0;
+      }
+    }
+  
+  
+    /*
+     * remove the affections so that the raw values are stored; otherwise the
+     * effects are doubled when the char logs back in.
+     */
 
-  if ((i >= MAX_AFFECT) && af && af->next)
-    log("SYSERR: WARNING: OUT OF STORE ROOM FOR AFFECTED TYPES!!!");
+    while (ch->affected)
+      affect_remove(ch, ch->affected);
+    if ((i >= MAX_AFFECT) && aff && aff->next)
+      log("SYSERR: WARNING: OUT OF STORE ROOM FOR AFFECTED TYPES!!!");
+
+    ch->aff_abils = ch->real_abils;
+
+    /* end char_to_store code */
+
+    if(GET_NAME(ch))
+      fprintf(fl, "Name: %s\n", GET_NAME(ch));
+    if(GET_PASSWD(ch))
+      fprintf(fl, "Pass: %s\n", GET_PASSWD(ch));
+    if(GET_TITLE(ch))
+      fprintf(fl, "Titl: %s\n", GET_TITLE(ch));
+    if(ch->player.description && *ch->player.description) {
+      strcpy(buf, ch->player.description);
+      genolc_strip_cr(buf);
+      fprintf(fl, "Desc:\n%s~\n", buf);
+    }
+    if(POOFIN(ch))
+      fprintf(fl, "PfIn: %s\n", POOFIN(ch));
+    if(POOFOUT(ch))
+      fprintf(fl, "PfOt: %s\n", POOFOUT(ch));
+      fprintf(fl, "Sex : %d\n", GET_SEX(ch)); 
+      fprintf(fl, "Clas: %d\n", GET_CLASS(ch)); 
+      fprintf(fl, "Levl: %d\n", GET_LEVEL(ch));
+      fprintf(fl, "Home: %d\n", GET_HOME(ch));
+      fprintf(fl, "Brth: %d\n", ch->player.time.birth);
+      fprintf(fl, "Plyd: %d\n", ch->player.time.played);
+      fprintf(fl, "Last: %d\n", ch->player.time.logon);
+    if(ch->desc->host)
+      fprintf(fl, "Host: %s\n", ch->desc->host);
+      fprintf(fl, "Hite: %d\n", GET_HEIGHT(ch));
+      fprintf(fl, "Wate: %d\n", GET_WEIGHT(ch));
+      fprintf(fl, "Alin: %d\n", GET_ALIGNMENT(ch));
+      fprintf(fl, "Id  : %d\n", GET_IDNUM(ch));
+      fprintf(fl, "Act : %d\n", PLR_FLAGS(ch));
+      sprintbits(AFF_FLAGS(ch), bits);
+      fprintf(fl, "Aff : %s\n", bits);
+      fprintf(fl, "Thr1: %d\n", GET_SAVE(ch, 0));
+      fprintf(fl, "Thr2: %d\n", GET_SAVE(ch, 1));
+      fprintf(fl, "Thr3: %d\n", GET_SAVE(ch, 2));
+      fprintf(fl, "Thr4: %d\n", GET_SAVE(ch, 3));
+      fprintf(fl, "Thr5: %d\n", GET_SAVE(ch, 4));
+//    if(GET_LEVEL(ch) < LVL_IMMORT) {
+      fprintf(fl, "Skil:\n");
+      for(i = 1; i <= MAX_SKILLS; i++) {
+		if(GET_SKILL(ch, i))
+		  fprintf(fl, "%d %d\n", i, GET_SKILL(ch, i));
+      }
+      fprintf(fl, "0 0\n");
+//    }
+      fprintf(fl, "Wimp: %d\n", GET_WIMP_LEV(ch));
+      fprintf(fl, "Frez: %d\n", GET_FREEZE_LEV(ch));
+      fprintf(fl, "Invs: %d\n", GET_INVIS_LEV(ch));
+      fprintf(fl, "Room: %d\n", GET_LOADROOM(ch));
+      sprintbits(PRF_FLAGS(ch), bits);
+      fprintf(fl, "Pref: %s\n", bits);
+      fprintf(fl, "Badp: %d\n", GET_BAD_PWS(ch));
+	  if(GET_LEVEL(ch) < LVL_IMMORT) {
+		fprintf(fl, "Hung: %d\n", GET_COND(ch, FULL));
+		fprintf(fl, "Thir: %d\n", GET_COND(ch, THIRST));
+		fprintf(fl, "Drnk: %d\n", GET_COND(ch, DRUNK));
+	  }
+      fprintf(fl, "Lern: %d\n", GET_PRACTICES(ch)); 
+      fprintf(fl, "Str : %d/%d\n", GET_STR(ch), GET_ADD(ch));
+      fprintf(fl, "Int : %d\n", GET_INT(ch));
+      fprintf(fl, "Wis : %d\n", GET_WIS(ch));
+      fprintf(fl, "Dex : %d\n", GET_DEX(ch));
+      fprintf(fl, "Con : %d\n", GET_CON(ch));
+      fprintf(fl, "Cha : %d\n", GET_CHA(ch));
+      fprintf(fl, "Hit : %d/%d\n", GET_HIT(ch), GET_MAX_HIT(ch));
+      fprintf(fl, "Mana: %d/%d\n", GET_MANA(ch), GET_MAX_MANA(ch));
+      fprintf(fl, "Move: %d/%d\n", GET_MOVE(ch), GET_MAX_MOVE(ch));
+      fprintf(fl, "Ac  : %d\n", GET_AC(ch));
+      fprintf(fl, "Gold: %d\n", GET_GOLD(ch));
+      fprintf(fl, "Bank: %d\n", GET_BANK_GOLD(ch));
+      fprintf(fl, "Exp : %d\n", GET_EXP(ch));
+      fprintf(fl, "Hrol: %d\n", GET_HITROLL(ch));
+      fprintf(fl, "Drol: %d\n", GET_DAMROLL(ch));
+
+    /* affected_type */
+    fprintf(fl, "Affs:\n");
+    for(i = 0; i < MAX_AFFECT; i++) {
+      aff = &tmp_aff[i];
+      if(aff->type)
+		fprintf(fl, "%d %d %d %d %d\n", aff->type, aff->duration,
+	  aff->modifier, aff->location, (int)aff->bitvector);
+    }
+    fprintf(fl, "0 0 0 0 0\n");
+    fclose(fl);
+ 
+    /* more char_to_store code to restore affects */
+  
+    /* add spell and eq affections back in now */
+    for (i = 0; i < MAX_AFFECT; i++) {
+      if (tmp_aff[i].type)
+        affect_to_char(ch, &tmp_aff[i]);
+    }
 
-  ch->aff_abils = ch->real_abils;
+    for (i = 0; i < NUM_WEARS; i++) {
+      if (char_eq[i])
+        equip_char(ch, char_eq[i], i);
+    }
 
-  st->birth = ch->player.time.birth;
-  st->played = ch->player.time.played;
-  st->played += (long) (time(0) - ch->player.time.logon);
-  st->last_logon = time(0);
+    /* end char_to_store code */
 
-  ch->player.time.played = st->played;
-  ch->player.time.logon = time(0);
+    if((id = find_name(GET_NAME(ch))) < 0)
+      return;
 
-  st->hometown = ch->player.hometown;
-  st->weight = GET_WEIGHT(ch);
-  st->height = GET_HEIGHT(ch);
-  st->sex = GET_SEX(ch);
-  st->chclass = GET_CLASS(ch);
-  st->level = GET_LEVEL(ch);
-  st->abilities = ch->real_abils;
-  st->points = ch->points;
-  st->char_specials_saved = ch->char_specials.saved;
-  st->player_specials_saved = ch->player_specials->saved;
-
-  st->points.armor = 100;
-  st->points.hitroll = 0;
-  st->points.damroll = 0;
+    /* update the player in the player index */
+    if(player_table[id].level != GET_LEVEL(ch)) {
+      save_index = TRUE;
+      player_table[id].level = GET_LEVEL(ch);
+    }
+    if(player_table[id].last != ch->player.time.logon) {
+      save_index = TRUE;
+      player_table[id].last = ch->player.time.logon;
+    }
+    i = player_table[id].flags;
+    if(PLR_FLAGGED(ch, PLR_DELETED))
+      SET_BIT(player_table[id].flags, PINDEX_DELETED);
+    else
+      REMOVE_BIT(player_table[id].flags, PINDEX_DELETED);
+    if(PLR_FLAGGED(ch, PLR_NODELETE) || PLR_FLAGGED(ch, PLR_CRYO))
+      SET_BIT(player_table[id].flags, PINDEX_NODELETE);
+    else
+      REMOVE_BIT(player_table[id].flags, PINDEX_NODELETE);
+    if(player_table[id].flags != i || save_index)
+      save_player_index();
+  }
+} /* char to store */
 
-  if (GET_TITLE(ch))
-    strcpy(st->title, GET_TITLE(ch));
-  else
-    *st->title = '\0';
+void tag_argument(char *argument, char *tag) {
+	char *tmp = argument, *ttag = tag, *wrt = argument;
+	int i;
 
-  if (ch->player.description)
-    strcpy(st->description, ch->player.description);
-  else
-    *st->description = '\0';
+	for (i=0;i<4;i++)
+		*(ttag++) = *(tmp++);
+	*ttag ='\0';
 
-  strcpy(st->name, GET_NAME(ch));
-  strcpy(st->pwd, GET_PASSWD(ch));
+	while(*tmp == ':' || *tmp == ' ')
+		tmp++;
 
-  /* add spell and eq affections back in now */
-  for (i = 0; i < MAX_AFFECT; i++) {
-    if (st->affected[i].type)
-      affect_to_char(ch, &st->affected[i]);
-  }
+	while (*tmp)
+		*(wrt++) = *(tmp++);
+	*wrt = '\0';
+}
 
-  for (i = 0; i < NUM_WEARS; i++) {
-    if (char_eq[i])
-      equip_char(ch, char_eq[i], i);
-  }
-/*   affect_total(ch); unnecessary, I think !?! */
-}				/* Char to store */
+void sprintbits(long vektor,char *outstring) {
+  int i;
+  char flags[53]="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
+  strcpy(outstring,"");
+  for (i=0;i<32;i++)
+  {
+    if (vektor & 1) {
+      *outstring=flags[i];
+      outstring++;
+    };
+    vektor>>=1;
+  };
+  *outstring=0;
+}
 
 
 void save_etext(struct char_data * ch)
@@ -2505,7 +2952,7 @@
   ch->points.armor = 100;
 
   if ((i = get_ptable_by_name(GET_NAME(ch))) != -1)
-    player_table[i].id = GET_IDNUM(ch) = ++top_idnum;
+    player_table[top_of_p_table].id = GET_IDNUM(ch) = top_of_p_table + 1;
   else
     log("SYSERR: init_char: Character '%s' not found in player table.", GET_NAME(ch));
 
Only in c:\mwan\src: db.c.old
diff -u c:\mud\src/db.h c:\mwan\src/db.h
--- c:\mud\src/db.h	Mon Mar 20 12:26:26 2000
+++ c:\mwan\src/db.h	Fri Nov 17 10:53:06 2000
@@ -95,6 +95,27 @@
 #define BAN_FILE	LIB_ETC"badsites" /* for the siteban system	*/
 #define HCONTROL_FILE	LIB_ETC"hcontrol"  /* for the house system	*/
 
+/* ascii pfiles file defines (will probably be ok in all but mac systems)
+*/
+#define PLR_PREFIX	"pfiles"
+#define RENT_PREFIX	"rent"
+#define MAIL_PREFIX	"mail"
+#define BACKUP_PREFIX	"pfiles/backup"
+#define PLR_INDEX_FILE	"pfiles/plr_index"
+
+/* change these if you want to put all files in the same directory (or if
+   you just like big file names
+*/
+#define PLR_SUFFIX	""
+#define RENT_SUFFIX	""
+#define MAIL_SUFFIX	""
+
+/* new bitvector data for use in player_index_element */
+#define PINDEX_DELETED		(1 << 0)	/* deleted player	*/
+#define PINDEX_NODELETE		(1 << 1)	/* protected player	*/
+#define PINDEX_SELFDELETE	(1 << 2)	/* player is selfdeleting*/
+
+
 /* public procedures in db.c */
 void	boot_db(void);
 int	create_entry(char *name);
@@ -104,9 +125,10 @@
 long	get_id_by_name(char *name);
 char	*get_name_by_id(long id);
 
-void	char_to_store(struct char_data *ch, struct char_file_u *st);
-void	store_to_char(struct char_file_u *st, struct char_data *ch);
-int	load_char(char *name, struct char_file_u *char_element);
+
+void char_to_store(struct char_data * ch);
+void store_to_char(char *name, struct char_data * ch);
+int load_char(char *name, struct char_data *ch);
 void	save_char(struct char_data *ch, room_rnum load_room);
 void	init_char(struct char_data *ch);
 struct char_data* create_char(void);
@@ -116,6 +138,7 @@
 void	clear_char(struct char_data *ch);
 void	reset_char(struct char_data *ch);
 void	free_char(struct char_data *ch);
+void	save_player_index(void);
 
 struct obj_data *create_obj(void);
 void	clear_object(struct obj_data *obj);
@@ -187,10 +210,16 @@
 };
 
 
-
+/* Added level, flags, and last, primarily for pfile autocleaning.  You
+   can also use them to keep online statistics, and can add race, class,
+   etc if you like.
+*/
 struct player_index_element {
    char	*name;
    long id;
+   int level;
+   int flags;
+   time_t last;
 };
 
 
Common subdirectories: c:\mud\src/docs and c:\mwan\src/docs
diff -u c:\mud\src/interpreter.c c:\mwan\src/interpreter.c
--- c:\mud\src/interpreter.c	Sun Mar 26 22:11:48 2000
+++ c:\mwan\src/interpreter.c	Tue Nov 21 11:05:10 2000
@@ -46,6 +46,8 @@
 extern struct index_data *mob_index;
 extern struct index_data *obj_index;
 extern struct room_data *world;
+extern int backup_wiped_pfiles;
+extern int selfdelete_fastwipe;
 
 /* external functions */
 void echo_on(struct descriptor_data *d);
@@ -56,6 +58,7 @@
 int isbanned(char *hostname);
 int Valid_Name(char *newname);
 void read_aliases(struct char_data *ch);
+void remove_player(int pfilepos);
 
 /* local functions */
 int perform_dupe_check(struct descriptor_data *d);
@@ -1297,7 +1300,6 @@
   char buf[128];
   int player_i, load_result;
   char tmp_name[MAX_INPUT_LENGTH];
-  struct char_file_u tmp_store;
   room_vnum load_room;
 
   /* OasisOLC states */
@@ -1343,11 +1345,15 @@
 		  "Name: ", d);
 	return;
       }
-      if ((player_i = load_char(tmp_name, &tmp_store)) > -1) {
-	store_to_char(&tmp_store, d->character);
+      if ((player_i = load_char(tmp_name, d->character)) > -1) {
 	GET_PFILEPOS(d->character) = player_i;
 
 	if (PLR_FLAGGED(d->character, PLR_DELETED)) {
+
+	  /* make sure old files are removed in case of deleted player */
+	  if((player_i = find_name(tmp_name)) >= 0)
+	    remove_player(player_i);
+
 	  /* We get a false positive from the original deleted character. */
 	  free_char(d->character);
 	  /* Check for multiple creations... */
@@ -1585,6 +1591,7 @@
     /* Now GET_NAME() will work properly. */
     init_char(d->character);
     save_char(d->character, NOWHERE);
+	save_player_index();
     SEND_TO_Q(motd, d);
     SEND_TO_Q("\r\n*** PRESS RETURN: ", d);
     STATE(d) = CON_RMOTD;
@@ -1732,6 +1739,11 @@
 	SET_BIT(PLR_FLAGS(d->character), PLR_DELETED);
       save_char(d->character, NOWHERE);
       Crash_delete_file(GET_NAME(d->character));
+      if(selfdelete_fastwipe)
+		if((player_i = find_name(GET_NAME(d->character))) >= 0) {
+			SET_BIT(player_table[player_i].flags, PINDEX_SELFDELETE);
+			remove_player(player_i);
+		}
       sprintf(buf, "Character '%s' deleted!\r\n"
 	      "Goodbye.\r\n", GET_NAME(d->character));
       SEND_TO_Q(buf, d);
diff -u c:\mud\src/structs.h c:\mwan\src/structs.h
--- c:\mud\src/structs.h	Sun Mar 26 22:17:26 2000
+++ c:\mwan\src/structs.h	Fri Nov 17 10:53:06 2000
@@ -695,6 +695,15 @@
    int	played;     /* This is the total accumulated time played in secs */
 };
 
+ 
+/* This structure is used to configure time/level criteria for the
+   pfile autowipe system.  Actual setup is in config.c.  This seems like
+   as good a place as any for the struct.
+*/
+struct pclean_criteria_data {
+  int level;		/* max level for this time limit		*/
+  int days;		/* time limit (in days)				*/
+};
 
 /* general player-related info, usually PC's and NPC's */
 struct char_player_data {
Common subdirectories: c:\mud\src/util and c:\mwan\src/util
