diff -r -C 3 stone_soup-0.3.2-src-orig/docs/crawl_options.txt stone_soup-0.3.2-src/docs/crawl_options.txt
*** stone_soup-0.3.2-src-orig/docs/crawl_options.txt	Sat Nov 10 00:11:15 2007
--- stone_soup-0.3.2-src/docs/crawl_options.txt	Wed Nov 28 00:47:22 2007
***************
*** 92,97 ****
--- 92,99 ----
  
  7-  Inline Lua.
  
+ 8-  Cheating.
+ 
  --------------------------------------------------------------------------------
  
  There are three broad types of Crawl options: true/false values
***************
*** 1290,1296 ****
          Will add a note for each spell memorised.
  
  6-  Miscellaneous.
! ==============
  
  6-a     All OS.
  ---------------
--- 1292,1298 ----
          Will add a note for each spell memorised.
  
  6-  Miscellaneous.
! ==================
  
  6-a     All OS.
  ---------------
***************
*** 1495,1501 ****
  
  
  7-      Inline Lua
! ------------------
  
  Lua code can be used directly in your init.txt/.crawlrc. You can use
  Lua to selectively include parts of your init.txt (based on character
--- 1497,1503 ----
  
  
  7-      Inline Lua
! ==================
  
  Lua code can be used directly in your init.txt/.crawlrc. You can use
  Lua to selectively include parts of your init.txt (based on character
***************
*** 1525,1527 ****
--- 1527,1597 ----
  : else
  autopickup = $?+"/!%
  : end
+ 
+ 
+ 8-      Cheating
+ ================
+ 
+ Certain options are *very* contrary to the spirit of Crawl.  They
+ are available for those who want a very different (and less
+ authentically roguelike) play experience.  Setting any of them flags
+ any character you load with them in your .crawlrc as a cheater, and
+ nasty messages to that effect will be printed in all high score
+ lists and character dumps.
+ 
+ This whole set of options is disabled by default; ALLOW_CHEATING
+ must be turned on in AppHdr.h at compile time.
+ 
+ cheating_monster_freq_div = 1
+ 	If set to anything higher than 1, multiplies the frequency
+ 	of monster spawning by that amount.  It's called _div for
+ 	internal reasons.  The maximum effective value is 240, but
+ 	anything above 20 or so is likely to present an
+ 	insurmountable challenge.  Values between 1 and 20 or so
+ 	make the game easier by allowing the player to rack up far
+ 	more experience and collect more bodies for food.
+     
+ cheating_no_death = false
+ 	If set to true, the game's basic response to character death
+ 	is to restore 1 hit point, and clear some things that are
+ 	likely to instantly kill the character again (poison,
+ 	disease, starvation, and paralysis).  A much more
+ 	interesting gaming experience can be achieved by combining
+ 	this option with some of the "Cheating Death Options" below,
+ 	all of which require this option to be true to have any
+ 	effect whatsoever.
+ 
+ 8-a     Cheating Death Options
+ ------------------------------
+ 
+ cheating_death_back_to_start = false
+ 	On death, the character is returned to the beginning of the
+ 	dungeon if they are still descending.  If they've gotten the
+ 	Orb and they are in the main dungeon, the are returned to
+ 	the bottom-most level (this is *supposed* to be a penalty,
+ 	you see).  In all other cases (i.e. have the Orb but aren't
+ 	in a normal dungeon level) nothing happens.
+ 
+ cheating_death_heal = false
+ 	Fully heals the character on death.
+ 	
+ cheating_death_fill_belly = false
+ 	Fully fills the character's belly on death (i.e. character
+ 	becomes Engorged).
+ 
+ cheating_death_lose_levels = 0
+ 	The number of levels the character has drained from them as
+ 	a penalty for death.  Note that when ascending with the Orb
+ 	and with cheating_death_back_to_start turned on, this can
+ 	lead to losing the levels and then being shunted back to
+ 	level 27 of the main dungeon, which is A Bad Thing.
+ 	
+ cheating_death_lose_gold = false
+ 	All gold is lost on death.
+ 	
+ cheating_death_lose_random_items = 0
+ 	Lose this number of randomly selected items on death.
+ 
+ cheating_death_lose_wielded_item = false
+ 	Lose the weapon you are wielding (presumably one of the most
+ 	important items you have) on death.
diff -r -C 3 stone_soup-0.3.2-src-orig/source/AppHdr.h stone_soup-0.3.2-src/source/AppHdr.h
*** stone_soup-0.3.2-src-orig/source/AppHdr.h	Sat Nov 10 00:11:08 2007
--- stone_soup-0.3.2-src/source/AppHdr.h	Wed Nov 28 00:48:05 2007
***************
*** 346,353 ****
--- 346,359 ----
  // Option to allow scoring of wizard characters.  Note that even if 
  // you define this option, wizard characters are still tagged as such 
  // in the score file.
+ //
  // #define SCORE_WIZARD_CHARACTERS
  
+ // Allow cheating options.  Characters are tagged as cheaters in all
+ // dumps and scores.
+ //
+ // #define ALLOW_CHEATING
+ 
  // ================================================= --------------------------
  //jmf: New defines for a bunch of optional features.
  // ================================================= --------------------------
***************
*** 395,401 ****
      // be dumped in the current directory.
      //
      // #define SAVE_DIR_PATH       "/opt/crawl/lib/"
!     // #define SAVE_DIR_PATH       ""
  
      // Define SAVE_PACKAGE_CMD to a command to compress and bundle the save
      // game files into a single unit... the two %s will be replaced with the
--- 401,407 ----
      // be dumped in the current directory.
      //
      // #define SAVE_DIR_PATH       "/opt/crawl/lib/"
!     #define SAVE_DIR_PATH       "/usr/games/crawl/saves/"
  
      // Define SAVE_PACKAGE_CMD to a command to compress and bundle the save
      // game files into a single unit... the two %s will be replaced with the
diff -r -C 3 stone_soup-0.3.2-src-orig/source/chardump.cc stone_soup-0.3.2-src/source/chardump.cc
*** stone_soup-0.3.2-src-orig/source/chardump.cc	Sat Nov 10 00:11:06 2007
--- stone_soup-0.3.2-src/source/chardump.cc	Wed Nov 28 00:47:22 2007
***************
*** 68,73 ****
--- 68,74 ----
  
  static void sdump_header(dump_params &);
  static void sdump_stats(dump_params &);
+ static void sdump_special(dump_params &);
  static void sdump_location(dump_params &);
  static void sdump_religion(dump_params &);
  static void sdump_burden(dump_params &);
***************
*** 120,125 ****
--- 121,127 ----
  static dump_section_handler dump_handlers[] = {
      { "header",         sdump_header        },
      { "stats",          sdump_stats         },
+     { "special",        sdump_special       },
      { "location",       sdump_location      },
      { "religion",       sdump_religion      },
      { "burden",         sdump_burden        },
***************
*** 345,350 ****
--- 347,353 ----
  
  static void sdump_misc(dump_params &par)
  {
+     sdump_special(par);
      sdump_location(par);
      sdump_religion(par);
      sdump_burden(par);
***************
*** 568,573 ****
--- 571,600 ----
      text += "\n";
  }
  
+ static void sdump_special(dump_params &par)
+ {
+     if( you.wizard )
+     {
+         par.text += "You were a *WIZARD*.\n";
+     }
+ 
+ #ifdef ALLOW_CHEATING
+     if( you.cheater )
+     {
+         par.text += "You were a damned dirty *CHEATER*";
+ 	if( you.num_cheater_deaths )
+ 	{
+ 	    char tmp_quant[20];
+ 	    par.text += " who cheated death ";
+ 	    itoa( you.num_cheater_deaths, tmp_quant, 10 );
+ 	    par.text += tmp_quant;
+ 	    par.text += " time(s)";
+ 	}
+ 	par.text += ".\n";
+     }
+ #endif
+ }
+ 
   //---------------------------------------------------------------
   //
   // dump_location
diff -r -C 3 stone_soup-0.3.2-src-orig/source/externs.h stone_soup-0.3.2-src/source/externs.h
*** stone_soup-0.3.2-src-orig/source/externs.h	Sat Nov 10 00:11:09 2007
--- stone_soup-0.3.2-src/source/externs.h	Wed Nov 28 00:47:22 2007
***************
*** 645,650 ****
--- 645,654 ----
    // This field is here even in non-WIZARD compiles, since the 
    // player might have been playing previously under wiz mode.
    bool          wizard;               // true if player has entered wiz mode.
+ #ifdef ALLOW_CHEATING
+   bool          cheater;              // true if player is using cheating options
+   unsigned char num_cheater_deaths;   // number of times the (cheating) player has died
+ #endif
    time_t        birth_time;           // start time of game
  
    time_t        start_time;           // start time of session
***************
*** 824,829 ****
--- 828,837 ----
      unsigned long experience;
      int experience_level;
      bool wizard;
+ #ifdef ALLOW_CHEATING
+     bool cheater;
+     unsigned num_cheater_deaths;
+ #endif
      species_type species;
      std::string class_name;
      player_save_info operator=(const player& rhs);
***************
*** 1489,1494 ****
--- 1497,1515 ----
      int         wiz_mode;       // yes, no, never in wiz mode to start
  #endif
  
+ #ifdef ALLOW_CHEATING
+     // CHEATING OPTIONS
+     unsigned	cheating_monster_freq_div;		// Make regular dungeon monster spawning this multiple more frequent
+     bool	cheating_no_death;			// "Death" gives back 1 HP
+     bool	cheating_death_back_to_start;		// "Death" teleports you back to the beginning of the dungeon
+     bool	cheating_death_heal;			// "Death" gives back all HP
+     bool	cheating_death_fill_belly;		// "Death" removes all hunger
+     unsigned	cheating_death_lose_levels;		// "Death" strips N experience levels
+     bool	cheating_death_lose_gold;		// "Death" strips all your gold
+     unsigned	cheating_death_lose_random_items;	// "Death" strips N random items
+     bool	cheating_death_lose_wielded_item;	// "Death" strips the weapon/item you are wielding (in addition to any random items)
+ #endif
+ 
      // internal use only:
      int         sc_entries;     // # of score entries
      int         sc_format;      // Format for score entries
diff -r -C 3 stone_soup-0.3.2-src-orig/source/hiscores.cc stone_soup-0.3.2-src/source/hiscores.cc
*** stone_soup-0.3.2-src-orig/source/hiscores.cc	Sat Nov 10 00:11:05 2007
--- stone_soup-0.3.2-src/source/hiscores.cc	Wed Nov 28 00:47:22 2007
***************
*** 531,536 ****
--- 531,540 ----
      piety = se.piety;
      penance = se.penance;
      wiz_mode = se.wiz_mode;
+ #ifdef ALLOW_CHEATING
+     cheater = se.cheater;
+     num_cheater_deaths = se.num_cheater_deaths;
+ #endif
      birth_time = se.birth_time;
      death_time = se.death_time;
      real_time = se.real_time;
***************
*** 643,648 ****
--- 647,656 ----
      piety = fields->int_field("piety");
      penance = fields->int_field("pen");
      wiz_mode = fields->int_field("wiz");
+ #ifdef ALLOW_CHEATING
+     cheater = fields->int_field("cheater");
+     num_cheater_deaths = fields->int_field("num_cheater_deaths");
+ #endif
      birth_time = parse_time(fields->str_field("start"));
      death_time = parse_time(fields->str_field("end"));
      real_time  = fields->long_field("dur");
***************
*** 695,700 ****
--- 703,716 ----
      if (wiz_mode)
          fields->add_field("wiz", "%d", wiz_mode);
      
+ #ifdef ALLOW_CHEATING
+     if (cheater)
+     {
+         fields->add_field("cheater", "%d", cheater);
+         fields->add_field("num_cheater_deaths", "%d", num_cheater_deaths);
+     }
+ #endif
+     
      fields->add_field("start", "%s", make_date_string(birth_time).c_str());
      fields->add_field("dur", "%ld", real_time);
      fields->add_field("turn", "%ld", num_turns);
***************
*** 880,885 ****
--- 896,905 ----
      piety = -1;
      penance = -1;
      wiz_mode = 0;
+ #ifdef ALLOW_CHEATING
+     cheater = 0;
+     num_cheater_deaths = 0;
+ #endif
      birth_time = 0;
      death_time = 0;
      real_time = -1;
***************
*** 997,1002 ****
--- 1017,1028 ----
  #else
      wiz_mode = 0;
  #endif
+ 
+ #ifdef ALLOW_CHEATING
+     cheater = (you.cheater ? 1 : 0);
+ 
+     num_cheater_deaths = you.num_cheater_deaths;
+ #endif
  }
  
  std::string scorefile_entry::hiscore_line(death_desc_verbosity verbosity) const
***************
*** 1159,1164 ****
--- 1185,1193 ----
  std::string scorefile_entry::single_cdesc() const
  {
      std::string char_desc;
+     char cheating[20];
+ 
+     sprintf( cheating, "" );
  
      if (race_class_name.empty())
      {
***************
*** 1176,1184 ****
      if (scname.length() > 10)
          scname = scname.substr(0, 10);
  
      return make_stringf(
!              "%8ld %-10s %s-%02d%s", points, scname.c_str(),
!              char_desc.c_str(), lvl, (wiz_mode == 1) ? "W" : "" );
  }
  
  std::string
--- 1205,1226 ----
      if (scname.length() > 10)
          scname = scname.substr(0, 10);
  
+ #ifdef ALLOW_CHEATING
+     if( cheater == 1 )
+     {
+ 	if( num_cheater_deaths > 0 )
+ 	{
+ 	    sprintf( cheating, "C%dD", num_cheater_deaths);
+ 	} else {
+ 	    sprintf( cheating, "C" );
+ 	}
+     }
+ #endif
+ 
      return make_stringf(
!              "%8ld %-10s %s-%02d%s%s", points, scname.c_str(),
!              char_desc.c_str(), lvl, (wiz_mode == 1) ? "W" : "",
! 	     cheating );
  }
  
  std::string
***************
*** 1227,1233 ****
--- 1269,1291 ----
          desc += " HPs";
      }
  
