diff -BbuprN -x '*.o' circle-3.1/src/act.informative.c circle-dev/src/act.informative.c
--- circle-3.1/src/act.informative.c	2004-06-29 19:30:00.000000000 -0400
+++ circle-dev/src/act.informative.c	2004-06-29 19:30:26.000000000 -0400
@@ -759,6 +759,7 @@ ACMD(do_score)
   
   send_to_char(ch, "Name: %s %s.\r\n", GET_NAME(ch), GET_TITLE(ch));
   send_to_char(ch, "Level: %d                   \r\n", GET_LEVEL(ch));
+  send_to_char(ch, "Remort level: %d            \r\n", GET_REMORT_LEVEL(ch));
   send_to_char(ch, "Align: %d                   \r\n", GET_ALIGNMENT(ch));
   send_to_char(ch, "AC: %d/10                   Age: %d\r\n", compute_armor_class(ch), GET_AGE(ch));
 
diff -BbuprN -x '*.o' circle-3.1/src/act.other.c circle-dev/src/act.other.c
--- circle-3.1/src/act.other.c	2004-06-29 19:10:01.000000000 -0400
+++ circle-dev/src/act.other.c	2004-06-29 19:28:09.000000000 -0400
@@ -28,6 +29,7 @@
 /* extern variables */
 extern struct spell_info_type spell_info[];
 extern const char *class_abbrevs[];
+extern const char *class_menu;
 
 /* extern procedures */
 void list_skills(struct char_data *ch);
@@ -38,6 +40,9 @@ SPECIAL(shop_keeper);
 ACMD(do_gen_comm);
 void die(struct char_data *ch, struct char_data * killer);
 void Crash_rentsave(struct char_data *ch, int cost);
+int parse_class(char arg);
+void do_remort_start(struct char_data *ch);
+
 
 /* local functions */
 ACMD(do_quit);
@@ -60,6 +65,7 @@ ACMD(do_wimpy);
 ACMD(do_display);
 ACMD(do_gen_write);
 ACMD(do_gen_tog);
+ACMD(do_remort);
 
 
 ACMD(do_quit)
@@ -982,3 +988,215 @@ ACMD(do_gen_tog)
   
   return;
 }