+ #ifdef ALLOW_CHEATING
+     if( cheater == 1 )
+     {
+ 	char cheating[20];
+ 	if( num_cheater_deaths > 0 )
+ 	{
+ 	    sprintf( cheating, ") *CHEATER*, cheated death %d time(s)", num_cheater_deaths);
+ 	} else {
+ 	    sprintf( cheating, ") *CHEATER*" );
+ 	}
+ 	desc += cheating;
+     } else {
+ 	desc += wiz_mode? ") *WIZ*" : ")";
+     }
+ #else
      desc += wiz_mode? ") *WIZ*" : ")";
+ #endif
      desc += hiscore_newline_string();
  
      if (verbose)
diff -r -C 3 stone_soup-0.3.2-src-orig/source/hiscores.h stone_soup-0.3.2-src/source/hiscores.h
*** stone_soup-0.3.2-src-orig/source/hiscores.h	Sat Nov 10 00:11:11 2007
--- stone_soup-0.3.2-src/source/hiscores.h	Wed Nov 28 00:47:22 2007
***************
*** 115,120 ****
--- 115,124 ----
      int         piety;              // piety 
      int         penance;            // penance
      char        wiz_mode;           // character used wiz mode
+ #ifdef ALLOW_CHEATING
+     char        cheater;            // character cheated
+     char        num_cheater_deaths; // character cheated death
+ #endif
      time_t      birth_time;         // start time of character
      time_t      death_time;         // end time of character
      long        real_time;          // real playing time in seconds
diff -r -C 3 stone_soup-0.3.2-src-orig/source/initfile.cc stone_soup-0.3.2-src/source/initfile.cc
*** stone_soup-0.3.2-src-orig/source/initfile.cc	Sat Nov 10 00:11:11 2007
--- stone_soup-0.3.2-src/source/initfile.cc	Wed Nov 28 00:47:22 2007
***************
*** 733,738 ****
--- 733,751 ----
  
      no_dark_brand    = true;
  
+ #ifdef ALLOW_CHEATING
+     // CHEATING OPTIONS
+     cheating_monster_freq_div = 1;
+     cheating_no_death = false;
+     cheating_death_back_to_start = false;
+     cheating_death_heal = false;
+     cheating_death_fill_belly = false;
+     cheating_death_lose_levels = 0;
+     cheating_death_lose_gold = false;
+     cheating_death_lose_random_items = 0;
+     cheating_death_lose_wielded_item = false;
+ #endif
+ 
  #ifdef WIZARD
      wiz_mode      = WIZ_NO;
  #endif
***************
*** 2589,2594 ****
--- 2602,2653 ----
          else
              pickup_mode = read_bool_or_number(field, pickup_mode, "auto:");
      }
+ #ifdef ALLOW_CHEATING
+     // CHEATING OPTIONS
+     else if (key == "cheating_monster_freq_div") {
+         cheating_monster_freq_div = atoi( field.c_str() );
+         if (cheating_monster_freq_div < 1)
+             cheating_monster_freq_div = 1;
+         if (cheating_monster_freq_div > 240)
+             cheating_monster_freq_div = 240;
+ 	if (cheating_monster_freq_div != 1)
+ 	    you.cheater = 1;
+     }
+     else if (key == "cheating_no_death") {
+ 	cheating_no_death = read_bool(field, cheating_no_death);
+ 	if (cheating_no_death)
+ 	    you.cheater = 1;
+     }
+     // you.cheater isn't set for these next few options because
+     // none of the cheating_death options have effect unless
+     // cheating_no_death is true, and cheating_no_death sets
+     // you.cheat.
+     else if (key == "cheating_death_back_to_start") {
+ 	cheating_death_back_to_start = read_bool(field, cheating_death_back_to_start);
+     }
+     else if (key == "cheating_death_heal") {
+ 	cheating_death_heal = read_bool(field, cheating_death_heal);
+     }
+     else if (key == "cheating_death_fill_belly") {
+ 	cheating_death_fill_belly = read_bool(field, cheating_death_fill_belly);
+     }
+     else if (key == "cheating_death_lose_gold") {
+ 	cheating_death_lose_gold = read_bool(field, cheating_death_lose_gold);
+     }
+     else if (key == "cheating_death_lose_wielded_item") {
+ 	cheating_death_lose_wielded_item = read_bool(field, cheating_death_lose_wielded_item);
+     }
+     else if (key == "cheating_death_lose_levels") {
+         cheating_death_lose_levels = atoi( field.c_str() );
+         if (cheating_death_lose_levels < 0)
+             cheating_death_lose_levels = 0;
+     }
+     else if (key == "cheating_death_lose_random_items") {
+         cheating_death_lose_random_items = atoi( field.c_str() );
+         if (cheating_death_lose_random_items < 0)
+             cheating_death_lose_random_items = 0;
+     }
+ #endif
      // Catch-all else, copies option into map
      else if (runscript)
      {
diff -r -C 3 stone_soup-0.3.2-src-orig/source/makefile.dep stone_soup-0.3.2-src/source/makefile.dep
*** stone_soup-0.3.2-src-orig/source/makefile.dep	Sat Nov 10 00:15:34 2007
--- stone_soup-0.3.2-src/source/makefile.dep	Wed Nov 28 00:47:22 2007
***************
*** 309,319 ****
    describe.h files.h Kills.h hiscores.h message.h mon-pick.h travel.h \
    mutation.h place.h religion.h skills2.h spl-util.h
  ouch.o: ouch.cc AppHdr.h libunix.h libutil.h defines.h enum.h ouch.h \
!   externs.h FixAry.h FixVec.h debug.h mpr.h chardump.h delay.h files.h \
!   hiscores.h invent.h menu.h format.h itemname.h itemprop.h items.h \
!   macro.h message.h misc.h mon-util.h monstuff.h notes.h player.h \
    randart.h religion.h shopping.h skills2.h spells4.h state.h stuff.h \
!   tutorial.h view.h
  output.o: output.cc AppHdr.h libunix.h libutil.h defines.h enum.h \
    output.h format.h externs.h FixAry.h FixVec.h debug.h mpr.h abl-show.h \
    describe.h direct.h ray.h fight.h randart.h initfile.h itemname.h \
--- 309,319 ----
    describe.h files.h Kills.h hiscores.h message.h mon-pick.h travel.h \
    mutation.h place.h religion.h skills2.h spl-util.h
  ouch.o: ouch.cc AppHdr.h libunix.h libutil.h defines.h enum.h ouch.h \
!   externs.h FixAry.h FixVec.h debug.h mpr.h chardump.h delay.h food.h \
!   files.h hiscores.h invent.h menu.h format.h itemname.h itemprop.h \
!   items.h macro.h message.h misc.h mon-util.h monstuff.h notes.h player.h \
    randart.h religion.h shopping.h skills2.h spells4.h state.h stuff.h \
!   tutorial.h view.h branch.h
  output.o: output.cc AppHdr.h libunix.h libutil.h defines.h enum.h \
    output.h format.h externs.h FixAry.h FixVec.h debug.h mpr.h abl-show.h \
    describe.h direct.h ray.h fight.h randart.h initfile.h itemname.h \
diff -r -C 3 stone_soup-0.3.2-src-orig/source/monplace.cc stone_soup-0.3.2-src/source/monplace.cc
*** stone_soup-0.3.2-src-orig/source/monplace.cc	Sat Nov 10 00:11:06 2007
--- stone_soup-0.3.2-src/source/monplace.cc	Wed Nov 28 00:47:22 2007
***************
*** 188,194 ****
      // place normal dungeon monsters,  but not in player LOS
      if (you.level_type == LEVEL_DUNGEON
          && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
!         && one_chance_in((you.char_direction == GDT_DESCENDING) ? 240 : 8))
      {
          proximity_type prox = (one_chance_in(10) ? PROX_NEAR_STAIRS 
                                                   : PROX_AWAY_FROM_PLAYER);
--- 188,198 ----
      // place normal dungeon monsters,  but not in player LOS
      if (you.level_type == LEVEL_DUNGEON
          && !player_in_branch( BRANCH_ECUMENICAL_TEMPLE )
! #ifdef ALLOW_CHEATING
!         && one_chance_in((you.char_direction == GDT_DESCENDING) ? (240 / Options.cheating_monster_freq_div) : 8))
! #else
!         && one_chance_in((you.char_direction == GDT_DESCENDING) ? (240) : 8))
! #endif
      {
          proximity_type prox = (one_chance_in(10) ? PROX_NEAR_STAIRS 
                                                   : PROX_AWAY_FROM_PLAYER);
diff -r -C 3 stone_soup-0.3.2-src-orig/source/ouch.cc stone_soup-0.3.2-src/source/ouch.cc
*** stone_soup-0.3.2-src-orig/source/ouch.cc	Sat Nov 10 00:11:07 2007
--- stone_soup-0.3.2-src/source/ouch.cc	Thu Nov 29 14:53:34 2007
***************
*** 53,61 ****
--- 53,63 ----
  
  #include "externs.h"
  
+ #include "branch.h"
  #include "chardump.h"
  #include "delay.h"
  #include "files.h"
+ #include "food.h"
  #include "hiscores.h"
  #include "invent.h"
  #include "itemname.h"
***************
*** 810,820 ****
          } // else hp <= 0
      }
  