+
+/* Added by ret for remort
+ * this is what actually changes your class, sets the right stats, etc.
+ */
+ACMD(do_remort) {
+  char arg[MAX_STRING_LENGTH];
+  
+  if (GET_LEVEL(ch) < (LVL_IMMORT - 1))
+    send_to_char(ch, "You cannot remort at this time.\r\n");
+  
+  else {
+    
+    if (GET_REMORT_LEVEL(ch) == 0)
+      {
+	one_argument(argument, arg);
+	
+	if (strcmp(arg, "warrior") == 0)
+	  {
+            GET_REMORT(ch) = GET_CLASS(ch); /* save what class they are before remort */
+	    GET_CLASS(ch) = CLASS_WARRIOR;  /* change their class */
+	    GET_REMORT_LEVEL(ch) = 1;       /* set back to level one */
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a warrior.\r\n");
+	  }
+	else if (strcmp(arg, "thief") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_THIEF;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	else if (strcmp(arg, "magic") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_MAGIC_USER;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a magic user.\r\n");
+	  }
+	
+	else if (strcmp(arg, "cleric") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_CLERIC;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a cleric.\r\n");
+	  }
+	else if (strcmp(arg, "vampire") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_VAMPIRE_HUNTER;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a vampire hunter.\r\n");
+	  }
+	else if (strcmp(arg, "gypsy") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_GYPSY;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a gypsy.\r\n");
+	  }
+	else if (strcmp(arg, "ch'an") == 0)
+	  {
+	    GET_REMORT(ch) = GET_CLASS(ch);
+	    GET_CLASS(ch) = CLASS_CHAN;
+	    GET_REMORT_LEVEL(ch) = 1;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a ch'an.\r\n");
+	  }
+	
+	else
+	  {
+	    send_to_char(ch, "Please use 'remort <class>' \r\n");
+	  }
+      }
+    
+    else if (GET_REMORT_LEVEL(ch) == 1)
+      {
+	one_argument(argument, arg);
+	
+	if (strcmp(arg, "warrior") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_WARRIOR;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a warrior.\r\n");
+	  }
+	else if (strcmp(arg, "thief") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_THIEF;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	else if (strcmp(arg, "magic") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_MAGIC_USER;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a magic user.\r\n");
+	  }
+	else if (strcmp(arg, "cleric") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_CLERIC;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a cleric.\r\n");
+	  }
+	else if (strcmp(arg, "vampire") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_VAMPIRE_HUNTER;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a vampire hunter.\r\n");
+	  }
+	else if (strcmp(arg, "gypsy") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_GYPSY;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a gypsy.\r\n");
+	  }
+	else if (strcmp(arg, "ch'an") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 2;  /* set the remort level */
+	    GET_REMORT_TWO(ch) = GET_CLASS(ch); /* save their current class before remort */
+	    GET_CLASS(ch) = CLASS_CHAN;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	
+	else
+	  {
+	    send_to_char(ch, "Please use 'remort <class>'\r\n");
+	  }
+      }
+    
+    else if (GET_REMORT_LEVEL(ch) == 2)
+      {
+	one_argument(argument, arg);
+	
+	if (strcmp(arg, "warrior") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_WARRIOR;
+	    do_remort_start(ch);
+	    send_to_char(ch, "You are now a warrior.\r\n");
+	  }
+	else if (strcmp(arg, "thief") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_THIEF;
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	else if (strcmp(arg, "cleric") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_CLERIC;
+	    send_to_char(ch, "You are now a cleric.\r\n");
+	  }
+	else if (strcmp(arg, "magic") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_MAGIC_USER;
+	    send_to_char(ch, "You are now a magic user.\r\n");
+	  }
+	else if (strcmp(arg, "vampire") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_VAMPIRE_HUNTER;
+	    send_to_char(ch, "You are now a vampire hunter.\r\n");
+	  }
+	else if (strcmp(arg, "gypsy") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_GYPSY;
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	else if (strcmp(arg, "ch'an") == 0)
+	  {
+	    GET_REMORT_LEVEL(ch) = 3;  /* set remort level */
+	    GET_REMORT_THREE(ch) = GET_CLASS(ch);  /* save their class prior to remort */
+	    GET_CLASS(ch) = CLASS_CHAN;
+	    send_to_char(ch, "You are now a thief.\r\n");
+	  }
+	
+	else
+	  {
+	    send_to_char(ch, "Please use 'remort <class>'\r\n");
+	  }
+      } 
+    else {
+      send_to_char(ch, "You cannot remort again.\r\n");
+    }
+  }
+}
diff -BbuprN -x '*.o' circle-3.1/src/class.c circle-dev/src/class.c
--- circle-3.1/src/class.c	2004-06-28 13:23:37.000000000 -0400
+++ circle-dev/src/class.c	2004-06-29 19:56:45.000000000 -0400
@@ -40,6 +40,8 @@ int invalid_class(struct char_data *ch, 
 int level_exp(int chclass, int level);
 const char *title_male(int chclass, int level);
 const char *title_female(int chclass, int level);
+void do_remort_start(struct char_data *ch);
+     
 
 /* Names first */
 
@@ -5217,6 +5219,7 @@ void do_start(struct char_data *ch)
 {
   GET_LEVEL(ch) = 1;
   GET_EXP(ch) = 1;
+  GET_REMORT_LEVEL(ch) = 0;
 
   set_title(ch, NULL);
 /*  roll_real_abils(ch); */
@@ -6728,3 +6731,67 @@ const char *title_female(int chclass, in
   /* Default title for classes which do not have titles defined */
   return "the Classless";
 }
+
+
+/** Added by ret for remort.
+ ** This just uses the necessary stuff from do_start() but leaves some out.
+ **/
+void do_remort_start(struct char_data *ch)
+{
+
+  int sortpos;
+    
+  set_title(ch, NULL);
+  GET_EXP(ch) = 1;
+  GET_LEVEL(ch) = 1;
+  GET_MAX_HIT(ch)  = 10;
+  GET_MAX_MANA(ch) = 100;
+  GET_MAX_MOVE(ch) = 82;
+
+  for (sortpos = 1; sortpos <= MAX_SKILLS; sortpos++)
+    {
+      SET_SKILL(ch, sortpos, 0);
+    }
+  
+  switch (GET_CLASS(ch)) {
+    
+  case CLASS_MAGIC_USER:
+    break;
+    
+  case CLASS_CLERIC:
+    break;
+    
+  case CLASS_THIEF:
+    SET_SKILL(ch, SKILL_SNEAK, 10);
+    SET_SKILL(ch, SKILL_HIDE, 5);
+    SET_SKILL(ch, SKILL_STEAL, 15);
+    SET_SKILL(ch, SKILL_BACKSTAB, 10);
+    SET_SKILL(ch, SKILL_PICK_LOCK, 10);
+    SET_SKILL(ch, SKILL_TRACK, 10);
+    break;
+    
+  case CLASS_WARRIOR:
+    break;
+    
+  case CLASS_VAMPIRE_HUNTER:
+    break;
+    
+  case CLASS_GYPSY:
+    break;
+    
+  case CLASS_CHAN:
+    break;
+  }
+  
+  GET_HIT(ch) = GET_MAX_HIT(ch);
+  GET_MANA(ch) = GET_MAX_MANA(ch);
+  GET_MOVE(ch) = GET_MAX_MOVE(ch);
+  
+  GET_COND(ch, THIRST) = 24;
+  GET_COND(ch, FULL) = 24;
+  GET_COND(ch, DRUNK) = 0;
+  
+  advance_level(ch);
+
+  
+}
diff -BbuprN -x '*.o' circle-3.1/src/db.c circle-dev/src/db.c
--- circle-3.1/src/db.c	2004-06-25 23:09:50.000000000 -0400
+++ circle-dev/src/db.c	2004-06-29 15:23:38.000000000 -0400
@@ -2571,6 +2571,11 @@ void store_to_char(struct char_file_u *s
   GET_SEX(ch) = st->sex;
   GET_CLASS(ch) = st->chclass;
   GET_RACE(ch) = st->race;
+  /* add these Malcor */
+  GET_REMORT(ch) = st->was_class;
+  GET_REMORT_TWO(ch) = st->was_class1;
+  GET_REMORT_THREE(ch) = st->was_class2;
+  /* end add these */  
   GET_LEVEL(ch) = st->level;
 
   ch->player.short_descr = NULL;
@@ -2692,6 +2697,11 @@ void char_to_store(struct char_data *ch,
   st->height = GET_HEIGHT(ch);
   st->sex = GET_SEX(ch);
   st->chclass = GET_CLASS(ch);
+  /* add these Malcor */
+  st->was_class = GET_REMORT(ch);
+  st->was_class1 = GET_REMORT_TWO(ch);
+  st->was_class2 = GET_REMORT_THREE(ch);
+  /* end add these */
   st->race = GET_RACE(ch);
   st->level = GET_LEVEL(ch);
   st->abilities = ch->real_abils;
diff -BbuprN -x '*.o' circle-3.1/src/interpreter.c circle-dev/src/interpreter.c
--- circle-3.1/src/interpreter.c	2004-06-29 19:23:52.000000000 -0400
+++ circle-dev/src/interpreter.c	2004-06-29 15:52:15.000000000 -0400
@@ -146,6 +146,7 @@ ACMD(do_qcomm);
 ACMD(do_quit);
 ACMD(do_reboot);
 ACMD(do_remove);
+ACMD(do_remort);
 ACMD(do_reply);
 ACMD(do_report);
 ACMD(do_rescue);
@@ -409,6 +410,7 @@ cpp_extern const struct command_info cmd
   { "recite"   , "reci"    , POS_RESTING , do_use      , 0, SCMD_RECITE },
   { "receive"  , "rece"    , POS_STANDING, do_not_here , 1, 0 },
   { "remove"   , "rem"     , POS_RESTING , do_remove   , 0, 0 },
+  { "remort"   , "remo"        , POS_STANDING, do_remort   , 100, 0 },
   { "rent"     , "rent"    , POS_STANDING, do_not_here , 1, 0 },
   { "report"   , "repo"    , POS_RESTING , do_report   , 0, 0 },
   { "reroll"   , "rero"    , POS_DEAD    , do_wizutil  , LVL_GRGOD, SCMD_REROLL },
diff -BbuprN -x '*.o' circle-3.1/src/spec_procs.c circle-dev/src/spec_procs.c
--- circle-3.1/src/spec_procs.c	2004-06-25 23:09:50.000000000 -0400
+++ circle-dev/src/spec_procs.c	2004-06-29 19:04:41.000000000 -0400
@@ -137,7 +137,13 @@ void list_skills(struct char_data *ch)
   
   for (sortpos = 1; sortpos <= MAX_SKILLS; sortpos++) {
     i = spell_sort_info[sortpos];
-    if (GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) {
+    if ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_CLASS(ch)]) ||
+    ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_REMORT(ch)]) &&
+     (GET_REMORT_LEVEL(ch) == 1)) ||
+    ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_REMORT_TWO(ch)]) &&
+     (GET_REMORT_LEVEL(ch) == 2)) ||
+    ((GET_LEVEL(ch) >= spell_info[i].min_level[(int) GET_REMORT_THREE(ch)]) &&
+     (GET_REMORT_LEVEL(ch) == 3))){
       nlen = snprintf(buf2 + len, sizeof(buf2) - len, "%-20s %s\r\n", spell_info[i].name, how_good(GET_SKILL(ch, i)));
       if (len + nlen >= sizeof(buf2) || nlen < 0)
         break;
@@ -171,8 +177,14 @@ SPECIAL(guild)
 
   skill_num = find_skill_num(argument);
 
-  if (skill_num < 1 ||
-      GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_CLASS(ch)]) {
+  if ((skill_num < 1) ||
+      (GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_CLASS(ch)]) &&
+       ((GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_REMORT(ch)]) &&
+	(GET_REMORT_LEVEL(ch) == 1))&&
+       ((GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_REMORT_TWO(ch)]) &&
+	(GET_REMORT_LEVEL(ch) == 2))&&
+       ((GET_LEVEL(ch) < spell_info[skill_num].min_level[(int) GET_REMORT_THREE(ch)])&&
+       (GET_REMORT_LEVEL(ch) == 3))){
     send_to_char(ch, "You do not know of that %s.\r\n", SPLSKL(ch));
     return (TRUE);
   }