- #ifdef WIZARD
      if (death_type != KILLED_BY_QUITTING 
          && death_type != KILLED_BY_WINNING
          && death_type != KILLED_BY_LEAVING)
      {
          if (you.wizard)
          {
  #ifdef USE_OPTIONAL_WIZARD_DEATH
--- 812,985 ----
          } // else hp <= 0
      }
  
      if (death_type != KILLED_BY_QUITTING 
          && death_type != KILLED_BY_WINNING
          && death_type != KILLED_BY_LEAVING)
      {
+ #ifdef ALLOW_CHEATING
+ 	// CHEATING options; death cheating, in particular.
+ 	if( you.cheater && Options.cheating_no_death )
+ 	{
+ 	    int old_level = you.your_level;
+ 
+ 	    mpr( "Your being a damned dirty cheater protects you from death!", MSGCH_DANGER );
+ 	    // Increment the deaths count.
+ 	    you.num_cheater_deaths++;
+ 
+ 	    // Give enough HP to be alive
+ 	    if( you.hp <= 0 )
+ 	    {
+ 		set_hp(1, false);
+ 	    }
+ 	    // Temporary enough-to-stay-alive stat bonuses 
+ 	    while( you.strength <= 0 )
+ 	    {
+ 		you.strength++;
+ 		you.redraw_strength = 1;
+ 	    }
+ 	    while( you.dex <= 0 )
+ 	    {
+ 		you.dex++;
+ 		you.redraw_dexterity = 1;
+ 	    }
+ 	    while( you.intel <= 0 )
+ 	    {
+ 		you.intel++;
+ 		you.redraw_intelligence = 1;
+ 	    }
+ 	    // Give enough levels/XP to be alive
+ 	    if( you.experience < 0 )
+ 	    {
+ 		you.experience = 0;
+ 		you.experience_level = 1;
+ 	    }
+ 	    // This shouldn't actually happen, by the way
+ 	    if( you.experience_level < 1 )
+ 	    {
+ 		you.experience = 0;
+ 		you.experience_level = 1;
+ 	    }
+ 	    // Don't be completely starving
+ 	    if( you.hunger < 2000 )
+ 	    {
+ 		set_hunger( 2000, true );
+ 	    }
+ 
+ 	    // Clear things likely to kill the player instantly
+ 	    reduce_poison_player( 1000 );
+ 	    if( you.disease )
+ 	    {
+ 		you.disease=1;
+ 		dec_disease_player();
+ 	    }
+ 	    if ( you.duration[DUR_PARALYSIS] > 0 )
+ 	    {
+ 		you.duration[DUR_PARALYSIS]=0;
+ 		mpr( "You can move again.", MSGCH_DURATION);
+ 	    }
+ 
+ 	    if( Options.cheating_death_heal )
+ 	    {
+ 		mpr( "Your being a damned dirty cheater restores your hit points!", MSGCH_DANGER );
+ 		set_hp(you.hp_max, false);
+ 	    }
+ 
+ 	    if( Options.cheating_death_fill_belly )
+ 	    {
+ 		mpr( "Your being a damned dirty cheater fills your belly!", MSGCH_DANGER );
+ 		set_hunger( 12000, true );
+ 	    }
+ 
+ 	    if( Options.cheating_death_lose_gold )
+ 	    {
+ 		mpr( "As a penalty for cheating death, you lose all your gold!", MSGCH_DANGER );
+ 		you.gold = 0;
+ 		you.redraw_gold = 1;
+ 	    }
+ 
+ 	    if( Options.cheating_death_lose_wielded_item && you.equip[EQ_WEAPON] != -1 )
+ 	    {
+ 		mprf( MSGCH_DANGER, "As a penalty for cheating death, you lose your weapon, %s!", (you.inv[you.equip[EQ_WEAPON]]).name(DESC_NOCAP_A).c_str() );
+ 		dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
+ 	    }
+ 
+ 	    for( unsigned i = 1; i <= Options.cheating_death_lose_levels; i++ )
+ 	    {
+ 		// Have to add a bit to deal with the grape jelly
+ 		// ouch in lose_levels
+ 		inc_hp( 4, true );
+ 
+ 		// Can't go below 1, because that would kill us
+ 		// again, which would bring us back here...
+ 		if( you.experience_level <= 1 )
+ 		{
+ 		    if( you.experience > 0 )
+ 		    {
+ 			mpr( "As a penalty for cheating death, you lose experience!", MSGCH_DANGER );
+ 		    }
+ 		    you.experience = 0;
+ 		    you.experience_level = 1;
+ 		}
+ 		if( you.experience_level >= 2 )
+ 		{
+ 		    mpr( "As a penalty for cheating death, you lose a level of experience!", MSGCH_DANGER );
+ 		    lose_level();
+ 		}
+ 
+ 		// Take back the free stuff
+ 		dec_max_hp(4);
+ 		dec_hp(4, false, NULL);
+ 	    }
+ 
+ 	    for( unsigned i = 1; i <= Options.cheating_death_lose_random_items; i++ )
+ 	    {
+ 		// Count the items, select a random number in that
+ 		// range, then find that item and destroy it
+ 		int num_items = inv_count();
+ 		int delete_item = random2(num_items);
+ 		int which_item = 0;
+ 
+ 		for (int j = 0; j < ENDOFPACK; ++j)
+ 		{
+ 		    if( is_valid_item(you.inv[j]) )
+ 			which_item++;
+ 		    if( which_item == delete_item )
+ 		    {
+ 			//mprf("You drop %s.", quant_name(you.inv[i], delay.parm2, DESC_NOCAP_A).c_str());
+ 			mprf( MSGCH_DANGER, "As a penalty for cheating death, you lose %s!", you.inv[j].name(DESC_NOCAP_A).c_str() );
+ 		    }
+ 		}
+ 	    }
+ 
+ 	    // Normal characters go back to the start
+ 	    if( Options.cheating_death_back_to_start && you.char_direction != GDT_ASCENDING )
+ 	    {
+ 		mpr( "As a penalty (sort of) for cheating death, you are returned to the start of the dungeon!", MSGCH_DANGER );
+ 		you.level_type = LEVEL_DUNGEON;
+ 		you.where_are_you = BRANCH_MAIN_DUNGEON;
+ 		you.your_level = -1;
+ 		down_stairs( old_level, DNGN_STONE_STAIRS_DOWN_I );
+ 	    }
+ 	    // Characters on their way up go back to the end
+ 	    if( Options.cheating_death_back_to_start && you.char_direction == GDT_ASCENDING )
+ 	    {
+ 		// -1 so we go down to the last level, -1 because
+ 		// the main dungeon counts from 0
+ 		you.level_type = LEVEL_DUNGEON;
+ 		you.where_are_you = BRANCH_MAIN_DUNGEON;
+ 		you.your_level = (your_branch().depth - 2);
+ 		magic_mapping(1000, 100, true, true);
+ 		mpr( "As a penalty for cheating death, you are returned to end of the dungeon!", MSGCH_DANGER );
+ 		down_stairs( old_level, DNGN_STONE_STAIRS_DOWN_I );
+ 	    }
+ 
+ 	    more();
+ 
+ 	    return;
+ 	}
+ #endif
+ 
+ #ifdef WIZARD
          if (you.wizard)
          {
  #ifdef USE_OPTIONAL_WIZARD_DEATH
***************
*** 836,843 ****
              return;
  #endif  // USE_OPTIONAL_WIZARD_DEATH
          }
-     }
  #endif  // WIZARD
  
      //okay, so you're dead:
  
--- 1001,1008 ----
              return;
  #endif  // USE_OPTIONAL_WIZARD_DEATH
          }
  #endif  // WIZARD
+     }
  
      //okay, so you're dead:
  
diff -r -C 3 stone_soup-0.3.2-src-orig/source/player.cc stone_soup-0.3.2-src/source/player.cc
*** stone_soup-0.3.2-src-orig/source/player.cc	Sat Nov 10 00:11:09 2007
--- stone_soup-0.3.2-src/source/player.cc	Wed Nov 28 00:47:22 2007
***************
*** 4840,4845 ****
--- 4840,4850 ----
      wizard = false;
  #endif
  
+ #ifdef ALLOW_CHEATING
+     cheater = false;
+     num_cheater_deaths = 0;
+ #endif
+ 
      your_name[0] = 0;
  
      banished = false;
***************
*** 4990,4995 ****
--- 4995,5004 ----
      experience = rhs.experience;
      experience_level = rhs.experience_level;
      wizard = rhs.wizard;
+ #ifdef ALLOW_CHEATING
+     cheater = rhs.cheater;
+     num_cheater_deaths = rhs.num_cheater_deaths;
+ #endif
      species = rhs.species;
      class_name = rhs.class_name;
      return *this;
***************
*** 5013,5018 ****
--- 5022,5035 ----
          desc << " (WIZ)";
  #endif
  