diff -BbuprN -x '*.o' circle-3.1/src/spell_parser.c circle-dev/src/spell_parser.c
--- circle-3.1/src/spell_parser.c	2004-06-25 23:09:50.000000000 -0400
+++ circle-dev/src/spell_parser.c	2004-06-29 19:05:18.000000000 -0400
@@ -549,7 +549,10 @@ ACMD(do_cast)
     send_to_char(ch, "Cast what?!?\r\n");
     return;
   }
-  if (GET_LEVEL(ch) < SINFO.min_level[(int) GET_CLASS(ch)]) {
+  if ((GET_LEVEL(ch) < SINFO.min_level[(int) GET_CLASS(ch)]) &&
+    (GET_LEVEL(ch) < SINFO.min_level[(int) GET_REMORT(ch)]) &&
+    (GET_LEVEL(ch) < SINFO.min_level[(int) GET_REMORT_TWO(ch)]) &&
+    (GET_LEVEL(ch) < SINFO.min_level[(int) GET_REMORT_THREE(ch)])){
     send_to_char(ch, "You do not know that spell!\r\n");
     return;
   }
diff -BbuprN -x '*.o' circle-3.1/src/structs.h circle-dev/src/structs.h
--- circle-3.1/src/structs.h	2004-06-29 19:20:12.000000000 -0400
+++ circle-dev/src/structs.h	2004-06-29 15:37:08.000000000 -0400
@@ -800,6 +800,9 @@ struct char_player_data {
    struct time_data time;  /* PC's AGE in days                 */
    ubyte weight;       /* PC / NPC's weight                    */
    ubyte height;       /* PC / NPC's height                    */
+  byte was_class;      /* PC's previous (1st) class */
+  byte was_class1;     /* PC's previous (2nd) class */
+  byte was_class2;     /* PC's previous (3rd) class */
 };
 
 
@@ -899,7 +902,7 @@ struct player_special_data_saved {
    ubyte spare5;
    int spells_to_learn;		/* How many can you learn yet this level*/
    int olc_zone;
-   int spare8;
+   int remort_level;            /* was int spare 8 */
    int spare9;
    int spare10;
    int spare11;
@@ -1016,6 +1019,9 @@ struct char_file_u {
    int	played;    /* Number of secs played in total */
    ubyte weight;
    ubyte height;
+  byte was_class;  /* first class */
+  byte was_class1; /* 2nd class */
+  byte was_class2; /* third class */
 
    char	pwd[MAX_PWD_LENGTH+1];    /* character's password */
 
diff -BbuprN -x '*.o' circle-3.1/src/utils.h circle-dev/src/utils.h
--- circle-3.1/src/utils.h	2004-06-25 23:09:50.000000000 -0400
+++ circle-dev/src/utils.h	2004-06-29 15:47:23.000000000 -0400
@@ -323,6 +323,7 @@ void	update_pos(struct char_data *victim
 #define GET_FREEZE_LEV(ch)	CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.freeze_level))
 #define GET_BAD_PWS(ch)		CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.bad_pws))
 #define GET_TALK(ch, i)		CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.talks[i]))
+#define GET_REMORT_LEVEL(ch)    CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.remort_level))
 #define POOFIN(ch)		CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->poofin))
 #define POOFOUT(ch)		CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->poofout))
 #define GET_OLC_ZONE(ch)	CHECK_PLAYER_SPECIAL((ch), ((ch)->player_specials->saved.olc_zone))
@@ -643,3 +644,9 @@ void	update_pos(struct char_data *victim
   /** Autowiz **/
 #define CONFIG_USE_AUTOWIZ      config_info.autowiz.use_autowiz
 #define CONFIG_MIN_WIZLIST_LEV  config_info.autowiz.min_wizlist_lev
+
+/** Remort stuff **/
+#define GET_REMORT(ch)           ((ch)->player.was_class)
+#define GET_REMORT_TWO(ch)       ((ch)->player.was_class1)
+#define GET_REMORT_THREE(ch)     ((ch)->player.was_class2)
+