+ #ifdef ALLOW_CHEATING
+     if (cheater)
+ 	desc << " (CHEATER)";
+     if (num_cheater_deaths)
+ 	desc << " (has died " << num_cheater_deaths << " times)";
+ #endif
+ 
+ 
      return desc.str();
  }
  
diff -r -C 3 stone_soup-0.3.2-src-orig/source/tags.cc stone_soup-0.3.2-src/source/tags.cc
*** stone_soup-0.3.2-src-orig/source/tags.cc	Sat Nov 10 00:11:13 2007
--- stone_soup-0.3.2-src/source/tags.cc	Wed Nov 28 00:47:22 2007
***************
*** 912,917 ****
--- 912,921 ----
  
      marshallLong( th, you.real_time );
      marshallLong( th, you.num_turns );
+ #ifdef ALLOW_CHEATING
+     marshallByte( th, you.cheater );
+     marshallByte( th, you.num_cheater_deaths );
+ #endif
  
      marshallShort(th, you.magic_contamination);
  
***************
*** 1252,1257 ****
--- 1256,1265 ----
  
      you.real_time = unmarshallLong(th);
      you.num_turns = unmarshallLong(th);
+ #ifdef ALLOW_CHEATING
+     you.cheater = unmarshallByte(th);
+     you.num_cheater_deaths = unmarshallByte(th);
+ #endif
  
      you.magic_contamination = unmarshallShort(th);
  
