diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Arch.des nethack/dat/Arch.des
--- nh_orig/dat/Arch.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Arch.des	2010-04-29 10:53:24.165721489 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Arc-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Arc-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (80,'S'), (16,"human mummy"), (4,'M')
 GEOMETRY:center,center
 MAP
@@ -23,5 +25,5 @@
 ....................}|.|...............|.......+.|.......|}.................
 ....................}|.|...............---------.---------}.................
-....................}|.S.\.............+.................+..................
+....................}|.S...............+.................+..................
 ....................}|.|...............---------.---------}.................
 ....................}|.|...............|.......+.|.......|}.................
@@ -69,23 +71,46 @@
 DOOR:locked,(49,14)
 # Lord Carnarvon
-MONSTER:'@',"Lord Carnarvon",(25,10)
+OBJECT:('\',"throne"),(25,10)
+MONSTER:('@',"Lord Carnarvon"),(25,10) {
+  OBJECT:('[',"fedora"),+5
+  OBJECT:')',+4
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+}
 # The treasure of Lord Carnarvon
-OBJECT:'(',"chest",(25,10)
+OBJECT:('(',"chest"),(25,10)
 # student guards for the audience chamber
-MONSTER:'@',"student",(26,09)
-MONSTER:'@',"student",(27,09)
-MONSTER:'@',"student",(28,09)
-MONSTER:'@',"student",(26,10)
-MONSTER:'@',"student",(28,10)
-MONSTER:'@',"student",(26,11)
-MONSTER:'@',"student",(27,11)
-MONSTER:'@',"student",(28,11)
+MONSTER:('@',"student"),(26,09) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(27,09) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(28,09) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(26,10) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(28,10) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(26,11) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(27,11) {
+  OBJECT:random
+}
+MONSTER:('@',"student"),(28,11) {
+  OBJECT:random
+}
 # city watch guards in the antechambers
-MONSTER:'@',"watchman",(50,06)
-MONSTER:'@',"watchman",(50,14)
+MONSTER:('@',"watchman"),(50,06)
+MONSTER:('@',"watchman"),(50,14)
 # Eels in the moat
-MONSTER:';',"giant eel",(20,10)
-MONSTER:';',"giant eel",(45,04)
-MONSTER:';',"giant eel",(33,16)
+MONSTER:(';',"giant eel"),(20,10)
+MONSTER:(';',"giant eel"),(45,04)
+MONSTER:(';',"giant eel"),(33,16)
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
@@ -98,16 +123,16 @@
 TRAP:random,random
 # Monsters on siege duty.
-MONSTER: 'S',random,(60,09)
-MONSTER: 'M',random,(60,10)
-MONSTER: 'S',random,(60,11)
-MONSTER: 'S',random,(60,12)
-MONSTER: 'M',random,(60,13)
-MONSTER: 'S',random,(61,10)
-MONSTER: 'S',random,(61,11)
-MONSTER: 'S',random,(61,12)
-MONSTER: 'S',random,(30,03)
-MONSTER: 'M',random,(20,17)
-MONSTER: 'S',random,(67,02)
-MONSTER: 'S',random,(10,19)
+MONSTER: 'S',(60,09)
+MONSTER: 'M',(60,10)
+MONSTER: 'S',(60,11)
+MONSTER: 'S',(60,12)
+MONSTER: 'M',(60,13)
+MONSTER: 'S',(61,10)
+MONSTER: 'S',(61,11)
+MONSTER: 'S',(61,12)
+MONSTER: 'S',(30,03)
+MONSTER: 'M',(20,17)
+MONSTER: 'S',(67,02)
+MONSTER: 'S',(10,19)
 
 #
@@ -118,6 +143,8 @@
 #
 
-MAZE: "Arc-loca",' '
-FLAGS: hardfloor
+LEVEL: "Arc-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (80,'S'), (16,"human mummy"), (4,'M')
 GEOMETRY:center,center
 MAP
@@ -185,19 +212,19 @@
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Treasure?
 ENGRAVING:random,engrave,"X marks the spot."
@@ -230,31 +257,31 @@
 TRAP:"rolling boulder",(40,16)
 # Random monsters.
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'M',random,random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',random,random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'M',random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:'M',random
 
 #
@@ -266,5 +293,8 @@
 #
 
-MAZE: "Arc-goal", ' '
+LEVEL: "Arc-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (80,'S'), (16,"human mummy"), (4,'M')
 GEOMETRY:center,center
 MAP
@@ -322,19 +352,19 @@
 ALTAR:(50,14),chaos,altar
 # Objects
-OBJECT:'(',"crystal ball",(50,14),blessed,5,"The Orb of Detection"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"crystal ball"),(50,14),blessed,5,NAME:"The Orb of Detection"
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Random traps
 TRAP:random,random
@@ -346,32 +376,37 @@
 TRAP:"rolling boulder",(46,14)
 # Random monsters.
-MONSTER:'&',"Minion of Huhetotl",(50,14)
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'S',random,random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',"human mummy",random
-MONSTER:'M',random,random
+MONSTER:('&',"Minion of Huhetotl"),(50,14) {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:random,cursed
+  OBJECT:random,cursed
+  OBJECT:random,cursed
+}
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:('M',"human mummy"),random
+MONSTER:'M',random
 
 #
@@ -385,76 +420,102 @@
 
 LEVEL: "Arc-fila"
+MON_GENERATION:86%, (80,'S'), (16,"human mummy"), (4,'M')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'S', random, random
+OBJECT: random,random
+MONSTER: 'S', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'S', random, random
+{
+OBJECT: random, random
+OBJECT: random, random
+MONSTER: 'S', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'S', random, random
+OBJECT: random, random
+MONSTER: 'S', random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
-MONSTER: 'M', "human mummy", random
+MONSTER: 'S', random
+MONSTER: ('M', "human mummy"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
+MONSTER: 'S', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
+MONSTER: 'S', random
+}
 
 RANDOM_CORRIDORS
 
 LEVEL: "Arc-filb"
+MON_GENERATION:86%, (80,'S'), (16,"human mummy"), (4,'M')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'M', random, random
+OBJECT: random,random
+MONSTER: 'M', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'M', random, random
+{
+OBJECT: random, random
+OBJECT: random, random
+MONSTER: 'M', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'M', random, random
+OBJECT: random,random
+MONSTER: 'M', random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
-MONSTER: 'M', "human mummy", random
+MONSTER: 'S', random
+MONSTER: ('M', "human mummy"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
+MONSTER: 'S', random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'S', random, random
+MONSTER: 'S', random
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Barb.des nethack/dat/Barb.des
--- nh_orig/dat/Barb.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Barb.des	2010-08-16 13:20:13.632708508 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Bar-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Bar-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"ogre"), (16,'O'), (16,"troll"), (4,'T')
 GEOMETRY:center,center
 MAP
@@ -19,7 +21,7 @@
 ........--------------......-----....PPP....................................
 ........|...S........|......+...|...PPP.....................................
-........|----........|......|...|....PP.....................................
-........|.\..........+......-----...........................................
-........|----........|...............PP.....................................
+........|----........|......|...|...PPP.....................................
+........|............+......-----....PP.....................................
+........|----........|..............PPP.....................................
 ........|...S........|...-----.......PPP....................................
 ........--------------...+...|......PPPPP...................................
@@ -34,4 +36,13 @@
 ....................................PP....PP................................
 ENDMAP
+
+# the forest beyond the river
+REPLACE_TERRAIN:(37,0,75,19),'.','T', 10%
+REPLACE_TERRAIN:(60,0,75,19),'.','T', 20%
+REPLACE_TERRAIN:(65,0,75,19),'.','T', 40%
+REPLACE_TERRAIN:(70,0,75,19),'.','T', 80%
+TERRAIN: (randline (37,7)-(62,02),7), '.'
+TERRAIN:(62,02),'.'
+
 # Dungeon Description
 REGION:(00,00,75,19),lit,"ordinary"
@@ -59,36 +70,61 @@
 DOOR:open,(28,05)
 # Elder
-MONSTER:'@',"Pelias",(10,07)
+OBJECT:('\',"throne"),(10,07)
+MONSTER:('@',"Pelias"),(10,07) {
+  OBJECT:(')',"runesword"),1d5
+  OBJECT:'[',1d5
+}
 # The treasure of Pelias
-OBJECT:'(',"chest",(09,05)
+OBJECT:('(',"chest"),(09,05)
 # chieftain guards for the audience chamber
-MONSTER:'@',"chieftain",(10,05)
-MONSTER:'@',"chieftain",(10,09)
-MONSTER:'@',"chieftain",(11,05)
-MONSTER:'@',"chieftain",(11,09)
-MONSTER:'@',"chieftain",(14,05)
-MONSTER:'@',"chieftain",(14,09)
-MONSTER:'@',"chieftain",(16,05)
-MONSTER:'@',"chieftain",(16,09)
+MONSTER:('@',"chieftain"),(10,05) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(10,09) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(11,05) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(11,09) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(14,05) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(14,09) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(16,05) {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"chieftain"),(16,09) {
+  OBJECT:')'
+  OBJECT:'['
+}
 # Non diggable walls
-NON_DIGGABLE:(00,00,75,19)
+NON_DIGGABLE:(00,00,35,19)
 # One trap to keep the ogres at bay.
 TRAP:"spiked pit",(37,07)
 # Eels in the river
-MONSTER:';',"giant eel",(36,01)
-MONSTER:';',"giant eel",(37,09)
-MONSTER:';',"giant eel",(39,15)
+MONSTER:(';',"giant eel"),(36,01)
+MONSTER:(';',"giant eel"),(37,09)
+MONSTER:(';',"giant eel"),(39,15)
 # Monsters on siege duty.
-MONSTER:'O',"ogre",(40,08),hostile
-MONSTER:'O',"ogre",(41,06),hostile
-MONSTER:'O',"ogre",(41,07),hostile
-MONSTER:'O',"ogre",(41,08),hostile
-MONSTER:'O',"ogre",(41,09),hostile
-MONSTER:'O',"ogre",(41,10),hostile
-MONSTER:'O',"ogre",(42,06),hostile
-MONSTER:'O',"ogre",(42,07),hostile
-MONSTER:'O',"ogre",(42,08),hostile
-MONSTER:'O',"ogre",(42,09),hostile
-MONSTER:'O',"ogre",(42,10),hostile
+REGION:(40,0,50,19),lit,"ordinary",unfilled {
+  LOOP [10 + 1d15] {
+    MONSTER:('O',"ogre"),random,hostile
+  }
+}
+
+# to cut down the trees
+OBJECT:"axe",random,eroded:1d3
 
 #
@@ -99,6 +135,8 @@
 #
 
-MAZE: "Bar-loca",' '
-FLAGS: hardfloor
+LEVEL: "Bar-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"ogre"), (16,'O'), (16,"troll"), (4,'T')
 GEOMETRY:center,center
 MAP
@@ -147,19 +185,19 @@
 STAIR:(70,13),down
 # Objects
-OBJECT:random,random,(42,03)
-OBJECT:random,random,(42,03)
-OBJECT:random,random,(42,03)
-OBJECT:random,random,(41,03)
-OBJECT:random,random,(41,03)
-OBJECT:random,random,(41,03)
-OBJECT:random,random,(41,03)
-OBJECT:random,random,(41,08)
-OBJECT:random,random,(41,08)
-OBJECT:random,random,(42,08)
-OBJECT:random,random,(42,08)
-OBJECT:random,random,(42,08)
-OBJECT:random,random,(71,13)
-OBJECT:random,random,(71,13)
-OBJECT:random,random,(71,13)
+OBJECT:random,(42,03)
+OBJECT:random,(42,03)
+OBJECT:random,(42,03)
+OBJECT:random,(41,03)
+OBJECT:random,(41,03)
+OBJECT:random,(41,03)
+OBJECT:random,(41,03)
+OBJECT:random,(41,08)
+OBJECT:random,(41,08)
+OBJECT:random,(42,08)
+OBJECT:random,(42,08)
+OBJECT:random,(42,08)
+OBJECT:random,(71,13)
+OBJECT:random,(71,13)
+OBJECT:random,(71,13)
 # Random traps
 TRAP:"spiked pit",(10,13)
@@ -172,31 +210,31 @@
 TRAP:random,random
 # Random monsters.
-MONSTER:'O',"ogre",(12,09),hostile
-MONSTER:'O',"ogre",(18,11),hostile
-MONSTER:'O',"ogre",(45,05),hostile
-MONSTER:'O',"ogre",(45,06),hostile
-MONSTER:'O',"ogre",(47,05),hostile
-MONSTER:'O',"ogre",(46,05),hostile
-MONSTER:'O',"ogre",(56,03),hostile
-MONSTER:'O',"ogre",(56,04),hostile
-MONSTER:'O',"ogre",(56,05),hostile
-MONSTER:'O',"ogre",(56,06),hostile
-MONSTER:'O',"ogre",(57,03),hostile
-MONSTER:'O',"ogre",(57,04),hostile
-MONSTER:'O',"ogre",(57,05),hostile
-MONSTER:'O',"ogre",(57,06),hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',random,random,hostile
-MONSTER:'T',random,random,hostile
-MONSTER:'T',"rock troll",(46,06),hostile
-MONSTER:'T',"rock troll",(47,06),hostile
-MONSTER:'T',"rock troll",(56,07),hostile
-MONSTER:'T',"rock troll",(57,07),hostile
-MONSTER:'T',"rock troll",(70,13),hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',random,random,hostile
+MONSTER:('O',"ogre"),(12,09),hostile
+MONSTER:('O',"ogre"),(18,11),hostile
+MONSTER:('O',"ogre"),(45,05),hostile
+MONSTER:('O',"ogre"),(45,06),hostile
+MONSTER:('O',"ogre"),(47,05),hostile
+MONSTER:('O',"ogre"),(46,05),hostile
+REGION:(56,03,57,04),unlit,"ordinary",unfilled,true {
+  LOOP [5 + 2d6] {
+    MONSTER:('O',"ogre"),random,hostile
+  }
+}
+
+LOOP [1d8 + 2] {
+  MONSTER:('O',"ogre"),random,hostile
+}
+MONSTER:'O',random,hostile
+MONSTER:'T',random,hostile
+REGION:(46,06,47,07),unlit,"ordinary",unfilled,true {
+  LOOP [1d8 + 2] {
+    MONSTER:('T',"rock troll"),random,hostile
+  }
+}
+
+LOOP [2 + 1d6] {
+  MONSTER:('T',"rock troll"),random,hostile
+}
+MONSTER:'T',random,hostile
 
 #
@@ -208,5 +246,8 @@
 #
 
-MAZE: "Bar-goal", ' '
+LEVEL: "Bar-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"ogre"), (16,'O'), (16,"troll"), (4,'T')
 GEOMETRY:center,center
 MAP
@@ -243,55 +284,33 @@
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:'*',"luckstone",(63,04),blessed,0,"The Heart of Ahriman"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-# Random traps
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+OBJECT:('*',"luckstone"),(63,04),blessed,0,NAME:"The Heart of Ahriman"
+#
+LOOP [5 + 2d6] {
+  OBJECT: random, random
+}
+#
+LOOP [5 + 1d6] {
 TRAP:random,random
+}
+#
 # Random monsters.
-MONSTER:'@',"Thoth Amon",(63,04),hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',"ogre",random,hostile
-MONSTER:'O',random,random,hostile
-MONSTER:'O',random,random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',"rock troll",random,hostile
-MONSTER:'T',random,random,hostile
+MONSTER:('@',"Thoth Amon"),(63,04),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:')',1d2
+  OBJECT:'['
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+}
+
+LOOP [15 + 2d6] {
+  MONSTER:('O',"ogre"),random,hostile
+}
+MONSTER:'O',random,hostile
+MONSTER:'O',random,hostile
+LOOP [7 + 1d6] {
+  MONSTER:('T',"rock troll"),random,hostile
+}
+MONSTER:'T',random,hostile
 WALLIFY
 
@@ -305,6 +324,8 @@
 #
 
-MAZE: "Bar-fila" , ' '
-INIT_MAP: '.' , '.' , true , true , unlit , false
+LEVEL: "Bar-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , '.' , true , true , unlit , false
+MON_GENERATION:86%, (64,"ogre"), (16,'O'), (16,"troll"), (4,'T')
 NOMAP
 #
@@ -312,25 +333,24 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 2d6] {
+  OBJECT: random, random
+}
 #
+LOOP [2 + 1d6] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', random, random, hostile
-MONSTER: 'T', "rock troll", random, hostile
+LOOP [1d6] {
+  MONSTER: ('O', "ogre"), random, hostile
+}
+MONSTER: 'O', random, hostile
+LOOP [1d3] {
+  MONSTER: ('T', "rock troll"), random, hostile
+}
 
-MAZE: "Bar-filb" , ' '
-INIT_MAP: '.' , ' ' , true , true , unlit , true
+LEVEL: "Bar-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ' , true , true , unlit , true
+MON_GENERATION:86%, (64,"ogre"), (16,'O'), (16,"troll"), (4,'T')
 NOMAP
 #
@@ -338,31 +358,18 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 2d6] {
+  OBJECT: random, random
+}
 #
+LOOP [2 + 1d6] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', "ogre", random, hostile
-MONSTER: 'O', random , random, hostile
-MONSTER: 'T', "rock troll", random, hostile
-MONSTER: 'T', "rock troll", random, hostile
-MONSTER: 'T', "rock troll", random, hostile
-MONSTER: 'T', random , random, hostile
+LOOP [5 + 1d6] {
+  MONSTER: ('O', "ogre"), random, hostile
+}
+MONSTER: 'O', random, hostile
+LOOP [2 + 1d3] {
+  MONSTER: ('T', "rock troll"), random, hostile
+}
+MONSTER: 'T', random, hostile
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/bigroom.des nethack/dat/bigroom.des
--- nh_orig/dat/bigroom.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/bigroom.des	2010-05-13 09:22:22.244762620 -0400
@@ -7,5 +7,7 @@
 #
 
-MAZE:"bigrm-1",' '
+LEVEL:"bigrm-1"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -29,4 +31,21 @@
 ---------------------------------------------------------------------------
 ENDMAP
+
+$terrains = TERRAIN:{'-', 'F', 'L', 'T', 'C'}
+SHUFFLE:$terrains
+
+IF [75%] {
+   TERRAIN:line (10,8)-(38, 8), $terrains[0]
+   TERRAIN:line (37,8)-(65, 8), $terrains[0]
+   TERRAIN:line (37,3)-(37, 8), $terrains[0]
+   TERRAIN:line (37,8)-(37,14), $terrains[0]
+} ELSE {
+   IF [99%] {
+      TERRAIN:rect (4,4,70,13), $terrains[0]
+      TERRAIN:line (25, 4)-(50, 4), '.'
+      TERRAIN:line (25,13)-(50,13), '.'
+   }
+}
+
 # Dungeon Description
 REGION:(01,01,73,16),lit,"ordinary"
@@ -37,59 +56,21 @@
 NON_DIGGABLE:(00,00,74,17)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [15] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+LOOP [28] {
+  MONSTER:random,random
+}
 
 #	Here, just play with the lighting...
 
-MAZE:"bigrm-2",' '
+LEVEL:"bigrm-2"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -114,13 +95,30 @@
 ENDMAP
 # Dungeon Description
-REGION:(01,01,23,06),lit,"ordinary"
-REGION:(01,07,23,10),unlit,"ordinary"
-REGION:(01,11,23,16),lit,"ordinary"
-REGION:(24,01,50,06),unlit,"ordinary"
-REGION:(24,07,50,10),lit,"ordinary"
-REGION:(24,11,50,16),unlit,"ordinary"
-REGION:(51,01,73,06),lit,"ordinary"
-REGION:(51,07,73,10),unlit,"ordinary"
-REGION:(51,11,73,16),lit,"ordinary"
+REGION:(01,01,73,16),lit,"ordinary"
+
+IF [50%] {
+  REGION:(00,07,23,10),unlit,"ordinary"
+  REGION:(24,00,50,06),unlit,"ordinary"
+  REGION:(24,11,50,17),unlit,"ordinary"
+  REGION:(51,07,74,10),unlit,"ordinary"
+} ELSE {
+  REGION:(24,00,50,17),unlit,"ordinary"
+}
+
+IF [40%] {
+   $terrain = TERRAIN:{ 'L', '}', 'I' }
+   SHUFFLE:$terrain
+   TERRAIN: (randline random-random,20), $terrain[0]
+   IF [50%] {
+      TERRAIN: (randline random-random,25), $terrain[0]
+   }
+   IF [50%] {
+      TERRAIN: grow(north|west, randline random-random,25), $terrain[0]
+   }
+   IF [25%] {
+      TERRAIN: grow(randline random-random,25), $terrain[0]
+   }
+}
+
 # Stairs
 STAIR:random,up
@@ -129,59 +127,21 @@
 NON_DIGGABLE:(00,00,74,17)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [15] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+LOOP [28] {
+  MONSTER:random,random
+}
 
 #	Now, let's get fancy...
 
-MAZE:"bigrm-3",' '
+LEVEL:"bigrm-3"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -205,4 +165,18 @@
 ---------------------------------------------------------------------------
 ENDMAP
+
+IF [30%] {
+   $outside = TERRAIN:{ 'L', 'T', '}', 'C' }
+   SHUFFLE: $outside
+   REPLACE_TERRAIN:(6,5, 68,11),'-',$outside[0],100%
+   REPLACE_TERRAIN:(6,5, 68,11),'|',$outside[0],100%
+   REPLACE_TERRAIN:(6,5, 68,11),' ',$outside[0],100%
+}
+
+IF [50%] {
+   REPLACE_TERRAIN:(1, 1, 73, 1),'|','F',100%
+   REPLACE_TERRAIN:(1,16, 73,16),'|','F',100%
+}
+
 # Dungeon Description
 REGION:(01,01,73,16),lit,"ordinary"
@@ -213,56 +187,44 @@
 NON_DIGGABLE:(00,00,74,17)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [15] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:random,random,(01,01)
-MONSTER:random,random,(13,01)
-MONSTER:random,random,(25,01)
-MONSTER:random,random,(37,01)
-MONSTER:random,random,(49,01)
-MONSTER:random,random,(61,01)
-MONSTER:random,random,(73,01)
-MONSTER:random,random,(07,07)
-MONSTER:random,random,(13,07)
-MONSTER:random,random,(25,07)
-MONSTER:random,random,(37,07)
-MONSTER:random,random,(49,07)
-MONSTER:random,random,(61,07)
-MONSTER:random,random,(67,07)
-MONSTER:random,random,(07,09)
-MONSTER:random,random,(13,09)
-MONSTER:random,random,(25,09)
-MONSTER:random,random,(37,09)
-MONSTER:random,random,(49,09)
-MONSTER:random,random,(61,09)
-MONSTER:random,random,(67,09)
-MONSTER:random,random,(01,16)
-MONSTER:random,random,(13,16)
-MONSTER:random,random,(25,16)
-MONSTER:random,random,(37,16)
-MONSTER:random,random,(49,16)
-MONSTER:random,random,(61,16)
-MONSTER:random,random,(73,16)
-MAZE:"bigrm-4",' '
+MONSTER:random,(01,01)
+MONSTER:random,(13,01)
+MONSTER:random,(25,01)
+MONSTER:random,(37,01)
+MONSTER:random,(49,01)
+MONSTER:random,(61,01)
+MONSTER:random,(73,01)
+MONSTER:random,(07,07)
+MONSTER:random,(13,07)
+MONSTER:random,(25,07)
+MONSTER:random,(37,07)
+MONSTER:random,(49,07)
+MONSTER:random,(61,07)
+MONSTER:random,(67,07)
+MONSTER:random,(07,09)
+MONSTER:random,(13,09)
+MONSTER:random,(25,09)
+MONSTER:random,(37,09)
+MONSTER:random,(49,09)
+MONSTER:random,(61,09)
+MONSTER:random,(67,09)
+MONSTER:random,(01,16)
+MONSTER:random,(13,16)
+MONSTER:random,(25,16)
+MONSTER:random,(37,16)
+MONSTER:random,(49,16)
+MONSTER:random,(61,16)
+MONSTER:random,(73,16)
+
+LEVEL:"bigrm-4"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -286,4 +248,18 @@
 -----------                                                     -----------
 ENDMAP
+
+$corners = selection: (05,02) & (05,15) & (69,02) & (69,15)
+$terrain = TERRAIN:{ 'L', 'T', '{', '.' }
+SHUFFLE:$terrain
+TERRAIN:$corners, $terrain[0]
+
+IF [30%] {
+   $outside = TERRAIN:{ 'L', 'T', '}' }
+   SHUFFLE: $outside
+   REPLACE_TERRAIN:(0,0, 74,17),'-',$outside[0],100%
+   REPLACE_TERRAIN:(0,0, 74,17),'|',$outside[0],100%
+   REPLACE_TERRAIN:(0,0, 74,17),' ',$outside[0],100%
+}
+
 # Dungeon Description
 REGION:(01,01,73,16),lit,"ordinary"
@@ -293,65 +269,22 @@
 # Non diggable walls
 NON_DIGGABLE:(00,00,74,17)
-# Fountains
-FOUNTAIN:(05,02)
-FOUNTAIN:(05,15)
-FOUNTAIN:(69,02)
-FOUNTAIN:(69,15)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [15] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+LOOP [28] {
+  MONSTER:random,random
+}
 
 #	Try an oval room...
 
-MAZE:"bigrm-5",' '
+LEVEL:"bigrm-5"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -378,4 +311,16 @@
 # Dungeon Description
 REGION:(00,00,72,18),lit,"ordinary"
+
+IF [33%] {
+   $terrain = TERRAIN:{ 'L', '}' }
+   SHUFFLE:$terrain
+   IF [50%] {
+      TERRAIN: grow(north|west, randline (37,0)-(37,18),20), $terrain[0]
+   } ELSE {
+      TERRAIN: grow(north|west, randline (0,10)-(73,10),20), $terrain[0]
+   }
+}
+
+
 # Stairs
 STAIR:random,up
@@ -383,54 +328,346 @@
 # Non diggable walls
 NON_DIGGABLE:(00,00,72,18)
-# Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-# Random traps
+
+LOOP [15] {
+  OBJECT:random,random
+}
+
+LOOP [6] {
 TRAP:random,random
+}
+
+LOOP [28] {
+  MONSTER:random,random
+}
+
+
+# The Four Circles
+
+LEVEL:"bigrm-6"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+MAP
+     ---------         ---------         ---------         ---------     
+   ---.......---     ---.......---     ---.......---     ---.......---   
+  --...........--   --...........--   --...........--   --...........--  
+ --.............-- --.............-- --.............-- --.............-- 
+ -...............- -...............- -...............- -...............- 
+|-...............---...............---...............---...............--
+|.................-.................-.................-.................|
+|........T.................T.................T.................T........|
+|.......................................................................|
+|......T.{.....................................................{.T......|
+|.......................................................................|
+|........T.................T.................T.................T........|
+|.................-.................-.................-.................|
+--...............---...............---...............---...............--
+ -...............- -...............- -...............- -...............- 
+ --.............-- --.............-- --.............-- --.............-- 
+  --...........--   --...........--   --...........--   --...........--  
+   ---.......---     ---.......---     ---.......---     ---.......---   
+     ---------         ---------         ---------         ---------     
+ENDMAP
+
+IF [20%] {
+  REPLACE_TERRAIN:(00,00,73,18),'T','{',100%
+}
+
+IF [20%] {
+  REPLACE_TERRAIN:(00,00,73,18),'-','T',100%
+  REPLACE_TERRAIN:(00,00,73,18),'|','T',100%
+}
+
+# Dungeon Description
+REGION:(01,01,72,17),lit,"ordinary"
+# Stairs
+STAIR:random,up
+STAIR:random,down
+# Non diggable walls
+NON_DIGGABLE:(00,00,72,18)
+
+LOOP [15] {
+  OBJECT:random,random
+}
+
+LOOP [6] {
 TRAP:random,random
+}
+
+LOOP [28] {
+  MONSTER:random,random
+}
+
+
+# Let's tilt it a bit
+
+LEVEL:"bigrm-7"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+MAP
+                                                        -----              
+                                                ---------...---            
+                                        ---------.........L...---          
+                                ---------.......................---        
+                        ---------.................................---      
+                ---------...........................................---    
+        ---------.....................................................---  
+|--------...............................................................--|
+|.........................................................................|
+|.L.....................................................................L.|
+|.........................................................................|
+|--...............................................................--------|
+  ---.....................................................---------        
+    ---...........................................---------                
+      ---.................................---------                        
+        ---.......................---------                                
+          ---...L.........---------                                        
+            ---...---------                                                
+              -----                                                        
+ENDMAP
+
+$terrain = TERRAIN:{ 'L', 'T', '{', '.' }
+SHUFFLE:$terrain
+REPLACE_TERRAIN:(00,00,74,18),'L',$terrain[0],100%
+
+# Dungeon Description
+REGION:(01,01,73,17),lit,"ordinary"
+# Stairs
+STAIR:random,up
+STAIR:random,down
+# Non diggable walls
+NON_DIGGABLE:(00,00,74,18)
+
+LOOP [15] {
+  OBJECT:random,random
+}
+
+LOOP [6] {
 TRAP:random,random
+}
+
+LOOP [28] {
+  MONSTER:random,random
+}
+
+
+# Two streams
+
+LEVEL:"bigrm-8"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+MAP
+        |------------------------       -------------------------        
+        |.......................|       |.......................|        
+        |.......................|       |................}}.....|        
+|-------|......}}}}.............|--------.....}}.}.....}}}}.....--------|
+|}}}......}}..}}}}}}..........}}}..........}}}..}.....}....}.}}..}}}}}}}|
+|}}}....}}.}}}.....}....}}...}...}}}....}.}...........}.....}}.}}....}}}|
+|}}}}}}}............}}}}..}}}.......}}}}}}}............}..............}}|
+|}}}}}...............}}...............}}...}............}...........}}}}|
+|-------|.......................|--------...}.........}}}.......--------|
+        |.......................|       |...}}......}}.}........|        
+|--------........LLLL....LL.....--------|....}}...}}............|-------|
+|LLL..........LLL.........LLL......LLL........}.}}}}.......LLL.........L|
+|LLLL........LLL.............L...LL..LLLLLL....}}.}.....LLL...LLL....LLL|
+|LLLLLLLL..LLL.LLLLLL.........LLL......LLLLL.........LLLL........LLLLLLL|
+|LLLLLL..LLL........LLL...LLLL............LLLLL..LLLL.LLLLL........LLLLL|
+|--------..............LLL......--------|.....LLL....LLLLLL.....|-------|
+        |.......................|       |...............LL......|        
+        |.......................|       |.......................|        
+        -------------------------       -------------------------        
+ENDMAP
+
+IF [40%] {
+   $terrain_from = TERRAIN:{ 'L', '}', 'I' }
+   $terrain_to   = TERRAIN:{ 'L', '}', 'I', '.' }
+   SHUFFLE:$terrain_from
+   SHUFFLE:$terrain_to
+   REPLACE_TERRAIN:(0,0,75,18),$terrain_from[0], $terrain_to[0], 100%
+   IF [50%] {
+      REPLACE_TERRAIN:(0,0,75,18),$terrain_from[1], $terrain_to[1], 100%
+   }
+}
+
+# Dungeon Description
+REGION:(01,01,72,17),lit,"ordinary"
+# Stairs
+STAIR:random,up
+STAIR:random,down
+#
+# Non diggable walls
+NON_DIGGABLE:(00,00,72,18)
+
+LOOP [15] {
+  OBJECT:random,random
+}
+
+LOOP [6] {
 TRAP:random,random
+}
+
+LOOP [28] {
+  MONSTER:random,random
+}
+
+
+# Slanted
+
+LEVEL:"bigrm-9"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+MAP
+----------------------------------------------                             
+|............................................---                           
+--.............................................---                         
+ ---......................................FF.....---                       
+   ---...................................FF........---                     
+     ---................................FF...........---                   
+       ---.............................FF..............---                 
+         ---..........................FF.................---               
+           ---.......................FF....................---             
+             ---....................FF.......................---           
+               ---.................FF..........................---         
+                 ---..............FF.............................---       
+                   ---...........FF................................----    
+                     ---........FF...................................---   
+                       ---.....FF......................................--- 
+                         ---.............................................--
+                           ---............................................|
+                             ----------------------------------------------
+ENDMAP
+
+IF [40%] {
+   $terrain = TERRAIN:{ 'L', '}', 'T', '.', '-', 'C' }
+   SHUFFLE:$terrain
+   REPLACE_TERRAIN:(0,0,74,17),'F', $terrain[0], 100%
+}
+
+# Dungeon Description
+REGION:(01,01,73,16),lit,"ordinary"
+# Stairs
+STAIR:random,up
+STAIR:random,down
+# Non diggable walls
+NON_DIGGABLE:(00,00,74,17)
+
+LOOP [15] {
+  OBJECT:random,random
+}
+
+LOOP [6] {
 TRAP:random,random
+}
+
+LOOP [28] {
+  MONSTER:random,random
+}
+
+# The Eye
+
+LEVEL:"bigrm-10"
+INIT_MAP:solidfill,'}'
+GEOMETRY:center,center
+MAP
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}................}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}................................}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}............................................}}}}}}}}}}}}}}}
+}}}}}}}}}}......................................................}}}}}}}}}}
+}}}}}}}............................................................}}}}}}}
+}}}}}.......................LLLLLLLLLLLLLLLLLL.......................}}}}}
+}}}....................LLLLLLLLLLLLLLLLLLLLLLLLLLL.....................}}}
+}....................LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL....................}
+}....................LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL....................}
+}....................LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL....................}
+}}}....................LLLLLLLLLLLLLLLLLLLLLLLLLLL.....................}}}
+}}}}}.......................LLLLLLLLLLLLLLLLLL.......................}}}}}
+}}}}}}}............................................................}}}}}}}
+}}}}}}}}}}......................................................}}}}}}}}}}
+}}}}}}}}}}}}}}}............................................}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}................................}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}................}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+ENDMAP
+
+IF [33%] {
+    REPLACE_TERRAIN:(0,0,73,18), 'L', 'T', 100%
+    REPLACE_TERRAIN:(0,0,73,18), 'T', '.', 75%
+}
+
+# Unlit, except 3 mapgrids around the "pupil"
+REGION:(00,00,73,18),unlit,"ordinary"
+REGION:(26,04,47,14),lit,"ordinary"
+REGION:(21,05,51,13),lit,"ordinary"
+REGION:(19,06,54,12),lit,"ordinary"
+# Stairs
+STAIR:random,up
+STAIR:random,down
+
+LOOP [15] {
+  OBJECT:random,random
+}
+LOOP [6] {
 TRAP:random,random
-# Random monsters.
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+}
+LOOP [28] {
+  MONSTER:random,random
+}
+
+
+# Fog Maze
+
+LEVEL:"bigrm-11"
+GEOMETRY:center,center
+MAP
+.......................................................................
+.......................................................................
+.......................................................................
+.......................................................................
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC...
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC...
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC...
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC...
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+...CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC...
+...C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C...
+.......................................................................
+.......................................................................
+.......................................................................
+.......................................................................
+ENDMAP
+
+IF [33%] {
+   # occasionally it's not a fog maze
+   $terrain = TERRAIN:{ 'L', '}', 'T', '-', 'F' }
+   SHUFFLE:$terrain
+   REPLACE_TERRAIN:(0,0,70,18),'C', $terrain[0], 100%
+}
+
+REGION:(00,00,70,18),lit,"ordinary"
+
+# when falling down on this level, never end up in the fog maze
+TELEPORT_REGION:(00,00,70,18),(02,03,68,15),down
+
+# Stairs up, not in the fog maze
+STAIR:(00,00,70,18),(02,03,68,15),up
+STAIR:random,down
+
+LOOP [15] {
+  OBJECT:random,random
+}
+LOOP [6] {
+  TRAP:random,random
+}
+LOOP [28] {
+  MONSTER:random,random
+}
+
+MAZEWALK:(4, 2), south
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/castle.des nethack/dat/castle.des
--- nh_orig/dat/castle.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/castle.des	2010-04-11 12:36:58.157750620 -0400
@@ -16,7 +16,11 @@
 # To motivate the player : there are 4 storerooms (armors, weapons, food and
 # gems) and a wand of wishing in one of the 4 towers...
+#
+# Castle level explicitly marked as graveyard to prevent getting
+# too many wraith corpses from VotD
 
-MAZE:"castle",random
-FLAGS: noteleport
+LEVEL:"castle"
+FLAGS: noteleport,mazelevel,graveyard
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -25,13 +29,13 @@
 }|.....|-----------------------------------------------|.....|}
 }|.....+...............................................+.....|}
-}-------------------------------+-----------------------------}
-}}}}}}|........|..........+...........|.......S.S.......|}}}}}}
+}-FFF---------------------------+-------------------------FFF-}
+}}}}}}|........|..........+...........|.......|.|.......|}}}}}}
 .....}|........|..........|...........|.......|.|.......|}.....
 .....}|........------------...........---------S---------}.....
-.....}|...{....+..........+.........\.S.................+......
+.....}|...{....+..........+...........S.................+......
 .....}|........------------...........---------S---------}.....
 .....}|........|..........|...........|.......|.|.......|}.....
-}}}}}}|........|..........+...........|.......S.S.......|}}}}}}
-}-------------------------------+-----------------------------}
+}}}}}}|........|..........+...........|.......|.|.......|}}}}}}
+}-FFF---------------------------+-------------------------FFF-}
 }|.....+...............................................+.....|}
 }|.....|-----------------------------------------------|.....|}
@@ -40,20 +44,41 @@
 ENDMAP
 
+# Treasure room 1
+$place = { (46,05),(44,07),(38,06),(40,04) }
+SHUFFLE: $place
+TERRAIN:$place[0],'S'
+# Treasure room 2
+$place = { (48,05),(54,07),(51,04) }
+SHUFFLE: $place
+TERRAIN:$place[0],'S'
+# Treasure room 3
+$place = { (46,11),(44,12),(38,11),(40,09) }
+SHUFFLE: $place
+TERRAIN:$place[0],'S'
+# Treasure room 4
+$place = { (48,11),(54,09),(51,12) }
+SHUFFLE: $place
+TERRAIN:$place[0],'S'
+
 # Random registers initialisation
-RANDOM_OBJECTS:'[',')','*','%'
-RANDOM_PLACES:(04,02),(58,02),(04,14),(58,14)
-RANDOM_MONSTERS:'L','N','E','H','M','O','R','T','X','Z'
+$object = OBJECT: { '[',')','*','%' }
+$place = { (04,02),(58,02),(04,14),(58,14) }
+$monster = MONSTER:{ 'L','N','E','H','M','O','R','T','X','Z' }
+SHUFFLE: $place
+SHUFFLE: $object
+SHUFFLE: $monster
 
 TELEPORT_REGION:levregion(01,00,10,20),(1,1,61,15),down
-TELEPORT_REGION:levregion(69,00,79,20),(1,1,61,15),up
+TELEPORT_REGION:levregion(69,00,77,20),(1,1,61,15),up
 STAIR:levregion(01,00,10,20),(0,0,62,16),up
+BRANCH:levregion(69,00,77,20),(1,1,61,15)
 FOUNTAIN:(10,08)
 # Doors
-DOOR:closed,(07,03)
-DOOR:closed,(55,03)
+DOOR:locked,(07,03)
+DOOR:locked,(55,03)
 DOOR:locked,(32,04)
 DOOR:locked,(26,05)
-DOOR:locked,(46,05)
-DOOR:locked,(48,05)
+# DOOR:locked,(46,05)
+# DOOR:locked,(48,05)
 DOOR:locked,(47,07)
 DOOR:closed,(15,08)
@@ -63,78 +88,95 @@
 DOOR:locked,(47,09)
 DOOR:locked,(26,11)
-DOOR:locked,(46,11)
-DOOR:locked,(48,11)
+# DOOR:locked,(46,11)
+# DOOR:locked,(48,11)
 DOOR:locked,(32,12)
-DOOR:closed,(07,13)
-DOOR:closed,(55,13)
+DOOR:locked,(07,13)
+DOOR:locked,(55,13)
 # The drawbridge
 DRAWBRIDGE:(05,08),east,closed
 # Storeroom number 1
-OBJECT:object[0],random,(39,05)
-OBJECT:object[0],random,(40,05)
-OBJECT:object[0],random,(41,05)
-OBJECT:object[0],random,(42,05)
-OBJECT:object[0],random,(43,05)
-OBJECT:object[0],random,(44,05)
-OBJECT:object[0],random,(45,05)
-OBJECT:object[0],random,(39,06)
-OBJECT:object[0],random,(40,06)
-OBJECT:object[0],random,(41,06)
-OBJECT:object[0],random,(42,06)
-OBJECT:object[0],random,(43,06)
-OBJECT:object[0],random,(44,06)
-OBJECT:object[0],random,(45,06)
+OBJECT:$object[0],(39,05)
+OBJECT:$object[0],(40,05)
+OBJECT:$object[0],(41,05)
+OBJECT:$object[0],(42,05)
+OBJECT:$object[0],(43,05)
+OBJECT:$object[0],(44,05)
+OBJECT:$object[0],(45,05)
+OBJECT:$object[0],(39,06)
+OBJECT:$object[0],(40,06)
+OBJECT:$object[0],(41,06)
+OBJECT:$object[0],(42,06)
+OBJECT:$object[0],(43,06)
+OBJECT:$object[0],(44,06)
+OBJECT:$object[0],(45,06)
 # Storeroom number 2
-OBJECT:object[1],random,(49,05)
-OBJECT:object[1],random,(50,05)
-OBJECT:object[1],random,(51,05)
-OBJECT:object[1],random,(52,05)
-OBJECT:object[1],random,(53,05)
-OBJECT:object[1],random,(54,05)
-OBJECT:object[1],random,(55,05)
-OBJECT:object[1],random,(49,06)
-OBJECT:object[1],random,(50,06)
-OBJECT:object[1],random,(51,06)
-OBJECT:object[1],random,(52,06)
-OBJECT:object[1],random,(53,06)
-OBJECT:object[1],random,(54,06)
-OBJECT:object[1],random,(55,06)
+OBJECT:$object[1],(49,05)
+OBJECT:$object[1],(50,05)
+OBJECT:$object[1],(51,05)
+OBJECT:$object[1],(52,05)
+OBJECT:$object[1],(53,05)
+OBJECT:$object[1],(54,05)
+OBJECT:$object[1],(55,05)
+OBJECT:$object[1],(49,06)
+OBJECT:$object[1],(50,06)
+OBJECT:$object[1],(51,06)
+OBJECT:$object[1],(52,06)
+OBJECT:$object[1],(53,06)
+OBJECT:$object[1],(54,06)
+OBJECT:$object[1],(55,06)
 # Storeroom number 3
-OBJECT:object[2],random,(39,10)
-OBJECT:object[2],random,(40,10)
-OBJECT:object[2],random,(41,10)
-OBJECT:object[2],random,(42,10)
-OBJECT:object[2],random,(43,10)
-OBJECT:object[2],random,(44,10)
-OBJECT:object[2],random,(45,10)
-OBJECT:object[2],random,(39,11)
-OBJECT:object[2],random,(40,11)
-OBJECT:object[2],random,(41,11)
-OBJECT:object[2],random,(42,11)
-OBJECT:object[2],random,(43,11)
-OBJECT:object[2],random,(44,11)
-OBJECT:object[2],random,(45,11)
+OBJECT:$object[2],(39,10)
+OBJECT:$object[2],(40,10)
+OBJECT:$object[2],(41,10)
+OBJECT:$object[2],(42,10)
+OBJECT:$object[2],(43,10)
+OBJECT:$object[2],(44,10)
+OBJECT:$object[2],(45,10)
+OBJECT:$object[2],(39,11)
+OBJECT:$object[2],(40,11)
+OBJECT:$object[2],(41,11)
+OBJECT:$object[2],(42,11)
+OBJECT:$object[2],(43,11)
+OBJECT:$object[2],(44,11)
+OBJECT:$object[2],(45,11)
 # Storeroom number 4
-OBJECT:object[3],random,(49,10)
-OBJECT:object[3],random,(50,10)
-OBJECT:object[3],random,(51,10)
-OBJECT:object[3],random,(52,10)
-OBJECT:object[3],random,(53,10)
-OBJECT:object[3],random,(54,10)
-OBJECT:object[3],random,(55,10)
-OBJECT:object[3],random,(49,11)
-OBJECT:object[3],random,(50,11)
-OBJECT:object[3],random,(51,11)
-OBJECT:object[3],random,(52,11)
-OBJECT:object[3],random,(53,11)
-OBJECT:object[3],random,(54,11)
-OBJECT:object[3],random,(55,11)
+OBJECT:$object[3],(49,10)
+OBJECT:$object[3],(50,10)
+OBJECT:$object[3],(51,10)
+OBJECT:$object[3],(52,10)
+OBJECT:$object[3],(53,10)
+OBJECT:$object[3],(54,10)
+OBJECT:$object[3],(55,10)
+OBJECT:$object[3],(49,11)
+OBJECT:$object[3],(50,11)
+OBJECT:$object[3],(51,11)
+OBJECT:$object[3],(52,11)
+OBJECT:$object[3],(53,11)
+OBJECT:$object[3],(54,11)
+OBJECT:$object[3],(55,11)
 # THE WAND OF WISHING in 1 of the 4 towers
-CONTAINER:'(',"chest",place[0]
-OBJECT:'/',"wishing",contained
-# Prevent monsters from eating it.  (@'s never eat objects)
-ENGRAVING:place[0],burn,"Elbereth"
+CONTAINER:('(',"chest"),$place[0] {
+  OBJECT:('/',"wishing")
+}
+# THE NOT QUITE WANDS OF WISHING
+# ...since you can see the chest now through the bars,
+# we have to find a better way to disguise where the wand is
+CONTAINER:('(',"chest"),$place[1] {
+  OBJECT:('/',"secret door detection")
+}
+CONTAINER:('(',"chest"),$place[2] {
+  OBJECT:'/'
+}
+CONTAINER:('(',"chest"),$place[3] {
+  OBJECT:'/'
+}
+# Prevent monsters from eating them.  (@'s never eat objects)
+ENGRAVING:$place[0],burn,"Elbereth"
+ENGRAVING:$place[1],burn,"Elbereth"
+ENGRAVING:$place[2],burn,"Elbereth"
+ENGRAVING:$place[3],burn,"Elbereth"
 # The treasure of the lord
-OBJECT:'(',"chest",(37,08)
+OBJECT:('(',"chest"),(37,08)
+OBJECT:('\',"throne"),(36,08)
 # Traps
 TRAP:"trap door",(40,08)
@@ -144,64 +186,36 @@
 TRAP:"trap door",(55,08)
 # Soldiers guarding the entry hall
-MONSTER:'@',"soldier",(08,06)
-MONSTER:'@',"soldier",(09,05)
-MONSTER:'@',"soldier",(11,05)
-MONSTER:'@',"soldier",(12,06)
-MONSTER:'@',"soldier",(08,10)
-MONSTER:'@',"soldier",(09,11)
-MONSTER:'@',"soldier",(11,11)
-MONSTER:'@',"soldier",(12,10)
-MONSTER:'@',"lieutenant",(09,08)
+MONSTER:('@',"soldier"),(08,06)
+MONSTER:('@',"soldier"),(09,05)
+MONSTER:('@',"soldier"),(11,05)
+MONSTER:('@',"soldier"),(12,06)
+MONSTER:('@',"soldier"),(08,10)
+MONSTER:('@',"soldier"),(09,11)
+MONSTER:('@',"soldier"),(11,11)
+MONSTER:('@',"soldier"),(12,10)
+MONSTER:('@',"lieutenant"),(09,08)
 # Soldiers guarding the towers
-MONSTER:'@',"soldier",(03,02)
-MONSTER:'@',"soldier",(05,02)
-MONSTER:'@',"soldier",(57,02)
-MONSTER:'@',"soldier",(59,02)
-MONSTER:'@',"soldier",(03,14)
-MONSTER:'@',"soldier",(05,14)
-MONSTER:'@',"soldier",(57,14)
-MONSTER:'@',"soldier",(59,14)
+MONSTER:('@',"sergeant"),(03,02)
+MONSTER:('@',"sergeant"),(05,02)
+MONSTER:('@',"sergeant"),(57,02)
+MONSTER:('@',"sergeant"),(59,02)
+MONSTER:('@',"sergeant"),(03,14)
+MONSTER:('@',"sergeant"),(05,14)
+MONSTER:('@',"sergeant"),(57,14)
+MONSTER:('@',"sergeant"),(59,14)
 # The four dragons that are guarding the storerooms
-MONSTER:'D',random,(47,05)
-MONSTER:'D',random,(47,06)
-MONSTER:'D',random,(47,10)
-MONSTER:'D',random,(47,11)
+MONSTER:'D',(47,05)
+MONSTER:'D',(47,06)
+MONSTER:'D',(47,10)
+MONSTER:'D',(47,11)
 # Sea monsters in the moat
-MONSTER:';',"giant eel",(05,07)
-MONSTER:';',"giant eel",(05,09)
-MONSTER:';',"giant eel",(57,07)
-MONSTER:';',"giant eel",(57,09)
-MONSTER:';',"shark",(05,00)
-MONSTER:';',"shark",(05,16)
-MONSTER:';',"shark",(57,00)
-MONSTER:';',"shark",(57,16)
-# The throne room and the court monsters
-MONSTER:monster[0],random,(27,05)
-MONSTER:monster[1],random,(30,05)
-MONSTER:monster[2],random,(33,05)
-MONSTER:monster[3],random,(36,05)
-MONSTER:monster[4],random,(28,06)
-MONSTER:monster[5],random,(31,06)
-MONSTER:monster[6],random,(34,06)
-MONSTER:monster[7],random,(37,06)
-MONSTER:monster[8],random,(27,07)
-MONSTER:monster[9],random,(30,07)
-MONSTER:monster[0],random,(33,07)
-MONSTER:monster[1],random,(36,07)
-MONSTER:monster[2],random,(28,08)
-MONSTER:monster[3],random,(31,08)
-MONSTER:monster[4],random,(34,08)
-MONSTER:monster[5],random,(27,09)
-MONSTER:monster[6],random,(30,09)
-MONSTER:monster[7],random,(33,09)
-MONSTER:monster[8],random,(36,09)
-MONSTER:monster[9],random,(28,10)
-MONSTER:monster[0],random,(31,10)
-MONSTER:monster[1],random,(34,10)
-MONSTER:monster[2],random,(37,10)
-MONSTER:monster[3],random,(27,11)
-MONSTER:monster[4],random,(30,11)
-MONSTER:monster[5],random,(33,11)
-MONSTER:monster[6],random,(36,11)
+MONSTER:(';',"giant eel"),(05,07)
+MONSTER:(';',"giant eel"),(05,09)
+MONSTER:(';',"giant eel"),(57,07)
+MONSTER:(';',"giant eel"),(57,09)
+MONSTER:(';',"shark"),(05,00)
+MONSTER:(';',"shark"),(05,16)
+MONSTER:(';',"shark"),(57,00)
+MONSTER:(';',"shark"),(57,16)
 # MazeWalks
 MAZEWALK:(00,10),west
@@ -216,5 +230,34 @@
 REGION:(57,05,62,11),lit,"ordinary"
 #   Throne room
-REGION:(27,05,37,11),lit,"throne",unfilled
+REGION:(27,05,37,11),lit,"throne",unfilled {
+  # the court monsters
+  MONSTER:$monster[0],random
+  MONSTER:$monster[1],random
+  MONSTER:$monster[2],random
+  MONSTER:$monster[3],random
+  MONSTER:$monster[4],random
+  MONSTER:$monster[5],random
+  MONSTER:$monster[6],random
+  MONSTER:$monster[7],random
+  MONSTER:$monster[8],random
+  MONSTER:$monster[9],random
+  MONSTER:$monster[0],random
+  MONSTER:$monster[1],random
+  MONSTER:$monster[2],random
+  MONSTER:$monster[3],random
+  MONSTER:$monster[4],random
+  MONSTER:$monster[5],random
+  MONSTER:$monster[6],random
+  MONSTER:$monster[7],random
+  MONSTER:$monster[8],random
+  MONSTER:$monster[9],random
+  MONSTER:$monster[0],random
+  MONSTER:$monster[1],random
+  MONSTER:$monster[2],random
+  MONSTER:$monster[3],random
+  MONSTER:$monster[4],random
+  MONSTER:$monster[5],random
+  MONSTER:$monster[6],random
+}
 #   Antechamber
 REGION:(07,05,14,11),lit,"ordinary"
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Caveman.des nethack/dat/Caveman.des
--- nh_orig/dat/Caveman.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Caveman.des	2010-08-16 13:20:13.634708200 -0400
@@ -9,29 +9,40 @@
 #	and receive your quest assignment.
 #
-MAZE: "Cav-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Cav-strt"
+FLAGS: noteleport,hardfloor,arboreal,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"tiger"), (16,'S'), (16,"ape"), (4,'f')
 GEOMETRY:center,center
 MAP
                                                                             
-  ......     ..........................       ...        ....  ......       
- ......       ..........................     ........       ....    .....   
-  ..BB      .............................    .........            ....  ..  
-     ..    ......................              .......      ..     ....  .. 
-     ..     ....................                     ..  .......    ..  ... 
-   ..              S   BB                .....     .......   ....      .... 
-    ..        ...  .   ..               ........  ..     ..   ..       ...  
-     ..      ......     ..             ............       ..          ...   
-       .      ....       ..             ........           ..  ...........  
-  ...   ..     ..        .............                  ................... 
- .....   .....            ...............................      ...........  
-  .....B................            ...                               ...   
-  .....     .  ..........        .... .      ...  ..........           ...  
-   ...     ..          .............  ..    ...................        .... 
-          BB       ..   .........      BB    ...  ..........  ..   ...  ... 
-       ......    .....  B          ........         ..         .. ....  ... 
-     ..........  ..........         ..... ...      .....        ........    
-       ..  ...    .  .....         ....    ..       ...            ..       
+  ......     ..........................       ... PP   P ....  ...... P     
+ ......       ..........................     .......P    PP .... PP .....P  
+  ..BB      ............................    P...P P...P      .P  P....  ..  
+     ..    ......................             P.......P  PP .. P  P....P .. 
+     ..  P BB...................         PP          ..  .......P  P.. P... 
+   ...   ...B      B                     ..... P  P....... PP....   PP .... 
+    ..P P.    ...  .  ...               ...P....P ..  PP ..   .. P     P..  
+     ..  .P  .......  ....            P...PPP...... P    PPPP P    PP ...   
+  PPP .. .    ....   ... . PP  P      P ........  P   P  P ..  ...........  
+  ... P...     ..   .... .B...........P  PP  PP  PP P  P.........PP........ 
+ .....  P.....             ..............................  PP  ...........P 
+P .PP..B..........PPP...   P  PPP   ... P P PPP  P  P PP     P  PPP   ...   
+  .....  PP .  ..........PP  PPP ....P.PP    ...  .......... PP       P...  
+  P...P    ..    PPP   .............  ..   P.........PPPP......     P P.... 
+          BB            .........PP    BB    ...  .....P....P .. PP... P... 
+       ......    .....  B     PP    .......   P PP P.. PPP   PP.. .P..  ... 
+     ..........  ..........        ...... ..      P.....   P    .........P  
+       ..  ...    .  .....         ....    ..       ...P       P   ..  P    
                                                                             
 ENDMAP
+
+REPLACE_TERRAIN:(40,1, 74,18), 'P', ' ', 25%
+REPLACE_TERRAIN:(40,1, 74,18), 'P', '.', 5%
+
+IF [90%] {
+   TERRAIN:(43,11),' '
+   TERRAIN:(40,10),'.'
+}
+
 # Dungeon Description
 REGION:(00,00,75,19),unlit,"ordinary"
@@ -43,49 +54,74 @@
 REGION:(05,17,14,18),lit,"ordinary",unfilled,true
 REGION:(17,16,23,18),lit,"ordinary",unfilled,true
-REGION:(35,16,44,18),lit,"ordinary",unfilled,true
+REGION:(37,16,44,18),lit,"ordinary",unfilled,true
 # Stairs
-STAIR:(02,03),down
+LADDER:(02,03),down
 # Portal arrival point
 BRANCH:(71,09,71,09),(0,0,0,0)
-# Doors
-DOOR:locked,(19,06)
 # The temple altar (this will force a priest(ess) to be created)
 ALTAR:(36,02),coaligned,shrine
 # Shaman Karnov
-MONSTER:'@',"Shaman Karnov",(35,02)
+MONSTER:('@',"Shaman Karnov"),(35,02) {
+  OBJECT:'[',1d6
+  OBJECT:')',1d6
+}
 # The treasure of Shaman Karnov
-OBJECT:'(',"chest",(34,02)
+OBJECT:('(',"chest"),(34,02)
 # neanderthal guards for the audience chamber
-MONSTER:'@',"neanderthal",(20,03)
-MONSTER:'@',"neanderthal",(20,02)
-MONSTER:'@',"neanderthal",(20,01)
-MONSTER:'@',"neanderthal",(21,03)
-MONSTER:'@',"neanderthal",(21,02)
-MONSTER:'@',"neanderthal",(21,01)
-MONSTER:'@',"neanderthal",(22,01)
-MONSTER:'@',"neanderthal",(26,09)
+MONSTER:('@',"neanderthal"),(20,03) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(20,02) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(20,01) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(21,03) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(21,02) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(21,01) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(22,01) {
+  OBJECT:')'
+}
+MONSTER:('@',"neanderthal"),(24,08) {
+  OBJECT:')'
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Random traps
-TRAP:"pit",(47,11)
-TRAP:"pit",(57,10)
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-# Monsters on siege duty (in the outer caves).
-MONSTER: 'h',"bugbear",(47,02),hostile
-MONSTER: 'h',"bugbear",(48,03),hostile
-MONSTER: 'h',"bugbear",(49,04),hostile
-MONSTER: 'h',"bugbear",(67,03),hostile
-MONSTER: 'h',"bugbear",(69,04),hostile
-MONSTER: 'h',"bugbear",(51,13),hostile
-MONSTER: 'h',"bugbear",(53,14),hostile
-MONSTER: 'h',"bugbear",(55,15),hostile
-MONSTER: 'h',"bugbear",(63,10),hostile
-MONSTER: 'h',"bugbear",(65,09),hostile
-MONSTER: 'h',"bugbear",(67,10),hostile
-MONSTER: 'h',"bugbear",(69,11),hostile
-WALLIFY
+TRAP:"pit",random
+TRAP:"pit",random
+TRAP:"pit",random
+TRAP:"spiked pit",random
+TRAP:"spiked pit",random
+TRAP:"spiked pit",random
+TRAP:"bear",(19,13)
+TRAP:"bear",(46,11)
+TRAP:"bear",random
+TRAP:"bear",random
+TRAP:"bear",random
+TRAP:"bear",random
+# Random jungle stuff
+LOOP [5 + 1d10] {
+  MONSTER: (';',"giant eel"),random,hostile
+}
+LOOP [10 + 1d5] {
+  MONSTER: ('Y',"monkey"),random,hostile
+}
+LOOP [4 + 1d3] {
+  MONSTER: ('Y',"ape"),random,hostile
+}
+LOOP [3 + 1d3] {
+  MONSTER: ('S',"python"),random,hostile
+}
+LOOP [3 + 1d3] {
+  MONSTER: ('f',"panther"),random,hostile
+}
 
 #
@@ -96,91 +132,71 @@
 #
 
-MAZE: "Cav-loca",' '
-FLAGS: hardfloor
+LEVEL: "Cav-loca"
+FLAGS: noteleport,hardfloor,arboreal,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"tiger"), (16,'S'), (16,"ape"), (4,'f')
 GEOMETRY:center,center
 MAP
                                                                             
     .............                     ...........                           
-   ...............                   .............                          
-    .............                  ...............        ..........        
-     ...........                    .............      ...............      
-        ...                                    ...   ..................     
-         ...                ..........          ... ..................      
-          ...              ............          BBB...................     
+   ........PPP....                   .............                          
+    ......PPP....                  ...............        ..........        
            ...              ..........          ......................      
-            .....                 ..      .....B........................    
-  ....       ...............      .    ........B..........................  
- ......     .. .............S..............         ..................      
-  ....     ..                ...........             ...............        
-     ..  ...                                    ....................        
+        ....  PP                               ...   ..................     
+         ...                ..........          ... ..................      
+         P...              ....PPP.....          BBB...................     
+           ... P            ..........          ......................      
+   PP       ..... PP   P          ..      ....PB........................    
+  ....       ...............      .  P .......PB..........................  
+ ......     .. .............P..............         ..................      
+  ....     ..  P   PPP       ...........             ...............        
+     ..  ...                      PPP           ....................        
       ....                                      BB...................       
-         ..                 ..                 ..  ...............          
-          ..   .......     ....  .....  ....  ..     .......   S            
-           ............     ....... ..  .......       .....    ...  ....    
-               .......       .....   ......                      .......    
+      PP .. P               ..                 ..  ...............          
+          ..   .......     ....  .....  ....  ..     .......   P            
+         P ......PPP...     ....... ..  .......       .....    ...  ....    
+            P  .......       .....   ......                      .......    
                                                                             
 ENDMAP
+
+REPLACE_TERRAIN:(00,00,25,19), ' ', 'P', 10%
+
 # Dungeon Description
 REGION:(00,00,75,19),unlit,"ordinary"
 REGION:(52,06,73,15),lit,"ordinary",unfilled,true
-# Doors
-DOOR:locked,(28,11)
 # Stairs
-STAIR:(04,03),up
-STAIR:(73,10),down
+LADDER:(04,03),up
+LADDER:(73,10),down
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 2d5] {
+  OBJECT:random,random
+}
 # Random traps
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-# Random monsters.
-MONSTER:'h',"bugbear",(02,10),hostile
-MONSTER:'h',"bugbear",(03,11),hostile
-MONSTER:'h',"bugbear",(04,12),hostile
-MONSTER:'h',"bugbear",(02,11),hostile
-MONSTER:'h',"bugbear",(16,16),hostile
-MONSTER:'h',"bugbear",(17,17),hostile
-MONSTER:'h',"bugbear",(18,18),hostile
-MONSTER:'h',"bugbear",(19,16),hostile
-MONSTER:'h',"bugbear",(30,06),hostile
-MONSTER:'h',"bugbear",(31,07),hostile
-MONSTER:'h',"bugbear",(32,08),hostile
-MONSTER:'h',"bugbear",(33,06),hostile
-MONSTER:'h',"bugbear",(34,07),hostile
-MONSTER:'h',"bugbear",random,hostile
-MONSTER:'h',"bugbear",random,hostile
-MONSTER:'h',"bugbear",random,hostile
-MONSTER:'h',"bugbear",random,hostile
-MONSTER:'h',random,random,hostile
-MONSTER:'H',random,random,hostile
-MONSTER:'H',"hill giant",(03,12),hostile
-MONSTER:'H',"hill giant",(20,17),hostile
-MONSTER:'H',"hill giant",(35,08),hostile
-MONSTER:'H',"hill giant",random,hostile
-MONSTER:'H',"hill giant",random,hostile
-MONSTER:'H',"hill giant",random,hostile
-MONSTER:'H',"hill giant",random,hostile
-MONSTER:'H',random,random,hostile
-WALLIFY
+LOOP [3 + 1d5] {
+  TRAP:"spiked pit",random
+}
+LOOP [4 + 1d5] {
+  TRAP:"bear",random
+}
+# Monsters...
+MONSTER:(';',"electric eel"),(28,11),hostile
+MONSTER:(';',"electric eel"),(46,09),hostile
+MONSTER:(';',"electric eel"),(46,10),hostile
+MONSTER:(';',"electric eel"),(63,16),hostile
+LOOP [3 + 1d6] {
+  MONSTER:(';',"giant eel"),random,hostile
+}
+LOOP [7 + 1d6] {
+  MONSTER:('Y',"carnivorous ape"),random,hostile
+}
+LOOP [3 + 1d5] {
+  MONSTER:('Y',"monkey"),random,hostile
+}
+LOOP [3 + 1d3] {
+  MONSTER:('S',"python"),random,hostile
+}
+# WALLIFY
 
 #
@@ -192,5 +208,8 @@
 #
 
-MAZE: "Cav-goal", ' '
+LEVEL: "Cav-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"tiger"), (16,'S'), (16,"ape"), (4,'f')
 GEOMETRY:center,center
 MAP
@@ -219,31 +238,88 @@
 REGION:(00,00,75,19),lit,"ordinary"
 # Stairs
-STAIR:random,up
+LADDER:random,up
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:')',"mace",(23,10),blessed,0,"The Sceptre of Might"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:(')',"mace"),(23,10),blessed,0,NAME:"The Sceptre of Might"
+LOOP [10 + 2d8] {
+  OBJECT:random,random
+}
 # monsters.
-MONSTER:'D',"Chromatic Dragon",(23,10),asleep
-MONSTER:'F',"shrieker",(26,13)
-MONSTER:'F',"shrieker",(25,8)
-MONSTER:'F',"shrieker",(45,11)
+MONSTER:('D',"Chromatic Dragon"),(23,10),asleep {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+}
+MONSTER:('F',"shrieker"),(26,13)
+MONSTER:('F',"shrieker"),(25,8)
+MONSTER:('F',"shrieker"),(45,11)
+LOOP [2 + 1d4] {
+  MONSTER:('Y',"carnivorous ape"),random,hostile
+  MONSTER[90%]:('f',"tiger"),random,hostile
+}
 WALLIFY
 
 #
+#	The level inbetween the original starting jungle and the lower levels
+#	where the actual caves are.
+#
+
+LEVEL: "Cav-fila"
+FLAGS: noteleport,hardfloor,arboreal,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"tiger"), (16,'S'), (16,"ape"), (4,'f')
+GEOMETRY: center,center
+MAP
+                                                                            
+                                          P                                 
+                                         PP                                 
+    ...                ....             .PP...            P  ....           
+   .....              ..PP...       ....PP.......          ........         
+   .....             ...PP...      .....PPP.........   P ..........         
+   .......           ........      .....PP..........................        
+     .....           .........      ...PPP............ P    ....P...        
+     ..P..         .....  ....       ..PP...     PPP        ...PPP..        
+     ..PP.         ....    ....       PPP                  P...PPP..        
+      .....        ...      ...       PP                    ....P...        
+      .....        ..       ...       P                    .........P       
+       ..... P     ..        ...                         ...........        
+       ......      ..        ...                  ..................        
+       ......      ..         .. P   PPP   .........PPPP...........P        
+        P  ...  PP ..         ..............................   PP           
+            ........               PPP    P   ..........                    
+             PPP                                                            
+                                                                            
+                                                                            
+ENDMAP
+#
+LADDER: (05,04), up
+LADDER: (36,05), down
+#
+REGION:(00,00,75,19),unlit,"ordinary"
+#
+NON_DIGGABLE:(00,00,75,19)
+#
+LOOP [5 + 1d5] {
+  OBJECT: random, random
+}
+#
+LOOP [2 + 1d3] {
+  TRAP[90%]: "pit", random
+  TRAP[90%]: "spiked pit", random
+  TRAP[90%]: "bear", random
+}
+TRAP: "bear", (37,15)
+#
+LOOP [5 + 1d10] {
+  MONSTER[90%]: ('f',"tiger"),random,hostile
+  MONSTER[90%]: ('S',"python"),random,hostile
+  MONSTER[90%]: ('Y',"carnivorous ape"),random,hostile
+}
+
+#
 #	The "fill" levels for the quest.
 #
@@ -253,64 +329,29 @@
 #	and goal levels.
 #
-
-MAZE: "Cav-fila" , ' '
-INIT_MAP: '.' , ' ' , true , true , random , true
-NOMAP
-#
-STAIR: random, up
-STAIR: random, down
-#
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-#
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+#	Obviously, "fila" has been hijacked and moved above.  :)
 #
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', random, random, hostile
-MONSTER: 'H', "hill giant", random, hostile
 
-MAZE: "Cav-filb" , ' '
-INIT_MAP: '.' , ' ' , true , true , random , true
+LEVEL: "Cav-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ' , true , true , random , true
+MON_GENERATION:86%, (64,"tiger"), (16,'S'), (16,"ape"), (4,'f')
 NOMAP
 #
-STAIR: random, up
-STAIR: random, down
+LADDER: random, up
+LADDER: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 1d5] {
+  OBJECT: random, random
+}
 #
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+LOOP [2 + 1d3] {
+  TRAP[90%]: "pit", random
+  TRAP[90%]: "spiked pit", random
+  TRAP[90%]: "bear", random
+}
 #
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', "bugbear", random, hostile
-MONSTER: 'h', random, random, hostile
-MONSTER: 'h', random, random, hostile
-MONSTER: 'H', "hill giant", random, hostile
-MONSTER: 'H', "hill giant", random, hostile
+LOOP [5 + 1d10] {
+  MONSTER[90%]: ('f',"tiger"),random,hostile
+  MONSTER[90%]: ('S',"python"),random,hostile
+  MONSTER[90%]: ('Y',"carnivorous ape"),random,hostile
+}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/dungeon.def nethack/dat/dungeon.def
--- nh_orig/dat/dungeon.def	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/dungeon.def	2010-04-23 14:27:35.945715831 -0400
@@ -22,11 +22,11 @@
 LEVALIGN:	neutral
 CHAINBRANCH:	"Sokoban" "oracle" + (1, 0) up
-RNDLEVEL:	"bigrm" "B" @ (10, 3) 40 5
+RNDLEVEL:	"bigrm" "B" @ (10, 3) 40 11
 CHAINBRANCH:	"The Quest" "oracle" + (6, 2) portal
 BRANCH:		"Fort Ludios" @ (18, 4) portal
-RNDLEVEL:	"medusa" "none" @ (-5, 4) 2
+RNDLEVEL:	"medusa" "none" @ (-5, 4) 4
 LEVALIGN:	chaotic
 LEVEL:		"castle" "none" @ (-1, 0)
-CHAINBRANCH:	"Gehennom" "castle" + (0, 0) no_down
+CHAINBRANCH:	"Gehennom" "castle" + (0, 0) down
 BRANCH:		"The Elemental Planes" @ (1, 0) no_down up
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/endgame.des nethack/dat/endgame.des
--- nh_orig/dat/endgame.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/endgame.des	2010-05-13 09:22:22.243714740 -0400
@@ -10,6 +10,7 @@
 # shrine.
 
-MAZE:"earth",' '
-FLAGS: noteleport,hardfloor,shortsighted
+LEVEL:"earth"
+FLAGS: noteleport,hardfloor,shortsighted,mazelevel
+INIT_MAP:solidfill,' '
 MESSAGE: "Well done, mortal!"
 MESSAGE: "But now thou must face the final Test..."
@@ -44,87 +45,93 @@
                                                                             
 ENDMAP
+
+REPLACE_TERRAIN:(0,0,75,19), ' ', ('.', unlit), 15%
+
+
 #  Since there are no stairs, this forces the hero's initial placement
 TELEPORT_REGION:(69,16,69,16),(0,0,0,0)
+TERRAIN:(69,16),'.'
 PORTAL:(0,0,75,19),(65,13,75,19),"air"
 #  Some helpful monsters.  Making sure a
 #  pick axe and at least one wand of digging
 #  are available.
-MONSTER:'@',"Elvenking",(67,16)
-MONSTER:'H',"minotaur",(67,14)
+MONSTER:('@',"Elvenking"),(67,16)
+MONSTER:('H',"minotaur"),(67,14)
 #  An assortment of earth-appropriate nasties
 #  in each cavern.
-MONSTER:'E',"earth elemental",(52,13),hostile
-MONSTER:'E',"earth elemental",(53,13),hostile
-MONSTER:'T',"rock troll",(53,12)
-MONSTER:'H',"stone giant",(54,12)
+MONSTER:('E',"earth elemental"),(52,13),hostile
+MONSTER:('E',"earth elemental"),(53,13),hostile
+MONSTER:('T',"rock troll"),(53,12)
+MONSTER:('H',"stone giant"),(54,12)
 #
-MONSTER:'S',"pit viper",(70,05)
-MONSTER:'&',"barbed devil",(69,06)
-MONSTER:'H',"stone giant",(69,08)
-MONSTER:''',"stone golem",(71,08)
-MONSTER:'&',"pit fiend",(70,09)
-MONSTER:'E',"earth elemental",(70,08),hostile
+MONSTER:('S',"pit viper"),(70,05)
+MONSTER:('&',"barbed devil"),(69,06)
+MONSTER:('H',"stone giant"),(69,08)
+MONSTER:(''',"stone golem"),(71,08)
+MONSTER:('&',"pit fiend"),(70,09)
+MONSTER:('E',"earth elemental"),(70,08),hostile
 #
-MONSTER:'E',"earth elemental",(60,03),hostile
-MONSTER:'H',"stone giant",(61,04)
-MONSTER:'E',"earth elemental",(62,04),hostile
-MONSTER:'E',"earth elemental",(61,05),hostile
-MONSTER:'s',"scorpion",(62,05)
-MONSTER:'p',"rock piercer",(63,05)
+MONSTER:('E',"earth elemental"),(60,03),hostile
+MONSTER:('H',"stone giant"),(61,04)
+MONSTER:('E',"earth elemental"),(62,04),hostile
+MONSTER:('E',"earth elemental"),(61,05),hostile
+MONSTER:('s',"scorpion"),(62,05)
+MONSTER:('p',"rock piercer"),(63,05)
 #
-MONSTER:'U',"umber hulk",(40,05)
-MONSTER:'v',"dust vortex",(42,05)
-MONSTER:'T',"rock troll",(38,06)
-MONSTER:'E',"earth elemental",(39,06),hostile
-MONSTER:'E',"earth elemental",(41,06),hostile
-MONSTER:'E',"earth elemental",(38,07),hostile
-MONSTER:'H',"stone giant",(39,07)
-MONSTER:'E',"earth elemental",(43,07),hostile
-MONSTER:''',"stone golem",(37,08)
-MONSTER:'S',"pit viper",(43,08)
-MONSTER:'S',"pit viper",(43,09)
-MONSTER:'T',"rock troll",(44,10)
+MONSTER:('U',"umber hulk"),(40,05)
+MONSTER:('v',"dust vortex"),(42,05)
+MONSTER:('T',"rock troll"),(38,06)
+MONSTER:('E',"earth elemental"),(39,06),hostile
+MONSTER:('E',"earth elemental"),(41,06),hostile
+MONSTER:('E',"earth elemental"),(38,07),hostile
+MONSTER:('H',"stone giant"),(39,07)
+MONSTER:('E',"earth elemental"),(43,07),hostile
+MONSTER:(''',"stone golem"),(37,08)
+MONSTER:('S',"pit viper"),(43,08)
+MONSTER:('S',"pit viper"),(43,09)
+MONSTER:('T',"rock troll"),(44,10)
 #
-MONSTER:'E',"earth elemental",(02,01),hostile
-MONSTER:'E',"earth elemental",(03,01),hostile
-MONSTER:''',"stone golem",(01,02)
-MONSTER:'E',"earth elemental",(02,02),hostile
-MONSTER:'T',"rock troll",(04,03)
-MONSTER:'T',"rock troll",(03,03)
-MONSTER:'&',"pit fiend",(03,04)
-MONSTER:'E',"earth elemental",(04,05),hostile
-MONSTER:'S',"pit viper",(05,06)
+MONSTER:('E',"earth elemental"),(02,01),hostile
+MONSTER:('E',"earth elemental"),(03,01),hostile
+MONSTER:(''',"stone golem"),(01,02)
+MONSTER:('E',"earth elemental"),(02,02),hostile
+MONSTER:('T',"rock troll"),(04,03)
+MONSTER:('T',"rock troll"),(03,03)
+MONSTER:('&',"pit fiend"),(03,04)
+MONSTER:('E',"earth elemental"),(04,05),hostile
+MONSTER:('S',"pit viper"),(05,06)
 #
-MONSTER:'E',"earth elemental",(21,02),hostile
-MONSTER:'E',"earth elemental",(21,03),hostile
-MONSTER:'H',"minotaur",(21,04)
-MONSTER:'E',"earth elemental",(21,05),hostile
-MONSTER:'T',"rock troll",(22,05)
-MONSTER:'E',"earth elemental",(22,06),hostile
-MONSTER:'E',"earth elemental",(23,06),hostile
+MONSTER:('E',"earth elemental"),(21,02),hostile
+MONSTER:('E',"earth elemental"),(21,03),hostile
+MONSTER:('H',"minotaur"),(21,04)
+MONSTER:('E',"earth elemental"),(21,05),hostile
+MONSTER:('T',"rock troll"),(22,05)
+MONSTER:('E',"earth elemental"),(22,06),hostile
+MONSTER:('E',"earth elemental"),(23,06),hostile
 #
-MONSTER:'S',"pit viper",(14,08)
-MONSTER:'&',"barbed devil",(14,09)
-MONSTER:'E',"earth elemental",(13,10),hostile
-MONSTER:'T',"rock troll",(12,11)
-MONSTER:'E',"earth elemental",(14,12),hostile
-MONSTER:'E',"earth elemental",(15,13),hostile
-MONSTER:'H',"stone giant",(17,13)
-MONSTER:''',"stone golem",(18,13)
-MONSTER:'&',"pit fiend",(18,12)
-MONSTER:'E',"earth elemental",(18,11),hostile
-MONSTER:'E',"earth elemental",(18,10),hostile
+MONSTER:('S',"pit viper"),(14,08)
+MONSTER:('&',"barbed devil"),(14,09)
+MONSTER:('E',"earth elemental"),(13,10),hostile
+MONSTER:('T',"rock troll"),(12,11)
+MONSTER:('E',"earth elemental"),(14,12),hostile
+MONSTER:('E',"earth elemental"),(15,13),hostile
+MONSTER:('H',"stone giant"),(17,13)
+MONSTER:(''',"stone golem"),(18,13)
+MONSTER:('&',"pit fiend"),(18,12)
+MONSTER:('E',"earth elemental"),(18,11),hostile
+MONSTER:('E',"earth elemental"),(18,10),hostile
 #
-MONSTER:'&',"barbed devil",(02,16)
-MONSTER:'E',"earth elemental",(03,16),hostile
-MONSTER:'T',"rock troll",(02,17)
-MONSTER:'E',"earth elemental",(04,17),hostile
-MONSTER:'E',"earth elemental",(04,18),hostile
+MONSTER:('&',"barbed devil"),(02,16)
+MONSTER:('E',"earth elemental"),(03,16),hostile
+MONSTER:('T',"rock troll"),(02,17)
+MONSTER:('E',"earth elemental"),(04,17),hostile
+MONSTER:('E',"earth elemental"),(04,18),hostile
 
-OBJECT:'`',"boulder",random
+OBJECT:('`',"boulder"),random
 
 
-MAZE:"air",' '
-FLAGS: noteleport,hardfloor,shortsighted
+LEVEL:"air"
+FLAGS: noteleport,hardfloor,shortsighted,mazelevel,stormy
+INIT_MAP:solidfill,' '
 # The following messages are somewhat obtuse, to make then
 # equally meaningful if the player can see or not.
@@ -138,25 +145,29 @@
 # is all "air".
 MAP
-AAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAACCCCCCAAAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAACCAACCCCCAAAAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAACCACCCCCCCAAAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAACCCCAAACCAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAACCCCAAAAAACCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAACCCCCCCAAAACCACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAACCCCAAAAAAACCACAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCAACCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCAAACCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACACCCCCAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCAAAACCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCAAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCCCCCCCCAACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACACCCCCCCCCCACCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAACCCCCCAAACCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAACCAAAAAACCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
 ENDMAP
+
+REPLACE_TERRAIN:(0,0,75,19), 'A', 'C', 35%
+REPLACE_TERRAIN:(25,0,50,19), 'A', 'C', 50%
+
 # Use up and down regions to partition the level into three parts;
 # teleportation can't cross from one part into another.
@@ -167,65 +178,66 @@
 PORTAL:levregion(57,01,78,19),(0,0,0,0),"fire"
 REGION:(00,00,75,19),lit,"ordinary"
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
-MONSTER:'E',"air elemental",random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
+MONSTER:('E',"air elemental"),random,hostile
 
-MONSTER:'e',"floating eye",random,hostile
-MONSTER:'e',"floating eye",random,hostile
-MONSTER:'e',"floating eye",random,hostile
+MONSTER:('e',"floating eye"),random,hostile
+MONSTER:('e',"floating eye"),random,hostile
+MONSTER:('e',"floating eye"),random,hostile
 
-MONSTER:'y',"yellow light",random,hostile
-MONSTER:'y',"yellow light",random,hostile
-MONSTER:'y',"yellow light",random,hostile
+MONSTER:('y',"yellow light"),random,hostile
+MONSTER:('y',"yellow light"),random,hostile
+MONSTER:('y',"yellow light"),random,hostile
 
-MONSTER:'A',"couatl",random
+MONSTER:('A',"couatl"),random
 
-MONSTER:'D',random,random
-MONSTER:'D',random,random
-MONSTER:'D',random,random
-MONSTER:'D',random,random
-MONSTER:'D',random,random
+MONSTER:'D',random
+MONSTER:'D',random
+MONSTER:'D',random
+MONSTER:'D',random
+MONSTER:'D',random
 
-MONSTER:'E',random,random
-MONSTER:'E',random,random
-MONSTER:'E',random,random
-MONSTER:'J',random,random
-MONSTER:'J',random,random
+MONSTER:'E',random
+MONSTER:'E',random
+MONSTER:'E',random
+MONSTER:'J',random
+MONSTER:'J',random
 
-MONSTER:'&',"djinni",random,hostile
-MONSTER:'&',"djinni",random,hostile
-MONSTER:'&',"djinni",random,hostile
+MONSTER:('&',"djinni"),random,hostile
+MONSTER:('&',"djinni"),random,hostile
+MONSTER:('&',"djinni"),random,hostile
 
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"fog cloud",random,hostile
-MONSTER:'v',"energy vortex",random,hostile
-MONSTER:'v',"energy vortex",random,hostile
-MONSTER:'v',"energy vortex",random,hostile
-MONSTER:'v',"energy vortex",random,hostile
-MONSTER:'v',"energy vortex",random,hostile
-MONSTER:'v',"steam vortex",random,hostile
-MONSTER:'v',"steam vortex",random,hostile
-MONSTER:'v',"steam vortex",random,hostile
-MONSTER:'v',"steam vortex",random,hostile
-MONSTER:'v',"steam vortex",random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"fog cloud"),random,hostile
+MONSTER:('v',"energy vortex"),random,hostile
+MONSTER:('v',"energy vortex"),random,hostile
+MONSTER:('v',"energy vortex"),random,hostile
+MONSTER:('v',"energy vortex"),random,hostile
+MONSTER:('v',"energy vortex"),random,hostile
+MONSTER:('v',"steam vortex"),random,hostile
+MONSTER:('v',"steam vortex"),random,hostile
+MONSTER:('v',"steam vortex"),random,hostile
+MONSTER:('v',"steam vortex"),random,hostile
+MONSTER:('v',"steam vortex"),random,hostile
 
 
-MAZE:"fire",' '
-FLAGS: noteleport,hardfloor,shortsighted
+LEVEL:"fire"
+FLAGS: noteleport,hardfloor,shortsighted,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 # The player lands, upon arrival, in the
@@ -256,5 +268,8 @@
 .................................LL....................LL...................
 ENDMAP
+
+REPLACE_TERRAIN:(0,0,75,19), '.', 'L', 30%
 TELEPORT_REGION:(69,16,69,16),(0,0,0,0)
+TERRAIN:(69,16),'.'
 PORTAL:(0,0,75,19),(65,13,75,19),"water"
 
@@ -300,83 +315,84 @@
 TRAP:"fire",random
 #  An assortment of fire-appropriate nasties
-MONSTER:'D',"red dragon",random
-MONSTER:'&',"balrog",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'v',"fire vortex",random
-MONSTER:'d',"hell hound",random
+MONSTER:('D',"red dragon"),random
+MONSTER:('&',"balrog"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('v',"fire vortex"),random
+MONSTER:('d',"hell hound"),random
 #
-MONSTER:'H',"fire giant",random
-MONSTER:'&',"barbed devil",random
-MONSTER:'d',"hell hound",random
-MONSTER:''',"stone golem",random
-MONSTER:'&',"pit fiend",random
-MONSTER:'E',"fire elemental",random,hostile
+MONSTER:('H',"fire giant"),random
+MONSTER:('&',"barbed devil"),random
+MONSTER:('d',"hell hound"),random
+MONSTER:(''',"stone golem"),random
+MONSTER:('&',"pit fiend"),random
+MONSTER:('E',"fire elemental"),random,hostile
 #
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'d',"hell hound",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'s',"scorpion",random
-MONSTER:'H',"fire giant",random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('d',"hell hound"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('s',"scorpion"),random
+MONSTER:('H',"fire giant"),random
 #
-MONSTER:'d',"hell hound",random
-MONSTER:'v',"dust vortex",random
-MONSTER:'v',"fire vortex",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'d',"hell hound",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:''',"stone golem",random
-MONSTER:'S',"pit viper",random
-MONSTER:'S',"pit viper",random
-MONSTER:'v',"fire vortex",random
+MONSTER:('d',"hell hound"),random
+MONSTER:('v',"dust vortex"),random
+MONSTER:('v',"fire vortex"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('d',"hell hound"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:(''',"stone golem"),random
+MONSTER:('S',"pit viper"),random
+MONSTER:('S',"pit viper"),random
+MONSTER:('v',"fire vortex"),random
 #
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'H',"fire giant",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'v',"fire vortex",random
-MONSTER:'v',"fire vortex",random
-MONSTER:'&',"pit fiend",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'S',"pit viper",random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('H',"fire giant"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('v',"fire vortex"),random
+MONSTER:('v',"fire vortex"),random
+MONSTER:('&',"pit fiend"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('S',"pit viper"),random
 #
-MONSTER:':',"salamander",random,hostile
-MONSTER:':',"salamander",random,hostile
-MONSTER:'H',"minotaur",random
-MONSTER:':',"salamander",random,hostile
-MONSTER:'v',"steam vortex",random
-MONSTER:':',"salamander",random,hostile
-MONSTER:':',"salamander",random,hostile
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:('H',"minotaur"),random
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:('v',"steam vortex"),random
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:(':',"salamander"),random,hostile
 #
-MONSTER:'H',"fire giant",random
-MONSTER:'&',"barbed devil",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'v',"fire vortex",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'d',"hell hound",random
-MONSTER:'H',"fire giant",random
-MONSTER:'&',"pit fiend",random
-MONSTER:'E',"fire elemental",random,hostile
-MONSTER:'E',"fire elemental",random,hostile
+MONSTER:('H',"fire giant"),random
+MONSTER:('&',"barbed devil"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('v',"fire vortex"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('d',"hell hound"),random
+MONSTER:('H',"fire giant"),random
+MONSTER:('&',"pit fiend"),random
+MONSTER:('E',"fire elemental"),random,hostile
+MONSTER:('E',"fire elemental"),random,hostile
 #
-MONSTER:'&',"barbed devil",random
-MONSTER:':',"salamander",random,hostile
-MONSTER:'v',"steam vortex",random
-MONSTER:':',"salamander",random,hostile
-MONSTER:':',"salamander",random,hostile
+MONSTER:('&',"barbed devil"),random
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:('v',"steam vortex"),random
+MONSTER:(':',"salamander"),random,hostile
+MONSTER:(':',"salamander"),random,hostile
 
-OBJECT:'`',"boulder",random
-OBJECT:'`',"boulder",random
-OBJECT:'`',"boulder",random
-OBJECT:'`',"boulder",random
-OBJECT:'`',"boulder",random
+OBJECT:('`',"boulder"),random
+OBJECT:('`',"boulder"),random
+OBJECT:('`',"boulder"),random
+OBJECT:('`',"boulder"),random
+OBJECT:('`',"boulder"),random
 
 
-MAZE:"water",' '
-FLAGS: noteleport,hardfloor,shortsighted
+LEVEL:"water"
+FLAGS: noteleport,hardfloor,shortsighted,mazelevel,shroud
+INIT_MAP:solidfill,' '
 MESSAGE: "You find yourself suspended in an air bubble surrounded by water."
 GEOMETRY:center,center
@@ -411,69 +427,70 @@
 PORTAL:(51,0,75,19),(0,0,0,0),"astral"
 # A fisherman's dream...
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"kraken",random
-MONSTER:';',"shark",random
-MONSTER:';',"shark",random
-MONSTER:';',"shark",random
-MONSTER:';',"shark",random
-MONSTER:';',"piranha",random
-MONSTER:';',"piranha",random
-MONSTER:';',"piranha",random
-MONSTER:';',"piranha",random
-MONSTER:';',"jellyfish",random
-MONSTER:';',"jellyfish",random
-MONSTER:';',"jellyfish",random
-MONSTER:';',"jellyfish",random
-MONSTER:';',random,random
-MONSTER:';',random,random
-MONSTER:';',random,random
-MONSTER:';',random,random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"piranha"),random
+MONSTER:(';',"piranha"),random
+MONSTER:(';',"piranha"),random
+MONSTER:(';',"piranha"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:';',random
+MONSTER:';',random
+MONSTER:';',random
+MONSTER:';',random
 # These guys feel like home here
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
-MONSTER:'E',"water elemental",random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
+MONSTER:('E',"water elemental"),random,hostile
 
 
-MAZE:"astral",' '
-FLAGS: noteleport,hardfloor,nommap,shortsighted
+LEVEL:"astral"
+FLAGS: noteleport,hardfloor,nommap,shortsighted,mazelevel
+INIT_MAP:solidfill,' '
 MESSAGE: "You arrive on the Astral Plane!"
 MESSAGE: "Here the High Temples of the aligned gods are located."
@@ -502,6 +519,23 @@
                              -----------------                             
 ENDMAP
+
+IF [75%] {
+  TERRAIN:fillrect (17,14, 30,18),'.'
+  TERRAIN:fillrect (44,14, 57,18),'.'
+  WALLIFY
+
+  $hall = selection:floodfill(37,18)
+  LOOP [6 + 3d4] {
+    MONSTER:('A',"Angel"),rndcoord($hall),noalign,hostile
+    MONSTER[50%]:random,rndcoord($hall),hostile
+  }
+
+  OBJECT:"brazier",(23,16)
+  OBJECT:"brazier",(51,16)
+}
+
 # Rider locations
-RANDOM_PLACES:(23,9),(37,14),(51,9)
+$place = { (23,9),(37,14),(51,9) }
+SHUFFLE:$place
 # Where the player will land on arrival
 TELEPORT_REGION:(29,15,45,15),(30,15,44,15)
@@ -534,27 +568,29 @@
 # Moloch's horde
 # West round room
-MONSTER:'@',"aligned priest",(18,09),noalign,hostile
-MONSTER:'@',"aligned priest",(19,08),noalign,hostile
-MONSTER:'@',"aligned priest",(19,09),noalign,hostile
-MONSTER:'@',"aligned priest",(19,10),noalign,hostile
-MONSTER:'A',"Angel",(20,09),noalign,hostile
-MONSTER:'A',"Angel",(20,10),noalign,hostile
-MONSTER:'&',"Pestilence",place[0],hostile
+MONSTER:('@',"aligned priest"),(18,09),noalign,hostile
+MONSTER:('@',"aligned priest"),(19,08),noalign,hostile
+MONSTER:('@',"aligned priest"),(19,09),noalign,hostile
+MONSTER:('@',"aligned priest"),(19,10),noalign,hostile
+MONSTER:('A',"Angel"),(20,09),noalign,hostile
+MONSTER:('A',"Angel"),(20,10),noalign,hostile
+MONSTER:('&',"Pestilence"),$place[0],hostile {
+  OBJECT:('!',"sickness")
+}
 # South-central round room
-MONSTER:'@',"aligned priest",(36,12),noalign,hostile
-MONSTER:'@',"aligned priest",(37,12),noalign,hostile
-MONSTER:'@',"aligned priest",(38,12),noalign,hostile
-MONSTER:'@',"aligned priest",(36,13),noalign,hostile
-MONSTER:'A',"Angel",(38,13),noalign,hostile
-MONSTER:'A',"Angel",(37,13),noalign,hostile
-MONSTER:'&',"Death",place[1],hostile
+MONSTER:('@',"aligned priest"),(36,12),noalign,hostile
+MONSTER:('@',"aligned priest"),(37,12),noalign,hostile
+MONSTER:('@',"aligned priest"),(38,12),noalign,hostile
+MONSTER:('@',"aligned priest"),(36,13),noalign,hostile
+MONSTER:('A',"Angel"),(38,13),noalign,hostile
+MONSTER:('A',"Angel"),(37,13),noalign,hostile
+MONSTER:('&',"Death"),$place[1],hostile
 # East round room
-MONSTER:'@',"aligned priest",(56,09),noalign,hostile
-MONSTER:'@',"aligned priest",(55,08),noalign,hostile
-MONSTER:'@',"aligned priest",(55,09),noalign,hostile
-MONSTER:'@',"aligned priest",(55,10),noalign,hostile
-MONSTER:'A',"Angel",(54,09),noalign,hostile
-MONSTER:'A',"Angel",(54,10),noalign,hostile
-MONSTER:'&',"Famine",place[2],hostile
+MONSTER:('@',"aligned priest"),(56,09),noalign,hostile
+MONSTER:('@',"aligned priest"),(55,08),noalign,hostile
+MONSTER:('@',"aligned priest"),(55,09),noalign,hostile
+MONSTER:('@',"aligned priest"),(55,10),noalign,hostile
+MONSTER:('A',"Angel"),(54,09),noalign,hostile
+MONSTER:('A',"Angel"),(54,10),noalign,hostile
+MONSTER:('&',"Famine"),$place[2],hostile
 #
 # The aligned horde
@@ -566,51 +602,51 @@
 #
 # West court
-MONSTER:'@',"aligned priest",(12,07),chaos,hostile
-MONSTER:'@',"aligned priest",(13,07),chaos,peaceful
-MONSTER:'@',"aligned priest",(14,07),law,hostile
-MONSTER:'@',"aligned priest",(12,11),law,peaceful
-MONSTER:'@',"aligned priest",(13,11),neutral,hostile
-MONSTER:'@',"aligned priest",(14,11),neutral,peaceful
-MONSTER:'A',"Angel",(11,05),chaos,hostile
-MONSTER:'A',"Angel",(12,05),chaos,peaceful
-MONSTER:'A',"Angel",(13,05),law,hostile
-MONSTER:'A',"Angel",(11,13),law,peaceful
-MONSTER:'A',"Angel",(12,13),neutral,hostile
-MONSTER:'A',"Angel",(13,13),neutral,peaceful
+MONSTER:('@',"aligned priest"),(12,07),chaos,hostile
+MONSTER:('@',"aligned priest"),(13,07),chaos,peaceful
+MONSTER:('@',"aligned priest"),(14,07),law,hostile
+MONSTER:('@',"aligned priest"),(12,11),law,peaceful
+MONSTER:('@',"aligned priest"),(13,11),neutral,hostile
+MONSTER:('@',"aligned priest"),(14,11),neutral,peaceful
+MONSTER:('A',"Angel"),(11,05),chaos,hostile
+MONSTER:('A',"Angel"),(12,05),chaos,peaceful
+MONSTER:('A',"Angel"),(13,05),law,hostile
+MONSTER:('A',"Angel"),(11,13),law,peaceful
+MONSTER:('A',"Angel"),(12,13),neutral,hostile
+MONSTER:('A',"Angel"),(13,13),neutral,peaceful
 # Central court
-MONSTER:'@',"aligned priest",(32,09),chaos,hostile
-MONSTER:'@',"aligned priest",(33,09),chaos,peaceful
-MONSTER:'@',"aligned priest",(34,09),law,hostile
-MONSTER:'@',"aligned priest",(40,09),law,peaceful
-MONSTER:'@',"aligned priest",(41,09),neutral,hostile
-MONSTER:'@',"aligned priest",(42,09),neutral,peaceful
-MONSTER:'A',"Angel",(31,08),chaos,hostile
-MONSTER:'A',"Angel",(32,08),chaos,peaceful
-MONSTER:'A',"Angel",(31,09),law,hostile
-MONSTER:'A',"Angel",(42,08),law,peaceful
-MONSTER:'A',"Angel",(43,08),neutral,hostile
-MONSTER:'A',"Angel",(43,09),neutral,peaceful
+MONSTER:('@',"aligned priest"),(32,09),chaos,hostile
+MONSTER:('@',"aligned priest"),(33,09),chaos,peaceful
+MONSTER:('@',"aligned priest"),(34,09),law,hostile
+MONSTER:('@',"aligned priest"),(40,09),law,peaceful
+MONSTER:('@',"aligned priest"),(41,09),neutral,hostile
+MONSTER:('@',"aligned priest"),(42,09),neutral,peaceful
+MONSTER:('A',"Angel"),(31,08),chaos,hostile
+MONSTER:('A',"Angel"),(32,08),chaos,peaceful
+MONSTER:('A',"Angel"),(31,09),law,hostile
+MONSTER:('A',"Angel"),(42,08),law,peaceful
+MONSTER:('A',"Angel"),(43,08),neutral,hostile
+MONSTER:('A',"Angel"),(43,09),neutral,peaceful
 # East court
-MONSTER:'@',"aligned priest",(60,07),chaos,hostile
-MONSTER:'@',"aligned priest",(61,07),chaos,peaceful
-MONSTER:'@',"aligned priest",(62,07),law,hostile
-MONSTER:'@',"aligned priest",(60,11),law,peaceful
-MONSTER:'@',"aligned priest",(61,11),neutral,hostile
-MONSTER:'@',"aligned priest",(62,11),neutral,peaceful
-MONSTER:'A',"Angel",(61,05),chaos,hostile
-MONSTER:'A',"Angel",(62,05),chaos,peaceful
-MONSTER:'A',"Angel",(63,05),law,hostile
-MONSTER:'A',"Angel",(61,13),law,peaceful
-MONSTER:'A',"Angel",(62,13),neutral,hostile
-MONSTER:'A',"Angel",(63,13),neutral,peaceful
+MONSTER:('@',"aligned priest"),(60,07),chaos,hostile
+MONSTER:('@',"aligned priest"),(61,07),chaos,peaceful
+MONSTER:('@',"aligned priest"),(62,07),law,hostile
+MONSTER:('@',"aligned priest"),(60,11),law,peaceful
+MONSTER:('@',"aligned priest"),(61,11),neutral,hostile
+MONSTER:('@',"aligned priest"),(62,11),neutral,peaceful
+MONSTER:('A',"Angel"),(61,05),chaos,hostile
+MONSTER:('A',"Angel"),(62,05),chaos,peaceful
+MONSTER:('A',"Angel"),(63,05),law,hostile
+MONSTER:('A',"Angel"),(61,13),law,peaceful
+MONSTER:('A',"Angel"),(62,13),neutral,hostile
+MONSTER:('A',"Angel"),(63,13),neutral,peaceful
 #
 # Assorted nasties
-MONSTER:'L',random,random,hostile
-MONSTER:'L',random,random,hostile
-MONSTER:'L',random,random,hostile
-MONSTER:'V',random,random,hostile
-MONSTER:'V',random,random,hostile
-MONSTER:'V',random,random,hostile
-MONSTER:'D',random,random,hostile
-MONSTER:'D',random,random,hostile
-MONSTER:'D',random,random,hostile
+MONSTER:'L',random,hostile
+MONSTER:'L',random,hostile
+MONSTER:'L',random,hostile
+MONSTER:'V',random,hostile
+MONSTER:'V',random,hostile
+MONSTER:'V',random,hostile
+MONSTER:'D',random,hostile
+MONSTER:'D',random,hostile
+MONSTER:'D',random,hostile
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/functions.des nethack/dat/functions.des
--- nh_orig/dat/functions.des	1969-12-31 19:00:00.000000000 -0500
+++ nethack/dat/functions.des	2009-10-17 10:45:04.637430539 -0400
@@ -0,0 +1,21 @@
+
+FUNCTION soko_loot()
+{
+  # Random objects
+  OBJECT:'%',random,random
+  OBJECT:'%',random,random
+  OBJECT:'%',random,random
+  OBJECT:'%',random,random
+  OBJECT:'=',random,random
+  OBJECT:'/',random,random
+}
+
+FUNCTION soko_prize()
+{
+  IF [50%] {
+    OBJECT:'"',"amulet of reflection",place[0]
+  } ELSE {
+    OBJECT:'(',"bag of holding",place[0]
+  }
+  ENGRAVING:place[0],burn,"Elbereth"
+}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/gehennom.des nethack/dat/gehennom.des
--- nh_orig/dat/gehennom.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/gehennom.des	2010-08-16 13:20:13.634708200 -0400
@@ -5,7 +5,10 @@
 #
 
-MAZE: "valley", ' '
-FLAGS: noteleport,hardfloor,nommap
+LEVEL: "valley"
+FLAGS: noteleport,hardfloor,nommap,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
+#         1         2         3         4         5         6         7
+#123456789012345678901234567890123456789012345678901234567890123456789012345
 MAP
 ----------------------------------------------------------------------------
@@ -13,28 +16,53 @@
 |---|.|.--.---.|  |......--- ----..........-----.-----....---........---.-.|
 |   |.|.|..| |.| --........| |.............|   |.......---| |-...........--|
-|   |...S..| |.| |.......-----.......------|   |--------..---......------- |
-|----------- |.| |-......| |....|...-- |...-----................----       |
-|.....S....---.| |.......| |....|...|  |..............-----------          |
-|.....|.|......| |.....--- |......---  |....---.......|                    |
-|.....|.|------| |....--   --....-- |-------- ----....---------------      |
-|.....|--......---BBB-|     |...--  |.......|    |..................|      |
-|..........||........-|    --...|   |.......|    |...||.............|      |
-|.....|...-||-........------....|   |.......---- |...||.............--     |
+|   |...S..| |.| |.......-----.......------|   |--------..--|......--...-- |
+|----------- |.| |-......| |....|...-- |...-----................----|...|  |
+|.....S....---.| |.......| |....|...|  |..............-----------   |...|  |
+|.....|.|......| |.....--- |......---  |....---.......|            -|...|  |
+|.....|.|------| |....--   --....-- |-------- ----BBBB--------------...--  |
+|.....|--......---BBB-|     |...--  |.......|    |...............B.....|   |
+|..........||........-|    --...|   |.......|    |...||..........B..----   |
+|.....|....||.........------....|   |.......---- |...||..........B..--     |
 |.....|--......---...........--------..........| |.......---------...--    |
 |.....| |------| |--.......--|   |..B......----- -----....| |.|  |....---  |
 |.....| |......--| ------..| |----..B......|       |.--------.-- |-.....---|
-|------ |........|  |.|....| |.....----BBBB---------...........---.........|
-|       |........|  |...|..| |.....|  |-.............--------...........---|
-|       --.....-----------.| |....-----.....----------     |.........----  |
-|        |..|..B...........| |.|..........|.|              |.|........|    |
+|-------|........|  |.|....| |.....----BBBB---------...........---.........|
+||....B.S........|  |...|..| |.....|  |-.............--------...........---|
+||....--|-.....-----------.| |....-----.....----------     |......... ---  |
+||....-  |..|..B...........| |.|..........|.|              |.|........|    |
 ----------------------------------------------------------------------------
 ENDMAP
+
+IF [50%] {
+   TERRAIN:line (50,8)-(53,8), '-'
+   TERRAIN:line (40,8)-(43,8), 'B'
+}
+
+IF [50%] {
+   TERRAIN:(27,12),'|'
+   TERRAIN:line (27,3)-(29,3), 'B'
+   TERRAIN:(28,2), '-'
+}
+
+IF [50%] {
+	TERRAIN:(60,5),'|'
+} ELSE {
+	TERRAIN:line (68,8)-(68,9),'|'
+}
+
+IF [50%] {
+   TERRAIN:line (16,10)-(16,11),'|'
+   TERRAIN:line (9,13)-(14,13), 'B'
+}
+
 # Dungeon Description
 # The shrine to Moloch.
-REGION:(01,06,05,14),lit,"temple"
+REGION:(01,06,05,14),unlit,"temple"
 # The Morgues
 REGION:(19,01,24,08),unlit,"morgue",filled,true
 REGION:(09,14,16,18),unlit,"morgue",filled,true
 REGION:(37,09,43,14),unlit,"morgue",filled,true
+REGION:(50,09,64,11),unlit,"morgue",filled,true
+REGION:(02,16,05,18),unlit,"morgue",filled,true
 # Stairs
 STAIR:(01,01),down
@@ -47,8 +75,13 @@
 DOOR:locked,(08,04)
 DOOR:locked,(06,06)
+DOOR:locked,(08,16)
 
 # The altar of Moloch.
 ALTAR:(03,10),noalign,shrine
 
+# Two sort-of light sources
+OBJECT:('\\',"brazier"),(03,06)
+OBJECT:('\\',"brazier"),(03,14)
+
 # Non diggable walls - everywhere!
 NON_DIGGABLE:(00,00,75,19)
@@ -59,58 +92,73 @@
 #       fate reserved for members of *those* classes.
 #
-OBJECT:'%',"corpse",random,"archeologist",0
-OBJECT:'%',"corpse",random,"archeologist",0
-OBJECT:'%',"corpse",random,"barbarian",0
-OBJECT:'%',"corpse",random,"barbarian",0
-OBJECT:'%',"corpse",random,"caveman",0
-OBJECT:'%',"corpse",random,"cavewoman",0
-OBJECT:'%',"corpse",random,"healer",0
-OBJECT:'%',"corpse",random,"healer",0
-OBJECT:'%',"corpse",random,"knight",0
-OBJECT:'%',"corpse",random,"knight",0
-OBJECT:'%',"corpse",random,"ranger",0
-OBJECT:'%',"corpse",random,"ranger",0
-OBJECT:'%',"corpse",random,"rogue",0
-OBJECT:'%',"corpse",random,"rogue",0
-OBJECT:'%',"corpse",random,"samurai",0
-OBJECT:'%',"corpse",random,"samurai",0
-OBJECT:'%',"corpse",random,"tourist",0
-OBJECT:'%',"corpse",random,"tourist",0
-OBJECT:'%',"corpse",random,"valkyrie",0
-OBJECT:'%',"corpse",random,"valkyrie",0
-OBJECT:'%',"corpse",random,"wizard",0
-OBJECT:'%',"corpse",random,"wizard",0
+OBJECT:('%',"corpse"),random,montype:"archeologist"
+OBJECT:('%',"corpse"),random,montype:"archeologist"
+OBJECT:('%',"corpse"),random,montype:"barbarian"
+OBJECT:('%',"corpse"),random,montype:"barbarian"
+OBJECT:('%',"corpse"),random,montype:"caveman"
+OBJECT:('%',"corpse"),random,montype:"cavewoman"
+OBJECT:('%',"corpse"),random,montype:"healer"
+OBJECT:('%',"corpse"),random,montype:"healer"
+OBJECT:('%',"corpse"),random,montype:"knight"
+OBJECT:('%',"corpse"),random,montype:"knight"
+OBJECT:('%',"corpse"),random,montype:"ranger"
+OBJECT:('%',"corpse"),random,montype:"ranger"
+OBJECT:('%',"corpse"),random,montype:"rogue"
+OBJECT:('%',"corpse"),random,montype:"rogue"
+OBJECT:('%',"corpse"),random,montype:"samurai"
+OBJECT:('%',"corpse"),random,montype:"samurai"
+OBJECT:('%',"corpse"),random,montype:"tourist"
+OBJECT:('%',"corpse"),random,montype:"tourist"
+OBJECT:('%',"corpse"),random,montype:"valkyrie"
+OBJECT:('%',"corpse"),random,montype:"valkyrie"
+OBJECT:('%',"corpse"),random,montype:"wizard"
+OBJECT:('%',"corpse"),random,montype:"wizard"
 #
 # Some random weapons and armor.
 #
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:')',random
+OBJECT:')',random
+OBJECT:')',random
+OBJECT:')',random
 #
 # Some random loot.
 #
-OBJECT:'*',"ruby",random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'/',random,random
-OBJECT:'/',random,random
-OBJECT:'=',random,random
-OBJECT:'=',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
-OBJECT:'(',random,random
-OBJECT:'(',random,random
-OBJECT:'(',random,random
+OBJECT:('*',"ruby"),random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'/',random
+OBJECT:'/',random
+OBJECT:'=',random
+OBJECT:'=',random
+OBJECT:'+',random
+OBJECT:'+',random
+OBJECT:'(',random
+OBJECT:'(',random
+OBJECT:'(',random
+#
+# Some less random loot.
+#
+CONTAINER:('(',"iron safe"),(02,18) {
+	OBJECT:('*',"diamond")
+	OBJECT:('*',"diamond")
+	OBJECT:'*'
+	OBJECT:'*'
+	OBJECT:'='
+	OBJECT:'='
+	OBJECT:'+'
+	OBJECT:'+'
+}
+OBJECT:('(',"chest"),(02,17)
+OBJECT:('(',"chest"),(03,18)
 
 # (Not so) Random traps.
@@ -120,6 +168,6 @@
 TRAP:"board", (21,12)
 TRAP:"board", random
-TRAP:"dart", (60,01)
-TRAP:"dart", (26,17)
+TRAP:"magic", (60,01)
+TRAP:"board", (26,17)
 TRAP:"anti magic", random
 TRAP:"anti magic", random
@@ -129,34 +177,34 @@
 # Random monsters.
 # The ghosts.
-MONSTER:' ',"ghost",random
-MONSTER:' ',"ghost",random
-MONSTER:' ',"ghost",random
-MONSTER:' ',"ghost",random
-MONSTER:' ',"ghost",random
-MONSTER:' ',"ghost",random
+MONSTER:(' ',"ghost"),random
+MONSTER:(' ',"ghost"),random
+MONSTER:(' ',"ghost"),random
+MONSTER:(' ',"ghost"),random
+MONSTER:(' ',"ghost"),random
+MONSTER:(' ',"ghost"),random
 # Add a few bats for atmosphere.
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
+MONSTER:('B',"vampire bat"),random
+MONSTER:('B',"vampire bat"),random
+MONSTER:('B',"vampire bat"),random
 # And a lich for good measure.
-MONSTER:'L',random,random
+MONSTER:'L',random
 # Some undead nasties for good measure
-MONSTER:'V',random,random
-MONSTER:'V',random,random
-MONSTER:'V',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
+MONSTER:'V',random
+MONSTER:'V',random
+MONSTER:'V',random
+MONSTER:'Z',random
+MONSTER:'Z',random
+MONSTER:'Z',random
+MONSTER:'Z',random
+MONSTER:'M',random
+MONSTER:'M',random
+MONSTER:'M',random
+MONSTER:'M',random
 #
 # The Juiblex level
 #
-MAZE:"juiblex",' '
-FLAGS:noteleport,shortsighted
-INIT_MAP:'.','}',true,true,unlit,false
+LEVEL:"juiblex"
+FLAGS:noteleport,shortsighted,mazelevel
+INIT_MAP:mines,'.','}',true,true,unlit,false
 # guarantee at least one open spot to ensure successful stair placement
 GEOMETRY:left,bottom
@@ -168,5 +216,5 @@
 }}}}}}}}
 ENDMAP
-OBJECT:'`',"boulder",random
+OBJECT:('`',"boulder"),random
 GEOMETRY:right,top
 MAP
@@ -177,5 +225,5 @@
 }}}}}}}}
 ENDMAP
-OBJECT:'`',"boulder",random
+OBJECT:('`',"boulder"),random
 # lair
 GEOMETRY:center,center
@@ -201,6 +249,7 @@
 ENDMAP
 # Random registers
-RANDOM_MONSTERS:'j','b','P','F'
-RANDOM_PLACES:(04,02),(46,02),(04,15),(46,15)
+$monster = MONSTER:{'j','b','P','F'}
+$place = { (04,02),(46,02),(04,15),(46,15) }
+SHUFFLE:$place
 # Dungeon description
 REGION:(00,00,50,17),unlit,"swamp"
@@ -212,55 +261,55 @@
 TELEPORT_REGION:levregion(01,00,11,20),(0,0,50,17),up
 TELEPORT_REGION:levregion(69,00,79,20),(0,0,50,17),down
-FOUNTAIN:place[0]
-MONSTER:'m',"giant mimic",place[1],m_feature "fountain"
-MONSTER:'m',"giant mimic",place[2],m_feature "fountain"
-MONSTER:'m',"giant mimic",place[3],m_feature "fountain"
+FOUNTAIN:$place[0]
+MONSTER:('m',"giant mimic"),$place[1],m_feature "fountain"
+MONSTER:('m',"giant mimic"),$place[2],m_feature "fountain"
+MONSTER:('m',"giant mimic"),$place[3],m_feature "fountain"
 # The demon of the swamp
-MONSTER:'&',"Juiblex",(25,08)
+MONSTER:('&',"Juiblex"),(25,08)
 # And a couple demons
-MONSTER:'i',"lemure",(43,08)
-MONSTER:'i',"lemure",(44,08)
-MONSTER:'i',"lemure",(45,08)
+MONSTER:('i',"lemure"),(43,08)
+MONSTER:('i',"lemure"),(44,08)
+MONSTER:('i',"lemure"),(45,08)
 # Some liquids and gems
-OBJECT:'*',random,(43,06)
-OBJECT:'*',random,(45,06)
-OBJECT:'!',random,(43,09)
-OBJECT:'!',random,(44,09)
-OBJECT:'!',random,(45,09)
+OBJECT:'*',(43,06)
+OBJECT:'*',(45,06)
+OBJECT:'!',(43,09)
+OBJECT:'!',(44,09)
+OBJECT:'!',(45,09)
 # And lots of blobby monsters
-MONSTER:monster[0],random,(25,06)
-MONSTER:monster[1],random,(24,07)
-MONSTER:monster[2],random,(26,07)
-MONSTER:monster[3],random,(23,08)
-MONSTER:monster[3],random,(27,08)
-MONSTER:monster[2],random,(24,09)
-MONSTER:monster[1],random,(26,09)
-MONSTER:monster[0],random,(25,10)
-MONSTER:'j',random,random
-MONSTER:'j',random,random
-MONSTER:'j',random,random
-MONSTER:'j',random,random
-MONSTER:'P',random,random
-MONSTER:'P',random,random
-MONSTER:'P',random,random
-MONSTER:'P',random,random
-MONSTER:'b',random,random
-MONSTER:'b',random,random
-MONSTER:'b',random,random
-MONSTER:'F',random,random
-MONSTER:'F',random,random
-MONSTER:'F',random,random
-MONSTER:'m',random,random
-MONSTER:'m',random,random
-MONSTER:';',"jellyfish",random
-MONSTER:';',"jellyfish",random
+MONSTER:$monster[0],(25,06)
+MONSTER:$monster[1],(24,07)
+MONSTER:$monster[2],(26,07)
+MONSTER:$monster[3],(23,08)
+MONSTER:$monster[3],(27,08)
+MONSTER:$monster[2],(24,09)
+MONSTER:$monster[1],(26,09)
+MONSTER:$monster[0],(25,10)
+MONSTER:'j',random
+MONSTER:'j',random
+MONSTER:'j',random
+MONSTER:'j',random
+MONSTER:'P',random
+MONSTER:'P',random
+MONSTER:'P',random
+MONSTER:'P',random
+MONSTER:'b',random
+MONSTER:'b',random
+MONSTER:'b',random
+MONSTER:'F',random
+MONSTER:'F',random
+MONSTER:'F',random
+MONSTER:'m',random
+MONSTER:'m',random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
 # Some random objects
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'`',"boulder",random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'%',random
+OBJECT:'%',random
+OBJECT:'%',random
+OBJECT:('`',"boulder"),random
 # Some traps
 TRAP:"sleep gas",random
@@ -273,6 +322,7 @@
 # The Orcus Level
 #
-MAZE:"orcus",random
-FLAGS: noteleport,shortsighted
+LEVEL:"orcus"
+FLAGS: noteleport,shortsighted,mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:right,center
 # A ghost town
@@ -304,28 +354,33 @@
 TELEPORT_REGION:levregion(01,00,12,20),levregion(20,01,70,20)
 # Wall "ruins"
-OBJECT:'`',"boulder",(19,02)
-OBJECT:'`',"boulder",(20,02)
-OBJECT:'`',"boulder",(21,02)
-OBJECT:'`',"boulder",(36,02)
-OBJECT:'`',"boulder",(36,03)
-OBJECT:'`',"boulder",(06,04)
-OBJECT:'`',"boulder",(05,05)
-OBJECT:'`',"boulder",(06,05)
-OBJECT:'`',"boulder",(07,05)
-OBJECT:'`',"boulder",(39,05)
-OBJECT:'`',"boulder",(08,08)
-OBJECT:'`',"boulder",(09,08)
-OBJECT:'`',"boulder",(10,08)
-OBJECT:'`',"boulder",(11,08)
-OBJECT:'`',"boulder",(06,10)
-OBJECT:'`',"boulder",(05,11)
-OBJECT:'`',"boulder",(06,11)
-OBJECT:'`',"boulder",(07,11)
-OBJECT:'`',"boulder",(21,11)
-OBJECT:'`',"boulder",(21,12)
-OBJECT:'`',"boulder",(13,13)
-OBJECT:'`',"boulder",(14,13)
-OBJECT:'`',"boulder",(15,13)
-OBJECT:'`',"boulder",(14,14)
+OBJECT:('`',"boulder"),(19,02)
+OBJECT:('`',"boulder"),(20,02)
+OBJECT:('`',"boulder"),(21,02)
+OBJECT:('`',"boulder"),(36,02)
+OBJECT:('`',"boulder"),(36,03)
+OBJECT:('`',"boulder"),(06,04)
+OBJECT:('`',"boulder"),(05,05)
+OBJECT:('`',"boulder"),(06,05)
+OBJECT:('`',"boulder"),(07,05)
+OBJECT:('`',"boulder"),(39,05)
+OBJECT:('`',"boulder"),(08,08)
+OBJECT:('`',"boulder"),(09,08)
+OBJECT:('`',"boulder"),(10,08)
+OBJECT:('`',"boulder"),(11,08)
+OBJECT:('`',"boulder"),(06,10)
+OBJECT:('`',"boulder"),(05,11)
+OBJECT:('`',"boulder"),(06,11)
+OBJECT:('`',"boulder"),(07,11)
+OBJECT:('`',"boulder"),(21,11)
+OBJECT:('`',"boulder"),(21,12)
+OBJECT:('`',"boulder"),(13,13)
+OBJECT:('`',"boulder"),(14,13)
+OBJECT:('`',"boulder"),(15,13)
+OBJECT:('`',"boulder"),(14,14)
+# Special rooms
+ALTAR:(24,07),noalign,sanctum
+REGION:(22,12,25,16),unlit,"morgue"
+REGION:(32,09,37,12),lit,"shop"
+REGION:(12,00,15,04),lit,"shop"
 # Doors
 DOOR:closed,(23,02)
@@ -345,9 +400,4 @@
 DOOR:open,(26,14)
 DOOR:closed,(06,15)
-# Special rooms
-ALTAR:(24,07),noalign,sanctum
-REGION:(22,12,25,16),unlit,"morgue"
-REGION:(32,09,37,12),lit,"shop"
-REGION:(12,00,15,04),lit,"shop"
 # Some traps.
 TRAP:"spiked pit", random
@@ -360,59 +410,62 @@
 TRAP:"magic", random
 # Some random objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # The resident nasty
-MONSTER:'&',"Orcus",(33,15)
+MONSTER:('&',"Orcus"),(33,15) {
+  OBJECT:('/',"death")
+}
 # And its preferred companions
-MONSTER:'Z',"human zombie",(32,15)
-MONSTER:' ',"shade",(32,14)
-MONSTER:' ',"shade",(32,16)
-MONSTER:'V',"vampire",(35,16)
-MONSTER:'V',"vampire",(35,14)
-MONSTER:'V',"vampire lord",(36,14)
-MONSTER:'V',"vampire lord",(36,15)
+MONSTER:('Z',"human zombie"),(32,15)
+MONSTER:(' ',"shade"),(32,14)
+MONSTER:(' ',"shade"),(32,16)
+MONSTER:('V',"vampire"),(35,16)
+MONSTER:('V',"vampire"),(35,14)
+MONSTER:('V',"vampire lord"),(36,14)
+MONSTER:('V',"vampire lord"),(36,15)
 # Randomly placed companions
-MONSTER:'Z',"skeleton",random
-MONSTER:'Z',"skeleton",random
-MONSTER:'Z',"skeleton",random
-MONSTER:'Z',"skeleton",random
-MONSTER:'Z',"skeleton",random
-MONSTER:' ',"shade",random
-MONSTER:' ',"shade",random
-MONSTER:' ',"shade",random
-MONSTER:' ',"shade",random
-MONSTER:'Z',"giant zombie",random
-MONSTER:'Z',"giant zombie",random
-MONSTER:'Z',"giant zombie",random
-MONSTER:'Z',"ettin zombie",random
-MONSTER:'Z',"ettin zombie",random
-MONSTER:'Z',"ettin zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'V',"vampire",random
-MONSTER:'V',"vampire",random
-MONSTER:'V',"vampire",random
-MONSTER:'V',"vampire lord",random
-MONSTER:'V',"vampire lord",random
+MONSTER:('Z',"skeleton"),random
+MONSTER:('Z',"skeleton"),random
+MONSTER:('Z',"skeleton"),random
+MONSTER:('Z',"skeleton"),random
+MONSTER:('Z',"skeleton"),random
+MONSTER:(' ',"shade"),random
+MONSTER:(' ',"shade"),random
+MONSTER:(' ',"shade"),random
+MONSTER:(' ',"shade"),random
+MONSTER:('Z',"giant zombie"),random
+MONSTER:('Z',"giant zombie"),random
+MONSTER:('Z',"giant zombie"),random
+MONSTER:('Z',"ettin zombie"),random
+MONSTER:('Z',"ettin zombie"),random
+MONSTER:('Z',"ettin zombie"),random
+MONSTER:('Z',"human zombie"),random
+MONSTER:('Z',"human zombie"),random
+MONSTER:('Z',"human zombie"),random
+MONSTER:('V',"vampire"),random
+MONSTER:('V',"vampire"),random
+MONSTER:('V',"vampire"),random
+MONSTER:('V',"vampire lord"),random
+MONSTER:('V',"vampire lord"),random
 # A few more for the party
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
 #
 # The Asmodeus Level
 #
-MAZE:"asmodeus",random
-FLAGS: noteleport
+LEVEL:"asmodeus"
+FLAGS: noteleport,mazelevel
+INIT_MAP:mazegrid,'-'
 # First part
 GEOMETRY:half-left,center
@@ -446,16 +499,19 @@
 REGION:(01,01,20,10),unlit,"ordinary"
 # The fellow in residence
-MONSTER:'&',"Asmodeus",(12,07)
+MONSTER:('&',"Asmodeus"),(12,07) {
+  OBJECT:('/',"cold")
+  OBJECT:('/',"fire")
+}
 # Some random weapons and armor.
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
-OBJECT:'*',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:')',random
+OBJECT:')',random
+OBJECT:'*',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
 # Some traps.
 TRAP:"spiked pit", (05,02)
@@ -467,11 +523,11 @@
 TRAP:"magic", random
 # Random monsters.
-MONSTER:' ',"ghost",(11,07)
-MONSTER:'&',"horned devil",(10,05)
-MONSTER:'L',random,random
+MONSTER:(' ',"ghost"),(11,07)
+MONSTER:('&',"horned devil"),(10,05)
+MONSTER:'L',random
 # Some Vampires for good measure
-MONSTER:'V',random,random
-MONSTER:'V',random,random
-MONSTER:'V',random,random
+MONSTER:'V',random
+MONSTER:'V',random
+MONSTER:'V',random
 # Second part
 GEOMETRY:half-right,center
@@ -487,7 +543,7 @@
 NON_DIGGABLE:(00,00,32,04)
 DOOR:closed,(32,02)
-MONSTER:'&',random,random
-MONSTER:'&',random,random
-MONSTER:'&',random,random
+MONSTER:'&',random
+MONSTER:'&',random
+MONSTER:'&',random
 TRAP:"anti magic", random
 TRAP:"fire", random
@@ -497,21 +553,31 @@
 # The Baalzebub level
 #
-MAZE:"baalz",random
-FLAGS: noteleport
-GEOMETRY:right,center
+LEVEL:"baalz"
+FLAGS: noteleport,mazelevel
+
+MON_GENERATION:80%, (5, 'a'), (1, 'P')
+
+$lvl = selection: fillrect(0,0,78,20)
+$sel = selection: filter(33%, $lvl)
+
+TERRAIN:$lvl, ('.',unlit)
+TERRAIN:$sel, ('}',unlit)
+
+
+GEOMETRY:center,center
 MAP
--------------------------------------------------
-|                    ---               ----      
-|          ----      |   ------------  |         
-| ------      |  --------|..........|---         
-| |....|  -------|...........--------------      
----....|--|..................S............|----  
-....--....S..----------------|............S...|  
----....|--|..................|............|----  
-| |....|  -------|...........-----S--------      
-| ------      |  --------|..........|---         
-|          ----     |    ------------  |         
-|                   ---                ----      
--------------------------------------------------
+xxxxxxxxxxxxxxxxxxxxxxxFxxxxxxxxxxxxxxxxxxFxxxxxx
+xxxxxxxxxxxFxxxxxxxxxFFFxxxxxxxxxxxxxxxFFFFxxxxxx
+xxxxxxxxxxxFFFFxxxxxxFxxx------------xxFxxxxxxxxx
+xxFFFFFFxxxxxxFxx--------|..........|FFFxxxxxxxxx
+xxF....Fxx-------|...........--------------xxxxxx
+---....|--|..................S............|----xx
+....--....S..----------------|............S...|xx
+---....|--|..................|............|----xx
+xxF....Fxx-------|...........-----S--------xxxxxx
+xxFFFFFFxxxxxxFxx--------|..........|FFFxxxxxxxxx
+xxxxxxxxxxxFFFFxxxxxFxxxx------------xxFxxxxxxxxx
+xxxxxxxxxxxFxxxxxxxxFFFxxxxxxxxxxxxxxxxFFFFxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxFxxxxxxxxxxxxxxxxxxFxxxxxx
 ENDMAP
 STAIR:levregion(01,00,15,20),levregion(15,1,70,16),up
@@ -519,19 +585,18 @@
 TELEPORT_REGION:levregion(01,00,15,20),levregion(15,1,70,16)
 NON_DIGGABLE:(00,00,46,12)
-MAZEWALK:(00,06),west
 STAIR:(44,06),down
 # The fellow in residence
-MONSTER:'&',"Baalzebub",(35,06)
+MONSTER:('&',"Baalzebub"),(35,06)
 # Some random weapons and armor.
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
-OBJECT:'*',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:')',random
+OBJECT:')',random
+OBJECT:'*',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
 # Some traps.
 TRAP:"spiked pit", random
@@ -539,22 +604,31 @@
 TRAP:"sleep gas", random
 TRAP:"anti magic", random
-TRAP:"fire", random
+TRAP:"rust", random
 TRAP:"magic", random
 TRAP:"magic", random
 # Random monsters.
-MONSTER:' ',"ghost",(37,07)
-MONSTER:'&',"horned devil",(32,05)
-MONSTER:'&',"barbed devil",(38,07)
-MONSTER:'L',random,random
+MONSTER:(' ',"ghost"),(37,07)
+MONSTER:('&',"horned devil"),(32,05)
+MONSTER:('&',"barbed devil"),(38,07)
+MONSTER:'L',random
 # Some Vampires for good measure
-MONSTER:'V',random,random
-MONSTER:'V',random,random
-MONSTER:'V',random,random
+MONSTER:'V',random
+MONSTER:'V',random
+MONSTER:'V',random
+
+LOOP [ 10 + 4d7 ] {
+  MONSTER:'a',random
+  MONSTER[25%]:'P',random
+}
+
 #
 # The Sanctum Level
 #
-MAZE:"sanctum", ' '
-FLAGS: noteleport,hardfloor,nommap
+LEVEL:"sanctum"
+FLAGS: noteleport,hardfloor,nommap,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
+#         1         2         3         4         5         6         7
+#123456789012345678901234567890123456789012345678901234567890123456789012345
 MAP
 ----------------------------------------------------------------------------
@@ -579,5 +653,7 @@
 ----------------------------------------------------------------------------
 ENDMAP
-REGION:(15,07,21,10),lit,"temple"
+REGION:(15,07,21,10),lit,"temple" {
+  ROOMDOOR:true, locked, north|south|east|west, random
+}
 ALTAR:(18,08),noalign,sanctum
 REGION:(41,06,48,11),unlit,"morgue",filled,true
@@ -591,4 +667,9 @@
 DOOR:closed,(46,12)
 DOOR:closed,(53,10)
+# Some mood lighting
+OBJECT:('\\',"brazier"),(08,09)
+OBJECT:('\\',"brazier"),(18,15)
+OBJECT:('\\',"brazier"),(28,05)
+OBJECT:('\\',"brazier"),(28,13)
 # Surround the temple with fire
 TRAP:"fire",(13,05)
@@ -634,41 +715,144 @@
 TRAP:"magic", random
 # Some random objects
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:'[',random,random
-OBJECT:')',random,random
-OBJECT:')',random,random
-OBJECT:'*',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:'[',random
+OBJECT:')',random
+OBJECT:')',random
+OBJECT:'*',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'?',random
 # Some monsters.
-MONSTER:'&',"horned devil",(14,12),hostile
-MONSTER:'&',"barbed devil",(18,08),hostile
-MONSTER:'&',"erinys",(10,04),hostile
-MONSTER:'&',"marilith",(07,09),hostile
-MONSTER:'&',"nalfeshnee",(27,08),hostile
+MONSTER:('&',"horned devil"),(14,12),hostile
+MONSTER:('&',"barbed devil"),(18,08),hostile
+MONSTER:('&',"erinys"),(10,04),hostile
+MONSTER:('&',"marilith"),(07,09),hostile
+MONSTER:('&',"nalfeshnee"),(27,08),hostile
 # Moloch's horde
-MONSTER:'@',"aligned priest",(20,03),noalign,hostile
-MONSTER:'@',"aligned priest",(15,04),noalign,hostile
-MONSTER:'@',"aligned priest",(11,05),noalign,hostile
-MONSTER:'@',"aligned priest",(11,07),noalign,hostile
-MONSTER:'@',"aligned priest",(11,09),noalign,hostile
-MONSTER:'@',"aligned priest",(11,12),noalign,hostile
-MONSTER:'@',"aligned priest",(15,13),noalign,hostile
-MONSTER:'@',"aligned priest",(17,13),noalign,hostile
-MONSTER:'@',"aligned priest",(21,13),noalign,hostile
+MONSTER:('@',"aligned priest"),(20,03),noalign,hostile
+MONSTER:('@',"aligned priest"),(15,04),noalign,hostile
+MONSTER:('@',"aligned priest"),(11,05),noalign,hostile
+MONSTER:('@',"aligned priest"),(11,07),noalign,hostile
+MONSTER:('@',"aligned priest"),(11,09),noalign,hostile
+MONSTER:('@',"aligned priest"),(11,12),noalign,hostile
+MONSTER:('@',"aligned priest"),(15,13),noalign,hostile
+MONSTER:('@',"aligned priest"),(17,13),noalign,hostile
+MONSTER:('@',"aligned priest"),(21,13),noalign,hostile
 # A few nasties
-MONSTER:'L',random,random
-MONSTER:'L',random,random
-MONSTER:'V',random,random
-MONSTER:'V',random,random
-MONSTER:'V',random,random
+MONSTER:'L',random
+MONSTER:'L',random
+MONSTER:'V',random
+MONSTER:'V',random
+MONSTER:'V',random
 STAIR:(63,15),up
+
+
+#	The "fill" level for Gehennom
+#
+#	This level is used to fill out any levels not occupied by
+#	specific levels as defined above.
+#
+LEVEL: "hellfill"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines,'.',' ',true,true,unlit,true,'L'
+TELEPORT_REGION:levregion(11,01,59,19),levregion(01,01,02,02)
+NOMAP
+#
+#  always put stairs relatively far apart
+#
+IF [50%] {
+  IF [50%] {
+    # Option 1: Up Left, Down Right
+    STAIR:levregion(01,01,20,20),levregion(40,10,44,12),up
+    STAIR:levregion(50,01,70,20),levregion(45,10,49,12),down
+  } ELSE {
+    # Option 2: Up Right, Down Left
+    STAIR:levregion(50,01,70,20),levregion(45,10,49,12),up
+    STAIR:levregion(01,01,20,20),levregion(40,10,44,12),down
+  }
+} ELSE {
+  IF [50%] {
+  # Option 3: Up Center, Down Elsewhere
+    STAIR:levregion(30,01,50,20),levregion(38,01,42,20),up
+    STAIR:levregion(01,01,70,20),levregion(30,01,50,20),down
+  } ELSE {
+  # Option 4: Down Center, Up Elsewhere
+    STAIR:levregion(01,01,70,20),levregion(30,01,50,20),up
+    STAIR:levregion(30,01,50,20),levregion(38,01,42,20),down
+  }
+}
+#
+$object = OBJECT:{ '(','/','=','+',')','[','?','*','%'}
+OBJECT: $object[0], random
+OBJECT: $object[0], random
+OBJECT: $object[1], random
+OBJECT: $object[2], random
+OBJECT: $object[3], random
+OBJECT: $object[4], random
+OBJECT: random, random
+OBJECT: random, random
+#
+$monster = MONSTER:{ 'V','D',' ','&','Z' }
+MONSTER:$monster[0],random,hostile
+MONSTER:$monster[0],random,hostile
+MONSTER:$monster[1],random,hostile
+MONSTER:$monster[1],random,hostile
+MONSTER:$monster[2],random,hostile
+MONSTER:$monster[3],random,hostile
+MONSTER:random,random,hostile
+MONSTER:'H',random,hostile
+# chance of evil critters
+IF [50%] {
+  MONSTER:'L',random,hostile
+} ELSE {
+  MONSTER:random,random,hostile
+}
+IF [66%] {
+# could be a snark now, so up the percentage a bit
+  MONSTER:'J',random,hostile
+} ELSE {
+  MONSTER:random,random,hostile
+}
+# chance of lava spillage, or maybe lava river?
+IF [50%] {
+	IF [60%] {
+	SPILL: random, 'L', north, 20
+	}
+	IF [60%] {
+	SPILL: random, 'L', south, 20
+	}
+	IF [60%] {
+	SPILL: random, 'L', east, 20
+	}
+	IF [60%] {
+	SPILL: random, 'L', west, 20
+	}
+} ELSE {
+	IF [50%] {
+		TERRAIN: grow(north|west, randline (30,00)-(50,19),10), 'L'
+	} ELSE {
+		TERRAIN: grow(north|west, randline (50,00)-(30,19),10), 'L'
+	}
+}
+
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+TRAP: random, random
+#
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Healer.des nethack/dat/Healer.des
--- nh_orig/dat/Healer.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Healer.des	2010-08-16 13:20:13.634708200 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Hea-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Hea-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"giant rat"), (16,'r'), (16,"snake"), (4,'Y')
 GEOMETRY:center,center
 MAP
@@ -23,5 +25,5 @@
 PPPP..........PPPPP.....|.S.|......-----------|S|.|......PPPPPP.PPP.......PP
 PPPPPP......PPPPPP......|.|.|......|...|......|.|.|.....PPPPPP...PP.......PP
-PPPPPPPPPPPPPPPPPPP.....+.|.|......S.\.S......|.|.+......PPPPPP.PPPP.......P
+PPPPPPPPPPPPPPPPPPP.....+.|.|......S...S......|.|.+......PPPPPP.PPPP.......P
 PPP...PPPPP...PPPP......|.|.|......|...|......|.|.|.......PPPPPPPPPPP.....PP
 PP.....PPP.....PPP......|.|S|-----------......|.S.|......PPPPPPPPPPPPPPPPPPP
@@ -34,4 +36,7 @@
 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
 ENDMAP
+
+REPLACE_TERRAIN:(01,01,74,18), 'P', '.', 15%
+
 # Dungeon Description
 REGION:(00,00,75,19),lit,"ordinary"
@@ -56,49 +61,60 @@
 DOOR:locked,(50,10)
 # Hippocrates
-MONSTER:'@',"Hippocrates",(37,10)
+OBJECT:('\',"throne"),(37,10)
+MONSTER:('@',"Hippocrates"),(37,10) {
+  OBJECT:'/'
+  OBJECT:'/'
+  OBJECT:'/'
+  OBJECT:'/'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:(')',"silver dagger"),1d4
+}
 # The treasure of Hippocrates
-OBJECT:'(',"chest",(37,10)
+OBJECT:('(',"chest"),(37,10)
 # intern guards for the audience chamber
-MONSTER:'@',"attendant",(29,08)
-MONSTER:'@',"attendant",(29,09)
-MONSTER:'@',"attendant",(29,10)
-MONSTER:'@',"attendant",(29,11)
-MONSTER:'@',"attendant",(40,09)
-MONSTER:'@',"attendant",(40,10)
-MONSTER:'@',"attendant",(40,11)
-MONSTER:'@',"attendant",(40,13)
+MONSTER:('@',"attendant"),(29,08) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(29,09) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(29,10) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(29,11) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(40,09) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(40,10) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(40,11) {
+  OBJECT[50%]:random
+}
+MONSTER:('@',"attendant"),(40,13) {
+  OBJECT[50%]:random
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Random traps
+LOOP [5 + 1d3] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Monsters on siege duty.
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: 'r',"rabid rat",random
-MONSTER: ';',"giant eel",random
-MONSTER: ';',"shark",random
-MONSTER: ';', random, random
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
+LOOP [8 + 1d6] {
+  MONSTER: ('r',"rabid rat"),random
+}
+MONSTER: (';',"giant eel"),random
+MONSTER: (';',"shark"),random
+MONSTER: ';', random
+LOOP [3 + 1d5] {
+  MONSTER: 'D',random,hostile
+}
+LOOP [3 + 1d5] {
+  MONSTER: 'S',random,hostile
+}
 #
 #	The "locate" level for the quest.
@@ -108,8 +124,9 @@
 #
 
-MAZE: "Hea-loca",' '
-FLAGS: hardfloor
+LEVEL: "Hea-loca"
+FLAGS: hardfloor,mazelevel
 #
-INIT_MAP: '.' , 'P', true , true , lit , false
+INIT_MAP: mines, '.' , 'P', true , true , lit , false
+MON_GENERATION:86%, (64,"giant rat"), (16,'r'), (16,"snake"), (4,'Y')
 GEOMETRY:center,center
 MAP
@@ -141,62 +158,29 @@
 ALTAR:(13,05), chaos, shrine
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 2d5] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [4 + 2d3] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',random,random,hostile
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"kraken",random
-MONSTER:';',"shark",random
-MONSTER:';',"shark",random
-MONSTER:';',random, random,hostile
-MONSTER:';',random, random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
+LOOP [8 + 2d4] {
+  MONSTER:('r',"rabid rat"),random
+  MONSTER[50%]:(';',"giant eel"),random
+  MONSTER[30%]:(';',"electric eel"),random
+}
+MONSTER:'r',random,hostile
+MONSTER:(';',"kraken"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"shark"),random
+MONSTER:';',random, hostile
+MONSTER:';',random, hostile
+LOOP [3 + 1d6] {
+  MONSTER: 'D',random,hostile
+}
+LOOP [8 + 2d3] {
+  MONSTER: 'S',random,hostile
+}
 
 #
@@ -208,7 +192,9 @@
 #
 
-MAZE: "Hea-goal", 'P'
+LEVEL: "Hea-goal"
+FLAGS:mazelevel
 #
-INIT_MAP: '.' , 'P' , false , true , lit , false
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"giant rat"), (16,'r'), (16,"snake"), (4,'Y')
 GEOMETRY:center,center
 MAP
@@ -233,60 +219,38 @@
 NON_DIGGABLE:(00,00,40,11)
 # Objects
-OBJECT:')',"quarterstaff",(20,06),blessed,0,"The Staff of Aesculapius"
-OBJECT:'/',"lightning",(20,06)
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:(')',"quarterstaff"),(20,06),blessed,0,NAME:"The Staff of Aesculapius"
+OBJECT:('/',"lightning"),(20,06)
+LOOP [10 + 1d5] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [3 + 2d3] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'H',"Cyclops",(20,06),hostile
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',"rabid rat",random
-MONSTER:'r',random,random,hostile
-MONSTER:'r',random,random,hostile
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"giant eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"electric eel",random
-MONSTER:';',"shark",random
-MONSTER:';',"shark",random
-MONSTER:';',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
+MONSTER:('H',"Cyclops"),(20,06),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'[',1d3
+}
+MONSTER:('r',"rabid rat"),random
+MONSTER:('r',"rabid rat"),random
+MONSTER:('r',"rabid rat"),random
+MONSTER:'r',random,hostile
+MONSTER:'r',random,hostile
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"electric eel"),random
+MONSTER:(';',"shark"),random
+MONSTER:(';',"shark"),random
+MONSTER:';',random, hostile
+LOOP [5 + 2d5] {
+  MONSTER[90%]: 'D',random,hostile
+  MONSTER: 'S',random,hostile
+}
 
 #
@@ -299,6 +263,8 @@
 #
 
-MAZE: "Hea-fila" , 'P'
-INIT_MAP: '.' , 'P' , false , true , lit , false
+LEVEL: "Hea-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"giant rat"), (16,'r'), (16,"snake"), (4,'Y')
 NOMAP
 #
@@ -306,34 +272,27 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 1d10] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'r', "rabid rat", random
-MONSTER: 'r', random, random,hostile
-MONSTER: 'r', random, random,hostile
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "electric eel", random
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
+MONSTER: ('r', "rabid rat"), random
+MONSTER: 'r', random, hostile
+MONSTER: 'r', random, hostile
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "electric eel"), random
+LOOP [3 + 1d4] {
+  MONSTER: 'D',random,hostile
+  MONSTER[90%]: 'S',random,hostile
+}
 #
+LOOP [3 + 1d3] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 
-MAZE: "Hea-filb" , 'P'
-INIT_MAP: '.' , 'P' , false , true , lit , false
+LEVEL: "Hea-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"giant rat"), (16,'r'), (16,"snake"), (4,'Y')
 NOMAP
 #
@@ -341,37 +300,25 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 1d10] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'r', "rabid rat", random
-MONSTER: 'r', "rabid rat", random
-MONSTER: 'r', random, random,hostile
-MONSTER: 'r', random, random,hostile
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "giant eel", random
-MONSTER: ';', "electric eel", random
-MONSTER: ';', "electric eel", random
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'D',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
-MONSTER: 'S',random,random,hostile
+MONSTER: ('r', "rabid rat"), random
+MONSTER: ('r', "rabid rat"), random
+MONSTER: 'r', random, hostile
+MONSTER: 'r', random, hostile
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "giant eel"), random
+MONSTER: (';', "electric eel"), random
+MONSTER: (';', "electric eel"), random
+LOOP [3 + 1d5] {
+  MONSTER: 'D',random,hostile
+  MONSTER[90%]: 'S',random,hostile
+}
 #
+LOOP [3 + 1d3] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/help nethack/dat/help
--- nh_orig/dat/help	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/help	2009-09-08 10:31:12.303292627 -0400
@@ -159,4 +159,6 @@
         *       Tell what equipment you are using; combines the preceding five.
         $       Count your gold pieces.
+        %       Set your chosen ranged weapon; this weapon will be auto-wielded
+                when you attempt to 'f'ire a missile.
         +       List the spells you know; also rearrange them if desired.
         \       Show what types of objects have been discovered.
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/hh nethack/dat/hh
--- nh_orig/dat/hh	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/hh	2009-09-08 10:30:53.085295913 -0400
@@ -73,4 +73,5 @@
 *               ask for combination of ),[,=,",( all at once
 $       gold    count your gold
+%       rwield  assign chosen ranged weapon
 +       spells  list the spells you know; also rearrange them if desired
 _       travel  move via a shortest-path algorithm to a point on the map 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Knight.des nethack/dat/Knight.des
--- nh_orig/dat/Knight.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Knight.des	2010-08-16 13:20:13.635707386 -0400
@@ -9,8 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Kni-strt",'.'
-FLAGS: noteleport,hardfloor
-# This is a kludge to init the level as a lit field.
-INIT_MAP: '.' , '.' , false , false , lit , false
+LEVEL: "Kni-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP: solidfill, ('.', lit)
+MON_GENERATION:86%, (64,"quasit"), (16,'i'), (16,"ochre jelly"), (4,'j')
 GEOMETRY:center,center
 MAP
@@ -22,5 +22,5 @@
 ...|.|-----------------|++|-----------------|.|...
 ...|.|.................|..|.........|.......|.|...
-...|.|...\.............+..+.........|.......|.|...
+...|.|.................+..+.........|.......|.|...
 ...|.|.................+..+.........+.......|.|...
 ...|.|.................|..|.........|.......|.|...
@@ -61,19 +61,53 @@
 DOOR:closed,(45,12)
 # King Arthur
-MONSTER:'@',"King Arthur",(09,07)
+OBJECT:('\',"throne"),(09,07)
+MONSTER:('@',"King Arthur"),(09,07) {
+  OBJECT:(')',"silver long sword"),1d4
+  OBJECT:'[',1d3
+}
 # The treasure of King Arthur
-OBJECT:'(',"chest",(09,07)
+OBJECT:('(',"chest"),(09,07)
 # knight guards for the watchrooms
-MONSTER:'@',"knight",(04,02),peaceful
-MONSTER:'@',"knight",(04,13),peaceful
-MONSTER:'@',"knight",(45,02),peaceful
-MONSTER:'@',"knight",(45,13),peaceful
+MONSTER:('@',"knight"),(04,02),peaceful {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"knight"),(04,13),peaceful {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"knight"),(45,02),peaceful {
+  OBJECT:')'
+  OBJECT:'['
+}
+MONSTER:('@',"knight"),(45,13),peaceful {
+  OBJECT:')'
+  OBJECT:'['
+}
 # page guards for the audience chamber
-MONSTER:'@',"page",(16,06)
-MONSTER:'@',"page",(18,06)
-MONSTER:'@',"page",(20,06)
-MONSTER:'@',"page",(16,09)
-MONSTER:'@',"page",(18,09)
-MONSTER:'@',"page",(20,09)
+MONSTER:('@',"page"),(16,06) {
+  OBJECT:')'
+  OBJECT:'?'
+}
+MONSTER:('@',"page"),(18,06) {
+  OBJECT:'?'
+  OBJECT:'['
+}
+MONSTER:('@',"page"),(20,06) {
+  OBJECT:'?'
+  OBJECT:'['
+}
+MONSTER:('@',"page"),(16,09) {
+  OBJECT:'?'
+  OBJECT:'?'
+}
+MONSTER:('@',"page"),(18,09) {
+  OBJECT:'?'
+  OBJECT:'?'
+}
+MONSTER:('@',"page"),(20,09) {
+  OBJECT:'?'
+  OBJECT:'['
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,49,15)
@@ -86,16 +120,16 @@
 TRAP:random,random
 # Monsters on siege duty.
-MONSTER: 'i',"quasit",(14,00),hostile
-MONSTER: 'i',"quasit",(16,00),hostile
-MONSTER: 'i',"quasit",(18,00),hostile
-MONSTER: 'i',"quasit",(20,00),hostile
-MONSTER: 'i',"quasit",(22,00),hostile
-MONSTER: 'i',"quasit",(24,00),hostile
-MONSTER: 'i',"quasit",(26,00),hostile
-MONSTER: 'i',"quasit",(28,00),hostile
-MONSTER: 'i',"quasit",(30,00),hostile
-MONSTER: 'i',"quasit",(32,00),hostile
-MONSTER: 'i',"quasit",(34,00),hostile
-MONSTER: 'i',"quasit",(36,00),hostile
+MONSTER: ('i',"quasit"),(14,00),hostile
+MONSTER: ('i',"quasit"),(16,00),hostile
+MONSTER: ('i',"quasit"),(18,00),hostile
+MONSTER: ('i',"quasit"),(20,00),hostile
+MONSTER: ('i',"quasit"),(22,00),hostile
+MONSTER: ('i',"quasit"),(24,00),hostile
+MONSTER: ('i',"quasit"),(26,00),hostile
+MONSTER: ('i',"quasit"),(28,00),hostile
+MONSTER: ('i',"quasit"),(30,00),hostile
+MONSTER: ('i',"quasit"),(32,00),hostile
+MONSTER: ('i',"quasit"),(34,00),hostile
+MONSTER: ('i',"quasit"),(36,00),hostile
 
 #
@@ -106,7 +140,8 @@
 #
 
-MAZE: "Kni-loca",' '
-FLAGS: hardfloor
-INIT_MAP: '.' , 'P' , false , true , lit , false
+LEVEL: "Kni-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"quasit"), (16,'i'), (16,"ochre jelly"), (4,'j')
 GEOMETRY:center,center
 MAP
@@ -135,19 +170,7 @@
 ALTAR:(17,05),neutral,shrine
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 2d5] {
+  OBJECT:random,random
+}
 # Random traps
 # All of the avenues are guarded by magic except for the East.
@@ -201,39 +224,17 @@
 TRAP:"magic",(32,00)
 # Even so, there are magic "sinkholes" around.
+LOOP [5 + 2d6] {
 TRAP:"anti magic",random
-TRAP:"anti magic",random
-TRAP:"anti magic",random
-TRAP:"anti magic",random
-TRAP:"anti magic",random
-TRAP:"anti magic",random
-TRAP:"anti magic",random
+}
 # Random monsters.
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'j',random,random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',random,random,hostile
+LOOP [10 + 3d8] {
+  MONSTER:('i',"quasit"),random,hostile
+}
+MONSTER:'i',random,hostile
+MONSTER:'j',random,hostile
+LOOP [5 + 2d5] {
+  MONSTER:('j',"ochre jelly"),random,hostile
+}
+MONSTER:'j',random,hostile
 
 #
@@ -245,5 +246,8 @@
 #
 
-MAZE: "Kni-goal", ' '
+LEVEL: "Kni-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"quasit"), (16,'i'), (16,"ochre jelly"), (4,'j')
 GEOMETRY:center,center
 MAP
@@ -269,4 +273,7 @@
 .......PPPP...                                                              
 ENDMAP
+
+REPLACE_TERRAIN:(00,00,15,19), '.', 'P', 15%
+
 # Dungeon Description
 REGION:(00,00,14,19),lit,"ordinary"
@@ -277,64 +284,45 @@
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:'(',"mirror",(50,06),blessed,0,"The Magic Mirror of Merlin"
-OBJECT:random,random,(33,01)
-OBJECT:random,random,(33,02)
-OBJECT:random,random,(33,03)
-OBJECT:random,random,(33,04)
-OBJECT:random,random,(33,05)
-OBJECT:random,random,(34,01)
-OBJECT:random,random,(34,02)
-OBJECT:random,random,(34,03)
-OBJECT:random,random,(34,04)
-OBJECT:random,random,(34,05)
-OBJECT:random,random,(35,01)
-OBJECT:random,random,(35,02)
-OBJECT:random,random,(35,03)
-OBJECT:random,random,(35,04)
-OBJECT:random,random,(35,05)
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"mirror"),(50,06),blessed,0,NAME:"The Magic Mirror of Merlin"
+OBJECT:random,(33,01)
+OBJECT:random,(33,02)
+OBJECT:random,(33,03)
+OBJECT:random,(33,04)
+OBJECT:random,(33,05)
+OBJECT:random,(34,01)
+OBJECT:random,(34,02)
+OBJECT:random,(34,03)
+OBJECT:random,(34,04)
+OBJECT:random,(34,05)
+OBJECT:random,(35,01)
+OBJECT:random,(35,02)
+OBJECT:random,(35,03)
+OBJECT:random,(35,04)
+OBJECT:random,(35,05)
+LOOP [3 + 1d3] {
+  OBJECT:random,random
+}
 # Random traps
 TRAP:"spiked pit",(13,07)
 TRAP:"spiked pit",(12,08)
 TRAP:"spiked pit",(12,09)
+LOOP [2 + 2d2] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'D',"Ixoth",(50,06),hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',"quasit",random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',"ochre jelly",random,hostile
-MONSTER:'j',random,random,hostile
+MONSTER:('D',"Ixoth"),(50,06),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'?'
+  OBJECT:'?'
+}
+LOOP [10 + 3d8] {
+  MONSTER:('i',"quasit"),random,hostile
+}
+MONSTER:'i',random,hostile
+MONSTER:'i',random,hostile
+LOOP [5 + 2d5] {
+  MONSTER:('j',"ochre jelly"),random,hostile
+}
+MONSTER:'j',random,hostile
 
 #
@@ -347,6 +335,8 @@
 #
 
-MAZE: "Kni-fila" , '.'
-INIT_MAP: '.' , 'P' , false , true , lit , false
+LEVEL: "Kni-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"quasit"), (16,'i'), (16,"ochre jelly"), (4,'j')
 NOMAP
 #
@@ -354,27 +344,22 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [6 + 2d4] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', random, random, hostile
-MONSTER: 'j', "ochre jelly", random, hostile
+LOOP [3 + 1d4] {
+  MONSTER: ('i', "quasit"), random, hostile
+}
+MONSTER: 'i', random, hostile
+MONSTER: ('j', "ochre jelly"), random, hostile
 #
+LOOP [3 + 1d5] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 
-MAZE: "Kni-filb" , '.'
-INIT_MAP: '.' , 'P' , false , true , lit , false
+LEVEL: "Kni-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'P' , false , true , lit , false
+MON_GENERATION:86%, (64,"quasit"), (16,'i'), (16,"ochre jelly"), (4,'j')
 NOMAP
 #
@@ -382,27 +367,17 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [6 + 2d4] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', "quasit", random, hostile
-MONSTER: 'i', random, random, hostile
-MONSTER: 'j', "ochre jelly", random, hostile
-MONSTER: 'j', "ochre jelly", random, hostile
-MONSTER: 'j', "ochre jelly", random, hostile
+LOOP [3 + 1d4] {
+  MONSTER: ('i', "quasit"), random, hostile
+}
+MONSTER: 'i', random, hostile
+LOOP [3 + 1d4] {
+  MONSTER: ('j', "ochre jelly"), random, hostile
+}
 #
+LOOP [3 + 1d5] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/knox.des nethack/dat/knox.des
--- nh_orig/dat/knox.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/knox.des	2010-04-11 12:36:58.219625888 -0400
@@ -1,9 +1,10 @@
-#	SCCS Id: @(#)knox.des	3.4	1994/08/20
+#	SCCS37 Id: @(#)knox.des	3.4	1994/08/20
 #	Copyright (c) 1989 by Jean-Christophe Collet
 #	Copyright (c) 1992 by Izchak Miller
 # NetHack may be freely redistributed.  See license for details.
 #
-MAZE:"knox",' '
-FLAGS: noteleport
+LEVEL:"knox"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -18,5 +19,5 @@
 |     |..........}}}|...............|..........|}}}.................+...|..|
 | -------..........}|...............S..........|}...................|...|..|
-| |.....|..........}|...............|......\...S}...................|...|..|
+| |.....|..........}|...............|..........S}...................|...|..|
 | |.....+........}}}|...............|..........|}}}.................+...|..|
 | |.....|........}---S------------------------S---}.................|...|..|
@@ -34,6 +35,10 @@
 BRANCH:(08,16,08,16),(0,0,0,0)
 #   Throne room, with Croesus on the throne
+OBJECT:('\',"throne"),(43,10)
 REGION:(37,08,46,11),lit,"throne"
-MONSTER:'@',"Croesus",(43,10),hostile
+MONSTER:('@',"Croesus"),(43,10),hostile {
+  OBJECT:(')',"two-handed sword")
+  OBJECT:'['
+}
 #   The Vault
 #   Using unfilled morgue for
@@ -63,42 +68,42 @@
 DOOR:closed,(66,14)
 # Soldiers guarding the fort
-MONSTER:'@',"soldier",(12,14)
-MONSTER:'@',"soldier",(12,13)
-MONSTER:'@',"soldier",(11,10)
-MONSTER:'@',"soldier",(13,02)
-MONSTER:'@',"soldier",(14,03)
-MONSTER:'@',"soldier",(20,02)
-MONSTER:'@',"soldier",(30,02)
-MONSTER:'@',"soldier",(40,02)
-MONSTER:'@',"soldier",(30,16)
-MONSTER:'@',"soldier",(32,16)
-MONSTER:'@',"soldier",(40,16)
-MONSTER:'@',"soldier",(54,16)
-MONSTER:'@',"soldier",(54,14)
-MONSTER:'@',"soldier",(54,13)
-MONSTER:'@',"soldier",(57,10)
-MONSTER:'@',"soldier",(57,09)
-MONSTER:'@',"lieutenant",(15,08)
+MONSTER:('@',"soldier"),(12,14)
+MONSTER:('@',"soldier"),(12,13)
+MONSTER:('@',"soldier"),(11,10)
+MONSTER:('@',"soldier"),(13,02)
+MONSTER:('@',"soldier"),(14,03)
+MONSTER:('@',"soldier"),(20,02)
+MONSTER:('@',"soldier"),(30,02)
+MONSTER:('@',"soldier"),(40,02)
+MONSTER:('@',"soldier"),(30,16)
+MONSTER:('@',"soldier"),(32,16)
+MONSTER:('@',"soldier"),(40,16)
+MONSTER:('@',"soldier"),(54,16)
+MONSTER:('@',"soldier"),(54,14)
+MONSTER:('@',"soldier"),(54,13)
+MONSTER:('@',"soldier"),(57,10)
+MONSTER:('@',"soldier"),(57,09)
+MONSTER:('@',"lieutenant"),(15,08)
 # Four dragons guarding each side
-MONSTER:'D',random,(18,09)
-MONSTER:'D',random,(49,10)
-MONSTER:'D',random,(33,05)
-MONSTER:'D',random,(33,14)
+MONSTER:'D',(18,09)
+MONSTER:'D',(49,10)
+MONSTER:'D',(33,05)
+MONSTER:'D',(33,14)
 # Eels in the moat
-MONSTER:';',"giant eel",(17,08)
-MONSTER:';',"giant eel",(17,11)
-MONSTER:';',"giant eel",(48,08)
-MONSTER:';',"giant eel",(48,11)
+MONSTER:(';',"giant eel"),(17,08)
+MONSTER:(';',"giant eel"),(17,11)
+MONSTER:(';',"giant eel"),(48,08)
+MONSTER:(';',"giant eel"),(48,11)
 # The corner rooms treasures
-OBJECT:'*',"diamond",(19,06)
-OBJECT:'*',"diamond",(20,06)
-OBJECT:'*',"diamond",(21,06)
-OBJECT:'*',"emerald",(19,13)
-OBJECT:'*',"emerald",(20,13)
-OBJECT:'*',"emerald",(21,13)
-OBJECT:'*',"ruby",(46,06)
-OBJECT:'*',"ruby",(47,06)
-OBJECT:'*',"ruby",(48,06)
-OBJECT:'*',"amethyst",(46,13)
-OBJECT:'*',"amethyst",(47,13)
-OBJECT:'*',"amethyst",(48,13)
+OBJECT:('*',"diamond"),(19,06)
+OBJECT:('*',"diamond"),(20,06)
+OBJECT:('*',"diamond"),(21,06)
+OBJECT:('*',"emerald"),(19,13)
+OBJECT:('*',"emerald"),(20,13)
+OBJECT:('*',"emerald"),(21,13)
+OBJECT:('*',"ruby"),(46,06)
+OBJECT:('*',"ruby"),(47,06)
+OBJECT:('*',"ruby"),(48,06)
+OBJECT:('*',"amethyst"),(46,13)
+OBJECT:('*',"amethyst"),(47,13)
+OBJECT:('*',"amethyst"),(48,13)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/medusa.des nethack/dat/medusa.des
--- nh_orig/dat/medusa.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/medusa.des	2010-04-11 12:36:58.163626289 -0400
@@ -7,6 +7,7 @@
 #
 
-MAZE:"medusa-1",' '
-FLAGS: noteleport
+LEVEL:"medusa-1"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -32,4 +33,7 @@
 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
 ENDMAP
+
+REPLACE_TERRAIN:(01,01,73,18), '}', '.', 5%
+
 # Dungeon Description
 # (must maintain one room definition; `unfilled' forces its room to be kept)
@@ -54,26 +58,27 @@
 NON_DIGGABLE:(30,06,46,13)
 # Objects
-CONTAINER:'`',"statue",(36,10),uncursed,"knight",3,"Perseus"
-OBJECT[75%]:'[',"shield of reflection",contained,cursed,+0
-OBJECT[25%]:'[',"levitation boots",contained,random,+0
-OBJECT[50%]:')',"scimitar",contained,blessed,+2
-OBJECT[50%]:'(',"sack",contained
+CONTAINER:('`',"statue"),(36,10),uncursed,montype:"knight",3,NAME:"Perseus" {
+  OBJECT[25%]:('[',"shield of reflection"),cursed,+0
+  OBJECT[75%]:('[',"levitation boots"),+0
+  OBJECT[50%]:(')',"scimitar"),blessed,+2
+  OBJECT[50%]:('(',"sack")
+}
 # These aren't really containers, but specifying CONTAINER forces them to be
 # empty, since CONTAINERs contain only what is explicitly specified.
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-CONTAINER:'`',"statue",random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Random traps
 TRAP:random,random
@@ -85,28 +90,29 @@
 TRAP:"board",(38,12)
 # Random monsters
-MONSTER:'@',"Medusa",(36,10),asleep
-MONSTER:';',"giant eel",(11,06)
-MONSTER:';',"giant eel",(23,13)
-MONSTER:';',"giant eel",(29,02)
-MONSTER:';',"jellyfish",(02,02)
-MONSTER:';',"jellyfish",(00,08)
-MONSTER:';',"jellyfish",(04,18)
-MONSTER:'T',"water troll",(51,03)
-MONSTER:'T',"water troll",(64,11)
-MONSTER:'S',random,(38,07)
-MONSTER:'S',random,(38,12)
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+MONSTER:('@',"Medusa"),(36,10),asleep
+MONSTER:(';',"giant eel"),(11,06)
+MONSTER:(';',"giant eel"),(23,13)
+MONSTER:(';',"giant eel"),(29,02)
+MONSTER:(';',"jellyfish"),(02,02)
+MONSTER:(';',"jellyfish"),(00,08)
+MONSTER:(';',"jellyfish"),(04,18)
+MONSTER:('T',"water troll"),(51,03)
+MONSTER:('T',"water troll"),(64,11)
+MONSTER:'S',(38,07)
+MONSTER:'S',(38,12)
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
 
-MAZE:"medusa-2",' '
-FLAGS: noteleport
+LEVEL:"medusa-2"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -132,4 +138,7 @@
 }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
 ENDMAP
+
+REPLACE_TERRAIN:(01,01,73,18), '}', '.', 5%
+
 # Dungeon Description
 REGION:(00,00,74,19),lit,"ordinary"
@@ -152,26 +161,27 @@
 NON_DIGGABLE:(60,02,73,17)
 # Objects
-CONTAINER:'`',"statue",(68,10),uncursed,"knight",3,"Perseus"
-OBJECT[25%]:'[',"shield of reflection",contained,cursed,+0
-OBJECT[75%]:'[',"levitation boots",contained,random,+0
-OBJECT[50%]:')',"scimitar",contained,blessed,+2
-OBJECT[50%]:'(',"sack",contained
-CONTAINER:'`',"statue",(64,08)
-CONTAINER:'`',"statue",(65,08)
-CONTAINER:'`',"statue",(64,09)
-CONTAINER:'`',"statue",(65,09)
-CONTAINER:'`',"statue",(64,10)
-CONTAINER:'`',"statue",(65,10)
-CONTAINER:'`',"statue",(64,11)
-CONTAINER:'`',"statue",(65,11)
-OBJECT:'`',"boulder",(04,04)
-OBJECT:'/',random,(52,09)
-OBJECT:'`',"boulder",(52,09)
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+CONTAINER:('`',"statue"),(68,10),uncursed,montype:"knight",3,NAME:"Perseus" {
+  OBJECT[25%]:('[',"shield of reflection"),cursed,+0
+  OBJECT[75%]:('[',"levitation boots"),+0
+  OBJECT[50%]:(')',"scimitar"),blessed,+2
+  OBJECT[50%]:('(',"sack")
+}
+CONTAINER:('`',"statue"),(64,08) { }
+CONTAINER:('`',"statue"),(65,08) { }
+CONTAINER:('`',"statue"),(64,09) { }
+CONTAINER:('`',"statue"),(65,09) { }
+CONTAINER:('`',"statue"),(64,10) { }
+CONTAINER:('`',"statue"),(65,10) { }
+CONTAINER:('`',"statue"),(64,11) { }
+CONTAINER:('`',"statue"),(65,11) { }
+OBJECT:('`',"boulder"),(04,04)
+OBJECT:'/',(52,09)
+OBJECT:('`',"boulder"),(52,09)
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Traps
 TRAP:"magic",(03,12)
@@ -181,35 +191,288 @@
 TRAP:random,random
 # Monsters.
-MONSTER:'@',"Medusa",(68,10),asleep
-MONSTER:'g',"gremlin",(02,14)
-MONSTER:'H',"titan",(02,05)
-MONSTER:';',"electric eel",(10,13)
-MONSTER:';',"electric eel",(11,13)
-MONSTER:';',"electric eel",(10,14)
-MONSTER:';',"electric eel",(11,14)
-MONSTER:';',"electric eel",(10,15)
-MONSTER:';',"electric eel",(11,15)
-MONSTER:';',"jellyfish",(01,01)
-MONSTER:';',"jellyfish",(00,08)
-MONSTER:';',"jellyfish",(04,19)
-MONSTER:''',"stone golem",(64,08),asleep
-MONSTER:''',"stone golem",(65,08),asleep
-MONSTER:''',"stone golem",(64,09),asleep
-MONSTER:''',"stone golem",(65,09),asleep
-MONSTER:'S',"cobra",(64,10),asleep
-MONSTER:'S',"cobra",(65,10),asleep
-MONSTER:'A',random,(72,08)
-MONSTER:'y',"yellow light",(72,11),asleep
-MONSTER:random,random,(17,07)
-MONSTER:random,random,(28,11)
-MONSTER:random,random,(32,13)
-MONSTER:random,random,(49,09)
-MONSTER:random,random,(48,07)
-MONSTER:random,random,(65,03)
-MONSTER:random,random,(70,04)
-MONSTER:random,random,(70,15)
-MONSTER:random,random,(65,16)
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
+MONSTER:('@',"Medusa"),(68,10),asleep
+MONSTER:('g',"gremlin"),(02,14)
+MONSTER:('H',"titan"),(02,05)
+MONSTER:(';',"electric eel"),(10,13)
+MONSTER:(';',"electric eel"),(11,13)
+MONSTER:(';',"electric eel"),(10,14)
+MONSTER:(';',"electric eel"),(11,14)
+MONSTER:(';',"electric eel"),(10,15)
+MONSTER:(';',"electric eel"),(11,15)
+MONSTER:(';',"jellyfish"),(01,01)
+MONSTER:(';',"jellyfish"),(00,08)
+MONSTER:(';',"jellyfish"),(04,19)
+MONSTER:(''',"stone golem"),(64,08),asleep
+MONSTER:(''',"stone golem"),(65,08),asleep
+MONSTER:(''',"stone golem"),(64,09),asleep
+MONSTER:(''',"stone golem"),(65,09),asleep
+MONSTER:('S',"cobra"),(64,10),asleep
+MONSTER:('S',"cobra"),(65,10),asleep
+MONSTER:'A',(72,08)
+MONSTER:('y',"yellow light"),(72,11),asleep
+MONSTER:random,(17,07)
+MONSTER:random,(28,11)
+MONSTER:random,(32,13)
+MONSTER:random,(49,09)
+MONSTER:random,(48,07)
+MONSTER:random,(65,03)
+MONSTER:random,(70,04)
+MONSTER:random,(70,15)
+MONSTER:random,(65,16)
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+MONSTER:random,random
+
+LEVEL:"medusa-3"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+#
+# Here you disturb ravens nesting in the trees.
+#
+MAP
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}.}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}T..T.}}}}}}}}}}}}}}}}}}}}..}}}}}}}}.}}}...}}}}}}}.}}}}}......}}}}}}}
+}}}}}}.......T.}}}}}}}}}}}..}}}}..T.}}}}}}...T...T..}}...T..}}..-----..}}}}}
+}}}...-----....}}}}}}}}}}.T..}}}}}...}}}}}.....T..}}}}}......T..|...|.T..}}}
+}}}.T.|...|...T.}}}}}}}.T......}}}}..T..}}.}}}.}}...}}}}}.T.....+...|...}}}}
+}}}}..|...|.}}.}}}}}.....}}}T.}}}}.....}}}}}}.T}}}}}}}}}}}}}..T.|...|.}}}}}}
+}}}}}.|...|.}}}}}}..T..}}}}}}}}}}}}}T.}}}}}}}}..}}}}}}}}}}}.....-----.}}}}}}
+}}}}}.--+--..}}}}}}...}}}}}}}}}}}}}}}}}}}T.}}}}}}}}}}}}}}}}.T.}........}}}}}
+}}}}}.......}}}}}}..}}}}}}}}}.}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.}}}.}}.T.}}}}}}
+}}.T...T...}}}}T}}}}}}}}}}}....}}}}}}}}}}T}}}}}.T}}...}}}}}}}}}}}}}}...}}}}}
+}}}...T}}}}}}}..}}}}}}}}}}}.T...}}}}}}}}.T.}.T.....T....}}}}}}}}}}}}}.}}}}}}
+}}}}}}}}}}}}}}}....}}}}}}}...}}.}}}}}}}}}}............T..}}}}}.T.}}}}}}}}}}}
+}}}}}}}}}}}}}}}}..T..}}}}}}}}}}}}}}..}}}}}..------+--...T.}}}....}}}}}}}}}}}
+}}}}.}..}}}}}}}.T.....}}}}}}}}}}}..T.}}}}.T.|...|...|....}}}}}.}}}}}...}}}}}
+}}}.T.}...}..}}}}T.T.}}}}}}.}}}}}}}....}}...|...+...|.}}}}}}}}}}}}}..T...}}}
+}}}}..}}}.....}}...}}}}}}}...}}}}}}}}}}}}}T.|...|...|}}}}}}}}}}}....T..}}}}}
+}}}}}..}}}.T..}}}.}}}}}}}}.T..}}}}}}}}}}}}}}---S-----}}}}}}}}}}}}}....}}}}}}
+}}}}}}}}}}}..}}}}}}}}}}}}}}}.}}}}}}}}}}}}}}}}}T..T}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+ENDMAP
+
+REPLACE_TERRAIN:(01,01,73,18), '}', '.', 5%
+
+$place = { (08,06),(66,05),(46,15) }
+SHUFFLE: $place
+REGION:(00,00,74,19),lit,"ordinary"
+REGION:(49,14,51,16),random,"ordinary",unfilled
+REGION:(07,05,09,07),unlit,"ordinary"
+REGION:(65,04,67,06),unlit,"ordinary"
+REGION:(45,14,47,16),unlit,"ordinary"
+# All places are accessible also with jumping, so don't bother
+# restricting the placement when teleporting from levels below this.
+TELEPORT_REGION:(33,02,38,07),(0,0,0,0),down
+STAIR:(32,01,39,07),(0,0,0,0),up
+STAIR:$place[0],down
+DOOR:locked,(08,08)
+DOOR:locked,(64,05)
+DOOR:random,(50,13)
+DOOR:locked,(48,15)
+# 
+FOUNTAIN:$place[1]
+#
+CONTAINER:('`',"statue"),$place[2],uncursed,montype:"knight",3,NAME:"Perseus" {
+  OBJECT[75%]:('[',"shield of reflection"),cursed,+0
+  OBJECT[25%]:('[',"levitation boots"),+0
+  OBJECT[50%]:(')',"scimitar"),blessed,+2
+  OBJECT[50%]:('(',"sack")
+}
+#
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:('?',"blank paper"),(48,18)
+OBJECT:('?',"blank paper"),(48,18)
+#
+TRAP:"rust",random
+TRAP:"rust",random
+TRAP:"board",random
+TRAP:"board",random
+TRAP:random,random
+#
+MONSTER:('@',"Medusa"),$place[0]
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:('n',"wood nymph"),random
+MONSTER:('n',"wood nymph"),random
+MONSTER:('n',"water nymph"),random
+MONSTER:('n',"water nymph"),random
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+MONSTER:('B',"raven"),random,hostile
+
+
+LEVEL:"medusa-4"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
+GEOMETRY:center,center
+#
+# Here the Medusa rules some slithery monsters from her 'palace', with
+# a yellow dragon nesting in the backyard.
+#
+MAP
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}........}}}}}}}}}}}}}}}}}}}}}}}..}}}.....}}}}}}}}}}}----|}}}}}
+}}}}}}..----------F-.....}}}}}}}}}}}}}}}}..---...}}}}....T.}}}}}}}....|}}}}}
+}}}.....|...F......S}}}}....}}}}}}}...}}.....|}}.}}}}}}}......}}}}|......}}}
+}}}.....+...|..{...|}}}}}}}}}}}}.....}}}}|...|}}}}}}}}}}}.}}}}}}}}----.}}}}}
+}}......|...|......|}}}}}}}}}......}}}}}}|.......}}}}}}}}}}}}}..}}}}}...}}}}
+}}|-+--F|-+--....|F|-|}}}}}....}}}....}}}-----}}.....}}}}}}}......}}}}.}}}}}
+}}|...}}|...|....|}}}|}}}}}}}..}}}}}}}}}}}}}}}}}}}}....}}}}}}}}....T.}}}}}}}
+}}|...}}F...+....F}}}}}}}..}}}}}}}}}}}}}}...}}}}}}}}}}}}}}}}}}}}}}....}}..}}
+}}|...}}|...|....|}}}|}....}}}}}}....}}}...}}}}}...}}}}}}}}}}}}}}}}}.....}}}
+}}--+--F|-+--....-F|-|....}}}}}}}}}}.T...}}}}....---}}}}}}}}}}}}}}}}}}}}}}}}
+}}......|...|......|}}}}}.}}}}}}}}}....}}}}}}}.....|}}}}}}}}}.}}}}}}}}}}}}}}
+}}}}....+...|..{...|.}}}}}}}}}}}}}}}}}}}}}}}}}}.|..|}}}}}}}......}}}}...}}}}
+}}}}}}..|...F......|...}}}}}}}}}}..---}}}}}}}}}}--.-}}}}}....}}}}}}....}}}}}
+}}}}}}}}-----S----F|....}}}}}}}}}|...|}}}}}}}}}}}}...}}}}}}...}}}}}}..}}}}}}
+}}}}}}}}}..............T...}}}}}.|.......}}}}}}}}}}}}}}..}...}.}}}}....}}}}}
+}}}}}}}}}}....}}}}...}...}}}}}.......|.}}}}}}}}}}}}}}.......}}}}}}}}}...}}}}
+}}}}}}}}}}..}}}}}}}}}}.}}}}}}}}}}-..--.}}}}}}}}..}}}}}}..T...}}}..}}}}}}}}}}
+}}}}}}}}}...}}}}}}}}}}}}}}}}}}}}}}}...}}}}}}}....}}}}}}}.}}}..}}}...}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.}}}}}}....}}}}}}}}}}}}}}}}}}}...}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+ENDMAP
+
+REPLACE_TERRAIN:(01,01,73,18), '}', '.', 5%
+
+#
+$place = { (04,08),(10,04),(10,08),(10,12) }
+SHUFFLE: $place
+#
+REGION:(00,00,74,19),lit,"ordinary"
+REGION:(13,03,18,13),lit,"ordinary",unfilled
+#
+TELEPORT_REGION:(64,01,74,17),(0,0,0,0),down
+TELEPORT_REGION:(02,02,18,13),(0,0,0,0),up
+#
+STAIR:(67,01,74,20),(0,0,0,0),up
+STAIR:$place[0],down
+# 
+DOOR:locked,(04,06)
+DOOR:locked,(04,10)
+DOOR:locked,(08,04)
+DOOR:locked,(08,12)
+DOOR:locked,(10,06)
+DOOR:locked,(10,10)
+DOOR:locked,(12,08)
+#
+BRANCH:levregion(27,00,79,20),(0,0,0,0)
+#
+NON_DIGGABLE:(01,01,22,14)
+#
+OBJECT:('(',"crystal ball"),(07,08)
+#
+CONTAINER:('`',"statue"),$place[1],uncursed,montype:"knight",3,NAME:"Perseus" {
+  OBJECT[75%]:('[',"shield of reflection"),cursed,+0
+  OBJECT[25%]:('[',"levitation boots"),+0
+  OBJECT[50%]:(')',"scimitar"),blessed,+2
+  OBJECT[50%]:('(',"sack")
+}
+#
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+CONTAINER:('`',"statue"),random { }
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+# 
+TRAP:random,random
+TRAP:random,random
+TRAP:random,random
+TRAP:random,random
+TRAP:random,random
+TRAP:random,random
+TRAP:random,random
+#
+MONSTER:('@',"Medusa"),$place[0]
+MONSTER:(';',"kraken"),(07,07)
+#
+# the nesting dragon
+MONSTER:('D',"yellow dragon"), (05,04), asleep
+MONSTER[50%]:('D',"baby yellow dragon"), (04,04), asleep
+MONSTER[25%]:('D',"baby yellow dragon"), (04,05), asleep
+OBJECT:('%',"egg"), (05,04), montype:"yellow dragon"
+OBJECT[50%]:('%',"egg"), (05,04), montype:"yellow dragon"
+OBJECT[25%]:('%',"egg"), (05,04), montype:"yellow dragon"
+#
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"giant eel"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:(';',"jellyfish"),random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:'S',random
+MONSTER:('N',"black naga hatchling"), random
+MONSTER:('N',"black naga hatchling"), random
+MONSTER:('N',"black naga hatchling"), random
+MONSTER:('N',"black naga hatchling"), random
+MONSTER:('N',"black naga"), random
+MONSTER:('N',"black naga"), random
+MONSTER:('N',"black naga"), random
+MONSTER:('N',"black naga"), random
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/mines.des nethack/dat/mines.des
--- nh_orig/dat/mines.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/mines.des	2010-04-29 10:53:24.172715470 -0400
@@ -10,6 +10,7 @@
 #	specific levels as defined below.
 #
-MAZE: "minefill" , ' '
-INIT_MAP: '.' , ' ' , true , true , random , true
+LEVEL: "minefill"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ' , true , true , random , true
 NOMAP
 #
@@ -17,114 +18,154 @@
 STAIR: random, down
 #
-OBJECT: '*', random, random
-OBJECT: '*', random, random
-OBJECT: '*', random, random
-OBJECT: '(', random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+OBJECT: '*', random
+OBJECT: '*', random
+OBJECT: '*', random
+OBJECT: '(', random
+LOOP [2d2] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome lord", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'G', random, random
-MONSTER: 'G', random, random
-MONSTER: 'h', random, random
+LOOP [4 + 2d5] {
+  MONSTER: ('G', "gnome"), random
+}
+MONSTER: ('G', "gnome lord"), random
+MONSTER: ('h', "dwarf"), random
+MONSTER: ('h', "dwarf"), random
+MONSTER: 'G', random
+MONSTER: 'G', random
+MONSTER: 'h', random
 #
+LOOP [4 + 1d5] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-
+}
 
 # Minetown variant 1
 # "Frontier Town"
 #
+# A tragic accident has occurred to Frontier Town....
+# 
+# Orcish Town - a variant of Frontier Town that has been
+# overrun by orcs.  Note the barricades (iron bars).
+#
 LEVEL: "minetn-1"
+FLAGS:mazelevel
+INIT_MAP:mines,'.',' ',true,true,random,true
+GEOMETRY:center,center
+MAP
+.....................................
+.----------------F------------------.
+.|.................................|.
+.|.-------------......------------.|.
+.|.|...|...|...|......|..|...|...|.|.
+.F.|...|...|...|......|..|...|...|.|.
+.|.|...|...|...|......|..|...|...|.F.
+.|.|...|...|----......------------.|.
+.|.---------.......................|.
+.|.................................|.
+.|.---------.....--...--...........|.
+.|.|...|...|----.|.....|.---------.|.
+.|.|...|...|...|.|.....|.|..|....|.|.
+.|.|...|...|...|.|.....|.|..|....|.|.
+.|.|...|...|...|.|.....|.|..|....|.|.
+.|.-------------.-------.---------.|.
+.|.................................F.
+.-----------F------------F----------.
+.....................................
+ENDMAP
 
-ROOM: "ordinary" , lit, (3,3), (center,center), (31,15)
-NAME: "town"
-FOUNTAIN: (13, 7)
-FOUNTAIN: (20, 7)
-
-# The Town Watch
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
-
-SUBROOM: "shop" , lit, (2,2), (3,4), "town"
-CHANCE: 90
-DOOR: false, closed, south, random
-
-SUBROOM: "tool shop", lit, (2,9), (3,4), "town"
-CHANCE: 90
-DOOR: false, closed, north, random
-
-SUBROOM: "ordinary", unlit, (6,2), (3,4), "town"
-DOOR: false, closed, south, random
-
-SUBROOM: "ordinary", lit, (6,9), (3,4), "town"
-DOOR: false, closed, north, random
-
-SUBROOM: "food shop", lit, (10,2), (2,3), "town"
-CHANCE: 90
-DOOR: false, closed, south, random
+# Don't let the player fall into his likely death
+TELEPORT_REGION:levregion(01,01,20,19),levregion(20,00,70,19)
+REGION:(00,00,36,16),lit,"ordinary"
+STAIR:levregion(01,03,20,19),(00,00,36,15),up
+STAIR:levregion(61,03,75,19),(00,00,36,15),down
 
-SUBROOM: "candle shop", lit, (22,2), (3,3), "town"
-DOOR: false, closed, south, random
+# shame we can't make polluted fountains
+FOUNTAIN:(16,09)
+FOUNTAIN:(25,09)
 
-SUBROOM: "ordinary", unlit, (10,10), (2,3), "town"
-DOOR: false, locked, east, random
-MONSTER: 'G', "gnome", random
+# the altar's defiled; useful for BUC but never coaligned
+ALTAR:(20,13),noalign,shrine
 
-SUBROOM: "ordinary", lit, (19,2),  (2,3), "town"
-DOOR: false, locked, west, random
-MONSTER: 'G', "gnome", random
+# set up the shop doors; could be broken down
+DOOR:random,(5,8)
+DOOR:random,(9,8)
+DOOR:random,(13,7)
+DOOR:random,(22,5)
+DOOR:random,(27,7)
+DOOR:random,(31,7)
+DOOR:random,(5,10)
+DOOR:random,(9,10)
+DOOR:random,(15,13)
+DOOR:random,(25,13)
+DOOR:random,(31,11)
 
-SUBROOM: "temple", lit, (15,9), (4,4), "town"
-DOOR: false, closed, north, random
-ALTAR:(02,02),align[0],shrine
-MONSTER: 'G', "gnomish wizard", random
-MONSTER: 'G', "gnomish wizard", random
+# knock a few holes in the shop interior walls
+REPLACE_TERRAIN:(07,04,11,06),'|','.',18%
+REPLACE_TERRAIN:(25,04,29,06),'|','.',18%
+REPLACE_TERRAIN:(07,12,11,14),'|','.',18%
+REPLACE_TERRAIN:(28,12,28,14),'|','.',33%
 
-SUBROOM: "ordinary", lit, (22,10), (2,3), "town"
-DOOR: false, locked, west, random
+# One spot each in most shops...
+$place = { (05,04),(09,05),(13,04),(26,04),(31,05),(30,14),(05,14),(10,13),(26,14),(27,13) }
+SHUFFLE:$place
 
-SUBROOM: "ordinary", lit, (26,2), (3,3), "town"
-DOOR: false, closed, south, random
-MONSTER: 'G', "gnome lord", random
+# scatter some bodies
+OBJECT:('%',"corpse"),(20,12),montype:"aligned priest"
+OBJECT:('%',"corpse"),$place[0],montype:"shopkeeper"
+OBJECT:('%',"corpse"),$place[1],montype:"shopkeeper"
+OBJECT:('%',"corpse"),$place[2],montype:"shopkeeper"
+OBJECT:('%',"corpse"),$place[3],montype:"shopkeeper"
+OBJECT:('%',"corpse"),$place[4],montype:"shopkeeper"
+OBJECT:('%',"corpse"),random,montype:"watchman"
+OBJECT:('%',"corpse"),random,montype:"watchman"
+OBJECT:('%',"corpse"),random,montype:"watchman"
+OBJECT:('%',"corpse"),random,montype:"watchman"
+OBJECT:('%',"corpse"),random,montype:"watch captain"
 
-SUBROOM: "ordinary", unlit, (25,10), (4,3), "town"
-DOOR: false, closed, north, random
+# Rubble!
+LOOP [9 + 2d5] {
+  OBJECT[90%]:('`',"boulder"),random
+  OBJECT:('*',"rock"),random
+}
 
-ROOM: "ordinary" , random, random, random, random
-STAIR: random, up
+# Guarantee 7 candles since we won't have Izchak available
+OBJECT:('(',"wax candle"),$place[0],quantity:1d2
+OBJECT:('(',"wax candle"),$place[1],quantity:2d2
+OBJECT:('(',"wax candle"),$place[2],quantity:1d2
+OBJECT:('(',"tallow candle"),$place[3],quantity:1d3
+OBJECT:('(',"tallow candle"),$place[2],quantity:1d2
+OBJECT:('(',"tallow candle"),$place[0],quantity:1d2
 
-ROOM: "ordinary" , random, random, random, random
-STAIR: random, down
-TRAP: random, random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
+# go ahead and leave a lamp next to one corpse to be suggestive
+# and some empty wands...
+OBJECT:('(',"oil lamp"),$place[2]
+OBJECT:('/',"striking"),$place[1],uncursed,0
+OBJECT:('/',"striking"),$place[3],uncursed,0
+OBJECT:('/',"striking"),$place[4],uncursed,0
+OBJECT:('/',"magic missile"),$place[4],uncursed,0
+OBJECT:('/',"magic missile"),$place[0],uncursed,0
 
-ROOM: "ordinary" , random, random, random, random
-MONSTER: 'h', "dwarf", random
+# the Orcish Army
 
-ROOM: "ordinary" , random, random, random, random
-TRAP: random, random
-MONSTER: 'G', "gnome", random
+$inside = selection: floodfill(18,8)
+$near_temple = selection: filter(fillrect(17,8, 23,14), $inside)
 
-RANDOM_CORRIDORS
+LOOP [5 + 1d10] {
+  MONSTER[50%]: ('o', "orc-captain"), rndcoord($inside), hostile
+  MONSTER[80%]: ('o', "Uruk-hai"), rndcoord($inside), hostile
+  MONSTER: ('o', "Mordor orc"), rndcoord($inside), hostile
+}
+# shamans can be hanging out in/near the temple
+LOOP [2d3] {
+  MONSTER: ('o', "orc shaman"), rndcoord($near_temple), hostile
+}
+# these are not such a big deal
+# to run into outside the bars
+LOOP [9 + 2d5] {
+  MONSTER[90%]: ('o', "hill orc"), random, hostile
+  MONSTER: ('o', "goblin"), random, hostile
+}
 
+WALLIFY:(1,0, 70,20)
 
 # Minetown variant 2
@@ -133,91 +174,156 @@
 LEVEL: "minetn-2"
 ROOM: "ordinary" , lit, (3,3), (center,center), (31,15)
-NAME: "town"
-FOUNTAIN: (17, 5)
-FOUNTAIN: (13, 8)
-
-# The Town Watch
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
+{
 
-SUBROOM: "ordinary", random, (2,0), (2,2), "town"
-DOOR: false, closed, west, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (2,0), (2,2)
+  {
+    ROOMDOOR: false, closed, west|south, random
+  }
+}
 
-SUBROOM: "ordinary", unlit, (5,0), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", unlit, (5,0), (2,2)
+  {
+    ROOMDOOR: false, closed, west|south, random
+  }
+}
 
-SUBROOM: "ordinary", random, (8,0), (2,2), "town"
-DOOR: false, closed, east, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (8,0), (2,2)
+  {
+    ROOMDOOR: false, closed, east|south, random
+  }
+}
 
-SUBROOM: "ordinary", lit, (16,0), (2,2), "town"
-DOOR: false, closed, west, random
+IF [75%] {
+  SUBROOM: "ordinary", lit, (16,0), (2,2)
+  {
+    ROOMDOOR: false, closed, west|south, random
+  }
+}
 
-SUBROOM: "ordinary", unlit, (19,0), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", unlit, (19,0), (2,2)
+  {
+    ROOMDOOR: false, closed, west|south, random
+  }
+}
 
-SUBROOM: "ordinary", random, (22,0), (2,2), "town"
-DOOR: false, locked, south, random
-MONSTER: 'G', "gnome", random
+IF [75%] {
+  SUBROOM: "ordinary", random, (22,0), (2,2)
+  {
+    ROOMDOOR: false, locked, west|south, random
+    MONSTER: ('G', "gnome"), random
+  }
+}
 
-SUBROOM: "ordinary", unlit, (25,0), (2,2), "town"
-DOOR: false, closed, east, random
+IF [75%] {
+  SUBROOM: "ordinary", unlit, (25,0), (2,2)
+  {
+    ROOMDOOR: false, closed, east|south|west, random
+  }
+}
 
-SUBROOM: "ordinary", lit, (2,5), (2,2), "town"
-DOOR: false, closed, north, random
+IF [75%] {
+  SUBROOM: "ordinary", lit, (2,5), (2,2)
+  {
+    ROOMDOOR: false, closed, north|south|west, random
+  }
+}
 
-SUBROOM: "ordinary", lit, (5,5), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (8,5), (2,2)
+  {
+    ROOMDOOR: false, locked, north|south|east, random
+    MONSTER: ('G', "gnome"), random
+  }
+}
 
-SUBROOM: "ordinary", random, (8,5), (2,2), "town"
-DOOR: false, locked, north, random
-MONSTER: 'G', "gnome", random
+IF [75%] {
+  SUBROOM: "ordinary", lit, (5,5), (2,2)
+  {
+    ROOMDOOR: false, closed, north|south|east|west, random
+  }
+}
 
-SUBROOM: "shop" , lit, (2,10), (4,3), "town"
-CHANCE: 90
-DOOR: false, closed, west, random
+SUBROOM: "shop" [90%] , lit, (2,10), (4,3)
+{
+ROOMDOOR: false, closed, north|south|west, random
+}
 
-SUBROOM: "tool shop", lit, (23,10), (4,3), "town"
-CHANCE: 90
-DOOR: false, closed, east, random
+SUBROOM: "tool shop" [90%], lit, (23,10), (4,3)
+{
+ROOMDOOR: false, closed, south|east, random
+}
 
-SUBROOM: "food shop", lit, (24,5), (3,4), "town"
-CHANCE: 90
-DOOR: false, closed, north, random
+SUBROOM: "food shop" [90%], lit, (24,5), (3,4)
+{
+ROOMDOOR: false, closed, north|east, random
+}
 
-SUBROOM: "candle shop", lit, (11,10), (4,3), "town"
-DOOR: false, closed, east, random
+SUBROOM: "candle shop", lit, (11,10), (4,3)
+{
+ROOMDOOR: false, closed, north|south|east, random
+}
 
-SUBROOM: "ordinary", unlit, (7,10), (3,3), "town"
-DOOR: false, locked, north, random
-MONSTER: 'G', "gnome", random
+IF [75%] {
+  SUBROOM: "ordinary", unlit, (7,10), (3,3)
+  {
+    ROOMDOOR: false, locked, north|south, random
+    MONSTER: ('G', "gnome"), random
+  }
+}
 
-SUBROOM: "temple", lit, (19,5), (4,4), "town"
-DOOR: false, closed, north, random
+SUBROOM: "temple", lit, (19,5), (4,4)
+{
+ROOMDOOR: false, closed, north|west, random
 ALTAR:(02,02),align[0],shrine
-MONSTER: 'G', "gnomish wizard", random
-MONSTER: 'G', "gnomish wizard", random
+MONSTER: ('G', "gnomish wizard"), random
+MONSTER: ('G', "gnomish wizard"), random
+}
 
-SUBROOM: "ordinary", lit, (18,10), (4,3), "town"
-DOOR: false, locked, west, random
-MONSTER: 'G', "gnome lord", random
+IF [75%] {
+  SUBROOM: "ordinary", lit, (18,10), (4,3)
+  {
+    ROOMDOOR: false, locked, south|west, random
+    MONSTER: ('G', "gnome lord"), random
+  }
+}
+
+FOUNTAIN: (17, 5)
+FOUNTAIN: (13, 8)
+
+# The Town Watch
+LOOP [2 + 1d7] {
+  MONSTER: ('@', "watchman"), random, peaceful
+}
+MONSTER: ('@', "watch captain"), random, peaceful
+
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
 TRAP: random, random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+MONSTER: ('G', "gnome"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-MONSTER: 'h', "dwarf", random
+{
+MONSTER: ('h', "dwarf"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 TRAP: random, random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+}
 
 RANDOM_CORRIDORS
@@ -229,86 +335,142 @@
 LEVEL: "minetn-3"
 ROOM: "ordinary",lit,(3,3),(center,center),(31,15)
-NAME: "town"
-FOUNTAIN:(01,06)
-FOUNTAIN:(29,13)
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
+{
 
-SUBROOM:"ordinary",random,(2,2),(2,2),"town"
-DOOR: false,closed,south,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(2,2),(2,2)
+  {
+    ROOMDOOR: false,closed,north|south|west,random
+  }
+}
 
-SUBROOM:"tool shop",lit,(5,3),(2,3),"town"
-CHANCE: 30
-DOOR: false,closed,south,random
+SUBROOM:"tool shop" [30%],lit,(5,3),(2,3)
+{
+ROOMDOOR: false,closed,north|south|east,random
+}
 
-SUBROOM:"ordinary",random,(2,10),(2,3),"town"
-DOOR: false, locked, north, random
-MONSTER: 'G',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(2,10),(2,3)
+  {
+    ROOMDOOR: false, locked, north|south|west, random
+    MONSTER: 'G',random
+  }
+}
 
-SUBROOM:"ordinary",random,(5,9),(2,2),"town"
-DOOR: false,closed,north,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(5,9),(2,2)
+  {
+    ROOMDOOR: false,closed,north|south|east,random
+  }
+}
 
-SUBROOM:"temple",lit,(10,2),(3,4),"town"
-DOOR: false,closed,east,random
+SUBROOM:"temple",lit,(10,2),(3,4)
+{
+ROOMDOOR: false,closed,north|west|east,random
 ALTAR:(1,1),align[0],shrine
-MONSTER: 'G', "gnomish wizard", random
-MONSTER: 'G', "gnomish wizard", random
+MONSTER: ('G', "gnomish wizard"), random
+MONSTER: ('G', "gnomish wizard"), random
+}
 
-SUBROOM:"ordinary",random,(11,7),(2,2),"town"
-DOOR: false,closed,west,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(11,7),(2,2)
+  {
+    ROOMDOOR: false,closed,west,random
+  }
+}
 
-SUBROOM:"shop",lit,(10,10),(3,3),"town"
-DOOR:false,closed,west,random
+SUBROOM:"shop",lit,(10,10),(3,3)
+{
+ROOMDOOR:false,closed,west|south,random
+}
 
-SUBROOM:"ordinary",random,(14,8),(2,2),"town"
-DOOR:false,locked,north,random
-MONSTER: 'G',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(14,8),(2,2)
+  {
+    ROOMDOOR:false,locked,north,random
+    MONSTER: 'G',random
+  }
+}
 
-SUBROOM:"ordinary",random,(14,11),(2,2),"town"
-DOOR:false,closed,south,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(14,11),(2,2)
+  {
+    ROOMDOOR:false,closed,north|south,random
+  }
+}
 
-SUBROOM:"tool shop",lit,(17,10),(3,3),"town"
-CHANCE:40
-DOOR:false,closed,north,random
+SUBROOM:"tool shop" [40%],lit,(17,10),(3,3)
+{
+ROOMDOOR:false,closed,north|south,random
+}
 
-SUBROOM:"ordinary",random,(21,11),(2,2),"town"
-DOOR:false,locked,east,random
-MONSTER:'G',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(21,11),(2,2)
+  {
+    ROOMDOOR:false,locked,north|south|east,random
+    MONSTER:'G',random
+  }
+}
 
-SUBROOM:"food shop",lit,(26,8),(3,2),"town"
-CHANCE:90
-DOOR:false,closed,west,random
+SUBROOM:"food shop" [90%],lit,(26,8),(3,2)
+{
+ROOMDOOR:false,closed,north|south|east|west,random
+}
 
-SUBROOM:"ordinary",random,(16,2),(2,2),"town"
-DOOR:false,closed,west,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(16,2),(2,2)
+  {
+    ROOMDOOR:false,closed,north|south|west,random
+  }
+}
 
-SUBROOM:"ordinary",random,(19,2),(2,2),"town"
-DOOR:false,closed,north,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(19,2),(2,2)
+  {
+    ROOMDOOR:false,closed,north|east|west,random
+  }
+}
 
-SUBROOM:"wand shop",lit,(19,5),(3,2),"town"
-CHANCE:30
-DOOR:false,closed,west,random
+SUBROOM:"wand shop" [30%],lit,(19,5),(3,2)
+{
+ROOMDOOR:false,closed,south|east|west,random
+}
 
-SUBROOM: "candle shop",lit,(25,2),(3,3),"town"
-DOOR:false,closed,south,random
+SUBROOM: "candle shop",lit,(25,2),(3,3)
+{
+ROOMDOOR:false,closed,north|south|east|west,random
+}
+
+FOUNTAIN:(01,06)
+FOUNTAIN:(29,13)
+LOOP [2 + 1d7] {
+  MONSTER: ('@', "watchman"), random, peaceful
+}
+MONSTER: ('@', "watch captain"), random, peaceful
+
+}
 
 ROOM: "ordinary", random, random, random, random
+{
 STAIR: random, up
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
 TRAP: random, random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+MONSTER: ('G', "gnome"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-MONSTER: 'h', "dwarf", random
+{
+MONSTER: ('h', "dwarf"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 TRAP: random, random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+}
 
 RANDOM_CORRIDORS
@@ -320,77 +482,120 @@
 LEVEL: "minetn-4"
 ROOM: "ordinary",lit,(3,3),(center,center),(30,15)
-NAME: "town"
-FOUNTAIN:(08,07)
-FOUNTAIN:(18,07)
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
+{
 
-SUBROOM:"book shop",lit,(4,2),(3,3),"town"
-DOOR: false,closed,south,random
+SUBROOM:"book shop",lit,(4,2),(3,3)
+{
+ROOMDOOR: false,closed,north|south|west,random
+}
 
-SUBROOM:"ordinary",random,(8,2),(2,2),"town"
-DOOR: false,closed,south,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(8,2),(2,2)
+  {
+    ROOMDOOR: false,closed,north|south,random
+  }
+}
 
-SUBROOM:"temple",lit,(11,3),(5,4),"town"
-DOOR: false,closed,south,random
+SUBROOM:"temple",lit,(11,3),(5,4)
+{
+ROOMDOOR: false,closed,north|south|east,random
 ALTAR:(2,1),align[0],shrine
-MONSTER: 'G', "gnomish wizard", random
-MONSTER: 'G', "gnomish wizard", random
+MONSTER: ('G', "gnomish wizard"), random
+MONSTER: ('G', "gnomish wizard"), random
+}
 
-SUBROOM:"ordinary",random,(19,2),(2,2),"town"
-DOOR: false,closed,south,random
-MONSTER: 'G', random, random
+IF [75%] {
+  SUBROOM:"ordinary",random,(19,2),(2,2)
+  {
+    ROOMDOOR: false,closed,north|south|west,random
+    MONSTER: 'G', random
+  }
+}
 
-SUBROOM:"candle shop",lit,(22,2),(3,3),"town"
-DOOR:false,closed,south,random
+SUBROOM:"candle shop",lit,(22,2),(3,3)
+{
+ROOMDOOR:false,closed,north|south,random
+}
 
-SUBROOM:"ordinary",random,(26,2),(2,2),"town"
-DOOR:false,locked,east,random
-MONSTER: 'G',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(26,2),(2,2)
+  {
+    ROOMDOOR:false,locked,north|south|east,random
+    MONSTER: 'G',random
+  }
+}
 
-SUBROOM:"tool shop",lit,(4,10),(3,3),"town"
-CHANCE:90
-DOOR:false,closed,north,random
+SUBROOM:"tool shop" [90%],lit,(4,10),(3,3)
+{
+ROOMDOOR:false,closed,north|south|west,random
+}
 
-SUBROOM:"ordinary",random,(8,11),(2,2),"town"
-DOOR:false,locked,south,random
-MONSTER: 'k',"kobold shaman",random
-MONSTER: 'k',"kobold shaman",random
-MONSTER: 'f',"kitten",random
-MONSTER: 'f',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(8,11),(2,2)
+  {
+    ROOMDOOR:false,locked,north|south,random
+    MONSTER: ('k',"kobold shaman"),random
+    MONSTER: ('k',"kobold shaman"),random
+    MONSTER: ('f',"kitten"),random
+    MONSTER: 'f',random
+  }
+}
 
-SUBROOM:"food shop",lit,(11,11),(3,2),"town"
-CHANCE:90
-DOOR:false,closed,east,random
+SUBROOM:"food shop" [90%],lit,(11,11),(3,2)
+{
+ROOMDOOR:false,closed,north|south|east,random
+}
 
-SUBROOM:"ordinary",random,(17,11),(2,2),"town"
-DOOR:false,closed,west,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(17,11),(2,2)
+  {
+    ROOMDOOR:false,closed,north|south|west,random
+  }
+}
 
-SUBROOM:"ordinary",random,(20,10),(2,2),"town"
-DOOR:false,locked,north,random
-MONSTER:'G',random,random
+IF [75%] {
+  SUBROOM:"ordinary",random,(20,10),(2,2)
+  {
+    ROOMDOOR:false,locked,north|south,random
+    MONSTER:'G',random
+  }
+}
 
-SUBROOM:"shop",lit,(23,10),(3,3),"town"
-CHANCE:90
-DOOR:false,closed,north,random
+SUBROOM:"shop" [90%],lit,(23,10),(3,3)
+{
+ROOMDOOR:false,closed,north|south|east,random
+}
+
+FOUNTAIN:(08,07)
+FOUNTAIN:(18,07)
+LOOP [2 + 1d7] {
+  MONSTER: ('@', "watchman"), random, peaceful
+}
+MONSTER: ('@', "watch captain"), random, peaceful
+
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
 TRAP: random, random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+MONSTER: ('G', "gnome"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-MONSTER: 'h', "dwarf", random
+{
+MONSTER: ('h', "dwarf"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 TRAP: random, random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+}
 
 RANDOM_CORRIDORS
@@ -399,5 +604,7 @@
 # "Grotto Town" by Kelly Bailey
 #
-MAZE: "minetn-5",' '
+LEVEL: "minetn-5"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 MAP
@@ -425,4 +632,34 @@
 ENDMAP
 
+IF [75%] {
+   IF [50%] {
+      TERRAIN:line (25,8)-(25,9), '|'
+   } ELSE {
+      TERRAIN:line (16,13)-(17,13), '-'
+   }
+}
+
+IF [75%] {
+   IF [50%] {
+      TERRAIN:line (36,10)-(36,11), '|'
+   } ELSE {
+      TERRAIN:line (32,15)-(33,15), '-'
+   }
+}
+
+IF [50%] {
+   TERRAIN:fillrect (21,4,22,5), '.'
+   TERRAIN:line (14,9)-(14,10), '|'
+}
+
+IF [50%] {
+   TERRAIN:(46,13), '|'
+   TERRAIN:line (43,5)-(47,5), '-'
+   TERRAIN:line (42,6)-(46,6), '.'
+   TERRAIN:(47,7), '.'
+}
+
+TERRAIN[50%]:fillrect (69,11,71,11), '-'
+
 STAIR:(01,01),up
 STAIR:(46,03),down
@@ -431,30 +668,26 @@
 FOUNTAIN:(66,18)
 
+OBJECT:('\\',"brazier"),(08,15)
+OBJECT:('\\',"brazier"),(12,15)
+OBJECT:('\\',"brazier"),(51,09)
+OBJECT:('\\',"brazier"),(65,18)
+OBJECT:('\\',"brazier"),(36,15)
+OBJECT:('\\',"brazier"),(40,15)
+
 REGION:(00,00,74,20),unlit,"ordinary"
-REGION:(09,13,11,17),lit,"ordinary"
-REGION:(08,14,12,16),lit,"ordinary"
-REGION:(49,07,51,11),lit,"ordinary"
-REGION:(48,08,52,10),lit,"ordinary"
-REGION:(64,17,68,19),lit,"ordinary"
-REGION:(37,13,39,17),lit,"ordinary"
-REGION:(36,14,40,17),lit,"ordinary"
 REGION:(59,02,72,10),lit,"ordinary"
 
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome lord", random
-MONSTER: 'G', "gnome lord", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'h', "dwarf", random
+LOOP [2 + 1d7] {
+  MONSTER: ('@', "watchman"), random, peaceful
+}
+MONSTER: ('@', "watch captain"), random, peaceful
+LOOP [4 + 1d8] {
+  MONSTER: ('G', "gnome"), random
+}
+MONSTER: ('G', "gnome lord"), random
+MONSTER: ('G', "gnome lord"), random
+MONSTER: ('h', "dwarf"), random
+MONSTER: ('h', "dwarf"), random
+MONSTER: ('h', "dwarf"), random
 
 # The shops
@@ -470,12 +703,12 @@
 DOOR:closed,(04,14)
 DOOR:locked,(01,17)
-MONSTER: 'G', "gnomish wizard", (02,19)
+MONSTER: ('G', "gnomish wizard"), (02,19)
 DOOR:locked,(20,16)
-MONSTER: 'G', random, (20,18)
+MONSTER: 'G', (20,18)
 DOOR:random,(21,14)
 DOOR:random,(25,14)
 DOOR:random,(42,08)
 DOOR:locked,(40,05)
-MONSTER: 'G', random, (38,07)
+MONSTER: 'G', (38,07)
 DOOR:random,(59,03)
 DOOR:random,(58,06)
@@ -486,13 +719,13 @@
 DOOR:closed,(69,04)
 DOOR:closed,(67,16)
-MONSTER: 'G', "gnomish wizard", (67,14)
-OBJECT: '=', random, (70,14)
+MONSTER: ('G', "gnomish wizard"), (67,14)
+OBJECT: '=', (70,14)
 DOOR:locked,(69,18)
-MONSTER: 'G', "gnome lord", (71,19)
+MONSTER: ('G', "gnome lord"), (71,19)
 DOOR:locked,(73,18)
-OBJECT: '(', "chest", (73,19)
+OBJECT: ('(', "chest"), (73,19)
 DOOR:locked,(50,06)
-OBJECT: '(', random, (50,03)
-OBJECT: '`', "statue", (38,15), "gnome king", 1
+OBJECT: '(', (50,03)
+OBJECT: ('`', "statue"), (38,15), montype:"gnome king", 1
 # Temple
 REGION:(29,02,33,04),lit,"temple"
@@ -501,24 +734,27 @@
 
 
-# "Bustling Town" by Kelly Bailey
+# Screw Bustling Town.  Let's make a zoo.  --DSR
 #
-MAZE: "minetn-6",' '
-INIT_MAP:'.','-',true,true,lit,true
+LEVEL: "minetn-6"
+FLAGS:mazelevel
+INIT_MAP:mines,'.','-',true,true,lit,true
 GEOMETRY:center,top
+#         1         2         3         4         5         6         7
+#1234567890123456789012345678901234567890123456789012345678901234567890
 MAP
-.-----................----------------.-
-.|...|................|...|..|...|...|..
-.|...+..--+--.........|...|..|...|...|..
-.|...|..|...|..-----..|...|..|-+---+--..
-.-----..|...|--|...|..--+---+-.........|
-........|...|..|...+.............-----..
-........-----..|...|......--+-...|...|..
-.----...|...|+------..{...|..|...+...|..
+.-----...................-------------.-
+.|...|...................|...|...|...|..
+.|...+..--+--...-FFF+F...|...|...|...|..
+.|...|..|...|...|....F...|...|-+---+--..
+.-----..|...|...|....F...---+-.........|
+........|...|...|....F...........-----..
+........-----...------....--+-...|...|..
+.----...|...|.{........{..|..|...+...|..
 .|..+...|...|.............|..|...|...|..
-.|..|...|...|-+-.....---+-------------.|
-.----...--+--..|..-+-|..................
+.|..|...|...|---.....---+-------------.|
+.----...--+--..|..---|..................
 ...|........|..|..|..|----....---------.
-...|..T.....----..|..|...+....|......|-.
-...|-....{........|..|...|....+......|-.
+...|..T.....-+--..+..|...+....|......|-.
+...|-....T........|..|...|....+......|-.
 ...--..-....T.....--------....|......|-.
 .......--.....................----------
@@ -528,10 +764,11 @@
 STAIR:levregion(01,03,20,19),(0,0,39,15),up
 STAIR:levregion(61,03,75,19),(0,0,39,15),down
-FOUNTAIN:(22,07)
-FOUNTAIN:(09,13)
-REGION:(13,5,14,6),unlit,"ordinary"
+FOUNTAIN:(23,07)
+FOUNTAIN:(14,07)
+# protect the zoo against dwarves and inquisitive players
+NON_DIGGABLE:(13,0,24,8)
 REGION:(9,7,11,9),lit,"candle shop"
-REGION:(16,4,18,6),lit,"tool shop"
-REGION:(23,1,25,3),lit,"shop"
+REGION:(9,3,11,5),lit,"tool shop"
+REGION:(26,1,28,3),lit,"shop"
 REGION:(22,12,24,13),lit,"food shop"
 REGION:(31,12,36,14),lit,"temple"
@@ -542,8 +779,6 @@
 DOOR:closed,(10,2)
 DOOR:closed,(10,10)
-DOOR:locked,(13,7)
-DOOR:locked,(14,9)
-DOOR:closed,(19,5)
-DOOR:closed,(19,10)
+DOOR:locked,(13,12)
+DOOR:locked,(20,2)
 DOOR:closed,(24,4)
 DOOR:closed,(24,9)
@@ -556,24 +791,40 @@
 DOOR:closed,(33,7)
 
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", (14,6)
-MONSTER: 'G', "gnome lord", (14,5)
-MONSTER: 'G', "gnome", (27,8)
-MONSTER: 'G', "gnome lord", random
-MONSTER: 'G', "gnome lord", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'h', "dwarf", random
-MONSTER: 'h', "dwarf", random
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
+$in_zoo = selection: floodfill(18,4)
+$outside = selection: filter(floodfill(18,8), fillrect (1,0,37,15))
+
+LOOP [4 + 1d8] {
+  MONSTER: ('G', "gnome"), rndcoord($outside)
+}
+MONSTER: ('G', "gnome"), rndcoord($outside)
+MONSTER: ('G', "gnome lord"), rndcoord($outside)
+MONSTER: ('G', "gnome"), rndcoord($outside)
+MONSTER: ('G', "gnome lord"), rndcoord($outside)
+MONSTER: ('G', "gnome lord"), rndcoord($outside)
+MONSTER: ('G', "gnomish wizard"), rndcoord($outside)
+MONSTER: ('G', "gnomish wizard"), rndcoord($outside)
+MONSTER: ('h', "dwarf"), rndcoord($outside)
 
+MONSTER: ('@', "watchman"), rndcoord($outside), peaceful
+MONSTER: ('@', "watchman"), rndcoord($outside), peaceful
+MONSTER: ('@', "watchman"), rndcoord($outside), peaceful
+MONSTER: ('@', "watch captain"), rndcoord($outside), peaceful
+MONSTER: ('@', "watch captain"), rndcoord($outside), peaceful
+# The zoo needs some stuff...
+MONSTER: ('f', "tiger"), rndcoord($in_zoo), hostile
+MONSTER: ('f', "panther"), rndcoord($in_zoo), hostile
+MONSTER: ('f', "jaguar"), rndcoord($in_zoo), hostile
+MONSTER: ('q', "mastodon"), rndcoord($in_zoo), hostile
+# and a couple token handlers
+MONSTER: ('o', "Mordor orc"), rndcoord($in_zoo), hostile {
+  OBJECT:(')', "bullwhip")
+}
+MONSTER: ('o', "Mordor orc"), rndcoord($in_zoo), hostile {
+  OBJECT:(')', "bullwhip")
+}
+# and a couple shiny prizes as temptation (for the handlers to use, possibly?)
+OBJECT: '/', rndcoord($in_zoo)
+OBJECT: '/', rndcoord($in_zoo)
+OBJECT: '=', rndcoord($in_zoo)
 
 # "Bazaar Town" by Kelly Bailey
@@ -581,113 +832,179 @@
 LEVEL: "minetn-7"
 ROOM: "ordinary" , lit, (3,3), (center,center), (30,15)
-NAME: "town"
-FOUNTAIN: (12, 07)
-FOUNTAIN: (11, 13)
-
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watchman", random, peaceful
-MONSTER: '@', "watch captain", random, peaceful
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'Y',"monkey",random
-MONSTER:'Y',"monkey",random
+{
 
-SUBROOM: "ordinary", random, (2,2), (4,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (2,2), (4,2)
+  {
+    ROOMDOOR: false, closed, north|south|west, random
+  }
+}
 
-SUBROOM: "ordinary", random, (7,2), (2,2), "town"
-DOOR: false, closed, north, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (7,2), (2,2)
+  {
+    ROOMDOOR: false, closed, north|west, random
+  }
+}
 
-SUBROOM: "ordinary", random, (7,5), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (7,5), (2,2)
+  {
+    ROOMDOOR: false, closed, south|west, random
+  }
+}
 
-SUBROOM: "ordinary", lit, (10,2), (3,4), "town"
-MONSTER:'G',"gnome",random
-MONSTER:'Y',"monkey",random
-MONSTER:'Y',"monkey",random
-MONSTER:'Y',"monkey",random
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", lit, (10,2), (3,4)
+  {
+    MONSTER:('G',"gnome"),random
+    MONSTER:('Y',"monkey"),random
+    MONSTER:('Y',"monkey"),random
+    MONSTER:('Y',"monkey"),random
+    ROOMDOOR: false, closed, north|south, random
+  }
+}
 
-SUBROOM: "ordinary", random, (14,2), (4,2), "town"
-DOOR: false, closed, south, 0
-MONSTER: 'n', random, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (14,2), (4,2)
+  {
+    ROOMDOOR: false, closed, south, 0
+    MONSTER: 'n', random
+  }
+}
 
-SUBROOM: "ordinary", random, (16,5), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (16,5), (2,2)
+  {
+    ROOMDOOR: false, closed, south|west, random
+  }
+}
 
-SUBROOM: "ordinary", unlit, (19,2), (2,2), "town"
-DOOR: false, locked, east, random
-MONSTER: 'G',"gnome king",random
+IF [75%] {
+  SUBROOM: "ordinary", unlit, (19,2), (2,2)
+  {
+    ROOMDOOR: false, locked, north|west|east, random
+    MONSTER: ('G',"gnome king"),random
+  }
+}
 
-SUBROOM: "food shop", lit, (19,5), (2,3), "town"
-CHANCE: 50
-DOOR: false, closed, south, random
+SUBROOM: "food shop" [50%], lit, (19,5), (2,3)
+{
+ROOMDOOR: false, closed, south|east, random
+}
 
-SUBROOM: "ordinary", random, (2,7), (2,2), "town"
-DOOR: false, closed, east, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (2,7), (2,2)
+  {
+    ROOMDOOR: false, closed, north|west|east, random
+  }
+}
 
-SUBROOM: "tool shop", lit, (2,10), (2,3), "town"
-CHANCE: 50
-DOOR: false, closed, south, random
+SUBROOM: "tool shop" [50%], lit, (2,10), (2,3)
+{
+ROOMDOOR: false, closed, south|west, random
+}
 
-SUBROOM: "candle shop", lit, (5,10),(3,3), "town"
-DOOR: false, closed, north, random
+SUBROOM: "candle shop", lit, (5,10),(3,3)
+{
+ROOMDOOR: false, closed, north|south|east, random
+}
 
-SUBROOM: "ordinary", random, (11,10), (2,2), "town"
-DOOR: false, locked, west, random
-MONSTER: 'G',random,random
+IF [75%] {
+  SUBROOM: "ordinary", random, (11,10), (2,2)
+  {
+    ROOMDOOR: false, locked, north|south|west, random
+    MONSTER: 'G',random
+  }
+}
 
-SUBROOM: "shop", lit, (14,10), (2,3), "town"
-CHANCE: 60
-DOOR: false, closed, north, random
+SUBROOM: "shop" [60%], lit, (14,10), (2,3)
+{
+ROOMDOOR: false, closed, north|south, random
+}
 
-SUBROOM: "ordinary", random, (17,11), (4,2), "town"
-DOOR: false, closed, north, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (17,11), (4,2)
+  {
+    ROOMDOOR: false, closed, north|south, random
+  }
+}
 
-SUBROOM: "ordinary", random, (22,11), (2,2), "town"
-DOOR: false, closed, south, random
+IF [75%] {
+  SUBROOM: "ordinary", random, (22,11), (2,2)
+  {
+    ROOMDOOR: false, closed, north|south|west, random
 SINK: (00,00)
+  }
+}
 
-SUBROOM: "food shop", lit, (25,11), (3,2), "town"
-CHANCE: 50
-DOOR: false, closed, east, random
+SUBROOM: "food shop" [50%], lit, (25,11), (3,2)
+{
+ROOMDOOR: false, closed, south|east, random
+}
 
-SUBROOM: "tool shop", lit, (25,2), (3,3), "town"
-CHANCE: 30
-DOOR: false, closed, west, random
+SUBROOM: "tool shop" [30%], lit, (25,2), (3,3)
+{
+ROOMDOOR: false, closed, north|west|east, random
+}
 
-SUBROOM: "temple", lit, (24,6), (4,4), "town"
-DOOR: false, closed, west, random
+SUBROOM: "temple", lit, (24,6), (4,4)
+{
+ROOMDOOR: false, closed, west, random
 ALTAR:(02,01),align[0],shrine
-MONSTER: 'G', "gnomish wizard", random
-MONSTER: 'G', "gnomish wizard", random
+MONSTER: ('G', "gnomish wizard"), random
+MONSTER: ('G', "gnomish wizard"), random
+}
+
+FOUNTAIN: (12, 07)
+FOUNTAIN: (11, 13)
+
+LOOP [2 + 1d7] {
+  MONSTER: ('@', "watchman"), random, peaceful
+}
+MONSTER: ('@', "watch captain"), random, peaceful
+LOOP [2 + 1d3] {
+  MONSTER:('G',"gnome"),random
+}
+MONSTER:('G',"gnome lord"),random
+MONSTER:('Y',"monkey"),random
+MONSTER:('Y',"monkey"),random
+
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
 TRAP: random, random
-MONSTER: 'G', "gnome", random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+MONSTER: ('G', "gnome"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-MONSTER: 'h', "dwarf", random
+{
+MONSTER: ('h', "dwarf"), random
+}
   
 ROOM: "ordinary" , random, random, random, random
+{
 TRAP: random, random
-MONSTER: 'G', "gnome", random
+MONSTER: ('G', "gnome"), random
+}
 
 RANDOM_CORRIDORS
   
 
+
 # Mine end level variant 1
 # "Mimic of the Mines"
 #
-MAZE: "minend-1", ' '
+LEVEL: "minend-1"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #1234567890123456789012345678901234567890123456789012345678901234567890
@@ -714,5 +1031,6 @@
 
 # Dungeon Description
-RANDOM_PLACES:(08,16),(13,07),(21,08),(41,14),(50,04),(50,16),(66,01)
+$place = { (08,16),(13,07),(21,08),(41,14),(50,04),(50,16),(66,01) }
+SHUFFLE:$place
 REGION:(26,01,32,01),unlit,"ordinary",filled,true
 REGION:(20,08,21,08),unlit,"ordinary"
@@ -732,39 +1050,39 @@
 # Niches
 # Note: place[6] empty
-OBJECT:'*',"diamond",place[0]
-OBJECT:'*',"emerald",place[0]
-OBJECT:'*',"worthless piece of violet glass",place[0]
-MONSTER:'m',random,place[0], m_object "luckstone"
-OBJECT:'*',"worthless piece of white glass",place[1]
-OBJECT:'*',"emerald",place[1]
-OBJECT:'*',"amethyst",place[1]
-MONSTER:'m',random,place[1], m_object "loadstone"
-OBJECT:'*',"diamond",place[2]
-OBJECT:'*',"worthless piece of green glass",place[2]
-OBJECT:'*',"amethyst",place[2]
-MONSTER:'m',random,place[2], m_object "flint"
-OBJECT:'*',"worthless piece of white glass",place[3]
-OBJECT:'*',"emerald",place[3]
-OBJECT:'*',"worthless piece of violet glass",place[3]
-MONSTER:'m',random,place[3], m_object "touchstone"
-OBJECT:'*',"worthless piece of red glass",place[4]
-OBJECT:'*',"ruby",place[4]
-OBJECT:'*',"loadstone",place[4]
-OBJECT:'*',"ruby",place[5]
-OBJECT:'*',"worthless piece of red glass",place[5]
-OBJECT:'*',"luckstone",place[5]
+OBJECT:('*',"diamond"),$place[0]
+OBJECT:('*',"emerald"),$place[0]
+OBJECT:('*',"worthless piece of violet glass"),$place[0]
+MONSTER:'m', $place[0], m_object "luckstone"
+OBJECT:('*',"worthless piece of white glass"),$place[1]
+OBJECT:('*',"emerald"),$place[1]
+OBJECT:('*',"amethyst"),$place[1]
+MONSTER:'m', $place[1], m_object "loadstone"
+OBJECT:('*',"diamond"),$place[2]
+OBJECT:('*',"worthless piece of green glass"),$place[2]
+OBJECT:('*',"amethyst"),$place[2]
+MONSTER:'m', $place[2], m_object "flint"
+OBJECT:('*',"worthless piece of white glass"),$place[3]
+OBJECT:('*',"emerald"),$place[3]
+OBJECT:('*',"worthless piece of violet glass"),$place[3]
+MONSTER:'m', $place[3], m_object "touchstone"
+OBJECT:('*',"worthless piece of red glass"),$place[4]
+OBJECT:('*',"ruby"),$place[4]
+OBJECT:('*',"loadstone"),$place[4]
+OBJECT:('*',"ruby"),$place[5]
+OBJECT:('*',"worthless piece of red glass"),$place[5]
+OBJECT:('*',"luckstone"),$place[5]
 # Random objects
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'(',random,random
-OBJECT:'(',random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'*',random
+OBJECT:'(',random
+OBJECT:'(',random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Random traps
 TRAP:random,random
@@ -775,25 +1093,20 @@
 TRAP:random,random
 # Random monsters
-MONSTER:'G',"gnome king",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnomish wizard",random
-MONSTER:'G',"gnomish wizard",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'h',"hobbit",random
-MONSTER:'h',"hobbit",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',random,random
+MONSTER:('G',"gnome king"),random
+LOOP [2 + 1d4] {
+  MONSTER:('G',"gnome lord"),random
+}
+LOOP [1d4] {
+  MONSTER:('G',"gnomish wizard"),random
+}
+LOOP [5 + 1d8] {
+  MONSTER:('G',"gnome"),random
+}
+MONSTER:('h',"hobbit"),random
+MONSTER:('h',"hobbit"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:'h',random
 
 
@@ -801,6 +1114,10 @@
 # "Gnome King's Wine Cellar"
 #
-MAZE: "minend-2", ' '
+LEVEL: "minend-2"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
+#         1         2         3         4         5         6         7
+#1234567890123456789012345678901234567890123456789012345678901234567890
 MAP
 ---------------------------------------------------------------------------
@@ -824,4 +1141,31 @@
 ENDMAP
 
+IF [50%] {
+   TERRAIN:(55,14),'-'
+   TERRAIN:(56,14),'-'
+   TERRAIN:(61,15),'|'
+   TERRAIN:(52,5), 'S'
+   DOOR:locked, (52,5)
+}
+
+IF [50%] {
+   TERRAIN:(18,1), '|'
+   TERRAIN:rect (7,12, 8,13), '.'
+}
+
+IF [50%] {
+   TERRAIN:(49,4), '|'
+   TERRAIN:(21,5), '.'
+}
+
+IF [50%] {
+   IF [50%] {
+      TERRAIN:(22,1), '|'
+   } ELSE {
+      TERRAIN:(50,7), '-'
+      TERRAIN:(51,7), '-'
+   }
+}
+
 # Dungeon Description
 FOUNTAIN:(14,13)
@@ -847,74 +1191,64 @@
 ENGRAVING:(12,03),engrave,"You are now entering the Gnome King's wine cellar."
 ENGRAVING:(12,04),engrave,"Trespassers will be persecuted!"
-OBJECT:'!',"booze",(10,07)
-OBJECT:'!',"booze",(10,07)
-OBJECT:'!',random,(10,07)
-OBJECT:'!',"booze",(10,08)
-OBJECT:'!',"booze",(10,08)
-OBJECT:'!',random,(10,08)
-OBJECT:'!',"booze",(10,09)
-OBJECT:'!',"booze",(10,09)
-OBJECT:'!',"object detection",(10,09)
+OBJECT:('!',"booze"),(10,07)
+OBJECT:('!',"booze"),(10,07)
+OBJECT:'!',(10,07)
+OBJECT:('!',"booze"),(10,08)
+OBJECT:('!',"booze"),(10,08)
+OBJECT:'!',(10,08)
+OBJECT:('!',"booze"),(10,09)
+OBJECT:('!',"booze"),(10,09)
+OBJECT:('!',"object detection"),(10,09)
 # Objects
 # The Treasure chamber...
-OBJECT:'*',"diamond",(69,04)
-OBJECT:'*',random,(69,04)
-OBJECT:'*',"diamond",(69,04)
-OBJECT:'*',random,(69,04)
-OBJECT:'*',"emerald",(70,04)
-OBJECT:'*',random,(70,04)
-OBJECT:'*',"emerald",(70,04)
-OBJECT:'*',random,(70,04)
-OBJECT:'*',"emerald",(69,05)
-OBJECT:'*',random,(69,05)
-OBJECT:'*',"ruby",(69,05)
-OBJECT:'*',random,(69,05)
-OBJECT:'*',"ruby",(70,05)
-OBJECT:'*',"amethyst",(70,05)
-OBJECT:'*',random,(70,05)
-OBJECT:'*',"amethyst",(70,05)
-OBJECT:'*',"luckstone",(70,05)
+OBJECT:('*',"diamond"),(69,04)
+OBJECT:'*',(69,04)
+OBJECT:('*',"diamond"),(69,04)
+OBJECT:'*',(69,04)
+OBJECT:('*',"emerald"),(70,04)
+OBJECT:'*',(70,04)
+OBJECT:('*',"emerald"),(70,04)
+OBJECT:'*',(70,04)
+OBJECT:('*',"emerald"),(69,05)
+OBJECT:'*',(69,05)
+OBJECT:('*',"ruby"),(69,05)
+OBJECT:'*',(69,05)
+OBJECT:('*',"ruby"),(70,05)
+OBJECT:('*',"amethyst"),(70,05)
+OBJECT:'*',(70,05)
+OBJECT:('*',"amethyst"),(70,05)
+OBJECT:('*',"luckstone"),(70,05)
 # Scattered gems...
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'*',random,random
-OBJECT:'(',random,random
-OBJECT:'(',random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [2 + 1d8] {
+  OBJECT:'*',random
+}
+OBJECT:'(',random
+OBJECT:'(',random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Random traps
+LOOP [4 + 1d8] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'G',"gnome king",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnome lord",random
-MONSTER:'G',"gnomish wizard",random
-MONSTER:'G',"gnomish wizard",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'G',"gnome",random
-MONSTER:'h',"hobbit",random
-MONSTER:'h',"hobbit",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',"dwarf",random
-MONSTER:'h',random,random
+MONSTER:('G',"gnome king"),(10,09),hostile
+MONSTER:('G',"gnomish wizard"),(11,09),hostile
+MONSTER:('G',"gnome king"),random
+LOOP [1 + 1d3] {
+  MONSTER:('G',"gnome lord"),random
+}
+LOOP [1d4] {
+  MONSTER:('G',"gnomish wizard"),random
+}
+LOOP [5 + 3d4] {
+  MONSTER:('G',"gnome"),random
+}
+MONSTER:('h',"hobbit"),random
+MONSTER:('h',"hobbit"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:('h',"dwarf"),random
+MONSTER:'h',random
 
 
@@ -922,6 +1256,7 @@
 # Relies on some very specific behavior of MAZEWALK.
 #
-MAZE:"minend-3",'-'
-FLAGS:nommap
+LEVEL:"minend-3"
+FLAGS:nommap,mazelevel
+INIT_MAP:solidfill,'-'
 GEOMETRY:center,bottom
 MAP
@@ -945,5 +1280,6 @@
 ENDMAP
 
-RANDOM_PLACES:(1,15),(68,6),(1,13)
+$place = { (1,15),(68,6),(1,13) }
+SHUFFLE:$place
 NON_DIGGABLE:(67,3,73,7)
 NON_DIGGABLE:(0,12,2,16)
@@ -960,61 +1296,50 @@
 
 # Objects
-OBJECT:'*',"diamond",random
-OBJECT:'*',random,random
-OBJECT:'*',"diamond",random
-OBJECT:'*',random,random
-OBJECT:'*',"emerald",random
-OBJECT:'*',random,random
-OBJECT:'*',"emerald",random
-OBJECT:'*',random,random
-OBJECT:'*',"emerald",random
-OBJECT:'*',random,random
-OBJECT:'*',"ruby",random
-OBJECT:'*',random,random
-OBJECT:'*',"ruby",random
-OBJECT:'*',"amethyst",random
-OBJECT:'*',random,random
-OBJECT:'*',"amethyst",random
-OBJECT:'*',"luckstone",place[0]
-OBJECT:'*',"flint",place[1]
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+OBJECT:('*',"diamond"),random
+OBJECT:'*',random
+OBJECT:('*',"diamond"),random
+OBJECT:'*',random
+OBJECT:('*',"emerald"),random
+OBJECT:'*',random
+OBJECT:('*',"emerald"),random
+OBJECT:'*',random
+OBJECT:('*',"emerald"),random
+OBJECT:'*',random
+OBJECT:('*',"ruby"),random
+OBJECT:'*',random
+OBJECT:('*',"ruby"),random
+OBJECT:('*',"amethyst"),random
+OBJECT:'*',random
+OBJECT:('*',"amethyst"),random
+OBJECT:('*',"luckstone"),$place[0]
+OBJECT:('*',"flint"),$place[1]
+LOOP [3d3] {
+  OBJECT:'?',random
+}
+LOOP [3d2] {
+  OBJECT:'+',random
+}
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+LOOP [2 + 3d3] {
 TRAP:random,random
+}
 # One-time annoyance factor
-TRAP:"level teleport",place[0]
-TRAP:"level teleport",place[1]
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',random,random
-MONSTER:'M',"ettin mummy",random
-MONSTER:'V',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'V',random,random
-MONSTER:'e',random,random
-MONSTER:'e',random,random
-MONSTER:'e',random,random
-MONSTER:'e',random,random
+TRAP:"level teleport",$place[0]
+TRAP:"level teleport",$place[1]
+LOOP [2 + 3d3] {
+  MONSTER:'M',random
+}
+MONSTER:('M',"ettin mummy"),random
+MONSTER:'V',random
+MONSTER:'V',random
+LOOP [3 + 3d3] {
+  MONSTER:'Z',random
+}
+MONSTER:'e',random
+MONSTER:'e',random
+MONSTER:'e',random
+MONSTER:'e',random
 
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Monk.des nethack/dat/Monk.des
--- nh_orig/dat/Monk.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Monk.des	2010-05-02 09:11:33.866715019 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Mon-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Mon-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,(' ', lit)
+MON_GENERATION:86%, (64,"earth elemental"), (16,'E'), (16,"xorn"), (4,'X')
 GEOMETRY:center,center
 MAP
@@ -20,10 +22,10 @@
 ....................|..------------..|--+-----+-----+--|....................
 ....................|..|..........|..|.................|....................
-....................|..|..........|..|+---+---+-----+--|....................
+....................|..|..........|..|+----------------|....................
 ..................---..|..........|......|...|...|.....|....................
 ..................+....|..........+......|...|...|.....|....................
 ..................+....|..........+......|...|...|.....|....................
 ..................---..|..........|......|...|...|.....|....................
-....................|..|..........|..|+-----+---+---+--|....................
+....................|..|..........|..|+----------------|....................
 ....................|..|..........|..|.................|....................
 ....................|..------------..|--+-----+-----+--|....................
@@ -37,5 +39,22 @@
 REGION:(00,00,75,19),lit,"ordinary"
 REGION:(24,06,33,13),lit,"temple"
+REGION:(42,08,44,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west|east, random
+  ROOMDOOR:false, locked, north|south|west|east, random
+}
+REGION:(46,08,48,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west|east, random
+  ROOMDOOR:false, locked, north|south|west|east, random
+}
+REGION:(50,08,54,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west, random
+  ROOMDOOR:false, locked, north|south|west, random
+}
+
+REPLACE_TERRAIN:(0,0,10,19),'.','T',10%
+REPLACE_TERRAIN:(65,0,75,19),'.','T',10%
+
 # Portal arrival point
+TERRAIN:(05,04),'.'
 BRANCH:(05,04,05,04),(0,0,0,0)
 # Stairs
@@ -50,11 +69,5 @@
 DOOR:closed,(52,05)
 DOOR:locked,(38,07)
-DOOR:closed,(42,07)
-DOOR:closed,(46,07)
-DOOR:closed,(52,07)
 DOOR:locked,(38,12)
-DOOR:closed,(44,12)
-DOOR:closed,(48,12)
-DOOR:closed,(52,12)
 DOOR:closed,(40,14)
 DOOR:closed,(46,14)
@@ -63,15 +76,38 @@
 ALTAR:(28,09),noalign,altar
 # The Grand Master
-MONSTER:'@',"Grand Master",(28,10)
+MONSTER:('@',"Grand Master"),(28,10) {
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+}
 # No treasure chest!
 # guards for the audience chamber
-MONSTER:'@',"abbot",(32,07)
-MONSTER:'@',"abbot",(32,08)
-MONSTER:'@',"abbot",(32,11)
-MONSTER:'@',"abbot",(32,12)
-MONSTER:'@',"abbot",(33,07)
-MONSTER:'@',"abbot",(33,08)
-MONSTER:'@',"abbot",(33,11)
-MONSTER:'@',"abbot",(33,12)
+MONSTER:('@',"abbot"),(32,07) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(32,08) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(32,11) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(32,12) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(33,07) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(33,08) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(33,11) {
+  OBJECT[50%]:'?'
+}
+MONSTER:('@',"abbot"),(33,12) {
+  OBJECT[50%]:'?'
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
@@ -84,16 +120,16 @@
 TRAP:random,random
 # Monsters on siege duty.
-MONSTER: 'E',"earth elemental",(37,01)
-MONSTER: 'E',"earth elemental",(37,18)
-MONSTER: 'E',"earth elemental",(03,03)
-MONSTER: 'E',"earth elemental",(65,04)
-MONSTER: 'E',"earth elemental",(12,11)
-MONSTER: 'E',"earth elemental",(60,12)
-MONSTER: 'E',"earth elemental",(14,08)
-MONSTER: 'E',"earth elemental",(55,00)
-MONSTER: 'X',"xorn",(18,18)
-MONSTER: 'X',"xorn",(59,10)
-MONSTER: 'X',"xorn",(13,09)
-MONSTER: 'X',"xorn",(01,17)
+MONSTER: ('E',"earth elemental"),(37,01)
+MONSTER: ('E',"earth elemental"),(37,18)
+MONSTER: ('E',"earth elemental"),(03,03)
+MONSTER: ('E',"earth elemental"),(65,04)
+MONSTER: ('E',"earth elemental"),(12,11)
+MONSTER: ('E',"earth elemental"),(60,12)
+MONSTER: ('E',"earth elemental"),(14,08)
+MONSTER: ('E',"earth elemental"),(55,00)
+MONSTER: ('X',"xorn"),(18,18)
+MONSTER: ('X',"xorn"),(59,10)
+MONSTER: ('X',"xorn"),(13,09)
+MONSTER: ('X',"xorn"),(01,17)
 
 #
@@ -104,5 +140,8 @@
 #
 
-MAZE: "Mon-loca",' '
+LEVEL: "Mon-loca"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"earth elemental"), (16,'E'), (16,"xorn"), (4,'X')
 GEOMETRY:center,center
 #         1         2         3         4         5         6         7 
@@ -132,5 +171,4 @@
 ENDMAP
 # Random Monsters
-RANDOM_MONSTERS: 'E', 'X'
 # Dungeon Description
 REGION:(00,00,75,20),lit,"ordinary"
@@ -141,50 +179,18 @@
 NON_DIGGABLE:(00,00,75,20)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 1d10] {
+OBJECT:random,random
+}
 # Random traps
+LOOP [3 + 2d3] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
+LOOP [13 + 2d5] {
+  MONSTER: ('E',"earth elemental"),random
+}
+LOOP [8 + 1d6] {
+  MONSTER: ('X',"xorn"),random
+}
 
 #
@@ -196,6 +202,8 @@
 #
 
-MAZE: "Mon-goal", ' '
-INIT_MAP: 'L' , '.' , false , false , unlit , false
+LEVEL: "Mon-goal"
+FLAGS:mazelevel
+INIT_MAP: mines, 'L' , '.' , false , false , unlit , false
+MON_GENERATION:86%, (64,"earth elemental"), (16,'E'), (16,"xorn"), (4,'X')
 GEOMETRY:center,center
 MAP
@@ -213,52 +221,35 @@
 ENDMAP
 # Dungeon Description
-RANDOM_PLACES:(14,04),(13,07)
+$place = { (14,04),(13,07) }
+SHUFFLE:$place
 REGION:(00,00,25,10),unlit,"ordinary"
 # Stairs
 STAIR:(20,05),up
 # Objects
-OBJECT:'(',"lenses",place[0],blessed,0,"The Eyes of the Overworld"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"lenses"),$place[0],blessed,0,NAME:"The Eyes of the Overworld"
+LOOP [10 + 1d10] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [3 + 1d3] {
 TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
+}
 TRAP:random,random
 TRAP:random,random
 # Random monsters.
-MONSTER:'@',"Master Kaen",place[0]
-ALTAR:place[0],noalign,altar
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'E',"earth elemental",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
-MONSTER: 'X',"xorn",random
+MONSTER:('@',"Master Kaen"),$place[0] {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:')',1d4
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+}
+ALTAR:$place[0],noalign,altar
+LOOP [10 + 1d6] {
+  MONSTER: ('E',"earth elemental"),random
+}
+LOOP [10 + 1d6] {
+  MONSTER: ('X',"xorn"),random
+}
 
 #
@@ -272,81 +263,105 @@
 
 LEVEL: "Mon-fila"
+MON_GENERATION:86%, (64,"earth elemental"), (16,'E'), (16,"xorn"), (4,'X')
 # Random Monsters
-RANDOM_MONSTERS: 'E', 'X'
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'E', random, random, hostile
+OBJECT: random,random
+MONSTER: 'E', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'E', random, random, hostile
+{
+OBJECT: random, random
+OBJECT: random, random
+MONSTER: 'E', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'X', "xorn", random
-MONSTER: 'E', "earth elemental", random
+OBJECT: random, random
+MONSTER: ('X', "xorn"), random
+MONSTER: ('E', "earth elemental"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'E', random, random, hostile
-MONSTER: 'E', "earth elemental", random
+MONSTER: 'E', random, hostile
+MONSTER: ('E', "earth elemental"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'X', random, random, hostile
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'E', "earth elemental", random
+MONSTER: ('E', "earth elemental"), random
+}
 
 RANDOM_CORRIDORS
 
 LEVEL: "Mon-filb"
+MON_GENERATION:86%, (64,"earth elemental"), (16,'E'), (16,"xorn"), (4,'X')
 # Random Monsters
-RANDOM_MONSTERS: 'E', 'X'
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'X', random, random, hostile
+OBJECT: random,random
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'X', random, random, hostile
+{
+OBJECT: random, random
+OBJECT: random, random
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'E', random, random, hostile
+OBJECT: random, random
+MONSTER: 'E', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'E', random, random, hostile
-MONSTER: 'E', "earth elemental", random
+MONSTER: 'E', random, hostile
+MONSTER: ('E', "earth elemental"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'X', random, random, hostile
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'E', "earth elemental", random
+MONSTER: ('E', "earth elemental"), random
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/opthelp nethack/dat/opthelp
--- nh_orig/dat/opthelp	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/opthelp	2009-08-02 13:49:39.554408799 -0400
@@ -93,4 +93,7 @@
 disclose      the types of information you want offered at the end of the
               game  [ni na nv ng nc]
+dumpfile      the name of the file where to dump the disclosure information
+              when the game ends (only if the patch has been compiled in)
+              [none]
 fruit         the name of a fruit you enjoy eating  [slime mold]
               (basically a whimsy which NetHack uses from time to time).
@@ -121,4 +124,9 @@
               You choose a combination of top scores, scores around the top
               scores, and all of your own scores.  [!own/3 top/2 around]
+sortloot      controls the sortloot patch [none]:
+              full -- All pickup lists of items are sorted by item description
+              loot -- When inventory letters are shown, has no effect.
+                      Otherwise sorts by description
+              none -- Works the traditional way, like without the patch
 suppress_alert disable various version-specific warnings about changes
               in game play or the user interface, such as notification given
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/oracle.des nethack/dat/oracle.des
--- nh_orig/dat/oracle.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/oracle.des	2010-04-11 12:36:58.149750771 -0400
@@ -8,49 +8,67 @@
 
 ROOM: "ordinary" , lit, (3,3), (center,center), (11,9)
-NAME: "central"
-OBJECT:'`',"statue",(0,0),"forest centaur",1
-OBJECT:'`',"statue",(0,8),"mountain centaur",1
-OBJECT:'`',"statue",(10,0),"mountain centaur",1
-OBJECT:'`',"statue",(10,8),"forest centaur",1
-OBJECT:'`',"statue",(5,1),"plains centaur",1
-OBJECT:'`',"statue",(5,7),"plains centaur",1
-OBJECT:'`',"statue",(2,4),"plains centaur",1
-OBJECT:'`',"statue",(8,4),"plains centaur",1
-MONSTER: random, random, random
-MONSTER: random, random, random
+{
 
-SUBROOM: "delphi" , lit , (4,3) , (3,3), "central"
+SUBROOM: "delphi" , lit , (4,3) , (3,3)
+{
 FOUNTAIN: (0, 1)
 FOUNTAIN: (1, 0)
 FOUNTAIN: (1, 2)
 FOUNTAIN: (2, 1)
-MONSTER: '@', "Oracle", (1,1)
-DOOR: false , nodoor , random, random
+MONSTER: ('@', "Oracle"), (1,1) {
+  OBJECT:'!'
+  OBJECT:'?'
+}
+ROOMDOOR: false , nodoor , random, random
+}
+
+OBJECT:('`',"statue"),(0,0),montype:'C',1
+OBJECT:('`',"statue"),(0,8),montype:'C',1
+OBJECT:('`',"statue"),(10,0),montype:'C',1
+OBJECT:('`',"statue"),(10,8),montype:'C',1
+OBJECT:('`',"statue"),(5,1),montype:'C',1
+OBJECT:('`',"statue"),(5,7),montype:'C',1
+OBJECT:('`',"statue"),(2,4),montype:'C',1
+OBJECT:('`',"statue"),(8,4),montype:'C',1
+MONSTER: random, random
+MONSTER: random, random
+
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
+OBJECT: random,random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: random, random, random
-MONSTER: random, random, random
+MONSTER: random, random
+MONSTER: random, random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-MONSTER: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
+MONSTER: random, random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: random, random, random
+MONSTER: random, random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: random, random, random
+MONSTER: random, random
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Priest.des nethack/dat/Priest.des
--- nh_orig/dat/Priest.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Priest.des	2010-05-02 09:11:33.865714749 -0400
@@ -9,6 +9,11 @@
 #	and receive your quest assignment.
 #
-MAZE: "Pri-strt",' '
-FLAGS: noteleport,hardfloor
+# All Priest quest levels are explicitly marked as graveyards
+# so there's less chance for undead corpses.
+#
+LEVEL: "Pri-strt"
+FLAGS: noteleport,hardfloor,mazelevel,graveyard
+INIT_MAP:solidfill,('.',lit)
+MON_GENERATION:86%, (64,"human zombie"), (16,'Z'), (16,"wraith"), (4,'W')
 GEOMETRY:center,center
 MAP
@@ -20,10 +25,10 @@
 ....................|..------------..|--+-----+-----+--|....................
 ....................|..|..........|..|.................|....................
-....................|..|..........|..|+---+---+-----+--|....................
+....................|..|..........|..|+----------------|....................
 ..................---..|..........|......|...|...|.....|....................
 ..................+....|..........+......|...|...|.....|....................
 ..................+....|..........+......|...|...|.....|....................
 ..................---..|..........|......|...|...|.....|....................
-....................|..|..........|..|+-----+---+---+--|....................
+....................|..|..........|..|+----------------|....................
 ....................|..|..........|..|.................|....................
 ....................|..------------..|--+-----+-----+--|....................
@@ -37,5 +42,22 @@
 REGION:(00,00,75,19),lit,"ordinary"
 REGION:(24,06,33,13),lit,"temple"
+REGION:(42,08,44,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west|east, random
+  ROOMDOOR:false, locked, north|south|west|east, random
+}
+REGION:(46,08,48,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west|east, random
+  ROOMDOOR:false, locked, north|south|west|east, random
+}
+REGION:(50,08,54,11),lit,"ordinary",unfilled,true {
+  ROOMDOOR:false, closed, north|south|west, random
+  ROOMDOOR:false, locked, north|south|west, random
+}
+
+REPLACE_TERRAIN:(0,0,10,19),'.','T',10%
+REPLACE_TERRAIN:(65,0,75,19),'.','T',10%
+
 # Portal arrival point
+TERRAIN:(05,04),'.'
 BRANCH:(05,04,05,04),(0,0,0,0)
 # Stairs
@@ -50,11 +72,5 @@
 DOOR:closed,(52,05)
 DOOR:locked,(38,07)
-DOOR:closed,(42,07)
-DOOR:closed,(46,07)
-DOOR:closed,(52,07)
 DOOR:locked,(38,12)
-DOOR:closed,(44,12)
-DOOR:closed,(48,12)
-DOOR:closed,(52,12)
 DOOR:closed,(40,14)
 DOOR:closed,(46,14)
@@ -63,16 +79,40 @@
 ALTAR:(28,09),noalign,altar
 # High Priest
-MONSTER:'@',"Arch Priest",(28,10)
+MONSTER:('@',"Arch Priest"),(28,10) {
+  OBJECT:('[',"robe"),1d4
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'+'
+  OBJECT:'+'
+}
 # The treasure of High Priest
-OBJECT:'(',"chest",(27,10)
+OBJECT:('(',"chest"),(27,10)
 # knight guards for the audience chamber
-MONSTER:'@',"acolyte",(32,07)
-MONSTER:'@',"acolyte",(32,08)
-MONSTER:'@',"acolyte",(32,11)
-MONSTER:'@',"acolyte",(32,12)
-MONSTER:'@',"acolyte",(33,07)
-MONSTER:'@',"acolyte",(33,08)
-MONSTER:'@',"acolyte",(33,11)
-MONSTER:'@',"acolyte",(33,12)
+MONSTER:('@',"acolyte"),(32,07) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(32,08) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(32,11) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(32,12) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(33,07) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(33,08) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(33,11) {
+  OBJECT:'?'
+}
+MONSTER:('@',"acolyte"),(33,12) {
+  OBJECT:'?'
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
@@ -85,16 +125,16 @@
 TRAP:random,random
 # Monsters on siege duty.
-MONSTER: 'Z',"human zombie",(37,01)
-MONSTER: 'Z',"human zombie",(37,18)
-MONSTER: 'Z',"human zombie",(03,03)
-MONSTER: 'Z',"human zombie",(65,04)
-MONSTER: 'Z',"human zombie",(12,11)
-MONSTER: 'Z',"human zombie",(60,12)
-MONSTER: 'Z',"human zombie",(14,08)
-MONSTER: 'Z',"human zombie",(55,00)
-MONSTER: 'Z',"human zombie",(18,18)
-MONSTER: 'Z',"human zombie",(59,10)
-MONSTER: 'Z',"human zombie",(13,09)
-MONSTER: 'Z',"human zombie",(01,17)
+MONSTER: ('Z',"human zombie"),(37,01)
+MONSTER: ('Z',"human zombie"),(37,18)
+MONSTER: ('Z',"human zombie"),(03,03)
+MONSTER: ('Z',"human zombie"),(65,04)
+MONSTER: ('Z',"human zombie"),(12,11)
+MONSTER: ('Z',"human zombie"),(60,12)
+MONSTER: ('Z',"human zombie"),(14,08)
+MONSTER: ('Z',"human zombie"),(55,00)
+MONSTER: ('Z',"human zombie"),(18,18)
+MONSTER: ('Z',"human zombie"),(59,10)
+MONSTER: ('Z',"human zombie"),(13,09)
+MONSTER: ('Z',"human zombie"),(01,17)
 
 #
@@ -105,8 +145,8 @@
 #
 
-MAZE: "Pri-loca",' '
-FLAGS: hardfloor
-# This is a kludge to init the level as a lit field.
-INIT_MAP: '.' , '.' , false , false , lit , false
+LEVEL: "Pri-loca"
+FLAGS: hardfloor,mazelevel,graveyard
+INIT_MAP: solidfill, ('.', lit)
+MON_GENERATION:86%, (64,"human zombie"), (16,'Z'), (16,"wraith"), (4,'W')
 GEOMETRY:center,center
 MAP
@@ -134,5 +174,5 @@
 # The altar inside the temple
 ALTAR:(20,07),noalign,shrine
-MONSTER:'@',"aligned priest",(20,07),noalign,hostile
+MONSTER:('@',"aligned priest"),(20,07),noalign,hostile
 # Doors
 DOOR:locked,(10,06)
@@ -149,19 +189,19 @@
 NON_DIGGABLE:(10,02,30,13)
 # Objects (inside the antechambers).
-OBJECT:random,random,(14,03)
-OBJECT:random,random,(15,03)
-OBJECT:random,random,(16,03)
-OBJECT:random,random,(14,10)
-OBJECT:random,random,(15,10)
-OBJECT:random,random,(16,10)
-OBJECT:random,random,(17,10)
-OBJECT:random,random,(24,03)
-OBJECT:random,random,(25,03)
-OBJECT:random,random,(26,03)
-OBJECT:random,random,(27,03)
-OBJECT:random,random,(24,10)
-OBJECT:random,random,(25,10)
-OBJECT:random,random,(26,10)
-OBJECT:random,random,(27,10)
+OBJECT:random,(14,03)
+OBJECT:random,(15,03)
+OBJECT:random,(16,03)
+OBJECT:random,(14,10)
+OBJECT:random,(15,10)
+OBJECT:random,(16,10)
+OBJECT:random,(17,10)
+OBJECT:random,(24,03)
+OBJECT:random,(25,03)
+OBJECT:random,(26,03)
+OBJECT:random,(27,03)
+OBJECT:random,(24,10)
+OBJECT:random,(25,10)
+OBJECT:random,(26,10)
+OBJECT:random,(27,10)
 # Random traps
 TRAP:random,(15,04)
@@ -181,6 +221,8 @@
 #
 
-MAZE: "Pri-goal", ' '
-INIT_MAP: 'L' , '.' , false , false , unlit , false
+LEVEL: "Pri-goal"
+FLAGS:mazelevel,graveyard
+INIT_MAP: mines, 'L' , '.' , false , false , unlit , false
+MON_GENERATION:86%, (64,"human zombie"), (16,'Z'), (16,"wraith"), (4,'W')
 GEOMETRY:center,center
 MAP
@@ -198,24 +240,14 @@
 ENDMAP
 # Dungeon Description
-RANDOM_PLACES:(14,04),(13,07)
+$place = { (14,04),(13,07) }
+SHUFFLE: $place
 REGION:(00,00,25,10),unlit,"ordinary"
 # Stairs
 STAIR:(20,05),up
 # Objects
-OBJECT:'[',"helm of brilliance",place[0],blessed,0,"The Mitre of Holiness"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('[',"helm of brilliance"),$place[0],blessed,0,NAME:"The Mitre of Holiness"
+LOOP [10 + 1d6] {
+  OBJECT:random,random
+}
 # Random traps
 TRAP:"fire",random
@@ -226,32 +258,18 @@
 TRAP:random,random
 # Random monsters.
-MONSTER:'&',"Nalzok",place[0]
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',"human zombie",random
-MONSTER:'Z',random,random
-MONSTER:'Z',random,random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',"wraith",random
-MONSTER:'W',random,random
+MONSTER:('&',"Nalzok"),$place[0] {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:')',1d6
+  OBJECT:'[',1d3
+}
+LOOP [15 + 2d5] {
+  MONSTER:('Z',"human zombie"),random
+}
+MONSTER:'Z',random
+MONSTER:'Z',random
+LOOP [4 + 2d4] {
+  MONSTER:('W',"wraith"),random
+}
+MONSTER:'W',random
 
 #
@@ -265,73 +283,101 @@
 
 LEVEL: "Pri-fila"
+FLAGS:graveyard
+MON_GENERATION:86%, (64,"human zombie"), (16,'Z'), (16,"wraith"), (4,'W')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'Z', "human zombie", random
+OBJECT: random,random
+MONSTER: ('Z', "human zombie"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
+{
+OBJECT: random, random
+OBJECT: random,random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'Z', "human zombie", random
+OBJECT: random,random
+MONSTER: ('Z', "human zombie"), random
+}
 
 ROOM: "morgue" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'W', "wraith", random
+MONSTER: ('W', "wraith"), random
+}
 
 ROOM: "morgue" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
+}
 
 RANDOM_CORRIDORS
 
 LEVEL: "Pri-filb"
+FLAGS:graveyard
+MON_GENERATION:86%, (64,"human zombie"), (16,'Z'), (16,"wraith"), (4,'W')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'Z', "human zombie", random
-MONSTER: 'W', "wraith", random
+OBJECT: random,random
+MONSTER: ('Z', "human zombie"), random
+MONSTER: ('W', "wraith"), random
+}
 
 ROOM: "morgue" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
+{
+OBJECT: random, random
+OBJECT: random, random
+OBJECT: random,random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'Z', "human zombie", random
-MONSTER: 'W', "wraith", random
+OBJECT: random,random
+MONSTER: ('Z', "human zombie"), random
+MONSTER: ('W', "wraith"), random
+}
 
 ROOM: "morgue" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
-OBJECT: random, random, random
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'Z', "human zombie", random
-MONSTER: 'W', "wraith", random
+MONSTER: ('Z', "human zombie"), random
+MONSTER: ('W', "wraith"), random
+}
 
 ROOM: "morgue" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/quest.txt nethack/dat/quest.txt
--- nh_orig/dat/quest.txt	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/quest.txt	2009-08-02 13:49:39.540409141 -0400
@@ -360,5 +360,5 @@
 "Pah!  You have betrayed the gods, %p.  You will never attain
 the glory which you aspire to.  Your failure to follow the true path has
-closed this future to you.
+closed that future to you.
 
 "I will protect these people as best I can, but soon %n will overcome
@@ -560,10 +560,10 @@
 #
 %Cc Cav 00001
-You descend through a barely familiar stairwell that you remember
+You walk through a barely familiar overgrown path that you remember
 %l showing you when you embarked upon your vision quest.
 
-You arrive back at %H, but something seems
-wrong here.  The usual smoke and glowing light of the fires of the
-outer caves are absent, and an uneasy quiet fills the damp air.
+You arrive back at %H, ... but something seems
+wrong here.  The jungle has a tense aura about it, and the beasts
+are snarling and hostile.  An uneasy quiet fills the damp air.
 %E
 %Cp Cav 00002
@@ -620,6 +620,5 @@
 %E
 %Cc Cav 00018
-"%pC!  You have sealed our fate.  You seem unable to reform yourself,
-so I must select another to take your place.
+"%pC!  You have sealed our fate by being unable to reform yourself.
 
 "Begone from %H!  You have betrayed us by choosing
@@ -640,5 +639,5 @@
 %Cc Cav 00020
 "%pC!  You have deviated from my teachings.  You no longer follow
-the path of the %a as you should.  I banish you from these caves, to
+the path of the %a as you should.  I banish you from this temple, to
 go forth and purify yourself.  Then, you might be able to accomplish this
 quest."
@@ -648,5 +647,5 @@
 great suffering among your people:
 
-"Shortly after you left on your vision quest, the caves were invaded by
+"Shortly after you left on your vision quest, the jungle was invaded by
 the creatures sent against us by %n.
 
@@ -655,10 +654,13 @@
 minions of %n managed to steal %o.
 They took it to %i and there, none of our
-%g warriors have been able to go.
+%g warriors have been able to go.  Worse, she has invoked its power
+against us, and now conflict ravages our once-peaceful jungle.
 
 "You must find %i, and within it wrest
 %o from %n.  She guards it as
 jealously as she guards all treasures she attains.  But with it,
-we can make our caves safe once more.
+we can make our jungle safe once more.  Without it, the spirit of the
+jungle cries out in pain, and the animals are crazed and attack all
+who pass near.
 
 "Please, %p, recover %o for us, and return it here."
@@ -699,10 +701,10 @@
 %E
 %Cc Cav 00035
-You %x many large claw marks on the ground.  The tunnels ahead
-of you are larger than most of those in any cave complex you have
-ever been in before.
+You %x many large claw marks on the ground.  Your brief respite 
+from the narrow jungle confines appears to be over... many paths lead
+into the trees in all directions, and stagnant pools cover the ground.
 
-Your nose detects the smell of carrion from within, and bones litter
-the sides of the tunnels.
+Your nose detects the smell of carrion from somewhere deep within, and
+unidentifiable, gnawed bones litter the nearby underbrush.
 %E
 %Cp Cav 00036
@@ -713,5 +715,5 @@
 nevertheless show signs of being scorched by fire.
 
-Bones litter the floor, and there are objects scattered everywhere.
+Bones cover the floor, and there are objects scattered everywhere.
 The air is close with the stench of sulphurous fumes.
 
@@ -784,4 +786,10 @@
     own.
 
+He takes it from your hands and does something you cannot see. You 
+feel the very trees relax as the magic-induced hatred melts away from
+the land.
+
+He returns it to you and says:
+
     To prevent further trouble, I would like you, %p,
     to take %o away with you.  It will help you as you
@@ -1149,13 +1157,13 @@
 far is a credit to thy valor, but thou art yet unprepared for
 the demands required as Our Champion.  %rA, no matter how
-pure, could never hope to defeat the foul %n.
+brave, could never hope to defeat the foul %n.
 
 "Journey forth from this place, and hone thy skills.  Return to
-Our presence when thou hast attained the noble title of %R."
+Our presence when thou hast attained the title of %R."
 %E
 %Cc Kni 00020
-"Thou dishonourest Us, %p!  Thou hast strayed from the path of
-chivalry! Go from Our presence and do penance.  Only when thou art again
-pure mayst thou return hence."
+"Thou dishonourest Us, %p!  Thou hast strayed from thine chosen 
+path!  Go from Our presence and do penance.  Only when thou 
+hast regained thy soul's direction mayst thou return hence."
 %E
 %Cc Kni 00021
@@ -2139,8 +2147,6 @@
 "Well %gp, it looks like our friend has forgotten who is the boss
 around here.  Our friend seems to think that %rp have been put in
-charge.  Wrong.  DEAD WRONG!"
+charge.  Wrong.  DEAD wrong, in fact..."
 
-Your sudden shift in surroundings prevents you from hearing the end
-of %ls curse.
 %E
 %Cc Rog 00019
@@ -2885,6 +2891,6 @@
 %Cc Val 00018
 "No, %p.  Your fate is sealed.  I must cast about for another
-champion.  Begone from my presence, and never return.  Know this, that
-you shall never succeed in this life, and Valhalla is denied to you."
+champion.  Begone from my presence, and never return.  Know that
+Valhalla shall be denied to you."
 %E
 %Cc Val 00019
@@ -3463,10 +3469,9 @@
 have done.
 
-Leave this place.  You shall never set foot at %H again.
-That which you seek is now lost forever, for without the Bell of Opening, 
-you will never be able to enter the place where he who has the Amulet 
-resides.
+Leave this place. You shall never set foot beyond %H again as long as I
+draw breath... and without the Bell of Opening, you will never be able to 
+enter the place where he who has the Amulet resides.
 
-Go now!  You are banished from this place.
+Begone from my sight!"
 %E
 #
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Ranger.des nethack/dat/Ranger.des
--- nh_orig/dat/Ranger.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Ranger.des	2010-08-16 13:20:13.633706782 -0400
@@ -9,12 +9,14 @@
 #	and receive your quest assignment.
 #
-MAZE: "Ran-strt",'.'
-FLAGS: noteleport,hardfloor,arboreal
-INIT_MAP:'.','.',true,true,lit,false
-GEOMETRY:left,center
+LEVEL: "Ran-strt"
+FLAGS: noteleport,hardfloor,arboreal,mazelevel
+INIT_MAP:mines,'.','.',true,true,lit,false
+REPLACE_TERRAIN:(0,0,76,19),'.', 'T', 5%
+MON_GENERATION:86%, (64,"forest centaur"), (16,'C'), (16,"scorpion"), (4,'s')
+GEOMETRY:(0,1)
 #1234567890123456789012345678901234567890123456789012345678901234567890
 MAP
-                                       ..
-   ...................................  .
+                                       xx
+   ...................................  x
   ..                                 ..  
  ..  ...............F...............  .. 
@@ -34,6 +36,6 @@
  ..  ...............F...............  .. 
   ..                                 ..  
-   ...................................  .
-                                       ..
+   ...................................  x
+                                       xx
 ENDMAP
 # Dungeon Description
@@ -44,16 +46,56 @@
 BRANCH:levregion(51,2,77,18),(0,0,40,20)
 # Orion
-MONSTER:'@',"Orion",(20,10)
+MONSTER:('@',"Orion"),(20,10) {
+  OBJECT:('[',"leather armor"),1d4
+  OBJECT:(')',"yumi"),1d4
+  OBJECT:(')',"arrow"),1d4,quantity:10d5
+}
 # The treasure of Orion
-OBJECT:'(',"chest",(20,10)
+OBJECT:('(',"chest"),(20,10)
 # Guards for the audience chamber
-MONSTER:'@',"hunter",(19,09)
-MONSTER:'@',"hunter",(20,09)
-MONSTER:'@',"hunter",(21,09)
-MONSTER:'@',"hunter",(19,10)
-MONSTER:'@',"hunter",(21,10)
-MONSTER:'@',"hunter",(19,11)
-MONSTER:'@',"hunter",(20,11)
-MONSTER:'@',"hunter",(21,11)
+MONSTER:('@',"hunter"),(19,09) {
+  OBJECT[25%]:('[',"leather armor")
+  IF [50%] {
+    OBJECT:(')',"bow")
+    OBJECT:(')',"arrow")
+  }
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(20,09) {
+  OBJECT[25%]:('[',"leather armor")
+  IF [50%] {
+    OBJECT:(')',"bow")
+    OBJECT:(')',"arrow")
+  }
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(21,09) {
+  OBJECT[25%]:('[',"leather armor")
+  IF [50%] {
+    OBJECT:(')',"bow")
+    OBJECT:(')',"arrow")
+  }
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(19,10) {
+  OBJECT[25%]:('[',"leather armor")
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(21,10) {
+  OBJECT[25%]:('[',"leather armor")
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(19,11) {
+  OBJECT[25%]:('[',"leather armor")
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(20,11) {
+  OBJECT[25%]:('[',"leather armor")
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"hunter"),(21,11) {
+  OBJECT[25%]:('[',"leather armor")
+  OBJECT[15%]:')'
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,40,20)
@@ -66,31 +108,28 @@
 TRAP:"bear",random
 # Monsters on siege duty.
-MONSTER: 'H',"minotaur",(33,09),hostile,asleep
-MONSTER: 'C',"forest centaur",(19,03),hostile
-MONSTER: 'C',"forest centaur",(19,04),hostile
-MONSTER: 'C',"forest centaur",(19,05),hostile
-MONSTER: 'C',"forest centaur",(21,03),hostile
-MONSTER: 'C',"forest centaur",(21,04),hostile
-MONSTER: 'C',"forest centaur",(21,05),hostile
-MONSTER: 'C',"forest centaur",(01,09),hostile
-MONSTER: 'C',"forest centaur",(02,09),hostile
-MONSTER: 'C',"forest centaur",(03,09),hostile
-MONSTER: 'C',"forest centaur",(01,11),hostile
-MONSTER: 'C',"forest centaur",(02,11),hostile
-MONSTER: 'C',"forest centaur",(03,11),hostile
-MONSTER: 'C',"forest centaur",(19,15),hostile
-MONSTER: 'C',"forest centaur",(19,16),hostile
-MONSTER: 'C',"forest centaur",(19,17),hostile
-MONSTER: 'C',"forest centaur",(21,15),hostile
-MONSTER: 'C',"forest centaur",(21,16),hostile
-MONSTER: 'C',"forest centaur",(21,17),hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 'C',"plains centaur",random,hostile
-MONSTER: 's',"scorpion",random,hostile
-MONSTER: 's',"scorpion",random,hostile
+MONSTER: ('H',"minotaur"),(33,09),hostile,asleep
+MONSTER: ('C',"forest centaur"),(19,03),hostile
+MONSTER: ('C',"forest centaur"),(19,04),hostile
+MONSTER: ('C',"forest centaur"),(19,05),hostile
+MONSTER: ('C',"forest centaur"),(21,03),hostile
+MONSTER: ('C',"forest centaur"),(21,04),hostile
+MONSTER: ('C',"forest centaur"),(21,05),hostile
+MONSTER: ('C',"forest centaur"),(01,09),hostile
+MONSTER: ('C',"forest centaur"),(02,09),hostile
+MONSTER: ('C',"forest centaur"),(03,09),hostile
+MONSTER: ('C',"forest centaur"),(01,11),hostile
+MONSTER: ('C',"forest centaur"),(02,11),hostile
+MONSTER: ('C',"forest centaur"),(03,11),hostile
+MONSTER: ('C',"forest centaur"),(19,15),hostile
+MONSTER: ('C',"forest centaur"),(19,16),hostile
+MONSTER: ('C',"forest centaur"),(19,17),hostile
+MONSTER: ('C',"forest centaur"),(21,15),hostile
+MONSTER: ('C',"forest centaur"),(21,16),hostile
+MONSTER: ('C',"forest centaur"),(21,17),hostile
+LOOP [4 + 2d5] {
+  MONSTER: ('C',"plains centaur"),random,hostile
+}
+MONSTER: ('s',"scorpion"),random,hostile
+MONSTER: ('s',"scorpion"),random,hostile
 
 
@@ -102,6 +141,8 @@
 #
 
-MAZE: "Ran-loca",' '
-FLAGS: hardfloor
+LEVEL: "Ran-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"forest centaur"), (16,'C'), (16,"scorpion"), (4,'s')
 GEOMETRY:center,center
 #1234567890123456789012345678901234567890123456789012345678901234567890
@@ -136,12 +177,12 @@
 NON_DIGGABLE:(00,00,54,19)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
+OBJECT:random,random
 # Random traps
 TRAP:"spiked pit",random
@@ -152,27 +193,14 @@
 TRAP:"arrow",random
 # Random monsters.
-MONSTER:'q',"wumpus",(27,18),hostile,asleep
-MONSTER:'B',"giant bat",random,hostile
-MONSTER:'B',"giant bat",random,hostile
-MONSTER:'B',"giant bat",random,hostile
-MONSTER:'B',"giant bat",random,hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',random,random,hostile
-MONSTER:'s',random,random,hostile
+MONSTER:('q',"wumpus"),(27,18),hostile,asleep
+LOOP [2 + 1d6] {
+  MONSTER:('B',"giant bat"),random,hostile
+  MONSTER:('C',"forest centaur"),random,hostile
+  MONSTER:('s',"scorpion"),random,hostile
+  MONSTER:('C',"mountain centaur"),random,hostile
+  MONSTER:('C',"mountain centaur"),random,hostile
+}
+MONSTER:'s',random,hostile
+MONSTER:'s',random,hostile
 
 
@@ -185,5 +213,8 @@
 #
 
-MAZE: "Ran-goal", ' '
+LEVEL: "Ran-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"forest centaur"), (16,'C'), (16,"scorpion"), (4,'s')
 GEOMETRY:center,center
 MAP
@@ -198,5 +229,5 @@
    .        S          .         .........   .S.    .S...............   .   
    .  ...   .     ...  .         .........          .                   .   
-   . ........    .....S.+.......+....\....+........+.                   .   
+   . ........    .....S.+.......+.........+........+.                   .   
    .  ...         ...    S       .........           ..      .....      .   
    .                    ..       .........            ..      ......    .   
@@ -216,26 +247,22 @@
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:')',"bow",(37,10),blessed,0,"The Longbow of Diana"
-OBJECT:'(',"chest",(37,10)
-OBJECT:random,random,(36,09)
-OBJECT:random,random,(36,10)
-OBJECT:random,random,(36,11)
-OBJECT:random,random,(37,09)
-OBJECT:random,random,(37,11)
-OBJECT:random,random,(38,09)
-OBJECT:random,random,(38,10)
-OBJECT:random,random,(38,11)
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('\',"throne"),(37,10)
+OBJECT:(')',"bow"),(37,10),blessed,0,NAME:"The Longbow of Diana"
+OBJECT:('(',"chest"),(37,10)
+OBJECT:random,(36,09)
+OBJECT:random,(36,10)
+OBJECT:random,(36,11)
+OBJECT:random,(37,09)
+OBJECT:random,(37,11)
+OBJECT:random,(38,09)
+OBJECT:random,(38,10)
+OBJECT:random,(38,11)
+LOOP [3 + 1d3] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [4 + 1d5] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # doors
 DOOR:locked,(12,08)
@@ -254,32 +281,38 @@
 DOOR:closed,(65,05)
 # Random monsters.
-MONSTER:'s',"Scorpius",(37,10),hostile
-MONSTER:'C',"forest centaur",(36,09),hostile
-MONSTER:'C',"forest centaur",(36,10),hostile
-MONSTER:'C',"forest centaur",(36,11),hostile
-MONSTER:'C',"forest centaur",(37,09),hostile
-MONSTER:'C',"forest centaur",(37,11),hostile
-MONSTER:'C',"forest centaur",(38,09),hostile
-MONSTER:'C',"mountain centaur",(38,10),hostile
-MONSTER:'C',"mountain centaur",(38,11),hostile
-MONSTER:'C',"mountain centaur",(02,02),hostile
-MONSTER:'C',"mountain centaur",(71,02),hostile
-MONSTER:'C',"mountain centaur",(02,16),hostile
-MONSTER:'C',"mountain centaur",(71,16),hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"forest centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',"mountain centaur",random,hostile
-MONSTER:'C',random,random,hostile
-MONSTER:'C',random,random,hostile
-MONSTER:'s',"scorpion",(03,02),hostile
-MONSTER:'s',"scorpion",(72,02),hostile
-MONSTER:'s',"scorpion",(03,17),hostile
-MONSTER:'s',"scorpion",(72,17),hostile
-MONSTER:'s',"scorpion",(41,10),hostile
-MONSTER:'s',"scorpion",(33,09),hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',"scorpion",random,hostile
-MONSTER:'s',random,random,hostile
+MONSTER:('s',"Scorpius"),(37,10),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+}
+MONSTER:('C',"forest centaur"),(36,09),hostile
+MONSTER:('C',"forest centaur"),(36,10),hostile
+MONSTER:('C',"forest centaur"),(36,11),hostile
+MONSTER:('C',"forest centaur"),(37,09),hostile
+MONSTER:('C',"forest centaur"),(37,11),hostile
+MONSTER:('C',"forest centaur"),(38,09),hostile
+MONSTER:('C',"mountain centaur"),(38,10),hostile
+MONSTER:('C',"mountain centaur"),(38,11),hostile
+MONSTER:('C',"mountain centaur"),(02,02),hostile
+MONSTER:('C',"mountain centaur"),(71,02),hostile
+MONSTER:('C',"mountain centaur"),(02,16),hostile
+MONSTER:('C',"mountain centaur"),(71,16),hostile
+MONSTER:('s',"scorpion"),(03,02),hostile
+MONSTER:('s',"scorpion"),(72,02),hostile
+MONSTER:('s',"scorpion"),(03,17),hostile
+MONSTER:('s',"scorpion"),(72,17),hostile
+MONSTER:('s',"scorpion"),(41,10),hostile
+MONSTER:('s',"scorpion"),(33,09),hostile
+LOOP [2 + 1d5] {
+  MONSTER:('C',"forest centaur"),random,hostile
+  MONSTER:('C',"mountain centaur"),random,hostile
+  MONSTER:'C',random,hostile
+  MONSTER:('s',"scorpion"),random,hostile
+  MONSTER:'s',random,hostile
+}
 
 WALLIFY
@@ -294,6 +327,8 @@
 #
 
-MAZE: "Ran-fila" , ' '
-INIT_MAP: '.' , 'T', true, true, random, true
+LEVEL: "Ran-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'T', true, true, random, true
+MON_GENERATION:86%, (64,"forest centaur"), (16,'C'), (16,"scorpion"), (4,'s')
 NOMAP
 #
@@ -301,27 +336,23 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 1d5] {
+  OBJECT: random, random
+}
 #
+LOOP [3 + 1d4] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', "forest centaur", random, hostile
-MONSTER: 'C', "forest centaur", random, hostile
-MONSTER: 'C', "forest centaur", random, hostile
-MONSTER: 'C', random, random, hostile
-MONSTER: 's', "scorpion", random, hostile
+LOOP [2 + 1d4] {
+  MONSTER: ('C', "mountain centaur"), random, hostile
+  MONSTER: ('C', "forest centaur"), random, hostile
+}
+MONSTER: 'C', random, hostile
+MONSTER: ('s', "scorpion"), random, hostile
 
-MAZE: "Ran-filb" , ' '
-INIT_MAP: '.' , ' ', true, true, random, true
+LEVEL: "Ran-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ', true, true, random, true
+MON_GENERATION:86%, (64,"forest centaur"), (16,'C'), (16,"scorpion"), (4,'s')
 NOMAP
 #
@@ -329,27 +360,16 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [9 + 1d5] {
+  OBJECT: random, random
+}
 #
+LOOP [2 + 1d5] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', "mountain centaur", random, hostile
-MONSTER: 'C', random, random, hostile
-MONSTER: 's', "scorpion", random, hostile
-MONSTER: 's', "scorpion", random, hostile
+LOOP [3 + 1d5] {
+  MONSTER: ('C', "mountain centaur"), random, hostile
+  MONSTER: 'C', random, hostile
+  MONSTER: ('s', "scorpion"), random, hostile
+}
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Rogue.des nethack/dat/Rogue.des
--- nh_orig/dat/Rogue.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Rogue.des	2010-04-29 10:53:24.166715096 -0400
@@ -8,6 +8,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Rog-strt",' '
-FLAGS: noteleport, hardfloor, nommap
+LEVEL: "Rog-strt"
+FLAGS: noteleport, hardfloor, nommap, mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"leprechaun"), (16,'n'), (16,"guardian naga"), (4,'N')
 GEOMETRY:center,center
 #         1         2         3         4         5         6         7
@@ -40,9 +42,13 @@
 # The down stairs is at one of the 4 "exits".  The others are mimics,
 # mimicing stairwells.
-RANDOM_PLACES: (33,0), (0,12), (25,20), (75,05)
-STAIR:place[0],down
-MONSTER:'m',"giant mimic", place[1], m_feature "staircase down"
-MONSTER:'m',"large mimic", place[2], m_feature "staircase down"
-MONSTER:'m',"small mimic", place[3], m_feature "staircase down"
+
+$streets = selection: floodfill(0,12)
+
+$place = { (33,0), (0,12), (25,20), (75,05) }
+SHUFFLE: $place
+STAIR:$place[0],down
+MONSTER:('m',"giant mimic"), $place[1], m_feature "staircase down"
+MONSTER:('m',"large mimic"), $place[2], m_feature "staircase down"
+MONSTER:('m',"small mimic"), $place[3], m_feature "staircase down"
 # Portal arrival point
 BRANCH:(19,09,19,09),(0,0,0,0)
@@ -97,73 +103,87 @@
 DOOR: closed, (68,18)
 # Master of Thieves
-MONSTER:'@',"Master of Thieves",(36,11)
+MONSTER:('@',"Master of Thieves"),(36,11) {
+  OBJECT:'['
+  OBJECT:')'
+  OBJECT:'!'
+  OBJECT:'!'
+  OBJECT:'!'
+  OBJECT:'!'
+}
 # The treasure of Master of Thieves
-OBJECT:'(',"chest",(36,11)
+OBJECT:('(',"chest"),(36,11)
 # thug guards, room #1
-MONSTER:'@',"thug",(28,10)
-MONSTER:'@',"thug",(29,11)
-MONSTER:'@',"thug",(30,09)
-MONSTER:'@',"thug",(31,07)
+MONSTER:('@',"thug"),(28,10) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(29,11) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(30,09) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(31,07) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
 # thug guards, room #2
-MONSTER:'@',"thug",(31,13)
-MONSTER:'@',"thug",(33,14)
-MONSTER:'@',"thug",(30,15)
+MONSTER:('@',"thug"),(31,13) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(33,14) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(30,15) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
 #thug guards, room #3
-MONSTER:'@',"thug",(35,09)
-MONSTER:'@',"thug",(36,13)
+MONSTER:('@',"thug"),(35,09) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
+MONSTER:('@',"thug"),(36,13) {
+  OBJECT[15%]:'['
+  OBJECT[15%]:')'
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,20)
 # Random traps
+LOOP [15 + 1d10] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 #
 # Monsters to get in the way.
 #
 # West exit
-MONSTER: 'l',"leprechaun",(01,12),hostile
-MONSTER: 'n',"water nymph",(02,12),hostile
+MONSTER: ('l',"leprechaun"),(01,12),hostile
+MONSTER: ('n',"water nymph"),(02,12),hostile
 # North exit
-MONSTER: 'n',"water nymph",(33,01),hostile
-MONSTER: 'l',"leprechaun",(33,02),hostile
+MONSTER: ('n',"water nymph"),(33,01),hostile
+MONSTER: ('l',"leprechaun"),(33,02),hostile
 # East exit
-MONSTER: 'n',"water nymph",(74,05),hostile
-MONSTER: 'l',"leprechaun",(74,04),hostile
+MONSTER: ('n',"water nymph"),(74,05),hostile
+MONSTER: ('l',"leprechaun"),(74,04),hostile
 # South exit
-MONSTER: 'l',"leprechaun",(25,19),hostile
-MONSTER: 'n',"water nymph",(25,18),hostile
-# Wandering the streets.  What I'd really like for this is a random
-# location, but make sure we're on a given type, e.g. street (if they
-# existed, of course).
-MONSTER: 'n',"water nymph",(07,05),hostile
-MONSTER: 'l',"leprechaun",(28,06),hostile
-MONSTER: 'n',"water nymph",(38,07),hostile
-MONSTER: 'l',"leprechaun",(45,01),hostile
-MONSTER: 'n',"water nymph",(59,07),hostile
-MONSTER: 'l',"leprechaun",(62,14),hostile
-MONSTER: 'n',"water nymph",(71,14),hostile
-MONSTER: 'l',"leprechaun",(39,13),hostile
-MONSTER: 'n',"water nymph",(18,14),hostile
-MONSTER: ':',"chameleon",(19,08),hostile
-MONSTER: ':',"chameleon",(22,08),hostile
-MONSTER: ':',"chameleon",(16,08),hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
+MONSTER: ('l',"leprechaun"),(25,19),hostile
+MONSTER: ('n',"water nymph"),(25,18),hostile
+# Wandering the streets.
+LOOP [3 + 2d2] {
+  MONSTER: ('n',"water nymph"),rndcoord($streets),hostile
+}
+LOOP [1 + 2d2] {
+  MONSTER: ('l',"leprechaun"),rndcoord($streets),hostile
+}
+LOOP [2d2] {
+  MONSTER: (':',"chameleon"),rndcoord($streets),hostile
+}
+LOOP [3 + 1d7] {
+  MONSTER: (':',"chameleon"),rndcoord($streets),hostile
+}
 
 #
@@ -174,5 +194,8 @@
 #
 
-MAZE: "Rog-loca",' '
+LEVEL: "Rog-loca"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"leprechaun"), (16,'n'), (16,"guardian naga"), (4,'N')
 GEOMETRY:center,center
 #         1         2         3         4         5         6         7
@@ -211,60 +234,26 @@
 NON_DIGGABLE:(00,00,75,20)
 # Objects
-OBJECT:'?',"teleportation",(11,18),cursed,0
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('?',"teleportation"),(11,18),cursed,0
+LOOP [10 + 1d6] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [ 5 + 1d6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',random,random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
+LOOP [15 + 2d6] {
+  MONSTER:('l',"leprechaun"),random,hostile
+}
+MONSTER:'l',random,hostile
+LOOP [5 + 1d6] {
+  MONSTER:('N',"guardian naga"),random,hostile
+}
+MONSTER:'N',random,hostile
+MONSTER:'N',random,hostile
+MONSTER:'N',random,hostile
+LOOP [4 + 1d3] {
+  MONSTER: (':',"chameleon"),random,hostile
+}
 
 #
@@ -276,6 +265,8 @@
 #	arrival point and his location.
 #
-MAZE: "Rog-goal", ' '
-FLAGS: noteleport
+LEVEL: "Rog-goal"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"leprechaun"), (16,'n'), (16,"guardian naga"), (4,'N')
 GEOMETRY:center,center
 #         1         2         3         4         5         6         7
@@ -314,71 +305,39 @@
 TRAP:"spiked pit",(37,07)
 # Objects
-OBJECT:'(',"skeleton key",(38,10),blessed,0,"The Master Key of Thievery"
-OBJECT:'%',"tin",(26,12),"chameleon",0
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"skeleton key"),(38,10),blessed,0,NAME:"The Master Key of Thievery"
+OBJECT:('%',"tin"),(26,12),montype:"chameleon",0
+LOOP [10 + 1d8] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [7 + 1d6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'@',"Master Assassin",(38,10),hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',"leprechaun",random,hostile
-MONSTER:'l',random,random,hostile
-MONSTER:'l',random,random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',"guardian naga",random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER:'N',random,random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER: ':',"chameleon",random,hostile
-MONSTER:';',"shark",(51,14),hostile
-MONSTER:';',"shark",(53,09),hostile
-MONSTER:';',"shark",(55,15),hostile
-MONSTER:';',"shark",(58,10),hostile
+MONSTER:('@',"Master Assassin"),(38,10),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'['
+  OBJECT:')'
+  OBJECT:'?'
+  OBJECT:'!'
+}
+LOOP [13 + 2d6] {
+  MONSTER:('l',"leprechaun"),random,hostile
+}
+MONSTER:'l',random,hostile
+MONSTER:'l',random,hostile
+LOOP [5 + 2d3] {
+  MONSTER:('N',"guardian naga"),random,hostile
+}
+MONSTER:'N',random,hostile
+MONSTER:'N',random,hostile
+MONSTER:'N',random,hostile
+LOOP [4 + 1d3] {
+  MONSTER: (':',"chameleon"),random,hostile
+}
+MONSTER:(';',"shark"),(51,14),hostile
+MONSTER:(';',"shark"),(53,09),hostile
+MONSTER:(';',"shark"),(55,15),hostile
+MONSTER:(';',"shark"),(58,10),hostile
 
 #
@@ -389,44 +348,57 @@
 #
 LEVEL: "Rog-fila"
+MON_GENERATION:86%, (64,"leprechaun"), (16,'n'), (16,"guardian naga"), (4,'N')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'l', "leprechaun", random, hostile
+OBJECT: random,random
+MONSTER: ('l', "leprechaun"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'l', "leprechaun", random, hostile
-MONSTER: 'N', "guardian naga", random, hostile
+{
+OBJECT: random, random
+OBJECT: random,random
+MONSTER: ('l', "leprechaun"), random, hostile
+MONSTER: ('N', "guardian naga"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'n', "water nymph", random, hostile
+OBJECT: random,random
+MONSTER: ('n', "water nymph"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', random, random, hostile
-MONSTER: 'N', "guardian naga", random, hostile
+MONSTER: 'l', random, hostile
+MONSTER: ('N', "guardian naga"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', "leprechaun", random, hostile
+MONSTER: ('l', "leprechaun"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', "leprechaun", random, hostile
-MONSTER: 'n', "water nymph", random, hostile
+MONSTER: ('l', "leprechaun"), random, hostile
+MONSTER: ('n', "water nymph"), random, hostile
+}
 
 RANDOM_CORRIDORS
@@ -436,44 +408,57 @@
 #
 LEVEL: "Rog-filb"
+MON_GENERATION:86%, (64,"leprechaun"), (16,'n'), (16,"guardian naga"), (4,'N')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'l', "leprechaun", random, hostile
+OBJECT: random,random
+MONSTER: ('l', "leprechaun"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'l', "leprechaun", random, hostile
-MONSTER: 'N', "guardian naga", random, hostile
+{
+OBJECT: random, random
+OBJECT: random,random
+MONSTER: ('l', "leprechaun"), random, hostile
+MONSTER: ('N', "guardian naga"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'n', "water nymph", random, hostile
+OBJECT: random,random
+MONSTER: ('n', "water nymph"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', random, random, hostile
-MONSTER: 'N', "guardian naga", random, hostile
+MONSTER: 'l', random, hostile
+MONSTER: ('N', "guardian naga"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', "leprechaun", random, hostile
+MONSTER: ('l', "leprechaun"), random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
 TRAP: random, random
-MONSTER: 'l', "leprechaun", random, hostile
-MONSTER: 'n', "water nymph", random, hostile
+MONSTER: ('l', "leprechaun"), random, hostile
+MONSTER: ('n', "water nymph"), random, hostile
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Samurai.des nethack/dat/Samurai.des
--- nh_orig/dat/Samurai.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Samurai.des	2010-08-16 13:20:13.635707386 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Sam-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Sam-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"wolf"), (16,'d'), (16,"stalker"), (4,'E')
 GEOMETRY:center,center
 MAP
@@ -53,39 +55,64 @@
 DOOR:closed,(50,06)
 # Lord Sato
-MONSTER:'@',"Lord Sato",(20,04)
+MONSTER:('@',"Lord Sato"),(20,04) {
+  OBJECT:('[',"splint mail"),1d4
+  OBJECT:(')',"katana"),1d4
+  OBJECT:'?'
+}
 # The treasure of Lord Sato
-OBJECT:'(',"chest",(20,04)
+OBJECT:('(',"chest"),(20,04)
 # roshi guards for the audience chamber
-MONSTER:'@',"roshi",(18,04)
-MONSTER:'@',"roshi",(18,05)
-MONSTER:'@',"roshi",(18,06)
-MONSTER:'@',"roshi",(18,07)
-MONSTER:'@',"roshi",(26,04)
-MONSTER:'@',"roshi",(26,05)
-MONSTER:'@',"roshi",(26,06)
-MONSTER:'@',"roshi",(26,07)
+MONSTER:('@',"roshi"),(18,04) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(18,05) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(18,06) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(18,07) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(26,04) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(26,05) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(26,06) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
+MONSTER:('@',"roshi"),(26,07) {
+  OBJECT[25%]:('[',"splint mail")
+  OBJECT[25%]:(')',"katana")
+}
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Random traps
+LOOP [4 + 1d6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Monsters on siege duty.
-MONSTER: '@',"ninja",(64,00),hostile
-MONSTER: 'd',"wolf",(65,01)
-MONSTER: '@',"ninja",(67,02),hostile
-MONSTER: '@',"ninja",(69,05),hostile
-MONSTER: '@',"ninja",(69,06),hostile
-MONSTER: 'd',"wolf",(69,07)
-MONSTER: '@',"ninja",(70,06),hostile
-MONSTER: '@',"ninja",(70,07),hostile
-MONSTER: '@',"ninja",(72,01),hostile
-MONSTER: 'd',"wolf",(75,09)
-MONSTER: '@',"ninja",(73,05),hostile
-MONSTER: '@',"ninja",(68,02),hostile
-MONSTER:'E',"stalker",random
+MONSTER: ('@',"ninja"),(64,00),hostile
+MONSTER: ('d',"wolf"),(65,01)
+MONSTER: ('@',"ninja"),(67,02),hostile
+MONSTER: ('@',"ninja"),(69,05),hostile
+MONSTER: ('@',"ninja"),(69,06),hostile
+MONSTER: ('d',"wolf"),(69,07)
+MONSTER: ('@',"ninja"),(70,06),hostile
+MONSTER: ('@',"ninja"),(70,07),hostile
+MONSTER: ('@',"ninja"),(72,01),hostile
+MONSTER: ('d',"wolf"),(75,09)
+MONSTER: ('@',"ninja"),(73,05),hostile
+MONSTER: ('@',"ninja"),(68,02),hostile
+MONSTER:('E',"stalker"),random
 
 #
@@ -96,6 +123,8 @@
 #
 
-MAZE: "Sam-loca",' '
-FLAGS: hardfloor
+LEVEL: "Sam-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"wolf"), (16,'d'), (16,"stalker"), (4,'E')
 GEOMETRY:center,center
 MAP
@@ -154,81 +183,72 @@
 NON_DIGGABLE:(00,00,75,19)
 # Objects
-OBJECT:'*',random,(25,05)
-OBJECT:'*',random,(26,05)
-OBJECT:'*',random,(27,05)
-OBJECT:'*',random,(28,05)
-OBJECT:'*',random,(25,06)
-OBJECT:'*',random,(26,06)
-OBJECT:'*',random,(27,06)
-OBJECT:'*',random,(28,06)
+OBJECT:'*',(25,05)
+OBJECT:'*',(26,05)
+OBJECT:'*',(27,05)
+OBJECT:'*',(28,05)
+OBJECT:'*',(25,06)
+OBJECT:'*',(26,06)
+OBJECT:'*',(27,06)
+OBJECT:'*',(28,06)
 #
-OBJECT:'[',random,(40,05)
-OBJECT:'[',random,(41,05)
-OBJECT:'[',random,(42,05)
-OBJECT:'[',random,(43,05)
-OBJECT:'[',random,(40,06)
-OBJECT:'[',random,(41,06)
-OBJECT:'[',random,(42,06)
-OBJECT:'[',random,(43,06)
+OBJECT:'[',(40,05)
+OBJECT:'[',(41,05)
+OBJECT:'[',(42,05)
+OBJECT:'[',(43,05)
+OBJECT:'[',(40,06)
+OBJECT:'[',(41,06)
+OBJECT:'[',(42,06)
+OBJECT:'[',(43,06)
 #
-OBJECT:')',random,(27,13)
-OBJECT:')',random,(28,13)
-OBJECT:')',random,(29,13)
-OBJECT:')',random,(30,13)
-OBJECT:')',random,(27,14)
-OBJECT:')',random,(28,14)
-OBJECT:')',random,(29,14)
-OBJECT:')',random,(30,14)
+OBJECT:')',(27,13)
+OBJECT:')',(28,13)
+OBJECT:')',(29,13)
+OBJECT:')',(30,13)
+OBJECT:')',(27,14)
+OBJECT:')',(28,14)
+OBJECT:')',(29,14)
+OBJECT:')',(30,14)
 #
-OBJECT:'(',random,(37,13)
-OBJECT:'(',random,(38,13)
-OBJECT:'(',random,(39,13)
-OBJECT:'(',random,(40,13)
-OBJECT:'(',random,(37,14)
-OBJECT:'(',random,(38,14)
-OBJECT:'(',random,(39,14)
-OBJECT:'(',random,(40,14)
+OBJECT:'(',(37,13)
+OBJECT:'(',(38,13)
+OBJECT:'(',(39,13)
+OBJECT:'(',(40,13)
+OBJECT:'(',(37,14)
+OBJECT:'(',(38,14)
+OBJECT:'(',(39,14)
+OBJECT:'(',(40,14)
 # Random traps
+LOOP [4 + 1d6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'@',"ninja",(15,05),hostile
-MONSTER:'@',"ninja",(16,05),hostile
-MONSTER:'d',"wolf",(17,05)
-MONSTER:'d',"wolf",(18,05)
-MONSTER:'@',"ninja",(19,05),hostile
-MONSTER:'d',"wolf",(15,14)
-MONSTER:'d',"wolf",(16,14)
-MONSTER:'@',"ninja",(17,14),hostile
-MONSTER:'@',"ninja",(18,14),hostile
-MONSTER:'d',"wolf",(56,05)
-MONSTER:'@',"ninja",(57,05),hostile
-MONSTER:'d',"wolf",(58,05)
-MONSTER:'d',"wolf",(59,05)
-MONSTER:'@',"ninja",(56,14),hostile
-MONSTER:'d',"wolf",(57,14)
-MONSTER:'@',"ninja",(58,14),hostile
-MONSTER:'d',random,(59,14)
-MONSTER:'d',"wolf",(60,14)
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
+MONSTER:('@',"ninja"),(15,05),hostile
+MONSTER:('@',"ninja"),(16,05),hostile
+MONSTER:('d',"wolf"),(17,05)
+MONSTER:('d',"wolf"),(18,05)
+MONSTER:('@',"ninja"),(19,05),hostile
+MONSTER:('d',"wolf"),(15,14)
+MONSTER:('d',"wolf"),(16,14)
+MONSTER:('@',"ninja"),(17,14),hostile
+MONSTER:('@',"ninja"),(18,14),hostile
+MONSTER:('d',"wolf"),(56,05)
+MONSTER:('@',"ninja"),(57,05),hostile
+MONSTER:('d',"wolf"),(58,05)
+MONSTER:('d',"wolf"),(59,05)
+MONSTER:('@',"ninja"),(56,14),hostile
+MONSTER:('d',"wolf"),(57,14)
+MONSTER:('@',"ninja"),(58,14),hostile
+MONSTER:'d',(59,14)
+MONSTER:('d',"wolf"),(60,14)
+LOOP [7 + 1d10] {
+  MONSTER:('E',"stalker"),random
+}
 #	"guards" for the central courtyard.
-MONSTER:'@',"samurai",(30,05),hostile
-MONSTER:'@',"samurai",(31,05),hostile
-MONSTER:'@',"samurai",(32,05),hostile
-MONSTER:'@',"samurai",(32,14),hostile
-MONSTER:'@',"samurai",(33,14),hostile
-MONSTER:'@',"samurai",(34,14),hostile
+MONSTER:('@',"samurai"),(30,05),hostile
+MONSTER:('@',"samurai"),(31,05),hostile
+MONSTER:('@',"samurai"),(32,05),hostile
+MONSTER:('@',"samurai"),(32,14),hostile
+MONSTER:('@',"samurai"),(33,14),hostile
+MONSTER:('@',"samurai"),(34,14),hostile
 
 #
@@ -240,11 +260,13 @@
 #
 
-MAZE: "Sam-goal", ' '
-FLAGS: noteleport
+LEVEL: "Sam-goal"
+FLAGS: noteleport,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"wolf"), (16,'d'), (16,"stalker"), (4,'E')
 GEOMETRY:center,center
 MAP
                                              
            .......................           
-       ......---------.---------......       
+       ......-------------------......       
     ......----.................----......    
    ....----.....-------------.....----....   
@@ -254,9 +276,9 @@
  ....|...||...---...--+--...---...||...|.... 
  ....|...|....|....|-...-|....|....|...|.... 
- ....|...|....|....+.....+....|........|.... 
+ ....|...|....|....+.....+....|....|...|.... 
  ....|...|....|....|-...-|....|....|...|.... 
  ....|...||...---...--+--...---...||...|.... 
   ...|....--....---.......---....--....|...  
-  ...||....---....----.----....---....||...  
+  ...||....---....---------....---....||...  
   ....--.....----...........----.....--....  
    ....----.....-------------.....----....   
@@ -266,5 +288,4 @@
 ENDMAP
 # Dungeon Description
-RANDOM_PLACES:(02,11),(42,09)
 REGION:(00,00,44,19),unlit,"ordinary"
 # Doors
@@ -274,23 +295,27 @@
 DOOR:closed,(25,10)
 # Stairs
-STAIR:place[0],up
+$place = { (02,11),(42,09) }
+SHUFFLE:$place
+STAIR:$place[0],up
+
+$place = { (22,14),(30,10),(22, 6),(14,10) }
+SHUFFLE:$place
+TERRAIN:$place[0],'.'
+
+$place = { (22, 4),(35,10),(22,16),( 9,10) }
+SHUFFLE:$place
+TERRAIN:$place[0],'.'
+
+$place = { (22, 2),(22,18) }
+SHUFFLE:$place
+TERRAIN:$place[0],'.'
+
 # Non diggable walls
 NON_DIGGABLE:(00,00,44,19)
 # Objects
-OBJECT:')',"tsurugi",(22,10),blessed,0,"The Tsurugi of Muramasa"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:(')',"tsurugi"),(22,10),blessed,0,NAME:"The Tsurugi of Muramasa"
+LOOP [9 + 1d6] {
+  OBJECT:random,random
+}
 #
 TRAP:"board",(22,09)
@@ -298,37 +323,20 @@
 TRAP:"board",(22,11)
 # Random traps
+LOOP [3 + 1d6] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'@',"Ashikaga Takauji",(22,10)
-MONSTER:'@',"samurai",random,hostile
-MONSTER:'@',"samurai",random,hostile
-MONSTER:'@',"samurai",random,hostile
-MONSTER:'@',"samurai",random,hostile
-MONSTER:'@',"samurai",random,hostile
-MONSTER:'@',"ninja",random,hostile
-MONSTER:'@',"ninja",random,hostile
-MONSTER:'@',"ninja",random,hostile
-MONSTER:'@',"ninja",random,hostile
-MONSTER:'@',"ninja",random,hostile
-MONSTER:'d',"wolf",random
-MONSTER:'d',"wolf",random
-MONSTER:'d',"wolf",random
-MONSTER:'d',"wolf",random
-MONSTER:'d',random,random
-MONSTER:'d',random,random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
-MONSTER:'E',"stalker",random
+MONSTER:('@',"Ashikaga Takauji"),(22,10) {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:('[',"splint mail")
+}
+LOOP [3 + 1d6] {
+  MONSTER:('@',"samurai"),random,hostile
+  MONSTER[90%]:('@',"ninja"),random,hostile
+  MONSTER:('d',"wolf"),random
+  MONSTER[50%]:'d',random
+  MONSTER:('E',"stalker"),random
+  MONSTER[90%]:('E',"stalker"),random
+}
 
 
@@ -342,6 +350,8 @@
 #
 
-MAZE: "Sam-fila", ' '
-INIT_MAP: '.' , 'P', true, true, random, true
+LEVEL: "Sam-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'P', true, true, random, true
+MON_GENERATION:86%, (64,"wolf"), (16,'d'), (16,"stalker"), (4,'E')
 NOMAP
 #
@@ -349,28 +359,22 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 1d6] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'd', random, random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'E', "stalker", random
+MONSTER: 'd', random
+LOOP [3 + 2d4] {
+  MONSTER: ('d', "wolf"), random
+}
+MONSTER: ('E', "stalker"), random
 #
+LOOP [3 + 1d6] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 
-MAZE: "Sam-filb", ' '
+LEVEL: "Sam-filb"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"wolf"), (16,'d'), (16,"stalker"), (4,'E')
 GEOMETRY:center,center
 MAP
@@ -402,25 +406,15 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [6 + 2d3] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'd', random, random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'd', "wolf", random
-MONSTER: 'E', "stalker", random
-MONSTER: 'E', "stalker", random
-MONSTER: 'E', "stalker", random
+MONSTER: 'd', random
+LOOP [3 + 2d3] {
+  MONSTER: ('d', "wolf"), random
+  MONSTER: ('E', "stalker"), random
+}
 #
+LOOP [1 + 2d3] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/sokoban.des nethack/dat/sokoban.des
--- nh_orig/dat/sokoban.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/sokoban.des	2010-04-11 12:36:58.221625824 -0400
@@ -31,8 +31,34 @@
 #   Bones files are not permitted.
 
+# Temporarily commented out 'til bugfix
+# INCLUDE "functions.des"
+
+FUNCTION soko_loot()
+{
+  # Random objects
+  OBJECT:'%',random
+  OBJECT:'%',random
+  OBJECT:'%',random
+  OBJECT:'%',random
+  OBJECT:'=',random
+  OBJECT:'/',random
+}
+
+# Unused temporarily.
+#FUNCTION soko_prize()
+#{
+#  IF [50%] {
+#    OBJECT:'"',"amulet of reflection",$place[0]
+#  } ELSE {
+#    OBJECT:'(',"bag of holding",$place[0]
+#  }
+#  ENGRAVING:$place[0],burn,"Elbereth"
+#}
+
 
 ### Bottom (first) level of Sokoban ###
-MAZE:"soko4-1",' '
-FLAGS:noteleport,hardfloor
+LEVEL:"soko4-1"
+FLAGS:noteleport,hardfloor,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -59,16 +85,16 @@
 
 # Boulders
-OBJECT:'`',"boulder",(02,02)
-OBJECT:'`',"boulder",(02,03)
+OBJECT:('`',"boulder"),(02,02)
+OBJECT:('`',"boulder"),(02,03)
 #
-OBJECT:'`',"boulder",(10,02)
-OBJECT:'`',"boulder",(09,03)
-OBJECT:'`',"boulder",(10,04)
+OBJECT:('`',"boulder"),(10,02)
+OBJECT:('`',"boulder"),(09,03)
+OBJECT:('`',"boulder"),(10,04)
 #
-OBJECT:'`',"boulder",(08,07)
-OBJECT:'`',"boulder",(09,08)
-OBJECT:'`',"boulder",(09,09)
-OBJECT:'`',"boulder",(08,10)
-OBJECT:'`',"boulder",(10,10)
+OBJECT:('`',"boulder"),(08,07)
+OBJECT:('`',"boulder"),(09,08)
+OBJECT:('`',"boulder"),(09,09)
+OBJECT:('`',"boulder"),(08,10)
+OBJECT:('`',"boulder"),(10,10)
 
 # Traps
@@ -84,18 +110,13 @@
 
 # A little help
-OBJECT:'?',"earth",(02,11)
-OBJECT:'?',"earth",(03,11)
+OBJECT:('?',"earth"),(02,11)
+OBJECT:('?',"earth"),(03,11)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
-MAZE:"soko4-2",' '
-FLAGS:noteleport,hardfloor
+LEVEL:"soko4-2"
+FLAGS:noteleport,hardfloor,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -120,18 +141,18 @@
 
 # Boulders
-OBJECT:'`',"boulder",(05,02)
-OBJECT:'`',"boulder",(06,02)
-OBJECT:'`',"boulder",(06,03)
-OBJECT:'`',"boulder",(07,03)
+OBJECT:('`',"boulder"),(05,02)
+OBJECT:('`',"boulder"),(06,02)
+OBJECT:('`',"boulder"),(06,03)
+OBJECT:('`',"boulder"),(07,03)
 #
-OBJECT:'`',"boulder",(09,05)
-OBJECT:'`',"boulder",(10,03)
-OBJECT:'`',"boulder",(11,02)
-OBJECT:'`',"boulder",(12,03)
+OBJECT:('`',"boulder"),(09,05)
+OBJECT:('`',"boulder"),(10,03)
+OBJECT:('`',"boulder"),(11,02)
+OBJECT:('`',"boulder"),(12,03)
 #
-OBJECT:'`',"boulder",(07,08)
-OBJECT:'`',"boulder",(08,08)
-OBJECT:'`',"boulder",(09,08)
-OBJECT:'`',"boulder",(10,08)
+OBJECT:('`',"boulder"),(07,08)
+OBJECT:('`',"boulder"),(08,08)
+OBJECT:('`',"boulder"),(09,08)
+OBJECT:('`',"boulder"),(10,08)
 
 # Traps
@@ -148,19 +169,14 @@
 
 # A little help
-OBJECT:'?',"earth",(01,09)
-OBJECT:'?',"earth",(02,09)
+OBJECT:('?',"earth"),(01,09)
+OBJECT:('?',"earth"),(02,09)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
 ### Second level ###
-MAZE:"soko3-1",' '
-FLAGS:noteleport
+LEVEL:"soko3-1"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -187,27 +203,27 @@
 
 # Boulders
-OBJECT:'`',"boulder",(03,02)
-OBJECT:'`',"boulder",(04,02)
+OBJECT:('`',"boulder"),(03,02)
+OBJECT:('`',"boulder"),(04,02)
 #
-OBJECT:'`',"boulder",(06,02)
-OBJECT:'`',"boulder",(06,03)
-OBJECT:'`',"boulder",(07,02)
+OBJECT:('`',"boulder"),(06,02)
+OBJECT:('`',"boulder"),(06,03)
+OBJECT:('`',"boulder"),(07,02)
 #
-OBJECT:'`',"boulder",(03,06)
-OBJECT:'`',"boulder",(02,07)
-OBJECT:'`',"boulder",(03,07)
-OBJECT:'`',"boulder",(03,08)
-OBJECT:'`',"boulder",(02,09)
-OBJECT:'`',"boulder",(03,09)
-OBJECT:'`',"boulder",(04,09)
+OBJECT:('`',"boulder"),(03,06)
+OBJECT:('`',"boulder"),(02,07)
+OBJECT:('`',"boulder"),(03,07)
+OBJECT:('`',"boulder"),(03,08)
+OBJECT:('`',"boulder"),(02,09)
+OBJECT:('`',"boulder"),(03,09)
+OBJECT:('`',"boulder"),(04,09)
 #
-OBJECT:'`',"boulder",(06,07)
-OBJECT:'`',"boulder",(06,09)
-OBJECT:'`',"boulder",(08,07)
-OBJECT:'`',"boulder",(08,10)
-OBJECT:'`',"boulder",(09,08)
-OBJECT:'`',"boulder",(09,09)
-OBJECT:'`',"boulder",(10,07)
-OBJECT:'`',"boulder",(10,10)
+OBJECT:('`',"boulder"),(06,07)
+OBJECT:('`',"boulder"),(06,09)
+OBJECT:('`',"boulder"),(08,07)
+OBJECT:('`',"boulder"),(08,10)
+OBJECT:('`',"boulder"),(09,08)
+OBJECT:('`',"boulder"),(09,09)
+OBJECT:('`',"boulder"),(10,07)
+OBJECT:('`',"boulder"),(10,10)
 
 # Traps
@@ -228,15 +244,10 @@
 TRAP:"hole",(26,10)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
-MAZE:"soko3-2",' '
-FLAGS:noteleport
+LEVEL:"soko3-2"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -265,20 +276,20 @@
 
 # Boulders
-OBJECT:'`',"boulder",(02,03)
-OBJECT:'`',"boulder",(08,03)
-OBJECT:'`',"boulder",(09,04)
-OBJECT:'`',"boulder",(02,05)
-OBJECT:'`',"boulder",(04,05)
-OBJECT:'`',"boulder",(09,05)
-OBJECT:'`',"boulder",(02,06)
-OBJECT:'`',"boulder",(05,06)
-OBJECT:'`',"boulder",(06,07)
-OBJECT:'`',"boulder",(03,08)
-OBJECT:'`',"boulder",(07,08)
-OBJECT:'`',"boulder",(05,09)
-OBJECT:'`',"boulder",(10,09)
-OBJECT:'`',"boulder",(07,10)
-OBJECT:'`',"boulder",(10,10)
-OBJECT:'`',"boulder",(03,11)
+OBJECT:('`',"boulder"),(02,03)
+OBJECT:('`',"boulder"),(08,03)
+OBJECT:('`',"boulder"),(09,04)
+OBJECT:('`',"boulder"),(02,05)
+OBJECT:('`',"boulder"),(04,05)
+OBJECT:('`',"boulder"),(09,05)
+OBJECT:('`',"boulder"),(02,06)
+OBJECT:('`',"boulder"),(05,06)
+OBJECT:('`',"boulder"),(06,07)
+OBJECT:('`',"boulder"),(03,08)
+OBJECT:('`',"boulder"),(07,08)
+OBJECT:('`',"boulder"),(05,09)
+OBJECT:('`',"boulder"),(10,09)
+OBJECT:('`',"boulder"),(07,10)
+OBJECT:('`',"boulder"),(10,10)
+OBJECT:('`',"boulder"),(03,11)
 
 # Traps
@@ -296,16 +307,11 @@
 TRAP:"hole",(23,10)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
 ### Third level ###
-MAZE:"soko2-1",' '
-FLAGS:noteleport
+LEVEL:"soko2-1"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -332,21 +338,21 @@
 
 # Boulders
-OBJECT:'`',"boulder",(02,02)
-OBJECT:'`',"boulder",(03,02)
+OBJECT:('`',"boulder"),(02,02)
+OBJECT:('`',"boulder"),(03,02)
 #
-OBJECT:'`',"boulder",(05,03)
-OBJECT:'`',"boulder",(07,03)
-OBJECT:'`',"boulder",(07,02)
-OBJECT:'`',"boulder",(08,02)
+OBJECT:('`',"boulder"),(05,03)
+OBJECT:('`',"boulder"),(07,03)
+OBJECT:('`',"boulder"),(07,02)
+OBJECT:('`',"boulder"),(08,02)
 #
-OBJECT:'`',"boulder",(10,03)
-OBJECT:'`',"boulder",(11,03)
+OBJECT:('`',"boulder"),(10,03)
+OBJECT:('`',"boulder"),(11,03)
 #
-OBJECT:'`',"boulder",(02,07)
-OBJECT:'`',"boulder",(02,08)
-OBJECT:'`',"boulder",(03,09)
+OBJECT:('`',"boulder"),(02,07)
+OBJECT:('`',"boulder"),(02,08)
+OBJECT:('`',"boulder"),(03,09)
 #
-OBJECT:'`',"boulder",(05,07)
-OBJECT:'`',"boulder",(06,06)
+OBJECT:('`',"boulder"),(05,07)
+OBJECT:('`',"boulder"),(06,06)
 
 # Traps
@@ -362,15 +368,10 @@
 TRAP:"hole",(17,09)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
-MAZE:"soko2-2",' '
-FLAGS:noteleport
+LEVEL:"soko2-2"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -398,20 +399,20 @@
 
 # Boulders
-OBJECT:'`',"boulder",(04,02)
-OBJECT:'`',"boulder",(04,03)
-OBJECT:'`',"boulder",(05,03)
-OBJECT:'`',"boulder",(07,03)
-OBJECT:'`',"boulder",(08,03)
-OBJECT:'`',"boulder",(02,04)
-OBJECT:'`',"boulder",(03,04)
-OBJECT:'`',"boulder",(05,05)
-OBJECT:'`',"boulder",(06,06)
-OBJECT:'`',"boulder",(09,06)
-OBJECT:'`',"boulder",(03,07)
-OBJECT:'`',"boulder",(04,07)
-OBJECT:'`',"boulder",(07,07)
-OBJECT:'`',"boulder",(06,09)
-OBJECT:'`',"boulder",(05,10)
-OBJECT:'`',"boulder",(05,11)
+OBJECT:('`',"boulder"),(04,02)
+OBJECT:('`',"boulder"),(04,03)
+OBJECT:('`',"boulder"),(05,03)
+OBJECT:('`',"boulder"),(07,03)
+OBJECT:('`',"boulder"),(08,03)
+OBJECT:('`',"boulder"),(02,04)
+OBJECT:('`',"boulder"),(03,04)
+OBJECT:('`',"boulder"),(05,05)
+OBJECT:('`',"boulder"),(06,06)
+OBJECT:('`',"boulder"),(09,06)
+OBJECT:('`',"boulder"),(03,07)
+OBJECT:('`',"boulder"),(04,07)
+OBJECT:('`',"boulder"),(07,07)
+OBJECT:('`',"boulder"),(06,09)
+OBJECT:('`',"boulder"),(05,10)
+OBJECT:('`',"boulder"),(05,11)
 
 # Traps
@@ -428,16 +429,11 @@
 TRAP:"hole",(17,11)
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 
 ### Top (last) level of Sokoban ###
-MAZE:"soko1-1",' '
-FLAGS:noteleport
+LEVEL:"soko1-1"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -462,5 +458,6 @@
 -----            -------  
 ENDMAP
-RANDOM_PLACES:(16,11),(16,13),(16,15)
+$place = { (16,11),(16,13),(16,15) }
+SHUFFLE: $place
 STAIR:(01,01),down
 REGION:(00,00,25,17),lit,"ordinary"
@@ -469,25 +466,25 @@
 
 # Boulders
-OBJECT:'`',"boulder",(03,05)
-OBJECT:'`',"boulder",(05,05)
-OBJECT:'`',"boulder",(07,05)
-OBJECT:'`',"boulder",(09,05)
-OBJECT:'`',"boulder",(11,05)
+OBJECT:('`',"boulder"),(03,05)
+OBJECT:('`',"boulder"),(05,05)
+OBJECT:('`',"boulder"),(07,05)
+OBJECT:('`',"boulder"),(09,05)
+OBJECT:('`',"boulder"),(11,05)
 #
-OBJECT:'`',"boulder",(04,07)
-OBJECT:'`',"boulder",(04,08)
-OBJECT:'`',"boulder",(06,07)
-OBJECT:'`',"boulder",(09,07)
-OBJECT:'`',"boulder",(11,07)
+OBJECT:('`',"boulder"),(04,07)
+OBJECT:('`',"boulder"),(04,08)
+OBJECT:('`',"boulder"),(06,07)
+OBJECT:('`',"boulder"),(09,07)
+OBJECT:('`',"boulder"),(11,07)
 #
-OBJECT:'`',"boulder",(03,12)
-OBJECT:'`',"boulder",(04,10)
-OBJECT:'`',"boulder",(05,12)
-OBJECT:'`',"boulder",(06,10)
-OBJECT:'`',"boulder",(07,11)
-OBJECT:'`',"boulder",(08,10)
-OBJECT:'`',"boulder",(09,12)
+OBJECT:('`',"boulder"),(03,12)
+OBJECT:('`',"boulder"),(04,10)
+OBJECT:('`',"boulder"),(05,12)
+OBJECT:('`',"boulder"),(06,10)
+OBJECT:('`',"boulder"),(07,11)
+OBJECT:('`',"boulder"),(08,10)
+OBJECT:('`',"boulder"),(09,12)
 #
-OBJECT:'`',"boulder",(03,14)
+OBJECT:('`',"boulder"),(03,14)
 
 # Traps
@@ -509,14 +506,8 @@
 TRAP:"hole",(23,01)
 
-MONSTER:'m',"giant mimic", random, m_object "boulder"
-MONSTER:'m',"giant mimic", random, m_object "boulder"
+MONSTER:('m',"giant mimic"), random, m_object "boulder"
+MONSTER:('m',"giant mimic"), random, m_object "boulder"
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 # Rewards
@@ -526,10 +517,17 @@
 DOOR:closed,(17,15)
 REGION:(18,10,22,16),lit,"zoo",filled,true
-OBJECT:'(',"bag of holding",place[0]
-ENGRAVING:place[0],burn,"Elbereth"
 
+#soko_prize()
+  IF [50%] {
+    OBJECT:('"',"amulet of reflection"),$place[0]
+  } ELSE {
+    OBJECT:('(',"bag of holding"),$place[0]
+  }
+  ENGRAVING:$place[0],burn,"Elbereth"
 
-MAZE:"soko1-2",' '
-FLAGS:noteleport
+
+LEVEL:"soko1-2"
+FLAGS:noteleport,mazelevel,premapped
+INIT_MAP:solidfill,' '
 GEOMETRY:center,center
 #12345678901234567890123456789012345678901234567890
@@ -553,5 +551,6 @@
      -------     -------  
 ENDMAP
-RANDOM_PLACES:(16,10),(16,12),(16,14)
+$place = { (16,10),(16,12),(16,14) }
+SHUFFLE:$place
 STAIR:(06,15),down
 REGION:(00,00,25,16),lit,"ordinary"
@@ -560,26 +559,26 @@
 
 # Boulders
-OBJECT:'`',"boulder",(04,04)
-OBJECT:'`',"boulder",(02,06)
-OBJECT:'`',"boulder",(03,06)
-OBJECT:'`',"boulder",(04,07)
-OBJECT:'`',"boulder",(05,07)
-OBJECT:'`',"boulder",(02,08)
-OBJECT:'`',"boulder",(05,08)
-OBJECT:'`',"boulder",(03,09)
-OBJECT:'`',"boulder",(04,09)
-OBJECT:'`',"boulder",(03,10)
-OBJECT:'`',"boulder",(05,10)
-OBJECT:'`',"boulder",(06,12)
+OBJECT:('`',"boulder"),(04,04)
+OBJECT:('`',"boulder"),(02,06)
+OBJECT:('`',"boulder"),(03,06)
+OBJECT:('`',"boulder"),(04,07)
+OBJECT:('`',"boulder"),(05,07)
+OBJECT:('`',"boulder"),(02,08)
+OBJECT:('`',"boulder"),(05,08)
+OBJECT:('`',"boulder"),(03,09)
+OBJECT:('`',"boulder"),(04,09)
+OBJECT:('`',"boulder"),(03,10)
+OBJECT:('`',"boulder"),(05,10)
+OBJECT:('`',"boulder"),(06,12)
 #
-OBJECT:'`',"boulder",(07,14)
+OBJECT:('`',"boulder"),(07,14)
 #
-OBJECT:'`',"boulder",(11,05)
-OBJECT:'`',"boulder",(12,06)
-OBJECT:'`',"boulder",(10,07)
-OBJECT:'`',"boulder",(11,07)
-OBJECT:'`',"boulder",(10,08)
-OBJECT:'`',"boulder",(12,09)
-OBJECT:'`',"boulder",(11,10)
+OBJECT:('`',"boulder"),(11,05)
+OBJECT:('`',"boulder"),(12,06)
+OBJECT:('`',"boulder"),(10,07)
+OBJECT:('`',"boulder"),(11,07)
+OBJECT:('`',"boulder"),(10,08)
+OBJECT:('`',"boulder"),(12,09)
+OBJECT:('`',"boulder"),(11,10)
 
 # Traps
@@ -603,14 +602,8 @@
 TRAP:"hole",(22,01)
 
-MONSTER:'m',"giant mimic", random, m_object "boulder"
-MONSTER:'m',"giant mimic", random, m_object "boulder"
+MONSTER:('m',"giant mimic"), random, m_object "boulder"
+MONSTER:('m',"giant mimic"), random, m_object "boulder"
 
-# Random objects
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'%',random,random
-OBJECT:'=',random,random
-OBJECT:'/',random,random
+soko_loot()
 
 # Rewards
@@ -620,4 +613,9 @@
 DOOR:closed,(17,14)
 REGION:(18,09,22,15),lit,"zoo",filled,true
-OBJECT:'"',"amulet of reflection",place[0]
-ENGRAVING:place[0],burn,"Elbereth"
+#soko_prize()
+  IF [50%] {
+    OBJECT:('"',"amulet of reflection"),$place[0]
+  } ELSE {
+    OBJECT:('(',"bag of holding"),$place[0]
+  }
+  ENGRAVING:$place[0],burn,"Elbereth"
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Tourist.des nethack/dat/Tourist.des
--- nh_orig/dat/Tourist.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Tourist.des	2010-08-16 13:20:13.633706782 -0400
@@ -9,6 +9,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Tou-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Tou-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"giant spider"), (16,'S'), (16,"forest centaur"), (4,'C')
 GEOMETRY:center,center
 MAP
@@ -16,5 +18,5 @@
 ........}}...|.......|..|.-------------------------------------------...|...
 .........}}..|.......|..|.|......|......|.............|......|......|...|...
-..........}}.|.......|..|.|......+......+.............+......+..\...|...|...
+..........}}.|.......|..|.|......+......+.............+......+......|...|...
 ...........}}}..........|.|......|......|.............|......|......|...|...
 .............}}.........|.|----S-|--S---|S----------S-|---S--|------|...|...
@@ -71,62 +73,89 @@
 DOOR:locked,(36,07)
 # Monsters on siege duty.
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',"giant spider",random
-MONSTER: 's',random,random
-MONSTER: 's',random,random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',"forest centaur",random
-MONSTER: 'C',random,random
+LOOP [10 + 1d10] {
+  MONSTER: ('s',"giant spider"),random
+}
+MONSTER: 's',random
+MONSTER: 's',random
+LOOP [6 + 1d10] {
+  MONSTER: ('C',"forest centaur"),random
+}
+MONSTER: 'C',random
 # Twoflower
-MONSTER:'@',"Twoflower",(64,03)
+OBJECT:('\',"throne"),(64,03)
+MONSTER:('@',"Twoflower"),(64,03) {
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+  OBJECT:random
+}
 # The treasure of Twoflower
-OBJECT:'(',"chest",(64,03)
+OBJECT:('(',"chest"),(64,03)
 # guides for the audience chamber
-MONSTER:'@',"guide",(29,03)
-MONSTER:'@',"guide",(32,04)
-MONSTER:'@',"guide",(35,02)
-MONSTER:'@',"guide",(38,03)
-MONSTER:'@',"guide",(45,03)
-MONSTER:'@',"guide",(48,02)
-MONSTER:'@',"guide",(49,04)
-MONSTER:'@',"guide",(51,03)
-MONSTER:'@',"guide",(57,03)
-MONSTER:'@',"guide",(62,04)
-MONSTER:'@',"guide",(66,04)
+MONSTER:('@',"guide"),(29,03) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(32,04) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(35,02) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(38,03) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(45,03) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(48,02) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(49,04) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(51,03) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(57,03) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(62,04) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"guide"),(66,04) {
+  OBJECT:random
+  OBJECT[25%]:random
+}
 # path guards
-MONSTER:'@',"watchman",(35,08)
-MONSTER:'@',"watchman",(36,08)
+MONSTER:('@',"watchman"),(35,08) {
+  OBJECT:'['
+  OBJECT:')'
+}
+MONSTER:('@',"watchman"),(36,08) {
+  OBJECT:'['
+  OBJECT:')'
+}
 # river monsters
-MONSTER:';',"giant eel",(62,12)
-MONSTER:';',"piranha",(47,10)
-MONSTER:';',"piranha",(29,11)
-MONSTER:';',"kraken",(34,09)
-MONSTER:';',"kraken",(37,09)
+MONSTER:(';',"giant eel"),(62,12)
+MONSTER:(';',"piranha"),(47,10)
+MONSTER:(';',"piranha"),(29,11)
+MONSTER:(';',"kraken"),(34,09)
+MONSTER:(';',"kraken"),(37,09)
 # Random traps
+LOOP [7 + 1d10] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 
 #
@@ -137,6 +166,8 @@
 #
 
-MAZE: "Tou-loca",' '
-FLAGS: hardfloor
+LEVEL: "Tou-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"giant spider"), (16,'S'), (16,"forest centaur"), (4,'C')
 GEOMETRY:center,center
 MAP
@@ -152,5 +183,5 @@
 |....+.....+.........S...|...........|....|-------|........................|
 |....|.....|.........|...|.|---------|....|.........|-------|.|----------|.|
-|....|.....|---------|---|.|......|..+....|-------|.|.......|.+......S.\.|.|
+|....|.....|---------|---|.|......|..+....|-------|.|.......|.+......S...|.|
 |....|.....+.........S...|.|......|..|....|.......|.|.......|.|......|...|.|
 |-------|..|.........|---|.|+-------------------+-|.|.......+.|----------|.|
@@ -243,50 +274,21 @@
 
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 1d10] {
+  OBJECT:random,random
+}
 # Toilet paper
-OBJECT:'?',"blank paper",(71,12)
-OBJECT:'?',"blank paper",(71,12)
+OBJECT:('\',"throne"),(71,11)
+OBJECT:('?',"blank paper"),(71,12)
+OBJECT:('?',"blank paper"),(71,12)
 # Random traps
+LOOP [5 + 1d10] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',random,random
-MONSTER:'s',random,random
+LOOP [10 + 2d10] {
+  MONSTER:('s',"giant spider"),random
+}
+MONSTER:'s',random
+MONSTER:'s',random
 
 #
@@ -298,5 +300,8 @@
 #
 
-MAZE: "Tou-goal", ' '
+LEVEL: "Tou-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"giant spider"), (16,'S'), (16,"forest centaur"), (4,'C')
 GEOMETRY:center,center
 MAP
@@ -385,68 +390,49 @@
 DOOR:open,(59,17)
 # Objects
-OBJECT:'(',"credit card",(04,01),blessed,0,"The Platinum Yendorian Express Card"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"credit card"),(04,01),blessed,0,NAME:"The Platinum Yendorian Express Card"
+LOOP [8 + 1d5] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [3 + 1d5] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Random monsters.
-MONSTER:'@',"Master of Thieves",(04,01),hostile
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',"giant spider",random
-MONSTER:'s',random,random
-MONSTER:'s',random,random
+MONSTER:('@',"Master of Thieves"),(04,01),hostile {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'['
+  OBJECT:')'
+  OBJECT:'!'
+  OBJECT:'!'
+  OBJECT:'!'
+  OBJECT:'!'
+}
+LOOP [10 + 2d5] {
+  MONSTER:('s',"giant spider"),random
+}
+MONSTER:'s',random
+MONSTER:'s',random
 # ladies of the evening
-MONSTER:'&',"succubus",(02,08)
-MONSTER:'&',"succubus",(08,08)
-MONSTER:'&',"incubus",(02,14)
-MONSTER:'&',"incubus",(08,14)
-MONSTER:'&',"incubus",(02,17)
-MONSTER:'&',"incubus",(08,17)
+MONSTER:('&',"succubus"),(02,08)
+MONSTER:('&',"succubus"),(08,08)
+MONSTER:('&',"incubus"),(02,14)
+MONSTER:('&',"incubus"),(08,14)
+MONSTER:('&',"incubus"),(02,17)
+MONSTER:('&',"incubus"),(08,17)
 # Police station (with drunken prisoners)
-MONSTER:'K',"Kop Kaptain",(24,09),hostile
-MONSTER:'K',"Kop Lieutenant",(20,09),hostile
-MONSTER:'K',"Kop Lieutenant",(22,11),hostile
-MONSTER:'K',"Kop Lieutenant",(22,07),hostile
-MONSTER:'K',"Keystone Kop",(19,07),hostile
-MONSTER:'K',"Keystone Kop",(19,08),hostile
-MONSTER:'K',"Keystone Kop",(22,09),hostile
-MONSTER:'K',"Keystone Kop",(24,11),hostile
-MONSTER:'K',"Keystone Kop",(19,11),hostile
-MONSTER:'@',"prisoner",(19,13)
-MONSTER:'@',"prisoner",(21,13)
-MONSTER:'@',"prisoner",(24,13)
+MONSTER:('K',"Kop Kaptain"),(24,09),hostile
+MONSTER:('K',"Kop Lieutenant"),(20,09),hostile
+MONSTER:('K',"Kop Lieutenant"),(22,11),hostile
+MONSTER:('K',"Kop Lieutenant"),(22,07),hostile
+MONSTER:('K',"Keystone Kop"),(19,07),hostile
+MONSTER:('K',"Keystone Kop"),(19,08),hostile
+MONSTER:('K',"Keystone Kop"),(22,09),hostile
+MONSTER:('K',"Keystone Kop"),(24,11),hostile
+MONSTER:('K',"Keystone Kop"),(19,11),hostile
+MONSTER:('@',"prisoner"),(19,13)
+MONSTER:('@',"prisoner"),(21,13)
+MONSTER:('@',"prisoner"),(24,13)
 #
-MONSTER:'@',"watchman",(33,10),hostile
+MONSTER:('@',"watchman"),(33,10),hostile
 
 WALLIFY
@@ -459,6 +445,8 @@
 #
 
-MAZE: "Tou-fila" , ' '
-INIT_MAP: '.' , ' ', true, true, random, true
+LEVEL: "Tou-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ', true, true, random, true
+MON_GENERATION:86%, (64,"giant spider"), (16,'S'), (16,"forest centaur"), (4,'C')
 NOMAP
 #
@@ -466,27 +454,22 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [2 + 2d4] {
+  OBJECT: random, random
+}
 #
+LOOP [2 + 2d4] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: '@', "soldier", random, hostile
-MONSTER: '@', "soldier", random, hostile
-MONSTER: '@', "soldier", random, hostile
-MONSTER: '@', "soldier", random, hostile
-MONSTER: '@', "soldier", random, hostile
-MONSTER: 'H', random, random, hostile
-MONSTER: 'C', random, random, hostile
+LOOP [2 + 2d4] {
+  MONSTER: ('@', "soldier"), random, hostile
+}
+MONSTER: 'H', random, hostile
+MONSTER: 'C', random, hostile
 
-MAZE: "Tou-filb" , ' '
-INIT_MAP: '.' , ' ', true, true, random, true
+LEVEL: "Tou-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , ' ', true, true, random, true
+MON_GENERATION:86%, (64,"giant spider"), (16,'S'), (16,"forest centaur"), (4,'C')
 NOMAP
 #
@@ -494,26 +477,19 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [7 + 2d4] {
+  OBJECT: random, random
+}
 #
+LOOP [4 + 2d4] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 #
-MONSTER: '@', "soldier", random, hostile
-MONSTER: '@', "captain", random, hostile
-MONSTER: '@', "captain", random, hostile
-MONSTER: 'H', random, random, hostile
-MONSTER: 'H', random, random, hostile
-MONSTER: 'C', random, random, hostile
-MONSTER: 's', random, random
+LOOP [2d4] {
+  MONSTER: ('@', "soldier"), random, hostile
+  MONSTER: 'C', random, hostile
+  MONSTER: 's', random
+}
+MONSTER: ('@', "captain"), random, hostile
+MONSTER: ('@', "captain"), random, hostile
+MONSTER: 'H', random, hostile
+MONSTER: 'H', random, hostile
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/tower.des nethack/dat/tower.des
--- nh_orig/dat/tower.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/tower.des	2010-04-11 12:36:58.306750100 -0400
@@ -4,6 +4,7 @@
 #
 # Upper stage of Vlad's tower
-MAZE:"tower1",' '
-FLAGS: noteleport,hardfloor
+LEVEL:"tower1"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:half-left,center
 MAP
@@ -13,5 +14,5 @@
 |.......+.+...|
 ---+-----.-----
-  |...\.|.+.|  
+  |.....|.+.|  
 ---+-----.-----
 |.......+.+...|
@@ -22,11 +23,15 @@
 LADDER:(11,05),down
 # The lord and his court
-MONSTER:'V',"Vlad the Impaler",(06,05)
-MONSTER:'V',random,(03,09)
-MONSTER:'V',random,(07,09)
-MONSTER:'V',random,(11,09)
-MONSTER:'V',random,(03,01)
-MONSTER:'V',random,(07,01)
-MONSTER:'V',random,(11,01)
+OBJECT:('\',"throne"),(06,05)
+MONSTER:('V',"Vlad the Impaler"),(06,05) {
+  OBJECT:(')',"two-handed sword"),1d3,NAME:"Lifestealer",cursed,erodeproof
+  OBJECT:('(',"Candelabrum of Invocation")
+}
+MONSTER:'V',(03,09)
+MONSTER:'V',(07,09)
+MONSTER:'V',(11,09)
+MONSTER:'V',(03,01)
+MONSTER:'V',(07,01)
+MONSTER:'V',(11,01)
 # The doors
 DOOR:closed,(08,03)
@@ -38,11 +43,11 @@
 DOOR:closed,(03,06)
 # treasures
-OBJECT:'(',"chest",(07,05)
-OBJECT:'(',"chest",(03,09)
-OBJECT:'(',"chest",(07,09)
-OBJECT:'(',"chest",(11,09)
-OBJECT:'(',"chest",(03,01)
-OBJECT:'(',"chest",(07,01)
-OBJECT:'(',"chest",(11,01)
+OBJECT:('(',"chest"),(07,05)
+OBJECT:('(',"chest"),(03,09)
+OBJECT:('(',"chest"),(07,09)
+OBJECT:('(',"chest"),(11,09)
+OBJECT:('(',"chest"),(03,01)
+OBJECT:('(',"chest"),(07,01)
+OBJECT:('(',"chest"),(11,01)
 # We have to protect the tower against outside attacks
 NON_DIGGABLE:(00,00,14,10)
@@ -50,6 +55,7 @@
 
 # Intermediate stage of Vlad's tower
-MAZE:"tower2",' '
-FLAGS: noteleport,hardfloor
+LEVEL:"tower2"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:half-left,center
 MAP
@@ -67,22 +73,25 @@
 ENDMAP
 # Random places are the 10 niches
-RANDOM_PLACES:(03,01),(07,01),(11,01),(01,03),(13,03),
-	      (01,07),(13,07),(03,09),(07,09),(11,09)
+$place = { (03,01),(07,01),(11,01),(01,03),(13,03),
+	      (01,07),(13,07),(03,09),(07,09),(11,09) }
+SHUFFLE:$place
 LADDER:(11,05),up
 LADDER:(03,07),down
 DOOR:locked,(10,04)
 DOOR:locked,(09,07)
-MONSTER:'&',random,place[0]
-MONSTER:'&',random,place[1]
-MONSTER:'d',"hell hound pup",place[2]
-MONSTER:'d',"hell hound pup",place[3]
-MONSTER:'d',"winter wolf",place[4]
-CONTAINER:'(',"chest",place[5]
-OBJECT:'"',"amulet of life saving",contained
-CONTAINER:'(',"chest",place[6]
-OBJECT:'"',"amulet of strangulation",contained
-OBJECT:'[',"water walking boots",place[7]
-OBJECT:'[',"crystal plate mail",place[8]
-OBJECT:'+',"invisibility",place[9]
+MONSTER:'&',$place[0]
+MONSTER:'&',$place[1]
+MONSTER:('d',"hell hound pup"),$place[2]
+MONSTER:('d',"hell hound pup"),$place[3]
+MONSTER:('d',"winter wolf"),$place[4]
+CONTAINER:('(',"chest"),$place[5] {
+  OBJECT:('"',"amulet of life saving")
+}
+CONTAINER:('(',"chest"),$place[6] {
+  OBJECT:('"',"amulet of strangulation")
+}
+OBJECT:('[',"water walking boots"),$place[7]
+OBJECT:('[',"crystal plate mail"),$place[8]
+OBJECT:('+',"invisibility"),$place[9]
 # Walls in the tower are non diggable
 NON_DIGGABLE:(00,00,14,10)
@@ -90,6 +99,7 @@
 
 # Bottom most stage of Vlad's tower
-MAZE:"tower3",' '
-FLAGS: noteleport,hardfloor
+LEVEL:"tower3"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
 GEOMETRY:half-left,center
 MAP
@@ -109,6 +119,7 @@
 ENDMAP
 # Random places are the 10 niches
-RANDOM_PLACES:(05,01),(09,01),(13,01),(03,03),(15,03),
-	      (03,07),(15,07),(05,09),(09,09),(13,09)
+$place = { (05,01),(09,01),(13,01),(03,03),(15,03),
+	      (03,07),(15,07),(05,09),(09,09),(13,09) }
+SHUFFLE:$place
 BRANCH:(02,05,02,05),(00,00,00,00)
 LADDER:(05,07),up
@@ -116,21 +127,18 @@
 DOOR:locked,(14,05)
 # Let's put a dragon behind the door, just for the fun...
-MONSTER:'D',random,(13,05)
-MONSTER:random,random,(12,04)
-MONSTER:random,random,(12,06)
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-MONSTER:random,random,random
-OBJECT:')',"long sword",place[0]
-TRAP:random,place[0]
-OBJECT:'(',"lock pick",place[1]
-TRAP:random,place[1]
-OBJECT:'[',"elven cloak",place[2]
-TRAP:random,place[2]
-OBJECT:'(',"blindfold",place[3]
-TRAP:random,place[3]
+MONSTER:'D',(13,05)
+MONSTER:random,(12,04)
+MONSTER:random,(12,06)
+LOOP [4 + 3d4] {
+  MONSTER:random,random
+}
+OBJECT:(')',"long sword"),$place[0]
+TRAP:random,$place[0]
+OBJECT:('(',"lock pick"),$place[1]
+TRAP:random,$place[1]
+OBJECT:('[',"elven cloak"),$place[2]
+TRAP:random,$place[2]
+OBJECT:('(',"blindfold"),$place[3]
+TRAP:random,$place[3]
 # Walls in the tower are non diggable
 NON_DIGGABLE:(00,00,18,12)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Valkyrie.des nethack/dat/Valkyrie.des
--- nh_orig/dat/Valkyrie.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Valkyrie.des	2010-08-16 13:20:13.633706782 -0400
@@ -9,29 +9,46 @@
 #	and receive your quest assignment.
 #
-MAZE: "Val-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Val-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,'I'
+
+# This works because the random coordinates in $pools are evaluated once,
+# when the variable is initialized.
+$pools = selection: random & random & random & random & random &
+	   random & random & random & random & random & random &
+	   random & random &
+	   grow(west, random) &
+	   grow(north, random) &
+	   grow(random & random)
+TERRAIN:grow($pools), 'P'
+TERRAIN:$pools, 'L'
+
+MON_GENERATION:86%, (64,"fire ant"), (16,'a'), (16,"fire giant"), (4,'H')
 GEOMETRY:center,center
 MAP
-IIIIIIPPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
-IIIIPPPPPIIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII...IIIIIIIIIIIIIIIIIIIII
-IIIIPLLPPIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..{..IIIIIIIIIIIIIIIIIIII
-IIIIPLPPIIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.....IIIIIIPPPIIIIIIIIII
-IIIPPPPPIIIIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.IIIIIPPLPIIIIIIIIII
-IIIIPIIIIIIII..IIIIPPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.IIIIIPLPPIIIIIIIIII
-IIIIIIIIIIII..IIIIIPLPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII..IIIIIPPPIIIIIIIIIII
-IIIIIIII.....IIIIIIPPPIIII|----------------|IIIIIPPPIII.IIIIIIIIIIIIIIIIIIII
-IIIIIII..III...IIIIIIIIIII|................|IIIIIPLPII..IIIIIIIIIIIIIIIIIIII
-IIIIII..IIIIII......IIIII.|................|.IIIIPPPII.IIIIIIIIIIIIIIIIIIIII
-IIIII..IIIIIIIIIIII.......+................+...IIIIIII.IIIIIIIIIIIIIIIIIIIII
-IIII..IIIIIIIII.....IIIII.|................|.I...IIIII.IIIIIIIIIIIIIIIIIIIII
-III..IIIIIIIII..IIIIIIIIII|................|IIII.......IIIIIIIIIIIIIIIIIIIII
-IIII..IIIIIII..IIIIIIIIIII|----------------|IIIIIIIIII...IIIIIIIIIIIIIIIIIII
-IIIIII..IIII..IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIPPPPIIII...IIIIIIIIIIIIIIIII
-IIIIIII......IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIPLLPPIIIII...IIIIIIIIIIIIIII
-IIIIPPPIP...IIIIIIIIIIIPIIIIIIIIIIIIIIIIIIIIIIIIPPPPIIIIIIII...I......IIIIII
-IIIPPLPPIIIIIIIIIIIIIIPPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.........IIIII
-IIIIPPPIIIIIIIIIIIIIIPPLPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII.......IIIIII
-IIIIIIIIIIIIIIIIIIIIIIPPPIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..{..xxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.....xxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx..xxxxxxxxxxxxxxxxxxx
+xxxxxxxx.....xxxxxxxxxxxxx|----------------|xxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx
+xxxxxxx..xxx...xxxxxxxxxxx|................|xxxxxxxxxx..xxxxxxxxxxxxxxxxxxxx
+xxxxxx..xxxxxx......xxxxx.|................|.xxxxxxxxx.xxxxxxxxxxxxxxxxxxxxx
+xxxxx..xxxxxxxxxxxx.......+................+...xxxxxxx.xxxxxxxxxxxxxxxxxxxxx
+xxxx..xxxxxxxxx.....xxxxx.|................|.x...xxxxx.xxxxxxxxxxxxxxxxxxxxx
+xxx..xxxxxxxxx..xxxxxxxxxx|................|xxxx.......xxxxxxxxxxxxxxxxxxxxx
+xxxx..xxxxxxx..xxxxxxxxxxx|----------------|xxxxxxxxxx...xxxxxxxxxxxxxxxxxxx
+xxxxxx..xxxx..xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxxxx
+xxxxxxx......xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...xxxxxxxxxxxxxxx
+xxxxxxxxx...xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx...x......xxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.........xxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.......xxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 ENDMAP
+
+REPLACE_TERRAIN:(00,00,75,19), 'I', 'P', 2%
+
 # Dungeon Description
 REGION:(00,00,75,19),lit,"ordinary"
@@ -46,38 +63,64 @@
 DOOR:locked,(43,10)
 # Norn
-MONSTER:'@',"Norn",(35,10)
+MONSTER:('@',"Norn"),(35,10) {
+  OBJECT:'['
+  OBJECT:')'
+  OBJECT:'?'
+  OBJECT:'?'
+}
 # The treasure of the Norn
-OBJECT:'(',"chest",(36,10)
+OBJECT:('(',"chest"),(36,10)
 # valkyrie guards for the audience chamber
-MONSTER:'@',"warrior",(27,08)
-MONSTER:'@',"warrior",(27,09)
-MONSTER:'@',"warrior",(27,11)
-MONSTER:'@',"warrior",(27,12)
-MONSTER:'@',"warrior",(42,08)
-MONSTER:'@',"warrior",(42,09)
-MONSTER:'@',"warrior",(42,11)
-MONSTER:'@',"warrior",(42,12)
+MONSTER:('@',"warrior"),(27,08) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(27,09) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(27,11) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(27,12) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(42,08) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(42,09) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(42,11) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
+MONSTER:('@',"warrior"),(42,12) {
+  OBJECT[75%]:'['
+  OBJECT[75%]:')'
+}
 # Non diggable walls
 NON_DIGGABLE:(26,07,43,13)
 # Random traps
+LOOP [3 + 3d5] {
 TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
+}
 # Monsters on siege duty.
-MONSTER: 'a',"fire ant",(04,12)
-MONSTER: 'a',"fire ant",(08,08)
-MONSTER: 'a',"fire ant",(14,04)
-MONSTER: 'a',"fire ant",(17,11)
-MONSTER: 'a',"fire ant",(24,10)
-MONSTER: 'a',"fire ant",(45,10)
-MONSTER: 'a',"fire ant",(54,02)
-MONSTER: 'a',"fire ant",(55,07)
-MONSTER: 'a',"fire ant",(58,14)
-MONSTER: 'a',"fire ant",(63,17)
-MONSTER: 'H',"fire giant",(18,01),hostile
-MONSTER: 'H',"fire giant",(10,16),hostile
+MONSTER: ('a',"fire ant"),(04,12)
+MONSTER: ('a',"fire ant"),(08,08)
+MONSTER: ('a',"fire ant"),(14,04)
+MONSTER: ('a',"fire ant"),(17,11)
+MONSTER: ('a',"fire ant"),(24,10)
+MONSTER: ('a',"fire ant"),(45,10)
+MONSTER: ('a',"fire ant"),(54,02)
+MONSTER: ('a',"fire ant"),(55,07)
+MONSTER: ('a',"fire ant"),(58,14)
+MONSTER: ('a',"fire ant"),(63,17)
+MONSTER: ('H',"fire giant"),(18,01),hostile
+MONSTER: ('H',"fire giant"),(10,16),hostile
 
 #
@@ -88,7 +131,8 @@
 #
 
-MAZE: "Val-loca",' '
-FLAGS: hardfloor
-INIT_MAP: '.' , 'I' , true , true , lit , false
+LEVEL: "Val-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP: mines, '.' , 'I' , true , true , lit , false
+MON_GENERATION:86%, (64,"fire ant"), (16,'a'), (16,"fire giant"), (4,'H')
 GEOMETRY:center,center
 MAP
@@ -115,54 +159,23 @@
 NON_DIGGABLE:(00,00,39,12)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [6 + 3d5] {
+  OBJECT:random,random
+}
 # Random traps
+LOOP [2 + 3d5] {
 TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
+}
 TRAP:random,random
 TRAP:random,random
 # Random monsters.
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',random,random
-MONSTER:'H',random,random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',random,random,hostile
+LOOP [10 + 3d5] {
+  MONSTER:('a',"fire ant"),random
+}
+MONSTER:'a',random
+MONSTER:'H',random,hostile
+LOOP [2 + 3d5] {
+  MONSTER:('H',"fire giant"),random,hostile
+}
+MONSTER:'H',random,hostile
 
 #
@@ -174,14 +187,16 @@
 #
 
-MAZE: "Val-goal", 'L'
-INIT_MAP: '.' , 'L' , true , true , lit , false
+LEVEL: "Val-goal"
+FLAGS:mazelevel
+INIT_MAP: mines, '.' , 'L' , true , true , lit , false
+MON_GENERATION:86%, (64,"fire ant"), (16,'a'), (16,"fire giant"), (4,'H')
 GEOMETRY:center,center
 MAP
-.L............................LLLLL
-LLL.........LLLLL.LLLLL.........LLL
-.LLL......LLLLLLLLLLLLLLL.......LL.
-.LLL.....LLL|---------|LLL.....L...
-..LL....LL|--.........--|LL.....LLL
-.......LL|-...LLLLLLL...-|LL.....L.
+xLxxxx......................xxLLLLL
+LLLx........LLLLL.LLLLL.......xxLLL
+xLLL......LLLLLLLLLLLLLLL......xLLx
+xLLL.....LLL|---------|LLL.....Lxxx
+xxLL....LL|--.........--|LL.....LLL
+x......LL|-...LLLLLLL...-|LL.....Lx
 .......LL|...LL.....LL...|LL.......
 ......LL|-..LL.......LL..-|LL......
@@ -189,10 +204,10 @@
 ......LL|-..LL.......LL..-|LL......
 .......LL|...LL.....LL...|LL.......
-.......LL|-...LLLLLLL...-|LL.......
-..L.....LL|--.........--|LL.....LL.
-..LL.....LLL|---------|LLL....LLLL.
-..LLL.....LLLLLLLLLLLLLLL...LLLLL..
-.LLLL.......LLLLL.LLLLL.....LLLL...
-..LL...............................
+.......LL|-...LLLLLLL...-|LL......x
+x.L.....LL|--.........--|LL.....LLx
+xxLL.....LLL|---------|LLL....LLLLx
+xxLLL.....LLLLLLLLLLLLLLL...LLLLLxx
+xLLLL.......LLLLL.LLLLL.....LLLLxxx
+xxLLxxx....................xxxxxxxx
 ENDMAP
 # Dungeon Description
@@ -207,51 +222,39 @@
 DRAWBRIDGE:(17,14),north,open
 # Objects
-OBJECT:'(',"crystal ball",(17,08),blessed,5,"The Orb of Fate"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('(',"crystal ball"),(17,08),blessed,5,NAME:"The Orb of Fate"
+LOOP [4 + 3d5] {
+  OBJECT:random,random
+}
 # Traps
 TRAP:"board",(13,08)
 TRAP:"board",(21,08)
 # Random traps
+LOOP [2 + 2d3] {
 TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
-TRAP:"fire",random
+}
 TRAP:"board",random
 TRAP:random,random
 TRAP:random,random
 # Random monsters.
-MONSTER:'H',"Lord Surtur",(17,08)
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',"fire ant",random
-MONSTER:'a',random,random
-MONSTER:'a',random,random
-MONSTER:'H',"fire giant",(10,06),hostile
-MONSTER:'H',"fire giant",(10,07),hostile
-MONSTER:'H',"fire giant",(10,08),hostile
-MONSTER:'H',"fire giant",(10,09),hostile
-MONSTER:'H',"fire giant",(10,10),hostile
-MONSTER:'H',"fire giant",(24,06),hostile
-MONSTER:'H',"fire giant",(24,07),hostile
-MONSTER:'H',"fire giant",(24,08),hostile
-MONSTER:'H',"fire giant",(24,09),hostile
-MONSTER:'H',"fire giant",(24,10),hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',"fire giant",random,hostile
-MONSTER:'H',random,random,hostile
+MONSTER:('H',"Lord Surtur"),(17,08) {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'['
+  OBJECT:')'
+  OBJECT:random
+  OBJECT:random
+}
+LOOP [2 + 2d3] {
+  MONSTER:('a',"fire ant"),random
+}
+MONSTER:'a',random
+MONSTER:'a',random
+REGION:(10,6,10,6),lit,"ordinary",filled, true {
+  LOOP [5 + 4d3] {
+    MONSTER:('H',"fire giant"),random,hostile
+  }
+}
+MONSTER:('H',"fire giant"),random,hostile
+MONSTER:('H',"fire giant"),random,hostile
+MONSTER:'H',random,hostile
 
 #
@@ -264,6 +267,8 @@
 #
 
-MAZE: "Val-fila" , 'I'
-INIT_MAP: '.' , 'I' , true , true , lit, false
+LEVEL: "Val-fila"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'I' , true , true , lit, false
+MON_GENERATION:86%, (64,"fire ant"), (16,'a'), (16,"fire giant"), (4,'H')
 NOMAP
 #
@@ -271,32 +276,22 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [5 + 2d3] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', random, random
-MONSTER: 'H', "fire giant", random, hostile
+LOOP [2 + 2d2] {
+  MONSTER: ('a', "fire ant"), random
+}
+MONSTER: 'a', random
+MONSTER: ('H', "fire giant"), random, hostile
 #
+LOOP [6 + 2d2] {
 TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
-TRAP: random, random
+}
 
-MAZE: "Val-filb" , 'L'
-INIT_MAP: '.' , 'L' , true , true , lit, false
+LEVEL: "Val-filb"
+FLAGS:mazelevel,noflip
+INIT_MAP: mines, '.' , 'L' , true , true , lit, false
+MON_GENERATION:86%, (64,"fire ant"), (16,'a'), (16,"fire giant"), (4,'H')
 NOMAP
 #
@@ -304,29 +299,17 @@
 STAIR: random, down
 #
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+LOOP [8 + 2d2] {
+  OBJECT: random, random
+}
 #
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', "fire ant", random
-MONSTER: 'a', random, random
-MONSTER: 'H', "fire giant", random, hostile
-MONSTER: 'H', "fire giant", random, hostile
-MONSTER: 'H', "fire giant", random, hostile
+LOOP [3 + 2d2] {
+  MONSTER: ('a', "fire ant"), random
+  MONSTER[80%]: ('H', "fire giant"), random, hostile
+}
+MONSTER: 'a', random
 #
+LOOP [3 + 3d2] {
 TRAP: "fire", random
-TRAP: "fire", random
-TRAP: "fire", random
-TRAP: "fire", random
-TRAP: "fire", random
+}
 TRAP: random, random
 TRAP: random, random
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/Wizard.des nethack/dat/Wizard.des
--- nh_orig/dat/Wizard.des	2003-12-07 18:39:12.000000000 -0500
+++ nethack/dat/Wizard.des	2010-04-29 10:53:24.170716015 -0400
@@ -8,6 +8,8 @@
 #	and receive your quest assignment.
 #
-MAZE: "Wiz-strt",' '
-FLAGS: noteleport,hardfloor
+LEVEL: "Wiz-strt"
+FLAGS: noteleport,hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"vampire bat"), (16,'B'), (16,"xorn"), (4,'W')
 GEOMETRY:center,center
 MAP
@@ -17,10 +19,10 @@
 ........CC........-----------.......C.C...C...C....C........................
 .......C.....---------------------...C..C..C..C.............................
-......C..C...------....\....------....C.....C...............................
+......C..C...------.........------....C.....C...............................
 ........C...||....|.........|....||.........................................
 .......C....||....|.........+....||.........................................
 .......C...||---+--.........|....|||........................................
 ......C....||...............|--S--||........................................
-...........||--+--|++----|---|..|.SS..........C......C......................
+...........||--+--|++----|---|..|.||..........C......C......................
 ........C..||.....|..|...|...|--|.||..CC..C.....C..........C................
 .......C...||.....|..|.--|.|.|....||.................C..C...................
@@ -33,4 +35,13 @@
 ......................CCC.C.................................................
 ENDMAP
+
+SPILL:(60,15), '}', west, 20
+SPILL:(69,15), '}', north, 20
+
+# first do cloud everywhere
+REPLACE_TERRAIN:(0,0, 75,19), '.', 'C', 10%
+# then replace clouds inside the tower back to floor
+REPLACE_TERRAIN:(13,5, 33,15), 'C', '.', 100%
+
 # Dungeon Description
 REGION:(00,00,75,19),lit,"ordinary"
@@ -42,4 +53,6 @@
 STAIR:(30,10),down
 # Portal arrival point
+# need to make sure it's clear
+TERRAIN:(63,06),'.'
 BRANCH:(63,06,63,06),(0,0,0,0)
 # Doors
@@ -47,51 +60,98 @@
 DOOR:closed,(16,08)
 DOOR:closed,(28,07)
-DOOR:locked,(34,10)
-DOOR:locked,(35,10)
 DOOR:closed,(15,10)
 DOOR:locked,(19,10)
 DOOR:locked,(20,10)
+
+# Entrance into the tower
+SWITCH [3] {
+  CASE 0:
+    TERRAIN:(20,16),'S'
+    TERRAIN:(20,17),'S'
+    DOOR:locked,(20,16)
+    DOOR:locked,(20,17)
+    BREAK
+  CASE 1:
+    TERRAIN:(32,15),'S'
+    TERRAIN:(32,16),'S'
+    DOOR:locked,(32,15)
+    DOOR:locked,(32,16)
+    BREAK
+  CASE 2:
+  DEFAULT:
+    TERRAIN:(34,10),'S'
+    TERRAIN:(35,10),'S'
+    DOOR:locked,(34,10)
+    DOOR:locked,(35,10)
+    BREAK
+}
+
 # Neferet the Green, the quest leader
-MONSTER:'@',"Neferet the Green",(23,05)
+OBJECT:('\',"throne"),(23,05)
+MONSTER:('@',"Neferet the Green"),(23,05) {
+  OBJECT:'/'
+  OBJECT:'/'
+  OBJECT:'?'
+  OBJECT:'?'
+  OBJECT:'['
+}
 # The treasure of the quest leader
-OBJECT:'(',"chest",(24,05)
+OBJECT:('(',"chest"),(24,05)
 # apprentice guards for the audience chamber
-MONSTER:'@',"apprentice",(30,07)
-MONSTER:'@',"apprentice",(24,06)
-MONSTER:'@',"apprentice",(15,06)
-MONSTER:'@',"apprentice",(15,12)
-MONSTER:'@',"apprentice",(26,11)
-MONSTER:'@',"apprentice",(27,11)
-MONSTER:'@',"apprentice",(19,09)
-MONSTER:'@',"apprentice",(20,09)
+MONSTER:('@',"apprentice"),(30,07) {
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(24,06) {
+  OBJECT:random
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(15,06) {
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(15,12) {
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(26,11) {
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(27,11) {
+  OBJECT:random
+}
+MONSTER:('@',"apprentice"),(19,09) {
+  OBJECT:random
+  OBJECT[50%]:random
+  OBJECT[25%]:random
+}
+MONSTER:('@',"apprentice"),(20,09) {
+  OBJECT:random
+  OBJECT[50%]:random
+  OBJECT[25%]:random
+}
 # Eels in the pond
-MONSTER:';',"giant eel",(62,14)
-MONSTER:';',"giant eel",(69,15)
-MONSTER:';',"giant eel",(67,17)
+MONSTER:(';',"giant eel"),(62,14)
+MONSTER:(';',"giant eel"),(69,15)
+MONSTER:(';',"giant eel"),(67,17)
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,19)
 # Random traps
+LOOP [3 + 3d3] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
 # Monsters on siege duty.
-MONSTER: 'B',random,(60,09),hostile
-MONSTER: 'W',random,(60,10),hostile
-MONSTER: 'B',random,(60,11),hostile
-MONSTER: 'B',random,(60,12),hostile
-MONSTER: 'i',random,(60,13),hostile
-MONSTER: 'B',random,(61,10),hostile
-MONSTER: 'B',random,(61,11),hostile
-MONSTER: 'B',random,(61,12),hostile
-MONSTER: 'B',random,(35,03),hostile
-MONSTER: 'i',random,(35,17),hostile
-MONSTER: 'B',random,(36,17),hostile
-MONSTER: 'B',random,(34,16),hostile
-MONSTER: 'i',random,(34,17),hostile
-MONSTER: 'W',random,(67,02),hostile
-MONSTER: 'B',random,(10,19),hostile
+MONSTER: 'B',(60,09),hostile
+MONSTER: 'W',(60,10),hostile
+MONSTER: 'B',(60,11),hostile
+MONSTER: 'B',(60,12),hostile
+MONSTER: 'i',(60,13),hostile
+MONSTER: 'B',(61,10),hostile
+MONSTER: 'B',(61,11),hostile
+MONSTER: 'B',(61,12),hostile
+MONSTER: 'B',(35,03),hostile
+MONSTER: 'i',(35,17),hostile
+MONSTER: 'B',(36,17),hostile
+MONSTER: 'B',(34,16),hostile
+MONSTER: 'i',(34,17),hostile
+MONSTER: 'W',(67,02),hostile
+MONSTER: 'B',(10,19),hostile
 
 #
@@ -102,44 +162,63 @@
 #
 
-MAZE: "Wiz-loca",' '
-FLAGS: hardfloor
+LEVEL: "Wiz-loca"
+FLAGS: hardfloor,mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"vampire bat"), (16,'B'), (16,"xorn"), (4,'W')
 GEOMETRY:center,center
 MAP
-.............        .......................................................
-..............       .............}}}}}}}.}}}}}}}}}}}}}}}}}}}.}}}}}}}.......
-..............      ..............}.................................}.......
-..............      ..............}.---------S---------------------.}.......
-...............     .........C....}.|.............................|.}.......
-...............    ..........C....}.|.---------------------------.|.}.......
-...............    .........CCC.....|.|.........................|.|.........
-................   ....C....CCC...}.|.|.---S-------------------.|.|.}.......
-.......C..C.....  .....C....CCC...}.|.|.|......+.......+......|.|.|.}.......
-.............C..CC.....C....CCC...}.|.|.|......|-------|......|.|.|.}.......
-................   ....C....CCC...}.|.|.|......|.......S......|.|.|.}.......
-......C..C.....    ....C....CCC...}.|.|.|......|-------|......|.|.|.}.......
-............C..     ...C....CCC...}.|.|.|......+.......+......|.|.|.}.......
-........C......    ....C....CCC...}.|.|.-----------------------.|.|.}.......
-....C......C...     ........CCC.....|.|.........................|.|.........
-......C..C....      .........C....}.|.--------------------S------.|.}.......
-..............      .........C....}.|.............................|.}.......
-.............       ..............}.-------------------------------.}.......
-.............        .............}.................................}.......
-.............        .............}}}}}}}.}}}}}}}}}}}}}}}}}}}.}}}}}}}.......
-.............        .......................................................
+.............         ......................................................
+.............         ............}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.......
+.............         ............}.................................}.......
+.............         ............}.-------------------------------.}.......
+.............         .......C....}.|.............................|.}.......
+.............         .......C....}.|.---------------------------.|.}.......
+.............         ......CCC...}.|.|.........................|.|.}.......
+.............         .C....CCC...}.|.|.-----------------------.|.|.}.......
+.......C..C..         .C....CCC...}.|.|.|......+.......+......|.|.|.}.......
+.............         .C....CCC...}.|.|.|......|-------|......|.|.|.}.......
+.............        C.C....CCC...}.|.|.|......|.......|......|.|.|.}.......
+......C..C...         .C....CCC...}.|.|.|......|-------|......|.|.|.}.......
+............C         .C....CCC...}.|.|.|......+.......+......|.|.|.}.......
+........C....         .C....CCC...}.|.|.-----------------------.|.|.}.......
+....C......C.         ......CCC...}.|.|.........................|.|.}.......
+......C..C...         .......C....}.|.---------------------------.|.}.......
+.............         .......C....}.|.............................|.}.......
+.............         ............}.-------------------------------.}.......
+.............         ............}.................................}.......
+.............         ............}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}.......
+.............         ......................................................
 ENDMAP
+
+REPLACE_TERRAIN:(0,0,30,20), '.', 'C', 15%
+REPLACE_TERRAIN:(68,0,75,20), '.', '}', 25%
+
+REPLACE_TERRAIN:(34,1,68,19), '}', '.', 2%
+
+# Fog Maze, with occasional broken walls.
+MAZEWALK:(12,10),east,false,'C'
+REPLACE_TERRAIN:(13,0,21,20), ' ', 'C', 4%
+
 # Dungeon Description
 REGION:(00,00,75,20),lit,"ordinary"
-REGION:(37,04,65,16),unlit,"ordinary"
-REGION:(41,08,46,12),lit,"ordinary"
-REGION:(56,08,61,12),lit,"ordinary"
+REGION:(37,04,65,16),unlit,"ordinary",filled,true {
+  ROOMDOOR:true,closed,north|south|west|east,random
+}
+REGION:(39,06,63,14),unlit,"ordinary",filled,true {
+  ROOMDOOR:true,closed,north|south|west|east,random
+}
+REGION:(41,08,46,12),lit,"ordinary",filled,true {
+  ROOMDOOR:true,closed,north|south|west,random
+}
+REGION:(56,08,61,12),lit,"ordinary",filled,true {
+  ROOMDOOR:true,closed,north|south|east,random
+}
 REGION:(48,08,54,08),unlit,"ordinary"
 REGION:(48,12,54,12),unlit,"ordinary"
-REGION:(48,10,54,10),unlit,"ordinary"
+REGION:(48,10,54,10),unlit,"ordinary",filled,true {
+  ROOMDOOR:true,closed,north|south|west|east,random
+}
 
 # Doors
-DOOR:locked,(45,03)
-DOOR:locked,(43,07)
-DOOR:locked,(58,15)
-DOOR:locked,(55,10)
 DOOR:locked,(55,08)
 DOOR:locked,(55,12)
@@ -148,23 +227,11 @@
 # Stairs
 STAIR:(03,17),up
-STAIR:(48,10),down
+STAIR:(51,10),down
 # Non diggable walls
 NON_DIGGABLE:(00,00,75,20)
 # Objects
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+LOOP [10 + 1d6] {
+  OBJECT:random,random
+}
 # Random traps
 TRAP:"spiked pit",(24,02)
@@ -190,31 +257,9 @@
 TRAP:"dart",random
 # Random monsters.
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'i',random,random,hostile
+LOOP [10 + 1d10] {
+  MONSTER:'B',random,hostile
+  MONSTER[80%]:'i',random,hostile
+  MONSTER[90%]:('B',"vampire bat"),random
+}
 
 #
@@ -226,5 +271,8 @@
 #
 
-MAZE: "Wiz-goal", ' '
+LEVEL: "Wiz-goal"
+FLAGS:mazelevel
+INIT_MAP:solidfill,' '
+MON_GENERATION:86%, (64,"vampire bat"), (16,'B'), (16,"xorn"), (4,'W')
 GEOMETRY:center,center
 MAP
@@ -232,7 +280,7 @@
                                                                             
                                                                             
-                   -------------                 -------------              
-                   |...........|                 |...........|              
-            -------|...........-------------------...........|              
+            --------------------                 -------------              
+            |......|...........|                 |...........|              
+            ---S---|...........-------------------...........|              
             |......S...........|..|..|..|..|..|..|...........|              
             |......|...........|..|..|..|..|..|..|...........|              
@@ -242,7 +290,7 @@
             |......|...........|..|..|..|..|..|..|...........|              
             |......|...........|..|..|..|..|..|..|...........|              
-            -------|...........-------------------...........|              
-                   |...........|                 |...........|              
-                   -------------                 -------------              
+            ----S--|...........-------------------...........|              
+            |......|...........|                 |...........|              
+            --------------------                 -------------              
                                                                             
                                                                             
@@ -268,4 +316,6 @@
 REGION:(47,11,48,12),unlit,"ordinary"
 REGION:(50,04,60,14),lit,"ordinary"
+REGION:(13,04,18,04),lit,"ordinary"
+REGION:(13,14,18,14),lit,"ordinary"
 # Doors
 DOOR:locked,(19,06)
@@ -285,4 +335,6 @@
 DOOR:locked,(48,10)
 DOOR:locked,(49,09)
+DOOR:locked,(16,13)
+DOOR:locked,(15,05)
 # Stairs
 STAIR:(55,05),up
@@ -292,64 +344,40 @@
 ALTAR:(16,11),noncoaligned,altar
 # Objects
-OBJECT:'"',"amulet of ESP",(16,11),blessed,0,"The Eye of the Aethiopica"
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
-OBJECT:random,random,random
+OBJECT:('"',"amulet of power"),(16,11),blessed,0,NAME:"The Eye of the Aethiopica"
+LOOP [9 + 2d5] {
+  OBJECT:random,random
+}
+OBJECT:('+',"knock"),(13,14)
+OBJECT:'+',(18,14)
+OBJECT:'+',(13,04)
+OBJECT:('+',"wizard lock"),(18,04)
 # Random traps
+LOOP [2 + 2d8] {
 TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
-TRAP:random,random
+}
+TRAP:random,(16,14)
+TRAP:random,(15,04)
 # Random monsters.
-MONSTER:'@',"Dark One",(16,11)
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'B',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'i',random,random,hostile
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'B',"vampire bat",random
-MONSTER:'i',random,random,hostile
+MONSTER:('@',"Dark One"),(16,11) {
+  OBJECT:('(', "Bell of Opening"),uncursed
+  OBJECT:'/'
+  OBJECT:'?'
+  OBJECT:'+'
+  OBJECT:'['
+}
+LOOP [8 + 3d8] {
+  MONSTER:'B',random,hostile
+  MONSTER:'i',random,hostile
+  MONSTER:('B',"vampire bat"),random
+}
 # Captive Monsters in the dungeon
-MONSTER:'@',"rogue",(35,06),peaceful,"Pug"
-MONSTER:'Y',"owlbear",(47,06),peaceful,asleep
-MONSTER:'@',"wizard",(32,11),peaceful,asleep,"Newt"
-MONSTER:'@',"Grey-elf",(44,11),peaceful
-MONSTER:'H',"hill giant",(47,11),peaceful,asleep
-MONSTER:'G',"gnomish wizard",(38,06),peaceful
-MONSTER:'@',"prisoner",(35,11),peaceful
-MONSTER:'@',"prisoner",(41,11),peaceful,asleep
+MONSTER:('@',"rogue"),(35,06),peaceful,"Pug"
+MONSTER:('Y',"owlbear"),(47,06),peaceful,asleep
+MONSTER:('@',"wizard"),(32,11),peaceful,asleep,"Newt"
+MONSTER:('@',"Grey-elf"),(44,11),peaceful
+MONSTER:('H',"hill giant"),(47,11),peaceful,asleep
+MONSTER:('G',"gnomish wizard"),(38,06),peaceful
+MONSTER:('@',"prisoner"),(35,11),peaceful
+MONSTER:('@',"prisoner"),(41,11),peaceful,asleep
 
 #
@@ -363,77 +391,103 @@
 
 LEVEL: "Wiz-fila"
+MON_GENERATION:86%, (64,"vampire bat"), (16,'B'), (16,"xorn"), (4,'W')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'i', random, random, hostile
+OBJECT: random,random
+MONSTER: 'i', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'i', random, random, hostile
+{
+OBJECT: random, random
+OBJECT: random,random
+MONSTER: 'i', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'B', "vampire bat", random
-MONSTER: 'B', "vampire bat", random
+OBJECT: random,random
+MONSTER: ('B', "vampire bat"), random
+MONSTER: ('B', "vampire bat"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'i', random, random, hostile
-MONSTER: 'B', "vampire bat", random
+MONSTER: 'i', random, hostile
+MONSTER: ('B', "vampire bat"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'i', random, random, hostile
+MONSTER: 'i', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'B', "vampire bat", random
+MONSTER: ('B', "vampire bat"), random
+}
 
 RANDOM_CORRIDORS
 
 LEVEL: "Wiz-filb"
+MON_GENERATION:86%, (64,"vampire bat"), (16,'B'), (16,"xorn"), (4,'W')
 #
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, up
-OBJECT: random,random,random
-MONSTER: 'X', random, random, hostile
+OBJECT: random,random
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random,random,random
-MONSTER: 'i', random, random, hostile
+{
+OBJECT: random, random
+OBJECT: random,random
+MONSTER: 'i', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-OBJECT: random,random,random
-MONSTER: 'X', random, random, hostile
+OBJECT: random,random
+MONSTER: 'X', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
+{
 STAIR: random, down
-OBJECT: random, random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'i', random, random, hostile
-MONSTER: 'B', "vampire bat", random
+MONSTER: 'i', random, hostile
+MONSTER: ('B', "vampire bat"), random
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'i', random, random, hostile
+MONSTER: 'i', random, hostile
+}
 
 ROOM: "ordinary" , random, random, random, random
-OBJECT: random, random, random
+{
+OBJECT: random, random
 TRAP: random, random
-MONSTER: 'B', "vampire bat", random
+MONSTER: ('B', "vampire bat"), random
+}
 
 RANDOM_CORRIDORS
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/dat/yendor.des nethack/dat/yendor.des
--- nh_orig/dat/yendor.des	2003-12-07 18:39:13.000000000 -0500
+++ nethack/dat/yendor.des	2010-04-11 12:36:58.301624882 -0400
@@ -6,6 +6,7 @@
 # The top (real) wizard level.
 # Keeping the Moat for old-time's sake
-MAZE:"wizard1",random
-FLAGS:noteleport,hardfloor
+LEVEL:"wizard1"
+FLAGS:noteleport,hardfloor,mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -28,7 +29,8 @@
 BRANCH:levregion(01,00,79,20),(0,0,28,12)
 TELEPORT_REGION:levregion(01,00,79,20),(0,0,27,12)
-# Make it a morgue for rm id in mkmaze.c
-# for the purpose of random sdoor placement
-REGION:(12,01,20,09),unlit,"morgue",unfilled
+
+REGION:(12,01,20,09),unlit,"morgue",unfilled {
+  ROOMDOOR:true, locked, south|east|west, random
+}
 MAZEWALK:(28,05),east
 LADDER:(06,05),down
@@ -45,27 +47,27 @@
 NON_PASSWALL:(21,00,27,10)
 # The wizard and his guards
-MONSTER:'@',"Wizard of Yendor",(16,05),asleep
-MONSTER:'d',"hell hound",(15,05)
-MONSTER:'V',"vampire lord",(17,05)
+MONSTER:('@',"Wizard of Yendor"),(16,05),asleep
+MONSTER:('d',"hell hound"),(15,05)
+MONSTER:('V',"vampire lord"),(17,05)
 # The local treasure
-OBJECT:'+',"Book of the Dead",(16,05)
+OBJECT:('+',"Book of the Dead"),(16,05)
 # Surrounding terror
-MONSTER:';',"kraken",(14,02)
-MONSTER:';',"giant eel",(17,02)
-MONSTER:';',"kraken",(13,04)
-MONSTER:';',"giant eel",(13,06)
-MONSTER:';',"kraken",(19,04)
-MONSTER:';',"giant eel",(19,06)
-MONSTER:';',"kraken",(15,08)
-MONSTER:';',"giant eel",(17,08)
-MONSTER:';',"piranha",(15,02)
-MONSTER:';',"piranha",(19,08)
+MONSTER:(';',"kraken"),(14,02)
+MONSTER:(';',"giant eel"),(17,02)
+MONSTER:(';',"kraken"),(13,04)
+MONSTER:(';',"giant eel"),(13,06)
+MONSTER:(';',"kraken"),(19,04)
+MONSTER:(';',"giant eel"),(19,06)
+MONSTER:(';',"kraken"),(15,08)
+MONSTER:(';',"giant eel"),(17,08)
+MONSTER:(';',"piranha"),(15,02)
+MONSTER:(';',"piranha"),(19,08)
 # Random monsters
-MONSTER:'D',random,random
-MONSTER:'H',random,random
-MONSTER:'&',random,random
-MONSTER:'&',random,random
-MONSTER:'&',random,random
-MONSTER:'&',random,random
+MONSTER:'D',random
+MONSTER:'H',random
+MONSTER:'&',random
+MONSTER:'&',random
+MONSTER:'&',random
+MONSTER:'&',random
 # And to make things a little harder.
 TRAP:"board",(16,04)
@@ -79,17 +81,18 @@
 TRAP:"magic",random
 # Some random loot.
-OBJECT:'*',"ruby",random
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
-OBJECT:'+',random,random
+OBJECT:('*',"ruby"),random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'+',random
+OBJECT:'+',random
+OBJECT:'+',random
 
 
 # The middle wizard level.
-MAZE:"wizard2",random
-FLAGS:noteleport,hardfloor
+LEVEL:"wizard2"
+FLAGS:noteleport,hardfloor,mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -131,17 +134,18 @@
 TRAP:"magic",random
 # Some random loot.
-OBJECT:'!',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'+',random,random
+OBJECT:'!',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'+',random
 # treasures
-OBJECT:'"',random,(04,06)
+OBJECT:'"',(04,06)
 
 
 # The bottom wizard level.
 # Memorialize the fakewiz setup.
-MAZE:"wizard3",random
-FLAGS:noteleport,hardfloor
+LEVEL:"wizard3"
+FLAGS:noteleport,hardfloor,mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -157,5 +161,5 @@
 |.....|.}}---}}.|..|.......|.
 |.....S.}}}}}}}.|..|.......|.
-|.....|.........|..S.......|.
+|.....|.........|..|.......|.
 ----------------------------.
 ENDMAP
@@ -170,7 +174,8 @@
 # make the entry chamber a real room; it affects monster arrival;
 # `unfilled' is a kludge to force an ordinary room to remain a room
-REGION:(20,06,26,11),unlit,"ordinary",unfilled
+REGION:(20,06,26,11),unlit,"ordinary",unfilled {
+  ROOMDOOR:true, locked, north|west, random
+}
 DOOR:closed,(18,05)
-DOOR:closed,(19,11)
 LADDER:(11,07),up
 # Non diggable walls
@@ -186,18 +191,18 @@
 NON_PASSWALL:(06,12,16,12)
 #
-MONSTER:'L',random,(10,07)
-MONSTER:'V',"vampire lord",(12,07)
+MONSTER:'L',(10,07)
+MONSTER:('V',"vampire lord"),(12,07)
 # Some surrounding horrors
-MONSTER:';',"kraken",(08,05)
-MONSTER:';',"giant eel",(08,08)
-MONSTER:';',"kraken",(14,05)
-MONSTER:';',"giant eel",(14,08)
+MONSTER:(';',"kraken"),(08,05)
+MONSTER:(';',"giant eel"),(08,08)
+MONSTER:(';',"kraken"),(14,05)
+MONSTER:(';',"giant eel"),(14,08)
 # Other monsters
-MONSTER:'L',random,random
-MONSTER:'D',random,random
-MONSTER:'D',random,(26,09)
-MONSTER:'&',random,random
-MONSTER:'&',random,random
-MONSTER:'&',random,random
+MONSTER:'L',random
+MONSTER:'D',random
+MONSTER:'D',(26,09)
+MONSTER:'&',random
+MONSTER:'&',random
+MONSTER:'&',random
 # And to make things a little harder.
 TRAP:"board",(10,07)
@@ -206,11 +211,11 @@
 TRAP:"board",(11,08)
 # Some loot
-OBJECT:')',random,random
-OBJECT:'!',random,random
-OBJECT:'?',random,random
-OBJECT:'?',random,random
-OBJECT:'(',random,random
+OBJECT:')',random
+OBJECT:'!',random
+OBJECT:'?',random
+OBJECT:'?',random
+OBJECT:'(',random
 # treasures
-OBJECT:'"',random,(11,07)
+OBJECT:'"',(11,07)
 
 
@@ -218,5 +223,7 @@
 # There are two of these, and we need to
 # distinguish between them for the portal.
-MAZE:"fakewiz1",random
+LEVEL:"fakewiz1"
+FLAGS:mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -237,7 +244,7 @@
 MAZEWALK:(08,05),east
 REGION:(04,03,06,06),unlit,"ordinary",unfilled,true
-MONSTER:'L',random,(04,04)
-MONSTER:'V',"vampire lord",(03,04)
-MONSTER:';',"kraken",(06,06)
+MONSTER:'L',(04,04)
+MONSTER:('V',"vampire lord"),(03,04)
+MONSTER:(';',"kraken"),(06,06)
 # And to make things a little harder.
 TRAP:"board",(04,03)
@@ -247,5 +254,7 @@
 
 
-MAZE:"fakewiz2",random
+LEVEL:"fakewiz2"
+FLAGS:mazelevel
+INIT_MAP:mazegrid,'-'
 GEOMETRY:center,center
 MAP
@@ -265,7 +274,7 @@
 MAZEWALK:(08,05),east
 REGION:(04,03,06,06),unlit,"ordinary",unfilled,true
-MONSTER:'L',random,(04,04)
-MONSTER:'V',"vampire lord",(03,04)
-MONSTER:';',"kraken",(06,06)
+MONSTER:'L',(04,04)
+MONSTER:('V',"vampire lord"),(03,04)
+MONSTER:(';',"kraken"),(06,06)
 # And to make things a little harder.
 TRAP:"board",(04,03)
@@ -274,3 +283,3 @@
 TRAP:"board",(05,04)
 # treasures
-OBJECT:'"',random,(04,04)
+OBJECT:'"',(04,04)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/doc/Guidebook.mn nethack/doc/Guidebook.mn
--- nh_orig/doc/Guidebook.mn	2003-12-07 18:39:13.000000000 -0500
+++ nethack/doc/Guidebook.mn	2009-08-02 13:49:34.150409063 -0400
@@ -1771,4 +1771,10 @@
 Name your starting dog (ex. ``dogname:Fang'').
 Cannot be set with the `O' command.
+.lp dumpfile
+The name of a file where the disclosure information is written when the
+game ends. You may use the macro %n that will be replaced with the name
+of your player character. The game must have write permissions to the
+directory where the file is written. Normally /tmp may be used for unix
+systems.
 .lp dungeon
 Set the graphics symbols for displaying the dungeon
@@ -2099,4 +2105,16 @@
 .lp "silent  "
 Suppress terminal beeps (default on).
+.lp sortloot
+Controls the behavior of the sortloot patch that sorts pickup lists for
+inventory and #loot commands and some others.
+The possible values are:
+.sd
+.si
+full - always sort the lists;
+loot - only sort the lists that don't use inventory
+       letters, like with the #loot and pickup commands;
+none - show lists the traditional way without sorting.
+.ei
+.ed
 .lp sortpack
 Sort the pack contents by type when displaying inventory (default on).
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/doc/Guidebook.tex nethack/doc/Guidebook.tex
--- nh_orig/doc/Guidebook.tex	2003-12-07 18:39:13.000000000 -0500
+++ nethack/doc/Guidebook.tex	2009-08-02 13:49:34.160408550 -0400
@@ -2210,4 +2210,11 @@
 Cannot be set with the `{\tt O}' command.
 %.lp
+\item[\ib{dumpfile}]
+The name of a file where the disclosure information is written when the
+game ends. You may use the macro %n that will be replaced with the name
+of your player character. The game must have write permissions to the
+directory where the file is written. Normally /tmp may be used for unix
+systems.
+%.lp
 \item[\ib{dungeon}]
 Set the graphics symbols for displaying the dungeon (default
@@ -2574,4 +2581,19 @@
 Suppress terminal beeps (default on).
 %.lp
+\item[\ib{sortloot}]
+Controls the behavior of the sortloot patch that sorts pickup lists for
+inventory and \#loot commands and some others.
+
+The possible values are:
+%.sd
+%.si
+{\tt full} --- always sort the lists;\\
+{\tt loot} --- only sort the lists that don't use inventory
+       letters, like with the \#loot and pickup commands;\\
+{\tt none} --- show lists the traditional way without sorting.
+%.ei
+%.ed
+%.lp
+The default is 'none', the way an unpatched game works.
 \item[\ib{sortpack}]
 Sort the pack contents by type when displaying inventory (default on).
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/doc/Guidebook.txt nethack/doc/Guidebook.txt
--- nh_orig/doc/Guidebook.txt	2003-12-07 18:39:13.000000000 -0500
+++ nethack/doc/Guidebook.txt	2009-08-02 13:49:34.157408524 -0400
@@ -2275,4 +2275,11 @@
             with the `O' command.
 
+          dumpfile
+            The name of a file where the disclosure information is
+            written when the game ends. You may use the macro %n that
+            will be replaced with the name of your player character.
+            The game must have write permissions to the directory where
+            the file is written. Normally /tmp may be used for unixes.
+
           dungeon
             Set the graphics symbols for displaying  the  dungeon  (default
@@ -2724,4 +2731,16 @@
             Suppress terminal beeps (default on).
 
+          sortloot
+               Controls the behavior of the sortloot patch that sorts
+               pickup lists for inventory and #loot commands and some
+               others.
+               The possible values are:
+
+                    full - always sort the lists
+                    loot - only sort the lists that don't use inventory
+                           letters, like with the #loot and pickup commands
+                    none - show lists the traditional way without sorting
+               The default is 'none', the way an unpatched game works.
+
           sortpack
             Sort the pack contents by type when displaying  inventory  (de-
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/align.h nethack/include/align.h
--- nh_orig/include/align.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/align.h	2009-08-02 13:49:33.026408602 -0400
@@ -13,6 +13,8 @@
 } align;
 
-/* bounds for "record" -- respect initial alignments of 10 */
-#define ALIGNLIM	(10L + (moves/200L))
+/* bounds for "record" -- respect initial alignments of 10.
+ * note that the maximum alignment is now 50, so that mortal
+ * sins always put you out of favor with your god. */
+#define ALIGNLIM	(min(50,10L + (moves/300L)))
 
 #define A_NONE	      (-128)	/* the value range of type */
@@ -40,3 +42,13 @@
 			 : ((x) == A_LAWFUL) ? AM_LAWFUL : (x) + 2)
 
+/*
+ * These will make it a bit easier to adjust alignment swings
+ * while trying to get it balanced out to where it matters...
+ */
+
+#define venial_sin() (adjalign(-5))
+#define minor_sin() (adjalign(-10))
+#define major_sin() (adjalign(-20))
+#define mortal_sin() (adjalign(-50))
+
 #endif /* ALIGN_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/artifact.h nethack/include/artifact.h
--- nh_orig/include/artifact.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/artifact.h	2009-08-02 13:49:33.036408503 -0400
@@ -35,5 +35,23 @@
 #define SPFX_XRAY   0x2000000L	/* gives X-RAY vision to player */
 #define SPFX_REFLECT 0x4000000L /* Reflection */
+#define SPFX_STR	  0x8000000L   /* item bestows STR 18(**) */
+#define SPFX_CON	  0x10000000L   /* item bestows CON 25 */
+#define SPFX_POLYC  0x20000000L	 /* items grants polymorph control */
 
+#define SPDF_NONE		  0x00000000L /* No special effects */
+#define SPDF_MAGIC	  0x00000001L /* Magic resistance */
+#define SPDF_FIRE		  0x00000002L /* Fire defense */
+#define SPDF_COLD		  0x00000004L /* Cold defense */
+#define SPDF_SLEEP	  0x00000008L /* Sleep defense */
+#define SPDF_DISINT	  0x00000010L /* Disintegration defense */
+#define SPDF_ELEC		  0x00000020L /* Shock defense */
+#define SPDF_POISON	  0x00000040L /* Poison defense */
+#define SPDF_ACID		  0x00000080L /* Acid defense */
+#define SPDF_BLIND	  0x00000100L /* Blinding resistance */
+#define SPDF_WERE		  0x00000200L /* Lycanthropy resistance */
+#define SPDF_DRAIN	  0x00000400L /* Drain level defense */
+#define SPDF_CONFUSE	  0x00000800L /* Confusion */
+#define SPDF_STUN		  0x00001000L /* Stunning */
+#define SPDF_ELEMENTAL 0x000000FEL	/* All elemental resistances (Dragonbane) */
 
 struct artifact {
@@ -43,5 +61,7 @@
 	unsigned long cspfx;	/* special effect just from carrying obj */
 	unsigned long mtype;	/* monster type, symbol, or flag */
-	struct attack attk, defn, cary;
+	struct attack attk;
+	unsigned long defn;	/* special defensive properties from wielding/wearing */
+	struct attack cary;
 	uchar	    inv_prop;	/* property obtained by invoking artifact */
 	aligntyp    alignment;	/* alignment of bequeathing gods */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/artilist.h nethack/include/artilist.h
--- nh_orig/include/artilist.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/artilist.h	2009-10-31 10:32:37.579669351 -0400
@@ -16,5 +16,4 @@
 
 #define     NO_ATTK	{0,0,0,0}		/* no attack */
-#define     NO_DFNS	{0,0,0,0}		/* no defense */
 #define     NO_CARY	{0,0,0,0}		/* no carry effects */
 #define     DFNS(c)	{0,c,0,0}
@@ -26,4 +25,5 @@
 #define     ELEC(a,b)	{0,AD_ELEC,a,b}		/* electrical shock */
 #define     STUN(a,b)	{0,AD_STUN,a,b}		/* magical attack */
+#define		DRST(a,b)	{0,AD_DRST,a,b}		/* poison attack */
 
 STATIC_OVL NEARDATA struct artifact artilist[] = {
@@ -39,9 +39,16 @@
 /*  dummy element #0, so that all interesting indices are non-zero */
 A("",				STRANGE_OBJECT,
-	0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L ),
+	0, 0, 0, NO_ATTK, SPDF_NONE, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L ),
 
 A("Excalibur",			LONG_SWORD,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_SEEK|SPFX_DEFN|SPFX_INTEL|SPFX_SEARCH),0,0,
-	PHYS(5,10),	DRLI(0,0),	NO_CARY,	0, A_LAWFUL, PM_KNIGHT, NON_PM, 4000L ),
+	PHYS(5,10),	SPDF_DRAIN,	NO_CARY,	0, A_LAWFUL, PM_KNIGHT, NON_PM, 4000L ),
+/* 
+ * The Knight needed a chaotic longsword to obtain, since Excalibur
+ * will be restricted from him... 
+*/
+A("Dirge",			LONG_SWORD,
+	(SPFX_ATTK|SPFX_NOGEN|SPFX_RESTR|SPFX_DEFN|SPFX_INTEL),0,0,
+	DRST(5,0),	SPDF_DRAIN,	NO_CARY,	0, A_CHAOTIC, NON_PM, NON_PM, 3000L ),
 /*
  *	Stormbringer only has a 2 because it can drain a level,
@@ -50,5 +57,13 @@
 A("Stormbringer",		RUNESWORD,
 	(SPFX_RESTR|SPFX_ATTK|SPFX_DEFN|SPFX_INTEL|SPFX_DRLI), 0, 0,
-	DRLI(5,2),	DRLI(0,0),	NO_CARY,	0, A_CHAOTIC, NON_PM, NON_PM, 8000L ),
+	DRLI(5,2),	SPDF_DRAIN,	NO_CARY,	0, A_CHAOTIC, NON_PM, NON_PM, 8000L ),
+/*
+ * Lifestealer gets the same restrictions as Stormy, but it's designed
+ * to be generated in Vlad's hands anyway, so this isn't such a big deal.
+ * It's two-handed so players (hopefully) won't really want to use it...
+ */
+A("Lifestealer",		TWO_HANDED_SWORD,
+	(SPFX_NOGEN|SPFX_RESTR|SPFX_ATTK|SPFX_DEFN|SPFX_INTEL|SPFX_DRLI), 0, 0,
+	DRLI(5,2),	SPDF_DRAIN,	NO_CARY,	0, A_CHAOTIC, NON_PM, NON_PM, 8000L ),
 /*
  *	Mjollnir will return to the hand of the wielder when thrown
@@ -57,29 +72,27 @@
 A("Mjollnir",			WAR_HAMMER,		/* Mjo:llnir */
 	(SPFX_RESTR|SPFX_ATTK),  0, 0,
-	ELEC(5,24),	NO_DFNS,	NO_CARY,	0, A_NEUTRAL, PM_VALKYRIE, NON_PM, 4000L ),
+	ELEC(5,24),	SPDF_NONE,	NO_CARY,	0, A_NEUTRAL, PM_VALKYRIE, NON_PM, 4000L ),
 
 A("Cleaver",			BATTLE_AXE,
 	SPFX_RESTR, 0, 0,
-	PHYS(3,6),	NO_DFNS,	NO_CARY,	0, A_NEUTRAL, PM_BARBARIAN, NON_PM, 1500L ),
+	PHYS(3,6),	SPDF_NONE,	NO_CARY,	0, A_NEUTRAL, PM_BARBARIAN, NON_PM, 1500L ),
 
 A("Grimtooth",			ORCISH_DAGGER,
 	SPFX_RESTR, 0, 0,
-	PHYS(2,6),	NO_DFNS,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ORC, 300L ),
+	PHYS(5,6),	SPDF_NONE,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ORC, 600L ),
 /*
  *	Orcrist and Sting have same alignment as elves.
- */
-A("Orcrist",			ELVEN_BROADSWORD,
-	SPFX_DFLAG2, 0, M2_ORC,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ELF, 2000L ),
-
-/*
  *	The combination of SPFX_WARN and M2_something on an artifact
  *	will trigger EWarn_of_mon for all monsters that have the appropriate
  *	M2_something flags.  In Sting's case it will trigger EWarn_of_mon
- *	for M2_ORC monsters.
+ *	for M2_SPIDER monsters; in Orcrist, for M2_ORC.
  */
+A("Orcrist",			ELVEN_BROADSWORD,
+	(SPFX_WARN|SPFX_DCLAS), 0, S_ORC,
+	PHYS(5,4),	SPDF_NONE,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ELF, 2000L ),
+
 A("Sting",			ELVEN_DAGGER,
-	(SPFX_WARN|SPFX_DFLAG2), 0, M2_ORC,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ELF, 800L ),
+	(SPFX_WARN|SPFX_DCLAS), 0, S_SPIDER,
+	PHYS(5,3),	SPDF_NONE,	NO_CARY,	0, A_CHAOTIC, NON_PM, PM_ELF, 800L ),
 /*
  *	Magicbane is a bit different!  Its magic fanfare
@@ -88,41 +101,41 @@
 A("Magicbane",			ATHAME,
 	(SPFX_RESTR|SPFX_ATTK|SPFX_DEFN), 0, 0,
-	STUN(3,4),	DFNS(AD_MAGM),	NO_CARY,	0, A_NEUTRAL, PM_WIZARD, NON_PM, 3500L ),
+	STUN(3,4),	SPDF_MAGIC,	NO_CARY,	0, A_NEUTRAL, PM_WIZARD, NON_PM, 3500L ),
 
 A("Frost Brand",		LONG_SWORD,
 	(SPFX_RESTR|SPFX_ATTK|SPFX_DEFN), 0, 0,
-	COLD(5,0),	COLD(0,0),	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 3000L ),
+	COLD(5,0),	SPDF_COLD,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 3000L ),
 
 A("Fire Brand",			LONG_SWORD,
 	(SPFX_RESTR|SPFX_ATTK|SPFX_DEFN), 0, 0,
-	FIRE(5,0),	FIRE(0,0),	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 3000L ),
+	FIRE(5,0),	SPDF_FIRE,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 3000L ),
 
-A("Dragonbane",			BROADSWORD,
-	(SPFX_RESTR|SPFX_DCLAS), 0, S_DRAGON,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 500L ),
+A("Dragonbane",			DWARVISH_SPEAR,
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS), 0, S_DRAGON,
+	PHYS(5,4),	SPDF_ELEMENTAL,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 1500L ),
 
-A("Demonbane",			LONG_SWORD,
-	(SPFX_RESTR|SPFX_DFLAG2), 0, M2_DEMON,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 2500L ),
+A("Demonbane",			SILVER_MACE,
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS), 0, S_DEMON,
+	PHYS(5,4),	SPDF_NONE,	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 2500L ),
 
 A("Werebane",			SILVER_SABER,
-	(SPFX_RESTR|SPFX_DFLAG2), 0, M2_WERE,
-	PHYS(5,0),	DFNS(AD_WERE),	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 1500L ),
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_POLYC), 0, S_WERE,
+	PHYS(5,4),	SPDF_WERE,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 1500L ),
 
 A("Grayswandir",		SILVER_SABER,
 	(SPFX_RESTR|SPFX_HALRES), 0, 0,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 8000L ),
+	PHYS(5,0),	SPDF_NONE,	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 8000L ),
 
-A("Giantslayer",		LONG_SWORD,
-	(SPFX_RESTR|SPFX_DFLAG2), 0, M2_GIANT,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_NEUTRAL, NON_PM, NON_PM, 200L ),
+A("Giantslayer",		SLING,
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_STR), 0, S_GIANT,
+	PHYS(5,8),	SPDF_NONE,	NO_CARY,	0, A_NEUTRAL, NON_PM, NON_PM, 1200L ),
 
 A("Ogresmasher",		WAR_HAMMER,
-	(SPFX_RESTR|SPFX_DCLAS), 0, S_OGRE,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 200L ),
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_CON), 0, S_OGRE,
+	PHYS(5,4),	SPDF_NONE,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 1200L ),
 
 A("Trollsbane",			MORNING_STAR,
-	(SPFX_RESTR|SPFX_DCLAS), 0, S_TROLL,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 200L ),
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS|SPFX_REGEN), 0, S_TROLL,
+	PHYS(5,4),	SPDF_NONE,	NO_CARY,	0, A_NONE, NON_PM, NON_PM, 1200L ),
 /*
  *	Two problems:  1) doesn't let trolls regenerate heads,
@@ -132,5 +145,5 @@
 A("Vorpal Blade",		LONG_SWORD,
 	(SPFX_RESTR|SPFX_BEHEAD), 0, 0,
-	PHYS(5,1),	NO_DFNS,	NO_CARY,	0, A_NEUTRAL, NON_PM, NON_PM, 4000L ),
+	PHYS(5,1),	SPDF_NONE,	NO_CARY,	0, A_NEUTRAL, NON_PM, NON_PM, 4000L ),
 /*
  *	Ah, never shall I forget the cry,
@@ -143,9 +156,13 @@
 A("Snickersnee",		KATANA,
 	SPFX_RESTR, 0, 0,
-	PHYS(0,8),	NO_DFNS,	NO_CARY,	0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L ),
+	PHYS(5,8),	SPDF_NONE,	NO_CARY,	0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L ),
 
-A("Sunsword",			LONG_SWORD,
-	(SPFX_RESTR|SPFX_DFLAG2), 0, M2_UNDEAD,
-	PHYS(5,0),	DFNS(AD_BLND),	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 1500L ),
+A("Sunsword",			SILVER_LONG_SWORD,
+	(SPFX_WARN|SPFX_RESTR|SPFX_DCLAS), 0, S_UNDEAD,
+	PHYS(5,4),	SPDF_BLIND,	NO_CARY,	0, A_LAWFUL, NON_PM, NON_PM, 1500L ),
+
+A("Keolewa",CLUB,
+	SPFX_RESTR, 0, 0,
+	PHYS(5,6), SPDF_NONE, NO_CARY, 0, A_NEUTRAL, PM_CAVEMAN, NON_PM, 1000L ),
 
 /*
@@ -155,5 +172,5 @@
 A("The Orb of Detection",	CRYSTAL_BALL,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), (SPFX_ESP|SPFX_HSPDAM), 0,
-	NO_ATTK,	NO_DFNS,	CARY(AD_MAGM),
+	NO_ATTK,	SPDF_NONE,	CARY(AD_MAGM),
 	INVIS,		A_LAWFUL, PM_ARCHEOLOGIST, NON_PM, 2500L ),
 
@@ -161,10 +178,10 @@
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), SPFX_STLTH, 0,
 	/* this stone does double damage if used as a projectile weapon */
-	PHYS(5,0),	NO_DFNS,	NO_CARY,
+	PHYS(5,0),	SPDF_NONE,	NO_CARY,
 	LEVITATION,	A_NEUTRAL, PM_BARBARIAN, NON_PM, 2500L ),
 
 A("The Sceptre of Might",	MACE,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_DALIGN), 0, 0,
-	PHYS(5,0),	NO_DFNS,	CARY(AD_MAGM),
+	PHYS(5,0),	SPDF_NONE,	CARY(AD_MAGM),
 	CONFLICT,	A_LAWFUL, PM_CAVEMAN, NON_PM, 2500L ),
 
@@ -179,25 +196,26 @@
 A("The Staff of Aesculapius",	QUARTERSTAFF,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_ATTK|SPFX_INTEL|SPFX_DRLI|SPFX_REGEN), 0,0,
-	DRLI(0,0),	DRLI(0,0),	NO_CARY,
+	DRLI(0,0),	SPDF_DRAIN,	NO_CARY,
 	HEALING,	A_NEUTRAL, PM_HEALER, NON_PM, 5000L ),
 
 A("The Magic Mirror of Merlin", MIRROR,
-	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_SPEAK), SPFX_ESP, 0,
-	NO_ATTK,	NO_DFNS,	CARY(AD_MAGM),
+	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_SPEAK|SPFX_REFLECT), 
+	(SPFX_REFLECT|SPFX_ESP|SPFX_HSPDAM), 0,
+	NO_ATTK,	SPDF_NONE,	NO_CARY,
 	0,		A_LAWFUL, PM_KNIGHT, NON_PM, 1500L ),
 
 A("The Eyes of the Overworld",	LENSES,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_XRAY), 0, 0,
-	NO_ATTK,	NO_DFNS,	CARY(AD_MAGM),
+	NO_ATTK,	SPDF_NONE,	CARY(AD_MAGM),
 	ENLIGHTENING,	A_NEUTRAL,	 PM_MONK, NON_PM, 2500L ),
 
 A("The Mitre of Holiness",	HELM_OF_BRILLIANCE,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_DFLAG2|SPFX_INTEL), 0, M2_UNDEAD,
-	NO_ATTK,	NO_DFNS,	CARY(AD_FIRE),
+	NO_ATTK,	SPDF_NONE,	CARY(AD_FIRE),
 	ENERGY_BOOST,	A_LAWFUL, PM_PRIEST, NON_PM, 2000L ),
 
 A("The Longbow of Diana", BOW,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_REFLECT), SPFX_ESP, 0,
-	PHYS(5,0),	NO_DFNS,	NO_CARY,
+	PHYS(5,0),	SPDF_NONE,	NO_CARY,
 	CREATE_AMMO, A_CHAOTIC, PM_RANGER, NON_PM, 4000L ),
 
@@ -205,10 +223,10 @@
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_SPEAK),
 		(SPFX_WARN|SPFX_TCTRL|SPFX_HPHDAM), 0,
-	NO_ATTK,	NO_DFNS,	NO_CARY,
+	NO_ATTK,	SPDF_NONE,	NO_CARY,
 	UNTRAP,		A_CHAOTIC, PM_ROGUE, NON_PM, 3500L ),
 
 A("The Tsurugi of Muramasa",	TSURUGI,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_BEHEAD|SPFX_LUCK), 0, 0,
-	PHYS(0,8),	NO_DFNS,	NO_CARY,
+	PHYS(0,8),	SPDF_NONE,	NO_CARY,
 	0,		A_LAWFUL, PM_SAMURAI, NON_PM, 4500L ),
 
@@ -217,5 +235,5 @@
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_DEFN),
 		(SPFX_ESP|SPFX_HSPDAM), 0,
-	NO_ATTK,	NO_DFNS,	CARY(AD_MAGM),
+	NO_ATTK,	SPDF_NONE,	CARY(AD_MAGM),
 	CHARGE_OBJ,	A_NEUTRAL, PM_TOURIST, NON_PM, 7000L ),
 #endif
@@ -223,11 +241,11 @@
 A("The Orb of Fate",		CRYSTAL_BALL,
 	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_LUCK),
-		(SPFX_WARN|SPFX_HSPDAM|SPFX_HPHDAM), 0,
-	NO_ATTK,	NO_DFNS,	NO_CARY,
+		(SPFX_WARN|SPFX_HPHDAM), 0,
+	NO_ATTK,	SPDF_NONE,	NO_CARY,
 	LEV_TELE,	A_NEUTRAL, PM_VALKYRIE, NON_PM, 3500L ),
 
-A("The Eye of the Aethiopica",	AMULET_OF_ESP,
-	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), (SPFX_EREGEN|SPFX_HSPDAM), 0,
-	NO_ATTK,	NO_DFNS,	CARY(AD_MAGM),
+A("The Eye of the Aethiopica",	AMULET_OF_POWER,
+	(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), (SPFX_ESP|SPFX_HSPDAM), 0,
+	NO_ATTK,	SPDF_NONE,	CARY(AD_MAGM),
 	CREATE_PORTAL,	A_NEUTRAL, PM_WIZARD, NON_PM, 4000L ),
 
@@ -235,5 +253,5 @@
  *  terminator; otyp must be zero
  */
-A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L )
+A(0, 0, 0, 0, 0, NO_ATTK, SPDF_NONE, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L )
 
 };	/* artilist[] (or artifact_names[]) */
@@ -243,5 +261,4 @@
 #ifndef MAKEDEFS_C
 #undef	NO_ATTK
-#undef	NO_DFNS
 #undef	DFNS
 #undef	PHYS
@@ -251,4 +268,5 @@
 #undef	ELEC
 #undef	STUN
+#undef	DRST
 #endif
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/color.h nethack/include/color.h
--- nh_orig/include/color.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/color.h	2009-09-07 11:17:28.044650941 -0400
@@ -6,4 +6,10 @@
 #define COLOR_H
 
+#ifdef MENU_COLOR
+# ifdef MENU_COLOR_REGEX
+#  include <regex.h>
+# endif
+#endif
+
 /*
  * The color scheme used is tailored for an IBM PC.  It consists of the
@@ -50,3 +56,38 @@
 #define HI_ZAP		CLR_BRIGHT_BLUE
 
+#ifdef MENU_COLOR
+struct menucoloring {
+# ifdef MENU_COLOR_REGEX
+#  ifdef MENU_COLOR_REGEX_POSIX
+    regex_t match;
+#  else
+    struct re_pattern_buffer match;
+#  endif
+# else
+    char *match;
+# endif
+    int color, attr;
+    struct menucoloring *next;
+};
+#endif /* MENU_COLOR */
+
+#ifdef STATUS_COLORS
+struct color_option {
+    int color;
+    int attr_bits;
+};
+
+struct percent_color_option {
+	int percentage;
+	struct color_option color_option;
+	const struct percent_color_option *next;
+};
+
+struct text_color_option {
+	const char *text;
+	struct color_option color_option;
+	const struct text_color_option *next;
+};
+#endif
+
 #endif /* COLOR_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/config.h nethack/include/config.h
--- nh_orig/include/config.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/config.h	2010-05-14 11:22:24.446714491 -0400
@@ -144,14 +144,19 @@
 #ifndef WIZARD		/* allow for compile-time or Makefile changes */
 # ifndef KR1ED
-#  define WIZARD  "wizard" /* the person allowed to use the -D option */
+#  define WIZARD  "derek" /* the person allowed to use the -D option */
 # else
 #  define WIZARD
-#  define WIZARD_NAME "wizard"
+#  define WIZARD_NAME "derek"
 # endif
 #endif
 
 #define LOGFILE "logfile"	/* larger file for debugging purposes */
+#define XLOGFILE "xlogfile" /* even larger logfile */
 #define NEWS "news"		/* the file containing the latest hack news */
 #define PANICLOG "paniclog"	/* log of panic and impossible events */
+#define DUMP_LOG				 /* turn on dumping */
+#define DUMP_FN "dumps/%n.lastlog"	 /* dump goes here */
+
+#define SERVER_ADMIN_MSG "admin_msg"
 
 /*
@@ -170,9 +175,9 @@
 #ifdef UNIX
 /* path and file name extension for compression program */
-#define COMPRESS "/usr/bin/compress"	/* Lempel-Ziv compression */
-#define COMPRESS_EXTENSION ".Z"		/* compress's extension */
+/* #define COMPRESS "/usr/bin/compress"	 Lempel-Ziv compression */
+/* #define COMPRESS_EXTENSION ".Z"	 compress's extension */
 /* An example of one alternative you might want to use: */
-/* #define COMPRESS "/usr/local/bin/gzip" */	/* FSF gzip compression */
-/* #define COMPRESS_EXTENSION ".gz" */		/* normal gzip extension */
+#define COMPRESS "/usr/bin/gzip" /* FSF gzip compression */
+#define COMPRESS_EXTENSION ".gz" 	/* normal gzip extension */
 #endif
 
@@ -186,5 +191,5 @@
  *	for detailed configuration.
  */
-/* #define DLB */	/* not supported on all platforms */
+#define DLB /* not supported on all platforms */
 
 /*
@@ -215,5 +220,5 @@
  * Of course SECURE is meaningful only if HACKDIR is defined.
  */
-/* #define SECURE */	/* do setuid(getuid()) after chdir() */
+#define SECURE 	/* do setuid(getuid()) after chdir() */
 
 /*
@@ -301,5 +306,5 @@
  */
 
-/* #define VISION_TABLES */ /* use vision tables generated at compile time */
+#define VISION_TABLES /* use vision tables generated at compile time */
 #ifndef VISION_TABLES
 # ifndef NO_MACRO_CPATH
@@ -328,4 +333,5 @@
 /* difficulty */
 #define ELBERETH	/* Engraving the E-word repels monsters */
+#define SORTLOOT
 /* I/O */
 #define REDO		/* support for redoing last command - DGK */
@@ -339,5 +345,25 @@
 
 #define EXP_ON_BOTL	/* Show experience on bottom line */
-/* #define SCORE_ON_BOTL */	/* added by Gary Erickson (erickson@ucivax) */
+#define SCORE_ON_BOTL /* added by Gary Erickson (erickson@ucivax) */
+
+/* #define REALTIME_ON_BOTL */  /* Show elapsed time on bottom line.  Note:
+                                 * this breaks savefile compatibility. */
+
+/* The options in this section require the extended logfile support */
+#ifdef XLOGFILE
+#define RECORD_CONDUCT  /* Record conducts kept in logfile */
+#define RECORD_TURNS    /* Record turns elapsed in logfile */
+#define RECORD_ACHIEVE  /* Record certain notable achievements in the
+                         * logfile.  Note: this breaks savefile compatibility
+                         * due to the addition of the u_achieve struct. */
+#define RECORD_REALTIME /* Record the amount of actual playing time (in
+                         * seconds) in the record file.  Note: this breaks
+                         * savefile compatibility. */
+#define RECORD_START_END_TIME /* Record to-the-second starting and ending
+                               * times; stored as 32-bit values obtained
+                               * from time(2) (seconds since the Epoch.) */
+#define RECORD_GENDER0   /* Record initial gender in logfile */
+#define RECORD_ALIGN0   /* Record initial alignment in logfile */
+#endif
 
 /*
@@ -349,6 +375,23 @@
  */
 
-/*#define GOLDOBJ */	/* Gold is kept on obj chains - Helge Hafting */
-/*#define AUTOPICKUP_EXCEPTIONS */ /* exceptions to autopickup */
+#if defined(TTY_GRAPHICS) || defined(MSWIN_GRAPHICS)
+# define MENU_COLOR
+# define MENU_COLOR_REGEX
+/* if MENU_COLOR_REGEX is defined, use regular expressions (regex.h,
+ * GNU specific functions by default, POSIX functions with
+ * MENU_COLOR_REGEX_POSIX).
+ *
+ * POSIX is required for OSX and possibly others.
+ *
+ * otherwise use pmatch() to match menu color lines.
+ * pmatch() provides basic globbing: '*' and '?' wildcards.
+ */
+#endif
+
+#define STATUS_COLORS
+#define GOLDOBJ /* Gold is kept on obj chains - Helge Hafting */
+#define AUTOPICKUP_EXCEPTIONS /* exceptions to autopickup */
+#define WHEREIS_FILE /* Write out player's current location to player.whereis */
+#define WISH_TRACKER /* Write all wishes to a tracking file */
 
 /* End of Section 5 */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/decl.h nethack/include/decl.h
--- nh_orig/include/decl.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/decl.h	2010-04-26 14:16:44.738840681 -0400
@@ -28,4 +28,5 @@
 
 E NEARDATA int multi;
+E char multi_txt[BUFSZ];
 #if 0
 E NEARDATA int warnlevel;
@@ -73,4 +74,8 @@
     d_level	d_qstart_level, d_qlocate_level, d_nemesis_level;
     d_level	d_knox_level;
+#ifdef RECORD_ACHIEVE
+    d_level     d_mineend_level;
+    d_level     d_sokoend_level;
+#endif
 } dungeon_topology;
 /* macros for accesing the dungeon levels by their old names */
@@ -105,4 +110,8 @@
 #define nemesis_level		(dungeon_topology.d_nemesis_level)
 #define knox_level		(dungeon_topology.d_knox_level)
+#ifdef RECORD_ACHIEVE
+#define mineend_level           (dungeon_topology.d_mineend_level)
+#define sokoend_level           (dungeon_topology.d_sokoend_level)
+#endif
 
 E NEARDATA stairway dnstair, upstair;		/* stairs up and down */
@@ -185,4 +194,7 @@
 #endif
 E char killer_buf[BUFSZ];
+#ifdef DUMP_LOG
+E char dump_fn[];		/* dumpfile name (dump patch) */
+#endif
 E const char *configfile;
 E NEARDATA char plname[PL_NSIZ];
@@ -244,5 +256,5 @@
 #endif
 	*uskin, *uamul, *uleft, *uright, *ublindf,
-	*uwep, *uswapwep, *uquiver;
+	*uwep, *uswapwep, *uquiver, *ulauncher;
 
 E NEARDATA struct obj *uchain;		/* defined only when punished */
@@ -252,4 +264,7 @@
 E NEARDATA struct obj zeroobj;		/* init'd and defined in decl.c */
 
+#include "engrave.h"
+E struct engr *head_engr;
+
 #include "you.h"
 E NEARDATA struct you u;
@@ -262,4 +277,6 @@
 E NEARDATA struct monst youmonst;	/* init'd and defined in decl.c */
 E NEARDATA struct monst *mydogs, *migrating_mons;
+E NEARDATA struct monst* polemonst;
+E NEARDATA struct monst* ukiller;
 
 E NEARDATA struct mvitals {
@@ -386,4 +403,38 @@
 #endif /* AUTOPICKUP_EXCEPTIONS */
 
+#ifdef RECORD_ACHIEVE
+struct u_achieve {
+        Bitfield(get_bell,1);        /* You have obtained the bell of 
+                                      * opening */
+        Bitfield(get_candelabrum,1); /* You have obtained the candelabrum */
+        Bitfield(get_book,1);        /* You have obtained the book of 
+                                      * the dead */
+        Bitfield(enter_gehennom,1);  /* Entered Gehennom (including the 
+                                      * Valley) by any means */
+        Bitfield(perform_invocation,1); /* You have performed the invocation
+                                         * ritual */
+        Bitfield(get_amulet,1);      /* You have obtained the amulet
+                                      * of Yendor */
+        Bitfield(ascended,1);        /* You ascended to demigod[dess]hood.
+                                      * Not quite the same as 
+                                      * u.uevent.ascended. */
+        Bitfield(get_luckstone,1);   /* You obtained the luckstone at the
+                                      * end of the mines. */
+        Bitfield(finish_sokoban,1);  /* You obtained the sokoban prize. */
+        Bitfield(killed_medusa,1);   /* You defeated Medusa. */
+};
+
+E struct u_achieve achieve;
+#endif
+
+#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)
+E struct realtime_data {
+  time_t realtime;    /* Amount of actual playing time up until the last time
+                       * the game was restored. */
+  time_t restoretime; /* The time that the game was started or restored. */
+  time_t last_displayed_time; /* Last time displayed on the status line */
+} realtime_data;
+#endif /* RECORD_REALTIME || REALTIME_ON_BOTL */
+
 #undef E
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/decl.h.~1~ nethack/include/decl.h.~1~
--- nh_orig/include/decl.h.~1~	1969-12-31 19:00:00.000000000 -0500
+++ nethack/include/decl.h.~1~	2009-11-22 07:19:36.043482113 -0500
@@ -0,0 +1,441 @@
+/*	SCCS Id: @(#)decl.h	3.4	2001/12/10	*/
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* NetHack may be freely redistributed.  See license for details. */
+
+#ifndef DECL_H
+#define DECL_H
+
+#define E extern
+
+E int NDECL((*occupation));
+E int NDECL((*afternmv));
+
+E const char *hname;
+E int hackpid;
+#if defined(UNIX) || defined(VMS)
+E int locknum;
+#endif
+#ifdef DEF_PAGER
+E char *catmore;
+#endif	/* DEF_PAGER */
+
+E char SAVEF[];
+#ifdef MICRO
+E char SAVEP[];
+#endif
+
+E NEARDATA int bases[MAXOCLASSES];
+
+E NEARDATA int multi;
+E char multi_txt[BUFSZ];
+#if 0
+E NEARDATA int warnlevel;
+#endif
+E NEARDATA int nroom;
+E NEARDATA int nsubroom;
+E NEARDATA int occtime;
+
+#define WARNCOUNT 6			/* number of different warning levels */
+E uchar warnsyms[WARNCOUNT];
+
+E int x_maze_max, y_maze_max;
+E int otg_temp;
+
+#ifdef REDO
+E NEARDATA int in_doagain;
+#endif
+
+E struct dgn_topology {		/* special dungeon levels for speed */
+    d_level	d_oracle_level;
+    d_level	d_bigroom_level;	/* unused */
+#ifdef REINCARNATION
+    d_level	d_rogue_level;
+#endif
+    d_level	d_medusa_level;
+    d_level	d_stronghold_level;
+    d_level	d_valley_level;
+    d_level	d_wiz1_level;
+    d_level	d_wiz2_level;
+    d_level	d_wiz3_level;
+    d_level	d_juiblex_level;
+    d_level	d_orcus_level;
+    d_level	d_baalzebub_level;	/* unused */
+    d_level	d_asmodeus_level;	/* unused */
+    d_level	d_portal_level;		/* only in goto_level() [do.c] */
+    d_level	d_sanctum_level;
+    d_level	d_earth_level;
+    d_level	d_water_level;
+    d_level	d_fire_level;
+    d_level	d_air_level;
+    d_level	d_astral_level;
+    xchar	d_tower_dnum;
+    xchar	d_sokoban_dnum;
+    xchar	d_mines_dnum, d_quest_dnum;
+    d_level	d_qstart_level, d_qlocate_level, d_nemesis_level;
+    d_level	d_knox_level;
+#ifdef RECORD_ACHIEVE
+    d_level     d_mineend_level;
+    d_level     d_sokoend_level;
+#endif
+} dungeon_topology;
+/* macros for accesing the dungeon levels by their old names */
+#define oracle_level		(dungeon_topology.d_oracle_level)
+#define bigroom_level		(dungeon_topology.d_bigroom_level)
+#ifdef REINCARNATION
+#define rogue_level		(dungeon_topology.d_rogue_level)
+#endif
+#define medusa_level		(dungeon_topology.d_medusa_level)
+#define stronghold_level	(dungeon_topology.d_stronghold_level)
+#define valley_level		(dungeon_topology.d_valley_level)
+#define wiz1_level		(dungeon_topology.d_wiz1_level)
+#define wiz2_level		(dungeon_topology.d_wiz2_level)
+#define wiz3_level		(dungeon_topology.d_wiz3_level)
+#define juiblex_level		(dungeon_topology.d_juiblex_level)
+#define orcus_level		(dungeon_topology.d_orcus_level)
+#define baalzebub_level		(dungeon_topology.d_baalzebub_level)
+#define asmodeus_level		(dungeon_topology.d_asmodeus_level)
+#define portal_level		(dungeon_topology.d_portal_level)
+#define sanctum_level		(dungeon_topology.d_sanctum_level)
+#define earth_level		(dungeon_topology.d_earth_level)
+#define water_level		(dungeon_topology.d_water_level)
+#define fire_level		(dungeon_topology.d_fire_level)
+#define air_level		(dungeon_topology.d_air_level)
+#define astral_level		(dungeon_topology.d_astral_level)
+#define tower_dnum		(dungeon_topology.d_tower_dnum)
+#define sokoban_dnum		(dungeon_topology.d_sokoban_dnum)
+#define mines_dnum		(dungeon_topology.d_mines_dnum)
+#define quest_dnum		(dungeon_topology.d_quest_dnum)
+#define qstart_level		(dungeon_topology.d_qstart_level)
+#define qlocate_level		(dungeon_topology.d_qlocate_level)
+#define nemesis_level		(dungeon_topology.d_nemesis_level)
+#define knox_level		(dungeon_topology.d_knox_level)
+#ifdef RECORD_ACHIEVE
+#define mineend_level           (dungeon_topology.d_mineend_level)
+#define sokoend_level           (dungeon_topology.d_sokoend_level)
+#endif
+
+E NEARDATA stairway dnstair, upstair;		/* stairs up and down */
+#define xdnstair	(dnstair.sx)
+#define ydnstair	(dnstair.sy)
+#define xupstair	(upstair.sx)
+#define yupstair	(upstair.sy)
+
+E NEARDATA stairway dnladder, upladder;		/* ladders up and down */
+#define xdnladder	(dnladder.sx)
+#define ydnladder	(dnladder.sy)
+#define xupladder	(upladder.sx)
+#define yupladder	(upladder.sy)
+
+E NEARDATA stairway sstairs;
+
+E NEARDATA dest_area updest, dndest;	/* level-change destination areas */
+
+E NEARDATA coord inv_pos;
+E NEARDATA dungeon dungeons[];
+E NEARDATA s_level *sp_levchn;
+#define dunlev_reached(x)	(dungeons[(x)->dnum].dunlev_ureached)
+
+#include "quest.h"
+E struct q_score quest_status;
+
+E NEARDATA char pl_character[PL_CSIZ];
+E NEARDATA char pl_race;		/* character's race */
+
+E NEARDATA char pl_fruit[PL_FSIZ];
+E NEARDATA int current_fruit;
+E NEARDATA struct fruit *ffruit;
+
+E NEARDATA char tune[6];
+
+#define MAXLINFO (MAXDUNGEON * MAXLEVEL)
+E struct linfo level_info[MAXLINFO];
+
+E NEARDATA struct sinfo {
+	int gameover;		/* self explanatory? */
+	int stopprint;		/* inhibit further end of game disclosure */
+#if defined(UNIX) || defined(VMS) || defined (__EMX__) || defined(WIN32)
+	int done_hup;		/* SIGHUP or moral equivalent received
+				 * -- no more screen output */
+#endif
+	int something_worth_saving;	/* in case of panic */
+	int panicking;		/* `panic' is in progress */
+#if defined(VMS) || defined(WIN32)
+	int exiting;		/* an exit handler is executing */
+#endif
+	int in_impossible;
+#ifdef PANICLOG
+	int in_paniclog;
+#endif
+} program_state;
+
+E boolean restoring;
+
+E const char quitchars[];
+E const char vowels[];
+E const char ynchars[];
+E const char ynqchars[];
+E const char ynaqchars[];
+E const char ynNaqchars[];
+E NEARDATA long yn_number;
+
+E const char disclosure_options[];
+
+E NEARDATA int smeq[];
+E NEARDATA int doorindex;
+E NEARDATA char *save_cm;
+#define KILLED_BY_AN	 0
+#define KILLED_BY	 1
+#define NO_KILLER_PREFIX 2
+E NEARDATA int killer_format;
+E const char *killer;
+E const char *delayed_killer;
+#ifdef GOLDOBJ
+E long done_money;
+#endif
+E char killer_buf[BUFSZ];
+#ifdef DUMP_LOG
+E char dump_fn[];		/* dumpfile name (dump patch) */
+#endif
+E const char *configfile;
+E NEARDATA char plname[PL_NSIZ];
+E NEARDATA char dogname[];
+E NEARDATA char catname[];
+E NEARDATA char horsename[];
+E char preferred_pet;
+E const char *occtxt;			/* defined when occupation != NULL */
+E const char *nomovemsg;
+E const char nul[];
+E char lock[];
+
+E const char sdir[], ndir[];
+E const schar xdir[], ydir[], zdir[];
+
+E NEARDATA schar tbx, tby;		/* set in mthrowu.c */
+
+E NEARDATA struct multishot { int n, i; short o; boolean s; } m_shot;
+
+E NEARDATA struct dig_info {		/* apply.c, hack.c */
+	int	effort;
+	d_level level;
+	coord	pos;
+	long lastdigtime;
+	boolean down, chew, warned, quiet;
+} digging;
+
+E NEARDATA long moves, monstermoves;
+E NEARDATA long wailmsg;
+
+E NEARDATA boolean in_mklev;
+E NEARDATA boolean stoned;
+E NEARDATA boolean unweapon;
+E NEARDATA boolean mrg_to_wielded;
+E NEARDATA struct obj *current_wand;
+
+E NEARDATA boolean in_steed_dismounting;
+
+E const int shield_static[];
+
+#include "spell.h"
+E NEARDATA struct spell spl_book[];	/* sized in decl.c */
+
+#include "color.h"
+#ifdef TEXTCOLOR
+E const int zapcolors[];
+#endif
+
+E const char def_oc_syms[MAXOCLASSES];	/* default class symbols */
+E uchar oc_syms[MAXOCLASSES];		/* current class symbols */
+E const char def_monsyms[MAXMCLASSES];	/* default class symbols */
+E uchar monsyms[MAXMCLASSES];		/* current class symbols */
+
+#include "obj.h"
+E NEARDATA struct obj *invent,
+	*uarm, *uarmc, *uarmh, *uarms, *uarmg, *uarmf,
+#ifdef TOURIST
+	*uarmu,				/* under-wear, so to speak */
+#endif
+	*uskin, *uamul, *uleft, *uright, *ublindf,
+	*uwep, *uswapwep, *uquiver, *ulauncher;
+
+E NEARDATA struct obj *uchain;		/* defined only when punished */
+E NEARDATA struct obj *uball;
+E NEARDATA struct obj *migrating_objs;
+E NEARDATA struct obj *billobjs;
+E NEARDATA struct obj zeroobj;		/* init'd and defined in decl.c */
+
+#include "engrave.h"
+E struct engr *head_engr;
+
+#include "you.h"
+E NEARDATA struct you u;
+
+#include "onames.h"
+#ifndef PM_H		/* (pm.h has already been included via youprop.h) */
+#include "pm.h"
+#endif
+
+E NEARDATA struct monst youmonst;	/* init'd and defined in decl.c */
+E NEARDATA struct monst *mydogs, *migrating_mons;
+E NEARDATA struct monst* polemonst;
+E NEARDATA struct monst* ukiller;
+
+E NEARDATA struct mvitals {
+	uchar	born;
+	uchar	died;
+	uchar	mvflags;
+} mvitals[NUMMONS];
+
+E NEARDATA struct c_color_names {
+    const char	*const c_black, *const c_amber, *const c_golden,
+		*const c_light_blue,*const c_red, *const c_green,
+		*const c_silver, *const c_blue, *const c_purple,
+		*const c_white;
+} c_color_names;
+#define NH_BLACK		c_color_names.c_black
+#define NH_AMBER		c_color_names.c_amber
+#define NH_GOLDEN		c_color_names.c_golden
+#define NH_LIGHT_BLUE		c_color_names.c_light_blue
+#define NH_RED			c_color_names.c_red
+#define NH_GREEN		c_color_names.c_green
+#define NH_SILVER		c_color_names.c_silver
+#define NH_BLUE			c_color_names.c_blue
+#define NH_PURPLE		c_color_names.c_purple
+#define NH_WHITE		c_color_names.c_white
+
+/* The names of the colors used for gems, etc. */
+E const char *c_obj_colors[];
+
+E struct c_common_strings {
+    const char	*const c_nothing_happens, *const c_thats_enough_tries,
+		*const c_silly_thing_to, *const c_shudder_for_moment,
+		*const c_something, *const c_Something,
+		*const c_You_can_move_again,
+		*const c_Never_mind, *c_vision_clears,
+		*const c_the_your[2];
+} c_common_strings;
+#define nothing_happens    c_common_strings.c_nothing_happens
+#define thats_enough_tries c_common_strings.c_thats_enough_tries
+#define silly_thing_to	   c_common_strings.c_silly_thing_to
+#define shudder_for_moment c_common_strings.c_shudder_for_moment
+#define something	   c_common_strings.c_something
+#define Something	   c_common_strings.c_Something
+#define You_can_move_again c_common_strings.c_You_can_move_again
+#define Never_mind	   c_common_strings.c_Never_mind
+#define vision_clears	   c_common_strings.c_vision_clears
+#define the_your	   c_common_strings.c_the_your
+
+/* material strings */
+E const char *materialnm[];
+
+/* Monster name articles */
+#define ARTICLE_NONE	0
+#define ARTICLE_THE	1
+#define ARTICLE_A	2
+#define ARTICLE_YOUR	3
+
+/* Monster name suppress masks */
+#define SUPPRESS_IT		0x01
+#define SUPPRESS_INVISIBLE	0x02
+#define SUPPRESS_HALLUCINATION  0x04
+#define SUPPRESS_SADDLE		0x08
+#define EXACT_NAME		0x0F
+
+/* Vision */
+E NEARDATA boolean vision_full_recalc;	/* TRUE if need vision recalc */
+E NEARDATA char **viz_array;		/* could see/in sight row pointers */
+
+/* Window system stuff */
+E NEARDATA winid WIN_MESSAGE, WIN_STATUS;
+E NEARDATA winid WIN_MAP, WIN_INVEN;
+E char toplines[];
+#ifndef TCAP_H
+E struct tc_gbl_data {	/* also declared in tcap.h */
+    char *tc_AS, *tc_AE;	/* graphics start and end (tty font swapping) */
+    int   tc_LI,  tc_CO;	/* lines and columns */
+} tc_gbl_data;
+#define AS tc_gbl_data.tc_AS
+#define AE tc_gbl_data.tc_AE
+#define LI tc_gbl_data.tc_LI
+#define CO tc_gbl_data.tc_CO
+#endif
+
+/* xxxexplain[] is in drawing.c */
+E const char * const monexplain[], invisexplain[], * const objexplain[], * const oclass_names[];
+
+/* Some systems want to use full pathnames for some subsets of file names,
+ * rather than assuming that they're all in the current directory.  This
+ * provides all the subclasses that seem reasonable, and sets up for all
+ * prefixes being null.  Port code can set those that it wants.
+ */
+#define HACKPREFIX	0
+#define LEVELPREFIX	1
+#define SAVEPREFIX	2
+#define BONESPREFIX	3
+#define DATAPREFIX	4	/* this one must match hardcoded value in dlb.c */
+#define SCOREPREFIX	5
+#define LOCKPREFIX	6
+#define CONFIGPREFIX	7
+#define TROUBLEPREFIX	8
+#define PREFIX_COUNT	9
+/* used in files.c; xxconf.h can override if needed */
+# ifndef FQN_MAX_FILENAME
+#define FQN_MAX_FILENAME 512
+# endif
+
+#if defined(NOCWD_ASSUMPTIONS) || defined(VAR_PLAYGROUND)
+/* the bare-bones stuff is unconditional above to simplify coding; for
+ * ports that actually use prefixes, add some more localized things
+ */
+#define PREFIXES_IN_USE
+#endif
+
+E char *fqn_prefix[PREFIX_COUNT];
+#ifdef PREFIXES_IN_USE
+E char *fqn_prefix_names[PREFIX_COUNT];
+#endif
+
+#ifdef AUTOPICKUP_EXCEPTIONS
+struct autopickup_exception {
+	char *pattern;
+	boolean grab;
+	struct autopickup_exception *next;
+};
+#endif /* AUTOPICKUP_EXCEPTIONS */
+
+#ifdef RECORD_ACHIEVE
+struct u_achieve {
+        Bitfield(get_bell,1);        /* You have obtained the bell of 
+                                      * opening */
+        Bitfield(get_candelabrum,1); /* You have obtained the candelabrum */
+        Bitfield(get_book,1);        /* You have obtained the book of 
+                                      * the dead */
+        Bitfield(enter_gehennom,1);  /* Entered Gehennom (including the 
+                                      * Valley) by any means */
+        Bitfield(perform_invocation,1); /* You have performed the invocation
+                                         * ritual */
+        Bitfield(get_amulet,1);      /* You have obtained the amulet
+                                      * of Yendor */
+        Bitfield(ascended,1);        /* You ascended to demigod[dess]hood.
+                                      * Not quite the same as 
+                                      * u.uevent.ascended. */
+        Bitfield(get_luckstone,1);   /* You obtained the luckstone at the
+                                      * end of the mines. */
+        Bitfield(finish_sokoban,1);  /* You obtained the sokoban prize. */
+        Bitfield(killed_medusa,1);   /* You defeated Medusa. */
+};
+
+E struct u_achieve achieve;
+#endif
+
+#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)
+E struct realtime_data {
+  time_t realtime;    /* Amount of actual playing time up until the last time
+                       * the game was restored. */
+  time_t restoretime; /* The time that the game was started or restored. */
+  time_t last_displayed_time; /* Last time displayed on the status line */
+} realtime_data;
+#endif /* RECORD_REALTIME || REALTIME_ON_BOTL */
+
+#undef E
+
+#endif /* DECL_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/display.h nethack/include/display.h
--- nh_orig/include/display.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/display.h	2010-03-24 12:55:58.944626078 -0400
@@ -27,5 +27,5 @@
 #define tp_sensemon(mon) (	/* The hero can always sense a monster IF:  */\
     (!mindless(mon->data)) &&	/* 1. the monster has a brain to sense AND  */\
-      ((Blind && Blind_telepat) ||	/* 2a. hero is blind and telepathic OR	    */\
+    ((Blind && Blind_telepat && (distu(mon->mx, mon->my) <= u.u_telepathy_dist)) ||	/* 2a. hero is blind and telepathic OR	    */ \
 				/* 2b. hero is using a telepathy inducing   */\
 				/*	 object and in range		    */\
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/dungeon.h nethack/include/dungeon.h
--- nh_orig/include/dungeon.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/dungeon.h	2009-09-07 11:23:57.339293253 -0400
@@ -122,4 +122,8 @@
 #define Is_nemesis(x)		(on_level(x, &nemesis_level))
 #define Is_knox(x)		(on_level(x, &knox_level))
+#ifdef RECORD_ACHIEVE
+#define Is_mineend_level(x)     (on_level(x, &mineend_level))
+#define Is_sokoend_level(x)     (on_level(x, &sokoend_level))
+#endif
 
 #define In_sokoban(x)		((x)->dnum == sokoban_dnum)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/eshk.h nethack/include/eshk.h
--- nh_orig/include/eshk.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/eshk.h	2009-11-23 13:59:51.796398963 -0500
@@ -43,3 +43,6 @@
 #define ANGRY(mon)	(!NOTANGRY(mon))
 
+#define match_shkrace(mon) ((urace.malenum == (mon)->mnum) || \
+				(urace.malenum == PM_ELF && (mon)->mnum == PM_GREEN_ELF))
+
 #endif /* ESHK_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/extern.h nethack/include/extern.h
--- nh_orig/include/extern.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/extern.h	2010-08-16 13:20:13.101707800 -0400
@@ -26,4 +26,7 @@
 E void NDECL(newgame);
 E void FDECL(welcome, (BOOLEAN_P));
+#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)
+E time_t NDECL(get_realtime);
+#endif
 
 /* ### apply.c ### */
@@ -132,4 +135,8 @@
 E const char *FDECL(rank_of, (int,SHORT_P,BOOLEAN_P));
 E void NDECL(bot);
+#ifdef DUMP_LOG
+E void FDECL(bot1str, (char *));
+E void FDECL(bot2str, (char *));
+#endif
 
 /* ### cmd.c ### */
@@ -167,4 +174,8 @@
 E void FDECL(enlightenment, (int));
 E void FDECL(show_conduct, (int));
+#ifdef DUMP_LOG
+E void FDECL(dump_enlightenment, (int));
+E void FDECL(dump_conduct, (int));
+#endif
 E int FDECL(xytod, (SCHAR_P,SCHAR_P));
 E void FDECL(dtoxy, (coord *,int));
@@ -243,4 +254,5 @@
 E void FDECL(rot_organic, (genericptr_t, long));
 E void FDECL(rot_corpse, (genericptr_t, long));
+E void NDECL(get_coal);
 #if 0
 E void FDECL(bury_monst, (struct monst *));
@@ -282,4 +294,7 @@
 E void NDECL(cls);
 E void FDECL(flush_screen, (int));
+#ifdef DUMP_LOG
+E void NDECL(dump_screen);
+#endif
 E int FDECL(back_to_glyph, (XCHAR_P,XCHAR_P));
 E int FDECL(zapdir_to_glyph, (int,int,int));
@@ -434,4 +449,6 @@
 /* ### dothrow.c ### */
 
+E int NDECL(boom_flightpath_menu);
+E struct monst * FDECL(camera_demon, (struct obj *,SCHAR_P, SCHAR_P));
 E int NDECL(dothrow);
 E int NDECL(dofire);
@@ -517,4 +534,5 @@
 E int NDECL(unfaint);
 #endif
+E char * FDECL(tin_content_text, (struct obj *));
 E boolean FDECL(is_edible, (struct obj *));
 E void NDECL(init_uhunger);
@@ -554,4 +572,8 @@
 E void FDECL(done, (int));
 E void FDECL(container_contents, (struct obj *,BOOLEAN_P,BOOLEAN_P));
+#ifdef DUMP_LOG
+E void FDECL(dump, (char *, char *));
+E void FDECL(do_containerconts, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
+#endif
 E void FDECL(terminate, (int));
 E int NDECL(num_genocides);
@@ -661,4 +683,12 @@
 E void NDECL(really_close);
 #endif
+#ifdef WHEREIS_FILE
+E void NDECL(touch_whereis);
+E void NDECL(delete_whereis);
+#endif
+#ifdef WISH_TRACKER
+E void FDECL(trackwish,(char *));
+E void FDECL(makeannounce,(char *));
+#endif
 
 /* ### fountain.c ### */
@@ -695,7 +725,8 @@
 E void NDECL(lookaround);
 E int NDECL(monster_nearby);
-E void FDECL(nomul, (int));
+E void FDECL(nomul, (int, const char *));
 E void FDECL(unmul, (const char *));
 E void FDECL(losehp, (int,const char *,BOOLEAN_P));
+E int FDECL(gainmaxhp, (int));
 E int NDECL(weight_cap);
 E int NDECL(inv_weight);
@@ -718,4 +749,6 @@
 E char *FDECL(upstart, (char *));
 E char *FDECL(mungspaces, (char *));
+E char *FDECL(stripctrl, (char *));
+E char *FDECL(trim, (char *));
 E char *FDECL(eos, (char *));
 E char *FDECL(strkitten, (char *,CHAR_P));
@@ -748,4 +781,5 @@
 E int NDECL(phase_of_the_moon);
 E boolean NDECL(friday_13th);
+E boolean NDECL(christmas);
 E int NDECL(night);
 E int NDECL(midnight);
@@ -791,4 +825,7 @@
 E int NDECL(ddoinv);
 E char FDECL(display_inventory, (const char *,BOOLEAN_P));
+#ifdef DUMP_LOG
+E char FDECL(dump_inventory, (const char *,BOOLEAN_P,BOOLEAN_P));
+#endif
 E int FDECL(display_binventory, (int,int,BOOLEAN_P));
 E struct obj *FDECL(display_cinventory,(struct obj *));
@@ -809,5 +846,5 @@
 E int NDECL(doprinuse);
 E void FDECL(useupf, (struct obj *,long));
-E char *FDECL(let_to_name, (CHAR_P,BOOLEAN_P));
+E char *FDECL(let_to_name, (CHAR_P,BOOLEAN_P,BOOLEAN_P));
 E void NDECL(free_invbuf);
 E void NDECL(reassign);
@@ -860,5 +897,5 @@
 E boolean FDECL(picking_at, (int,int));
 E void NDECL(reset_pick);
-E int FDECL(pick_lock, (struct obj *));
+E int FDECL(pick_lock, (struct obj *,int,int));
 E int NDECL(doforce);
 E boolean FDECL(boxlock, (struct obj *,struct obj *));
@@ -909,4 +946,5 @@
 /* ### mail.c ### */
 
+E void NDECL(ck_server_admin_msg);
 #ifdef MAIL
 # ifdef UNIX
@@ -953,4 +991,5 @@
 
 E int FDECL(fightm, (struct monst *));
+E boolean FDECL(resist_conflict, (struct monst *));
 E int FDECL(mattackm, (struct monst *,struct monst *));
 E int FDECL(noattacks, (struct permonst *));
@@ -996,6 +1035,7 @@
 E void FDECL(add_subroom, (struct mkroom *,int,int,int,int,
 			   BOOLEAN_P,SCHAR_P,BOOLEAN_P));
-E void NDECL(makecorridors);
+E void FDECL(makecorridors, (int));
 E void FDECL(add_door, (int,int,struct mkroom *));
+E void NDECL(mkpoolroom);
 E void NDECL(mklev);
 #ifdef SPECIALIZATION
@@ -1011,4 +1051,5 @@
 E void FDECL(mkstairs, (XCHAR_P,XCHAR_P,CHAR_P,struct mkroom *));
 E void NDECL(mkinvokearea);
+E void FDECL(wallwalk_right, (XCHAR_P,XCHAR_P,SCHAR_P,SCHAR_P,SCHAR_P,int));
 
 /* ### mkmap.c ### */
@@ -1020,5 +1061,6 @@
 
 E void FDECL(wallification, (int,int,int,int));
-E void FDECL(walkfrom, (int,int));
+E void FDECL(wall_extends, (int,int,int,int));
+E void FDECL(walkfrom, (int,int, SCHAR_P));
 E void FDECL(makemaz, (const char *));
 E void FDECL(mazexy, (coord *));
@@ -1072,4 +1114,5 @@
 E int FDECL(add_to_minv, (struct monst *, struct obj *));
 E struct obj *FDECL(add_to_container, (struct obj *, struct obj *));
+E long FDECL(get_container_weight, (struct obj *));
 E void FDECL(add_to_migration, (struct obj *));
 E void FDECL(add_to_buried, (struct obj *));
@@ -1083,4 +1126,5 @@
 /* ### mkroom.c ### */
 
+E struct mkroom * FDECL(pick_room,(BOOLEAN_P));
 E void FDECL(mkroom, (int));
 E void FDECL(fill_zoo, (struct mkroom *));
@@ -1100,4 +1144,5 @@
 /* ### mon.c ### */
 
+E void FDECL(remove_monster, (int, int));
 E int FDECL(undead_to_corpse, (int));
 E int FDECL(genus, (int,int));
@@ -1152,4 +1197,5 @@
 E boolean FDECL(angry_guards, (BOOLEAN_P));
 E void NDECL(pacify_guards);
+E boolean FDECL(damage_mon,(struct monst*,int,int));
 
 /* ### mondata.c ### */
@@ -1162,4 +1208,5 @@
 E boolean FDECL(resists_magm, (struct monst *));
 E boolean FDECL(resists_blnd, (struct monst *));
+E boolean FDECL(vulnerable_to, (struct monst *,int));
 E boolean FDECL(can_blnd, (struct monst *,struct monst *,UCHAR_P,struct obj *));
 E boolean FDECL(ranged_attk, (struct permonst *));
@@ -1212,4 +1259,5 @@
 /* ### mplayer.c ### */
 
+E const char *FDECL(elf_name, (size_t));
 E struct monst *FDECL(mk_mplayer, (struct permonst *,XCHAR_P,
 				   XCHAR_P,BOOLEAN_P));
@@ -1358,7 +1406,12 @@
 E boolean FDECL(the_unique_obj, (struct obj *obj));
 E char *FDECL(doname, (struct obj *));
+E char *FDECL(doname_with_price, (struct obj *));
 E boolean FDECL(not_fully_identified, (struct obj *));
 E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));
 E char *FDECL(cxname, (struct obj *));
+E void FDECL(add_erosion_words, (struct obj *, char *));
+#ifdef SORTLOOT
+E char *FDECL(cxname2, (struct obj *));
+#endif
 E char *FDECL(killer_xname, (struct obj *));
 E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P)));
@@ -1406,4 +1459,7 @@
 E void NDECL(free_autopickup_exceptions);
 #endif /* AUTOPICKUP_EXCEPTIONS */
+#ifdef MENU_COLOR
+E boolean FDECL(add_menu_coloring, (char *));
+#endif /* MENU_COLOR */
 
 /* ### pager.c ### */
@@ -1544,4 +1600,8 @@
 E void FDECL(set_itimeout, (long *,long));
 E void FDECL(incr_itimeout, (long *,int));
+E void FDECL(incr_resistance, (long *,int));
+E void FDECL(decr_resistance, (long *,int));
+E int FDECL(how_resistant, (int));
+E int FDECL(resist_reduce, (int,int));
 E void FDECL(make_confused, (long,BOOLEAN_P));
 E void FDECL(make_stunned, (long,BOOLEAN_P));
@@ -1624,5 +1684,5 @@
 E void FDECL(com_pager, (int));
 E void FDECL(qt_pager, (int));
-E struct permonst *NDECL(qt_montype);
+E char *FDECL(string_subst, (char *));
 
 /* ### random.c ### */
@@ -1677,5 +1737,5 @@
 E void FDECL(save_regions, (int,int));
 E void FDECL(rest_regions, (int,BOOLEAN_P));
-E NhRegion* FDECL(create_gas_cloud, (XCHAR_P, XCHAR_P, int, int));
+E NhRegion* FDECL(create_gas_cloud, (XCHAR_P, XCHAR_P, int, size_t));
 
 /* ### restore.c ### */
@@ -1827,8 +1887,10 @@
 E void FDECL(check_unpaid, (struct obj *));
 E void FDECL(costly_gold, (XCHAR_P,XCHAR_P,long));
+E long FDECL(get_cost_of_shop_item, (struct obj *));
 E boolean FDECL(block_door, (XCHAR_P,XCHAR_P));
 E boolean FDECL(block_entry, (XCHAR_P,XCHAR_P));
 E char *FDECL(shk_your, (char *,struct obj *));
 E char *FDECL(Shk_Your, (char *,struct obj *));
+E void FDECL(shk_holler, (struct monst*));
 
 /* ### shknam.c ### */
@@ -1941,4 +2003,5 @@
 E void FDECL(tele_trap, (struct trap *));
 E void FDECL(level_tele_trap, (struct trap *));
+E boolean FDECL(rloc_pos_ok, (int,int,struct monst *));
 E void FDECL(rloc_to, (struct monst *,int,int));
 E boolean FDECL(rloc, (struct monst *, BOOLEAN_P));
@@ -1987,4 +2050,7 @@
 
 E void FDECL(topten, (int));
+#ifdef LOGFILE
+E void FDECL(write_log_entry, (int,long));
+#endif
 E void FDECL(prscore, (int,char **));
 E struct obj *FDECL(tt_oname, (struct obj *));
@@ -2238,4 +2304,7 @@
 E int NDECL(dbon);
 E int NDECL(enhance_weapon_skill);
+#ifdef DUMP_LOG
+E void NDECL(dump_weapon_skill);
+#endif
 E void FDECL(unrestrict_weapon_skill, (int));
 E void FDECL(use_skill, (int,int));
@@ -2260,8 +2329,10 @@
 E void FDECL(setuwep, (struct obj *));
 E void FDECL(setuqwep, (struct obj *));
+E void FDECL(setulauncher, (struct obj *));
 E void FDECL(setuswapwep, (struct obj *));
 E int NDECL(dowield);
 E int NDECL(doswapweapon);
 E int NDECL(dowieldquiver);
+E int NDECL(dowieldlauncher);
 E boolean FDECL(wield_tool, (struct obj *,const char *));
 E int NDECL(can_twoweapon);
@@ -2271,6 +2342,8 @@
 E void NDECL(uswapwepgone);
 E void NDECL(uqwepgone);
+E void NDECL(ulwepgone);
 E void NDECL(untwoweapon);
-E void FDECL(erode_obj, (struct obj *,BOOLEAN_P,BOOLEAN_P));
+E boolean FDECL(_erode_obj, (struct obj *,int));
+E void FDECL(erode_obj, (struct obj *,BOOLEAN_P,BOOLEAN_P,BOOLEAN_P));
 E int FDECL(chwepon, (struct obj *,int));
 E int FDECL(welded, (struct obj *));
@@ -2293,5 +2366,5 @@
 E void NDECL(clonewiz);
 E int NDECL(pick_nasty);
-E int FDECL(nasty, (struct monst*));
+E int FDECL(nasty, (struct monst*,BOOLEAN_P));
 E void NDECL(resurrect);
 E void NDECL(intervene);
@@ -2369,9 +2442,9 @@
 E struct monst *FDECL(bhit, (int,int,int,int,int (*)(MONST_P,OBJ_P),
 			     int (*)(OBJ_P,OBJ_P),struct obj *));
-E struct monst *FDECL(boomhit, (int,int));
+E struct monst *FDECL(boomhit, (int,int,int));
 E int FDECL(burn_floor_paper, (int,int,BOOLEAN_P,BOOLEAN_P));
 E void FDECL(buzz, (int,int,XCHAR_P,XCHAR_P,int,int));
 E void FDECL(melt_ice, (XCHAR_P,XCHAR_P));
-E int FDECL(zap_over_floor, (XCHAR_P,XCHAR_P,int,boolean *));
+E int FDECL(zap_over_floor, (XCHAR_P,XCHAR_P,int,boolean *,boolean));
 E void FDECL(fracture_rock, (struct obj *));
 E boolean FDECL(break_statue, (struct obj *));
@@ -2380,4 +2453,7 @@
 E int FDECL(resist, (struct monst *,CHAR_P,int,int));
 E void NDECL(makewish);
+E void FDECL(monstseesu,(unsigned long));
+E void FDECL(monstseesulose,(unsigned long));
+E void NDECL(blindingflash);
 
 #endif /* !MAKEDEFS_C && !LEV_LEX_C */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/flag.h nethack/include/flag.h
--- nh_orig/include/flag.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/flag.h	2010-08-16 13:20:13.102707769 -0400
@@ -184,4 +184,10 @@
 	boolean  extmenu;	/* extended commands use menu interface */
 #endif
+#ifdef MENU_COLOR
+	boolean use_menu_color;	/* use color in menus; only if wc_color */
+#endif
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	boolean use_status_colors; /* use color in status line; only if wc_color */
+#endif
 #ifdef MFLOPPY
 	boolean  checkspace;	/* check disk space before writing files */
@@ -217,4 +223,7 @@
 	boolean lan_mail_fetched; /* mail is awaiting display */
 #endif
+#ifdef SORTLOOT
+	char sortloot;          /* sort items to loot alphabetically */
+#endif
 /*
  * Window capability support.
@@ -264,4 +273,6 @@
 	boolean wc2_softkeyboard;	/* use software keyboard */
 	boolean wc2_wraptext;		/* wrap text */
+	boolean wc2_darkgray;		/* try to use PC dark-gray color
+					 * to represent black object */
 
 	boolean  cmdassist;	/* provide detailed assistance for some commands */
@@ -270,5 +281,11 @@
 	boolean  lootabc;	/* use "a/b/c" rather than "o/i/b" when looting */
 	boolean  showrace;	/* show hero glyph by race rather than by role */
+	boolean  showobjsym;	/* show object class symbol in menus where available */
 	boolean  travelcmd;	/* allow travel command */
+	boolean  show_dgn_name; /* show dungeon names instead of Dlvl: on bottom line
+										 probably only good for people taking advantage of 
+										 the wide terminals allowed in Spork */
+    int boom_flight_path; /* boomerang flight path */
+
 	int	 runmode;	/* update screen display during run moves */
 #ifdef AUTOPICKUP_EXCEPTIONS
@@ -281,4 +298,8 @@
 	char	 altkeyhandler[MAX_ALTKEYHANDLER];
 #endif
+#ifdef REALTIME_ON_BOTL
+  boolean  showrealtime; /* show actual elapsed time */
+#endif
+    boolean  dark_room;	/* show shadows in lit rooms */
 };
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/global.h nethack/include/global.h
--- nh_orig/include/global.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/global.h	2009-09-07 09:52:23.773293399 -0400
@@ -237,4 +237,8 @@
 #endif
 
+#ifdef OSX
+# define MENU_COLOR_REGEX_POSIX
+#endif
+
 #ifdef VMS
 /* vms_exit() (sys/vms/vmsmisc.c) expects the non-VMS EXIT_xxx values below.
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/hack.h nethack/include/hack.h
--- nh_orig/include/hack.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/hack.h	2009-08-02 13:49:33.029408334 -0400
@@ -19,5 +19,5 @@
 #define ON		1
 #define OFF		0
-#define BOLT_LIM	8 /* from this distance ranged attacks will be made */
+#define BOLT_LIM	16 /* from this distance ranged attacks may be made */
 #define MAX_CARR_CAP	1000	/* so that boulders can be heavier */
 #define DUMMY { 0 }
@@ -100,7 +100,8 @@
 #define FLASHED_LIGHT	3
 #define INVIS_BEAM	4
-
 #define MATCH_WARN_OF_MON(mon)	 (Warn_of_mon && flags.warntype && \
-		   		 (flags.warntype & (mon)->data->mflags2))
+		   		 ((flags.warntype == (unsigned long)(mon)->data->mlet) || \
+						(flags.warntype == S_WERE && (mon)->data->mflags2 & M2_WERE) || \
+					   (flags.warntype == S_UNDEAD && (mon)->data->mflags2 & M2_UNDEAD)))
 
 #include "trap.h"
@@ -142,4 +143,5 @@
 #define MM_IGNOREWATER	  0x80	/* ignore water when positioning */
 #define MM_ADJACENTOK	  0x100 /* it is acceptable to use adjacent coordinates */
+#define MM_UNSAFEOK		  0x200 /* potentially dangerous locations (lava) are OK */
 
 /* special mhpmax value when loading bones monster to flag as extinct or genocided */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/mkroom.h nethack/include/mkroom.h
--- nh_orig/include/mkroom.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/mkroom.h	2009-12-03 16:14:46.415273207 -0500
@@ -12,4 +12,5 @@
 	schar rtype;		/* type of room (zoo, throne, etc...) */
 	schar rlit;		/* is the room lit ? */
+	schar needfill;		/* does the room need filling? */
 	schar doorct;		/* door count */
 	schar fdoor;		/* index for the first door of the room */
@@ -62,17 +63,19 @@
 #define COCKNEST	12	/* cockatrice nest (Tom Proudfoot) */
 #define ANTHOLE		13	/* ants (Tom Proudfoot) */
-#define SHOPBASE	14	/* everything above this is a shop */
-#define ARMORSHOP	15	/* specific shop defines for level compiler */
-#define SCROLLSHOP	16
-#define POTIONSHOP	17
-#define WEAPONSHOP	18
-#define FOODSHOP	19
-#define RINGSHOP	20
-#define WANDSHOP	21
-#define TOOLSHOP	22
-#define BOOKSHOP	23
-#define UNIQUESHOP	24	/* shops here & above not randomly gen'd. */
-#define CANDLESHOP	24
-#define MAXRTYPE	24	/* maximum valid room type */
+#define TRAPROOM	14
+#define POOLROOM	15
+#define SHOPBASE	16	/* everything above this is a shop */
+#define ARMORSHOP	17	/* specific shop defines for level compiler */
+#define SCROLLSHOP	18
+#define POTIONSHOP	19
+#define WEAPONSHOP	20
+#define FOODSHOP	21
+#define RINGSHOP	22
+#define WANDSHOP	23
+#define TOOLSHOP	24
+#define BOOKSHOP	25
+#define UNIQUESHOP	26	/* shops here & above not randomly gen'd. */
+#define CANDLESHOP	26
+#define MAXRTYPE	26	/* maximum valid room type */
 
 /* Special type for search_special() */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/monattk.h nethack/include/monattk.h
--- nh_orig/include/monattk.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/monattk.h	2009-08-02 13:49:33.032408767 -0400
@@ -25,4 +25,5 @@
 #define AT_GAZE		15	/* gaze - ranged */
 #define AT_TENT		16	/* tentacles */
+#define AT_SCRE	   17 /* scream - sonic attack */
 
 #define AT_WEAP		254	/* uses weapon */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/mondata.h nethack/include/mondata.h
--- nh_orig/include/mondata.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/mondata.h	2010-04-29 10:53:23.669716280 -0400
@@ -19,4 +19,6 @@
 #define resists_acid(mon)	(((mon)->mintrinsics & MR_ACID) != 0)
 #define resists_ston(mon)	(((mon)->mintrinsics & MR_STONE) != 0)
+#define resists_sick(mon)  ((mon)->data->mlet == S_FUNGUS || \
+										(mon)->data == &mons[PM_GHOUL])
 
 #define is_lminion(mon)		(is_minion((mon)->data) && \
@@ -27,4 +29,5 @@
 #define is_flyer(ptr)		(((ptr)->mflags1 & M1_FLY) != 0L)
 #define is_floater(ptr)		((ptr)->mlet == S_EYE)
+#define is_flying(mon)		((mon)->mflying != 0L)
 #define is_clinger(ptr)		(((ptr)->mflags1 & M1_CLING) != 0L)
 #define is_swimmer(ptr)		(((ptr)->mflags1 & M1_SWIM) != 0L)
@@ -69,4 +72,10 @@
 				 (ptr) == &mons[PM_MIND_FLAYER] || \
 				 (ptr) == &mons[PM_MASTER_MIND_FLAYER])
+#define gives_telepathy(ptr)	(telepathic((ptr)) ||		       \
+				 ((ptr) == &mons[PM_KOBOLD_SHAMAN]) || \
+				 ((ptr) == &mons[PM_GOBLIN_SHAMAN]) || \
+				 ((ptr) == &mons[PM_ORC_SHAMAN]) || \
+				 ((ptr) == &mons[PM_HILL_GIANT_SHAMAN]) || \
+				 ((ptr) == &mons[PM_GNOMISH_WIZARD]))
 #define is_armed(ptr)		attacktype(ptr, AT_WEAP)
 #define acidic(ptr)		(((ptr)->mflags1 & M1_ACID) != 0L)
@@ -128,4 +137,8 @@
 				 ((ptr) == &mons[PM_LONG_WORM_TAIL]))
 #define is_covetous(ptr)	((ptr->mflags3 & M3_COVETOUS))
+#define is_skittish(ptr)   ((ptr->mflags3 & M3_SKITTISH))
+#define is_accurate(ptr)   ((ptr->mflags3 & M3_EAGLEEYE))
+#define is_berserker(ptr)  ((ptr->mflags3 & M3_BERSERK))
+#define is_shopguard(ptr)  ((ptr->mflags3 & M3_SHOPGUARD))
 #define infravision(ptr)	((ptr->mflags3 & M3_INFRAVISION))
 #define infravisible(ptr)	((ptr->mflags3 & M3_INFRAVISIBLE))
@@ -147,4 +160,6 @@
 				  (ptr) == &mons[PM_FLAMING_SPHERE] || \
 				  (ptr) == &mons[PM_SHOCKING_SPHERE] || \
+				  (ptr) == &mons[PM_GOLD_DRAGON] || \
+				  (ptr) == &mons[PM_BABY_GOLD_DRAGON] || \
 				  (ptr) == &mons[PM_FIRE_VORTEX]) ? 1 : \
 				 ((ptr) == &mons[PM_FIRE_ELEMENTAL]) ? 1 : 0)
@@ -189,5 +204,10 @@
 
 #define befriend_with_obj(ptr, obj) ((obj)->oclass == FOOD_CLASS && \
-				     is_domestic(ptr))
+				(is_domestic(ptr) || (Role_if(PM_CAVEMAN) && (ptr) == &mons[PM_MASTODON]) || \
+				 ((obj)->otyp == BANANA && ((ptr) == &mons[PM_MONKEY] || (ptr) == &mons[PM_APE]))))
+
+#define is_rockbreaker(ptr)							\
+				(((ptr)->msound == MS_LEADER || is_rider((ptr))) && \
+				 !mtmp->mpeaceful)
 
 #endif /* MONDATA_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/monflag.h nethack/include/monflag.h
--- nh_orig/include/monflag.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/monflag.h	2009-08-02 13:49:33.023408895 -0400
@@ -153,11 +153,19 @@
 #define M3_WAITFORU	0x0040		/* waits to see you or get attacked */
 #define M3_CLOSE	0x0080		/* lets you close unless attacked */
+/* Infravision is currently implemented for players only */
+#define M3_INFRAVISION	0x0100		/* has infravision */
+#define M3_INFRAVISIBLE 0x0200		/* visible by infravision */
+#define M3_SKITTISH  0x0400	   /* tends to stay a few squares away from you */
+#define M3_EAGLEEYE  0x0800		/* gets an accuracy bonus to hit */
+#define M3_BERSERK   0x1000	   /* extremely indiscriminate in its attacks */
+#define M3_SHOPGUARD	0x2000	   /* Guardian for a shop */
 
 #define M3_COVETOUS	0x001f		/* wants something */
 #define M3_WAITMASK	0x00c0		/* waiting... */
 
-/* Infravision is currently implemented for players only */
-#define M3_INFRAVISION	0x0100		/* has infravision */
-#define M3_INFRAVISIBLE 0x0200		/* visible by infravision */
+#define M4_VULNERABLE_FIRE		0x0001	 /* inherent elemental vulnerabilities */
+#define M4_VULNERABLE_COLD		0x0002
+#define M4_VULNERABLE_ELEC		0x0004
+#define M4_VULNERABLE_ACID		0x0008
 
 #define MZ_TINY		0		/* < 2' */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/monst.h nethack/include/monst.h
--- nh_orig/include/monst.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/monst.h	2009-09-07 11:18:19.719417264 -0400
@@ -41,5 +41,5 @@
 	struct monst *nmon;
 	struct permonst *data;
-	unsigned m_id;
+	size_t m_id;
 	short mnum;		/* permanent monster index number */
 	short movement;		/* movement points (derived from permonst definition and added effects */
@@ -64,4 +64,24 @@
 	int mspec_used;		/* monster's special ability attack timeout */
 
+/* These should stay in the same order as monattk.h so
+ * the mask translations will work properly */
+
+#define M_SEEN_NOTHING	0x0000
+#define M_SEEN_MAGR		0x0001
+#define M_SEEN_FIRE		0x0002
+#define M_SEEN_COLD		0x0004
+#define M_SEEN_SLEEP		0x0008
+#define M_SEEN_DISINT	0x0010
+#define M_SEEN_ELEC		0x0020
+#define M_SEEN_POISON	0x0040
+#define M_SEEN_ACID	 	0x0080
+#define M_SEEN_REFL		0x0100
+
+#define m_seenres(mon,mask)	((mon)->seen_resistance & (mask))
+#define m_setseen(mon,mask)	((mon)->seen_resistance |= (mask))
+#define m_sawlose(mon,mask)	((mon)->seen_resistance &= (~mask))
+
+	unsigned long seen_resistance;  /* Has seen you resist an element or magical effect */
+
 	Bitfield(female,1);	/* is female */
 	Bitfield(minvis,1);	/* currently invisible */
@@ -96,4 +116,5 @@
 	Bitfield(mcanmove,1);	/* paralysis, similar to mblinded */
 	Bitfield(mfrozen,7);
+	Bitfield(mflying,1);	  /* is monster levitating/flying artificially? */
 
 	Bitfield(msleeping,1);	/* asleep until woken */
@@ -103,7 +124,10 @@
 	Bitfield(mtrapped,1);	/* trapped in a pit, web or bear trap */
 	Bitfield(mleashed,1);	/* monster is on a leash */
+	Bitfield(mberserk,1);    /* monster is berserk */
+
 	Bitfield(isshk,1);	/* is shopkeeper */
 	Bitfield(isminion,1);	/* is a minion */
 
+	Bitfield(isshopguard,1);	 /* monster is a shop guard */
 	Bitfield(isgd,1);	/* is guard */
 	Bitfield(ispriest,1);	/* is a priest */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/monsym.h nethack/include/monsym.h
--- nh_orig/include/monsym.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/monsym.h	2009-08-02 13:49:33.040407823 -0400
@@ -74,4 +74,7 @@
 #define MAXMCLASSES 61	/* number of monster classes */
 
+#define S_WERE		100	/* don't include this in MAXMCLASSES, it's a hack for warning */
+#define S_UNDEAD	101	/* etc */
+
 #if 0	/* moved to decl.h so that makedefs.c won't see them */
 extern const char def_monsyms[MAXMCLASSES];	/* default class symbols */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/objclass.h nethack/include/objclass.h
--- nh_orig/include/objclass.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/objclass.h	2010-04-25 13:07:29.176715584 -0400
@@ -71,4 +71,5 @@
 /* is_flammable(otmp), is_rottable(otmp) in mkobj.c */
 #define is_rustprone(otmp)	(objects[otmp->otyp].oc_material == IRON)
+#define is_meltable(otmp)	(objects[otmp->otyp].oc_material == COPPER || objects[otmp->otyp].oc_material == GOLD)
 
 /* secondary damage: rot/acid/acid */
@@ -140,5 +141,6 @@
 #define CHAIN_CLASS	16
 #define VENOM_CLASS	17
-#define MAXOCLASSES	18
+#define FURNITURE_CLASS	18
+#define MAXOCLASSES	19
 
 #define ALLOW_COUNT	(MAXOCLASSES+1) /* Can be used in the object class */
@@ -148,4 +150,5 @@
 #define BURNING_OIL	(MAXOCLASSES+1) /* Can be used as input to explode. */
 #define MON_EXPLODE	(MAXOCLASSES+2) /* Exploding monster (e.g. gas spore) */
+#define MON_CASTBALL	(MAXOCLASSES+3) /* For monsters casting area-effect spells */
 
 #if 0	/* moved to decl.h so that makedefs.c won't see them */
@@ -173,4 +176,5 @@
 #define CHAIN_SYM	'_'
 #define VENOM_SYM	'.'
+#define FURNITURE_SYM	'\\'
 
 struct fruit {
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/obj.h nethack/include/obj.h
--- nh_orig/include/obj.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/obj.h	2010-05-13 09:22:22.141715011 -0400
@@ -23,5 +23,5 @@
 
 	struct obj *cobj;	/* contents list for containers */
-	unsigned o_id;
+	size_t o_id;
 	xchar ox,oy;
 	short otyp;		/* object class number */
@@ -67,4 +67,6 @@
 	Bitfield(oeroded2,2);	/* corroded/rotted weapon/armor */
 #define greatest_erosion(otmp) (int)((otmp)->oeroded > (otmp)->oeroded2 ? (otmp)->oeroded : (otmp)->oeroded2)
+#define set_erodeproof(otmp) { (otmp)->oeroded = (otmp)->oeroded2 = 0; (otmp)->oerodeproof = TRUE; }
+
 #define MAX_ERODE 3
 #define orotten oeroded		/* rotten food */
@@ -98,6 +100,13 @@
 #define spestudied corpsenm	/* # of times a spellbook has been studied */
 #define fromsink  corpsenm	/* a potion from a sink */
+
+#ifdef RECORD_ACHIEVE
+#define record_achieve_special corpsenm
+#endif
+
 	unsigned oeaten;	/* nutrition left in food, if partly eaten */
 	long age;		/* creation date */
+	long capacity;	  /* how much can this container hold? */
+#define MAX_CAPACITY 0xFFFFFF	  /* "lots" */
 
 	uchar onamelth;		/* length of name (following oxlth) */
@@ -139,6 +148,5 @@
 #define is_pole(otmp)	((otmp->oclass == WEAPON_CLASS || \
 			otmp->oclass == TOOL_CLASS) && \
-			 (objects[otmp->otyp].oc_skill == P_POLEARMS || \
-			 objects[otmp->otyp].oc_skill == P_LANCE))
+			 (objects[otmp->otyp].oc_skill == P_POLEARMS))
 #define is_spear(otmp)	(otmp->oclass == WEAPON_CLASS && \
 			 objects[otmp->otyp].oc_skill >= P_SPEAR && \
@@ -158,4 +166,11 @@
 			 objects[otmp->otyp].oc_skill >= -P_BOOMERANG && \
 			 objects[otmp->otyp].oc_skill <= -P_DART)
+#define is_thrown(otmp)	  ((otmp->oclass == WEAPON_CLASS) && \
+		  ((objects[otmp->otyp].oc_skill >= P_DART && \
+			 objects[otmp->otyp].oc_skill <= P_BOOMERANG) || \
+			 objects[otmp->otyp].oc_skill == P_DAGGER || \
+			 objects[otmp->otyp].oc_skill == P_KNIFE || \
+			(objects[otmp->otyp].oc_skill >= P_SPEAR && \
+			 objects[otmp->otyp].oc_skill <= P_TRIDENT)))
 #define is_weptool(o)	((o)->oclass == TOOL_CLASS && \
 			 objects[(o)->otyp].oc_skill != P_NONE)
@@ -218,6 +233,7 @@
 #define Has_contents(o) (/* (Is_container(o) || (o)->otyp == STATUE) && */ \
 			 (o)->cobj != (struct obj *)0)
-#define Is_container(o) ((o)->otyp >= LARGE_BOX && (o)->otyp <= BAG_OF_TRICKS)
-#define Is_box(otmp)	(otmp->otyp == LARGE_BOX || otmp->otyp == CHEST)
+#define Is_container(o) ((o)->otyp >= LARGE_BOX && (o)->otyp <= BAG_OF_POO)
+#define Is_box(otmp)	(otmp->otyp == LARGE_BOX || otmp->otyp == CHEST || \
+								otmp->otyp == IRON_SAFE)
 #define Is_mbag(otmp)	(otmp->otyp == BAG_OF_HOLDING || \
 			 otmp->otyp == BAG_OF_TRICKS)
@@ -273,5 +289,6 @@
 				|| (otmp)->otyp == TALLOW_CANDLE\
 				|| (otmp)->otyp == WAX_CANDLE\
-				|| (otmp)->otyp == POT_OIL)
+				|| (otmp)->otyp == POT_OIL\
+				|| (otmp)->otyp == BAG_OF_POO)
 /* object can be ignited */
 #define ignitable(otmp)	((otmp)->otyp == BRASS_LANTERN\
@@ -280,11 +297,12 @@
 				|| (otmp)->otyp == TALLOW_CANDLE\
 				|| (otmp)->otyp == WAX_CANDLE\
-				|| (otmp)->otyp == POT_OIL)
+				|| (otmp)->otyp == POT_OIL\
+				|| (otmp)->otyp == FUR_BRAZIER\
+				|| (otmp)->otyp == BAG_OF_POO)
 
 /* special stones */
 #define is_graystone(obj)	((obj)->otyp == LUCKSTONE || \
-				 (obj)->otyp == LOADSTONE || \
-				 (obj)->otyp == FLINT     || \
-				 (obj)->otyp == TOUCHSTONE)
+				 (obj)->otyp == LOADSTONE || (obj)->otyp == FLINT     || \
+				 (obj)->otyp == TOUCHSTONE || (obj)->otyp == SALT_CHUNK)
 
 /* misc */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/patchlevel.h nethack/include/patchlevel.h
--- nh_orig/include/patchlevel.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/patchlevel.h	2010-04-29 11:10:56.036011963 -0400
@@ -3,7 +3,7 @@
 /* NetHack may be freely redistributed.  See license for details. */
 
-/* NetHack 3.4.3 */
-#define VERSION_MAJOR	3
-#define VERSION_MINOR	4
+/* SporkHack 0.3.0 */
+#define VERSION_MAJOR	0
+#define VERSION_MINOR	6
 /*
  * PATCHLEVEL is updated for each release.
@@ -17,8 +17,8 @@
 
 #define COPYRIGHT_BANNER_A \
-"NetHack, Copyright 1985-2003"
+"SporkHack, copyright 2007 Derek S. Ray; a variant of NetHack 3.4.3, "
 
 #define COPYRIGHT_BANNER_B \
-"         By Stichting Mathematisch Centrum and M. Stephenson."
+"  copyright 1985-2003 by Stichting Mathematisch Centrum and M. Stephenson."
 
 #define COPYRIGHT_BANNER_C \
@@ -34,5 +34,7 @@
  * with all four numbers specified as two hexadecimal digits.
  */
-#define VERSION_COMPATIBILITY 0x03040000L	/* 3.4.0-0 */
+
+/*                            0xMMmmPPeeL            */
+#define VERSION_COMPATIBILITY 0x00060300L	/* 0.6.1-0 */
 
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/permonst.h nethack/include/permonst.h
--- nh_orig/include/permonst.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/permonst.h	2009-09-13 08:38:18.966292366 -0400
@@ -56,7 +56,8 @@
 	uchar		mresists;		/* resistances */
 	uchar		mconveys;		/* conveyed by eating */
-	unsigned long	mflags1,		/* boolean bitflags */
-			mflags2;		/* more boolean bitflags */
-	unsigned short	mflags3;		/* yet more boolean bitflags */
+	unsigned long	mflags1;		/* boolean bitflags */
+	unsigned long  mflags2;		/* more boolean bitflags */
+	unsigned long	mflags3;		/* yet more boolean bitflags */
+	unsigned long	mflags4;	  /* Add room for more */
 # ifdef TEXTCOLOR
 	uchar		mcolor;			/* color to use */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/prop.h nethack/include/prop.h
--- nh_orig/include/prop.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/prop.h	2009-09-05 10:47:01.555291838 -0400
@@ -74,5 +74,14 @@
 #define WARN_OF_MON		65
 #define DETECT_MONSTERS		66
-#define LAST_PROP		(DETECT_MONSTERS)
+#define WERE_RES			67
+#define BLIND_RES			68
+#define SLOW				69
+#define VISION				70
+#define LUCKY				71
+#define VULN_FIRE			72
+#define VULN_COLD			73
+#define VULN_ELEC			74
+#define VULN_ACID			75
+#define LAST_PROP		 	(VULN_ACID)
 
 /*** Where the properties come from ***/
@@ -100,4 +109,5 @@
 #	define W_ART	    0x00001000L /* Carrying artifact (not really worn) */
 #	define W_ARTI	    0x00002000L /* Invoked artifact  (not really worn) */
+#  define W_LAUNCHER  0x00004000L /* Selected ranged launcher */
 	/* Amulets, rings, tools, and other items */
 #	define W_AMUL	    0x00010000L /* Amulet */
@@ -123,5 +133,6 @@
 #	define FROMRACE     0x02000000L /* Gain/lose with experience, for race */
 #	define FROMOUTSIDE  0x04000000L /* By corpses, prayer, thrones, etc. */
-#	define INTRINSIC    (FROMOUTSIDE|FROMRACE|FROMEXPER)
+#  define HAVEPARTIAL  0x08000000L /* This is no longer a timeout, but a partial resistance */
+#	define INTRINSIC    (FROMOUTSIDE|FROMRACE|FROMEXPER|HAVEPARTIAL)
 	/* Control flags */
 #	define I_SPECIAL    0x10000000L /* Property is controllable */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/rm.h nethack/include/rm.h
--- nh_orig/include/rm.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/rm.h	2010-05-14 11:22:24.447714895 -0400
@@ -31,42 +31,42 @@
 
 /* Level location types */
-#define STONE		0
-#define VWALL		1
-#define HWALL		2
-#define TLCORNER	3
-#define TRCORNER	4
-#define BLCORNER	5
-#define BRCORNER	6
-#define CROSSWALL	7	/* For pretty mazes and special levels */
-#define TUWALL		8
-#define TDWALL		9
-#define TLWALL		10
-#define TRWALL		11
-#define DBWALL		12
-#define TREE		13	/* KMH */
-#define SDOOR		14
-#define SCORR		15
-#define POOL		16
-#define MOAT		17	/* pool that doesn't boil, adjust messages */
-#define WATER		18
-#define DRAWBRIDGE_UP	19
-#define LAVAPOOL	20
-#define IRONBARS	21	/* KMH */
-#define DOOR		22
-#define CORR		23
-#define ROOM		24
-#define STAIRS		25
-#define LADDER		26
-#define FOUNTAIN	27
-#define THRONE		28
-#define SINK		29
-#define GRAVE		30
-#define ALTAR		31
-#define ICE		32
-#define DRAWBRIDGE_DOWN 33
-#define AIR		34
-#define CLOUD		35
-
-#define MAX_TYPE	36
+enum {
+    STONE = 0,
+    VWALL,
+    HWALL,
+    TLCORNER,
+    TRCORNER,
+    BLCORNER,
+    BRCORNER,
+    CROSSWALL,		/* For pretty mazes and special levels */
+    TUWALL,
+    TDWALL,
+    TLWALL,
+    TRWALL,
+    DBWALL,
+    TREE,			/* KMH */
+    SDOOR,
+    SCORR,
+    POOL,
+    MOAT,			/* pool that doesn't boil, adjust messages */
+    WATER,
+    DRAWBRIDGE_UP,
+    LAVAPOOL,
+    IRONBARS,		/* KMH */
+    DOOR,
+    CORR,
+    ROOM,
+    STAIRS,
+    LADDER,
+    FOUNTAIN,
+    SINK,
+    GRAVE,
+    ALTAR,
+    ICE,
+    DRAWBRIDGE_DOWN,
+    AIR,
+    CLOUD,
+    MAX_TYPE
+};
 #define INVALID_TYPE	127
 
@@ -87,5 +87,4 @@
 #define SPACE_POS(typ)	((typ) > DOOR)
 #define IS_POOL(typ)	((typ) >= POOL && (typ) <= DRAWBRIDGE_UP)
-#define IS_THRONE(typ)	((typ) == THRONE)
 #define IS_FOUNTAIN(typ) ((typ) == FOUNTAIN)
 #define IS_SINK(typ)	((typ) == SINK)
@@ -104,113 +103,117 @@
 
 /* begin dungeon characters */
-
-#define S_stone		0
-#define S_vwall		1
-#define S_hwall		2
-#define S_tlcorn	3
-#define S_trcorn	4
-#define S_blcorn	5
-#define S_brcorn	6
-#define S_crwall	7
-#define S_tuwall	8
-#define S_tdwall	9
-#define S_tlwall	10
-#define S_trwall	11
-#define S_ndoor		12
-#define S_vodoor	13
-#define S_hodoor	14
-#define S_vcdoor	15	/* closed door, vertical wall */
-#define S_hcdoor	16	/* closed door, horizontal wall */
-#define S_bars		17	/* KMH -- iron bars */
-#define S_tree		18	/* KMH */
-#define S_room		19
-#define S_corr		20
-#define S_litcorr	21
-#define S_upstair	22
-#define S_dnstair	23
-#define S_upladder	24
-#define S_dnladder	25
-#define S_altar		26
-#define S_grave		27
-#define S_throne	28
-#define S_sink		29
-#define S_fountain	30
-#define S_pool		31
-#define S_ice		32
-#define S_lava		33
-#define S_vodbridge	34
-#define S_hodbridge	35
-#define S_vcdbridge	36	/* closed drawbridge, vertical wall */
-#define S_hcdbridge	37	/* closed drawbridge, horizontal wall */
-#define S_air		38
-#define S_cloud		39
-#define S_water		40
+enum {
+    S_stone = 0,
+    S_vwall,
+    S_hwall,
+    S_tlcorn,
+    S_trcorn,
+    S_blcorn,
+    S_brcorn,
+    S_crwall,
+    S_tuwall,
+    S_tdwall,
+    S_tlwall,
+    S_trwall,
+    S_ndoor,
+    S_vodoor,
+    S_hodoor,
+    S_vcdoor,		/* closed door, vertical wall */
+    S_hcdoor,		/* closed door, horizontal wall */
+    S_bars,		/* KMH -- iron bars */
+    S_tree,		/* KMH */
+    S_room,
+    S_darkroom,
+    S_corr,
+    S_litcorr,
+    S_upstair,
+    S_dnstair,
+    S_upladder,
+    S_dnladder,
+    S_altar,
+    S_grave,
+    S_sink,
+    S_fountain,
+    S_pool,
+    S_ice,
+    S_lava,
+    S_vodbridge,
+    S_hodbridge,
+    S_vcdbridge,       	/* closed drawbridge, vertical wall */
+    S_hcdbridge,	/* closed drawbridge, horizontal wall */
+    S_air,
+    S_cloud,
+    S_water,
 
 /* end dungeon characters, begin traps */
 
-#define S_arrow_trap		41
-#define S_dart_trap		42
-#define S_falling_rock_trap	43
-#define S_squeaky_board		44
-#define S_bear_trap		45
-#define S_land_mine		46
-#define S_rolling_boulder_trap	47
-#define S_sleeping_gas_trap	48
-#define S_rust_trap		49
-#define S_fire_trap		50
-#define S_pit			51
-#define S_spiked_pit		52
-#define S_hole			53
-#define S_trap_door		54
-#define S_teleportation_trap	55
-#define S_level_teleporter	56
-#define S_magic_portal		57
-#define S_web			58
-#define S_statue_trap		59
-#define S_magic_trap		60
-#define S_anti_magic_trap	61
-#define S_polymorph_trap	62
+    S_arrow_trap,
+    S_dart_trap,
+    S_falling_rock_trap,
+    S_squeaky_board,
+    S_bear_trap,
+    S_land_mine,
+    S_rolling_boulder_trap,
+    S_sleeping_gas_trap,
+    S_rust_trap,
+    S_fire_trap,
+    S_pit,
+    S_spiked_pit,
+    S_hole,
+    S_trap_door,
+    S_teleportation_trap,
+    S_level_teleporter,
+    S_magic_portal,
+    S_web,
+    S_statue_trap,
+    S_magic_trap,
+    S_anti_magic_trap,
+    S_polymorph_trap,
+    S_spear_trap,
+    S_falling_rocks_trap,
+    S_magic_beam_trap,
 
 /* end traps, begin special effects */
 
-#define S_vbeam		63	/* The 4 zap beam symbols.  Do NOT separate. */
-#define S_hbeam		64	/* To change order or add, see function     */
-#define S_lslant	65	/* zapdir_to_glyph() in display.c.	    */
-#define S_rslant	66
-#define S_digbeam	67	/* dig beam symbol */
-#define S_flashbeam	68	/* camera flash symbol */
-#define S_boomleft	69	/* thrown boomerang, open left, e.g ')'    */
-#define S_boomright	70	/* thrown boomerand, open right, e.g. '('  */
-#define S_ss1		71	/* 4 magic shield glyphs */
-#define S_ss2		72
-#define S_ss3		73
-#define S_ss4		74
+    S_vbeam,		/* The 4 zap beam symbols.  Do NOT separate. */
+    S_hbeam,		/* To change order or add, see function     */
+    S_lslant,		/* zapdir_to_glyph() in display.c.	    */
+    S_rslant,
+    S_digbeam,		/* dig beam symbol */
+    S_flashbeam,	/* camera flash symbol */
+    S_boomleft,		/* thrown boomerang, open left, e.g ')'    */
+    S_boomright,	/* thrown boomerand, open right, e.g. '('  */
+    S_ss1,		/* 4 magic shield glyphs */
+    S_ss2,
+    S_ss3,
+    S_ss4,
 
 /* The 8 swallow symbols.  Do NOT separate.  To change order or add, see */
 /* the function swallow_to_glyph() in display.c.			 */
-#define S_sw_tl		75	/* swallow top left [1]			*/
-#define S_sw_tc		76	/* swallow top center [2]	Order:	*/
-#define S_sw_tr		77	/* swallow top right [3]		*/
-#define S_sw_ml		78	/* swallow middle left [4]	1 2 3	*/
-#define S_sw_mr		79	/* swallow middle right [6]	4 5 6	*/
-#define S_sw_bl		80	/* swallow bottom left [7]	7 8 9	*/
-#define S_sw_bc		81	/* swallow bottom center [8]		*/
-#define S_sw_br		82	/* swallow bottom right [9]		*/
+    S_sw_tl,			/* swallow top left [1]			*/
+    S_sw_tc,			/* swallow top center [2]	Order:	*/
+    S_sw_tr,			/* swallow top right [3]		*/
+    S_sw_ml,			/* swallow middle left [4]	1 2 3	*/
+    S_sw_mr,			/* swallow middle right [6]	4 5 6	*/
+    S_sw_bl,			/* swallow bottom left [7]	7 8 9	*/
+    S_sw_bc,			/* swallow bottom center [8]		*/
+    S_sw_br,			/* swallow bottom right [9]		*/
 
-#define S_explode1	83	/* explosion top left			*/
-#define S_explode2	84	/* explosion top center			*/
-#define S_explode3	85	/* explosion top right		 Ex.	*/
-#define S_explode4	86	/* explosion middle left		*/
-#define S_explode5	87	/* explosion middle center	 /-\	*/
-#define S_explode6	88	/* explosion middle right	 |@|	*/
-#define S_explode7	89	/* explosion bottom left	 \-/	*/
-#define S_explode8	90	/* explosion bottom center		*/
-#define S_explode9	91	/* explosion bottom right		*/
+    S_explode1,		/* explosion top left			*/
+    S_explode2,		/* explosion top center			*/
+    S_explode3,		/* explosion top right		 Ex.	*/
+    S_explode4,		/* explosion middle left		*/
+    S_explode5,		/* explosion middle center	 /-\	*/
+    S_explode6,		/* explosion middle right	 |@|	*/
+    S_explode7,		/* explosion bottom left	 \-/	*/
+    S_explode8,		/* explosion bottom center		*/
+    S_explode9,		/* explosion bottom right		*/
 
 /* end effects */
 
-#define MAXPCHARS	92	/* maximum number of mapped characters */
+    MAXPCHARS		/* maximum number of mapped characters */
+};
 #define MAXDCHARS	41	/* maximum of mapped dungeon characters */
-#define MAXTCHARS	22	/* maximum of mapped trap characters */
+#define MAXTCHARS	25	/* maximum of mapped trap characters */
 #define MAXECHARS	29	/* maximum of mapped effects characters */
 #define MAXEXPCHARS	9	/* number of explosion characters */
@@ -246,4 +249,5 @@
 #define D_LOCKED	8
 #define D_TRAPPED	16
+#define D_SECRET	32 /* only used by sp_lev.c, NOT in rm-struct */
 
 /*
@@ -253,9 +257,4 @@
 
 /*
- * Thrones should only be looted once.
- */
-#define T_LOOTED	1
-
-/*
  * Trees have more than one kick result.
  */
@@ -343,4 +342,15 @@
 };
 
+
+#define SET_TYPLIT(x,y,ttyp,llit)				\
+{								\
+    if ((ttyp) < MAX_TYPE) levl[(x)][(y)].typ = (ttyp);		\
+    if ((ttyp) == LAVAPOOL) levl[(x)][(y)].lit = 1;		\
+    else if ((schar)(llit) != -2) {				\
+	if ((schar)(llit) == -1) levl[(x)][(y)].lit = rn2(2);	\
+	else levl[(x)][(y)].lit = (llit);			\
+    }								\
+}
+
 /*
  * Add wall angle viewing by defining "modes" for each wall type.  Each
@@ -463,7 +473,39 @@
 	Bitfield(graveyard,1);		/* has_morgue, but remains set */
 	Bitfield(is_maze_lev,1);
+	Bitfield(stormy,1);		/* thunderous clouds */
 
 	Bitfield(is_cavernous_lev,1);
 	Bitfield(arboreal, 1);		/* Trees replace rock */
+	/* and where it is written "ad aquarium"... */
+	Bitfield(vault_is_aquarium,1);
+};
+
+struct mon_gen_tuple {
+    int freq;
+    boolean is_sym;
+    int monid;
+    struct mon_gen_tuple *next;
+};
+
+struct mon_gen_override {
+    int override_chance;
+    int total_mon_freq;
+    struct mon_gen_tuple *gen_chances;
+};
+
+#define LVLSND_HEARD	0	/* You_hear(msg); */
+#define LVLSND_PLINED	1	/* pline(msg); */
+#define LVLSND_VERBAL	2	/* verbalize(msg); */
+#define LVLSND_FELT	3	/* You_feel(msg); */
+
+struct lvl_sound_bite {
+    int flags; /* LVLSND_foo */
+    char *msg;
+};
+
+struct lvl_sounds {
+    int freq;
+    int n_sounds;
+    struct lvl_sound_bite *sounds;
 };
 
@@ -485,4 +527,6 @@
     struct damage	*damagelist;
     struct levelflags	flags;
+    struct mon_gen_override *mon_gen;
+    struct lvl_sounds	*sounds;
 }
 dlevel_t;
@@ -513,10 +557,5 @@
 #define MON_BURIED_AT(x,y)	(level.monsters[x][y] != (struct monst *)0 && \
 				(level.monsters[x][y])->mburied)
-#ifndef STEED
-#define place_monster(m,x,y)	((m)->mx=(x),(m)->my=(y),\
-				 level.monsters[(m)->mx][(m)->my]=(m))
-#endif
 #define place_worm_seg(m,x,y)	level.monsters[x][y] = m
-#define remove_monster(x,y)	level.monsters[x][y] = (struct monst *)0
 #define m_at(x,y)		(MON_AT(x,y) ? level.monsters[x][y] : \
 						(struct monst *)0)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/sp_lev.h nethack/include/sp_lev.h
--- nh_orig/include/sp_lev.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/sp_lev.h	2010-04-26 14:12:02.404715531 -0400
@@ -18,13 +18,262 @@
 
     /* Per level flags */
-#define NOTELEPORT	1
-#define HARDFLOOR	2
-#define NOMMAP		4
-#define SHORTSIGHTED	8
-#define ARBOREAL	16
+#define NOTELEPORT	0x00000001L
+#define HARDFLOOR	0x00000002L
+#define NOMMAP		0x00000004L
+#define SHORTSIGHTED	0x00000008L
+#define ARBOREAL	0x00000010L
+#define NOFLIPX		0x00000020L
+#define NOFLIPY		0x00000040L
+#define MAZELEVEL	0x00000080L
+#define PREMAPPED	0x00000100L
+#define SHROUD		0x00000200L
+#define STORMY		0x00000400L
+#define GRAVEYARD	0x00000800L
 
-    /* special level types */
-#define SP_LEV_ROOMS	1
-#define SP_LEV_MAZE	2
+/* different level layout initializers */
+#define LVLINIT_NONE		0
+#define LVLINIT_SOLIDFILL	1
+#define LVLINIT_MAZEGRID	2
+#define LVLINIT_MINES		3
+
+/* max. layers of object containment */
+#define MAX_CONTAINMENT 10
+
+/* max. # of random registers */
+#define MAX_REGISTERS	10
+
+/* max. nested depth of subrooms */
+#define MAX_NESTED_ROOMS 5
+
+/* max. # of opcodes per special level */
+#define SPCODER_MAX_RUNTIME	65536
+
+/* Opcodes for creating the level
+ * If you change these, also change opcodestr[] in util/lev_main.c
+ */
+enum opcode_defs {
+    SPO_NULL = 0,
+    SPO_MESSAGE,
+    SPO_MONSTER,
+    SPO_OBJECT,
+    SPO_ENGRAVING,
+    SPO_ROOM,
+    SPO_SUBROOM,
+    SPO_DOOR,
+    SPO_STAIR,
+    SPO_LADDER,
+    SPO_ALTAR,
+    SPO_FOUNTAIN,
+    SPO_SINK,
+    SPO_POOL,
+    SPO_TRAP,
+    SPO_GOLD,
+    SPO_CORRIDOR,
+    SPO_LEVREGION,
+    SPO_DRAWBRIDGE,
+    SPO_MAZEWALK,
+    SPO_NON_DIGGABLE,
+    SPO_NON_PASSWALL,
+    SPO_WALLIFY,
+    SPO_MAP,
+    SPO_ROOM_DOOR,
+    SPO_REGION,
+    SPO_CMP,
+    SPO_JMP,
+    SPO_JL,
+    SPO_JLE,
+    SPO_JG,
+    SPO_JGE,
+    SPO_JE,
+    SPO_JNE,
+    SPO_SPILL,
+    SPO_TERRAIN,
+    SPO_REPLACETERRAIN,
+    SPO_EXIT,
+    SPO_ENDROOM,
+    SPO_POP_CONTAINER,
+    SPO_PUSH,
+    SPO_POP,
+    SPO_RN2,
+    SPO_DEC,
+    SPO_INC,
+    SPO_MATH_ADD,
+    SPO_MATH_SUB,
+    SPO_MATH_MUL,
+    SPO_MATH_DIV,
+    SPO_MATH_MOD,
+    SPO_COPY,
+    SPO_MON_GENERATION,
+    SPO_END_MONINVENT,
+    SPO_GRAVE,
+    SPO_FRAME_PUSH,
+    SPO_FRAME_POP,
+    SPO_CALL,
+    SPO_RETURN,
+    SPO_INITLEVEL,
+    SPO_LEVEL_FLAGS,
+    SPO_LEVEL_SOUNDS,
+    SPO_WALLWALK,
+    SPO_VAR_INIT, /* variable_name data */
+    SPO_SHUFFLE_ARRAY,
+    SPO_DICE,
+
+    SPO_SEL_ADD,
+    SPO_SEL_POINT,
+    SPO_SEL_RECT,
+    SPO_SEL_FILLRECT,
+    SPO_SEL_LINE,
+    SPO_SEL_RNDLINE,
+    SPO_SEL_GROW,
+    SPO_SEL_FLOOD,
+    SPO_SEL_RNDCOORD,
+    SPO_SEL_ELLIPSE,
+    SPO_SEL_FILTER,
+
+    MAX_SP_OPCODES
+};
+
+/* MONSTER and OBJECT can take a variable number of parameters,
+ * they also pop different # of values from the stack. So,
+ * first we pop a value that tells what the _next_ value will
+ * mean.
+ */
+/* MONSTER */
+#define SP_M_V_PEACEFUL         0
+#define SP_M_V_ALIGN            1
+#define SP_M_V_ASLEEP           2
+#define SP_M_V_APPEAR           3
+#define SP_M_V_NAME             4
+
+#define SP_M_V_FEMALE		5
+#define SP_M_V_INVIS		6
+#define SP_M_V_CANCELLED	7
+#define SP_M_V_REVIVED		8
+#define SP_M_V_AVENGE		9
+#define SP_M_V_FLEEING		10
+#define SP_M_V_BLINDED		11
+#define SP_M_V_PARALYZED	12
+#define SP_M_V_STUNNED		13
+#define SP_M_V_CONFUSED		14
+#define SP_M_V_SEENTRAPS	15
+
+#define SP_M_V_END              16 /* end of variable parameters */
+
+/* OBJECT */
+#define SP_O_V_SPE              0
+#define SP_O_V_CURSE            1
+#define SP_O_V_CORPSENM         2
+#define SP_O_V_NAME             3
+#define SP_O_V_QUAN		4
+#define SP_O_V_BURIED		5
+#define SP_O_V_LIT		6
+#define SP_O_V_ERODED		7
+#define SP_O_V_LOCKED		8
+#define SP_O_V_TRAPPED		9
+#define SP_O_V_RECHARGED	10
+#define SP_O_V_INVIS		11
+#define SP_O_V_GREASED		12
+#define SP_O_V_BROKEN		13
+#define SP_O_V_COORD		14
+#define SP_O_V_END              15 /* end of variable parameters */
+
+
+/* When creating objects, we need to know whether
+ * it's a container and/or contents.
+ */
+#define SP_OBJ_CONTENT		0x1
+#define SP_OBJ_CONTAINER	0x2
+
+
+
+#define SPOVAR_NULL	0x00
+#define SPOVAR_INT	0x01 /* l */
+#define SPOVAR_STRING	0x02 /* str */
+#define SPOVAR_VARIABLE	0x03 /* str (contains the variable name) */
+#define SPOVAR_COORD	0x04 /* coordinate, encoded in l; use SP_COORD_X() and SP_COORD_Y() */
+#define SPOVAR_REGION	0x05 /* region, encoded in l; use SP_REGION_X1() etc */
+#define SPOVAR_MAPCHAR	0x06 /* map char, in l */
+#define SPOVAR_MONST	0x07 /* monster class & specific monster, encoded in l; use SP_MONST_... */
+#define SPOVAR_OBJ	0x08 /* object class & specific object type, encoded in l; use SP_OBJ_... */
+#define SPOVAR_SEL	0x09 /* selection. char[COLNO][ROWNO] in str */
+#define SPOVAR_ARRAY	0x40 /* used in splev_var & lc_vardefs, not in opvar */
+
+#define SP_COORD_X(l)	(l & 0xff)
+#define SP_COORD_Y(l)	((l >> 16) & 0xff)
+#define SP_COORD_PACK(x,y) ((( x ) & 0xff) + ((( y ) & 0xff) << 16))
+
+#define SP_REGION_X1(l)	(l & 0xff)
+#define SP_REGION_Y1(l)	((l >> 8) & 0xff)
+#define SP_REGION_X2(l)	((l >> 16) & 0xff)
+#define SP_REGION_Y2(l)	((l >> 24) & 0xff)
+#define SP_REGION_PACK(x1,y1,x2,y2) ((( x1 ) & 0xff) + ((( y1 ) & 0xff) << 8) + ((( x2 ) & 0xff) << 16) + ((( y2 ) & 0xff) << 24))
+
+#define SP_MONST_CLASS(l) (l & 0xff)
+#define SP_MONST_PM(l)	  ((l >> 8) & 0xffff)
+#define SP_MONST_PACK(m,c) ((( m ) << 8) + ((char)( c )))
+
+#define SP_OBJ_CLASS(l)	  (l & 0xff)
+#define SP_OBJ_TYP(l)	  ((l >> 8) & 0xffff)
+#define SP_OBJ_PACK(o,c)  ((( o ) << 8) + ((char)( c )))
+
+#define SP_MAPCHAR_TYP(l) (l & 0xff)
+#define SP_MAPCHAR_LIT(l) ((l >> 8) & 0xff)
+#define SP_MAPCHAR_PACK(typ,lit) ((( lit ) << 8) + ((char)( typ )))
+
+struct opvar {
+    xchar spovartyp; /* one of SPOVAR_foo */
+    union {
+	char *str;
+	long l;
+    } vardata;
+};
+
+struct splev_var {
+    struct splev_var *next;
+    char *name;
+    xchar svtyp; /* SPOVAR_foo */
+    union {
+	struct opvar *value;
+	struct opvar **arrayvalues;
+    } data;
+    long array_len;
+};
+
+struct splevstack {
+    long depth;
+    long depth_alloc;
+    struct opvar **stackdata;
+};
+
+
+struct sp_frame {
+    struct sp_frame *next;
+    struct splevstack *stack;
+    struct splev_var *variables;
+    long n_opcode;
+};
+
+
+struct sp_coder {
+    struct splevstack *stack;
+    struct sp_frame *frame;
+    int allow_flips;
+    int premapped;
+    struct mkroom *croom;
+    struct mkroom *tmproomlist[MAX_NESTED_ROOMS+1];
+    boolean failed_room[MAX_NESTED_ROOMS+1];
+    int n_subroom;
+    boolean exit_script;
+    int  lvl_is_joined;
+
+    int opcode;  /* current opcode */
+    struct opvar *opdat; /* current push data (req. opcode == SPO_PUSH) */
+};
+
+/* special level coder CPU flags */
+#define SP_CPUFLAG_LT	1
+#define SP_CPUFLAG_GT	2
+#define SP_CPUFLAG_EQ	4
+#define SP_CPUFLAG_ZERO	8
 
 /*
@@ -32,4 +281,20 @@
  */
 
+typedef struct {
+    xchar x1,y1,x2,y2;
+    xchar fg, lit;
+    int roughness;
+    xchar thick;
+} randline;
+
+typedef struct {
+	int cmp_what;
+	int cmp_val;
+} opcmp;
+
+typedef struct {
+	long jmp_target;
+} opjmp;
+
 typedef union str_or_len {
 	char *str;
@@ -38,8 +303,10 @@
 
 typedef struct {
-	boolean init_present, padding;
+	xchar   init_style; /* one of LVLINIT_foo */
 	char	fg, bg;
 	boolean smoothed, joined;
 	xchar	lit, walled;
+	long	flags;
+	schar	filling;
 } lev_init;
 
@@ -53,5 +320,5 @@
 
 typedef struct {
-	xchar x, y, chance, type;
+	xchar x, y, type;
 } trap;
 
@@ -60,6 +327,9 @@
 	short id;
 	aligntyp align;
-	xchar x, y, chance, class, appear;
+	xchar x, y, class, appear;
 	schar peaceful, asleep;
+        short female, invis, cancelled, revived, avenge, fleeing, blinded, paralyzed, stunned, confused;
+        long seentraps;
+	short has_invent;
 } monster;
 
@@ -68,6 +338,10 @@
 	int   corpsenm;
 	short id, spe;
-	xchar x, y, chance, class, containment;
+	xchar x, y, class, containment;
 	schar curse_state;
+	int   quan;
+	short buried;
+	short lit;
+        short eroded, locked, trapped, recharged, invis, greased, broken;
 } object;
 
@@ -83,5 +357,5 @@
 
 typedef struct {
-	xchar x, y, dir;
+    xchar x, y, dir, stocked, typ;
 } walk;
 
@@ -103,4 +377,16 @@
 } region;
 
+typedef struct {
+    xchar areatyp;
+    xchar x1,y1,x2,y2;
+    xchar ter, tlit;
+} terrain;
+
+typedef struct {
+    xchar chance;
+    xchar x1,y1,x2,y2;
+    xchar fromter, toter, tolit;
+} replaceterrain;
+
 /* values for rtype are defined in dungeon.h */
 typedef struct {
@@ -135,92 +421,21 @@
 } pool;
 
-typedef struct {
-	char halign, valign;
-	char xsize, ysize;
-	char **map;
-	char nrobjects;
-	char *robjects;
-	char nloc;
-	char *rloc_x;
-	char *rloc_y;
-	char nrmonst;
-	char *rmonst;
-	char nreg;
-	region **regions;
-	char nlreg;
-	lev_region **lregions;
-	char ndoor;
-	door **doors;
-	char ntrap;
-	trap **traps;
-	char nmonster;
-	monster **monsters;
-	char nobject;
-	object **objects;
-	char ndrawbridge;
-	drawbridge **drawbridges;
-	char nwalk;
-	walk **walks;
-	char ndig;
-	digpos **digs;
-	char npass;
-	digpos **passs;
-	char nlad;
-	lad **lads;
-	char nstair;
-	stair **stairs;
-	char naltar;
-	altar **altars;
-	char ngold;
-	gold **golds;
-	char nengraving;
-	engraving **engravings;
-	char nfountain;
-	fountain **fountains;
-} mazepart;
-
-typedef struct {
-	long flags;
-	lev_init init_lev;
-	schar filling;
-	char numpart;
-	mazepart **parts;
-} specialmaze;
-
 typedef struct _room {
-	char  *name;
-	char  *parent;
+	Str_or_Len name;
+	Str_or_Len parent;
 	xchar x, y, w, h;
 	xchar xalign, yalign;
 	xchar rtype, chance, rlit, filled;
-	char ndoor;
-	room_door **doors;
-	char ntrap;
-	trap **traps;
-	char nmonster;
-	monster **monsters;
-	char nobject;
-	object **objects;
-	char naltar;
-	altar **altars;
-	char nstair;
-	stair **stairs;
-	char ngold;
-	gold **golds;
-	char nengraving;
-	engraving **engravings;
-	char nfountain;
-	fountain **fountains;
-	char nsink;
-	sink **sinks;
-	char npool;
-	pool **pools;
-	/* These three fields are only used when loading the level... */
-	int nsubroom;
-	struct _room *subrooms[MAX_SUBROOMS];
-	struct mkroom *mkr;
 } room;
 
 typedef struct {
+    	schar zaligntyp;
+	schar keep_region;
+	schar halign, valign;
+	char xsize, ysize;
+	char **map;
+} mazepart;
+
+typedef struct {
 	struct {
 		xchar room;
@@ -230,17 +445,35 @@
 } corridor;
 
-/* used only by lev_comp */
 typedef struct {
-	long flags;
-	lev_init init_lev;
-	char nrobjects;
-	char *robjects;
-	char nrmonst;
-	char *rmonst;
-	xchar nroom;
-	room **rooms;
-	xchar ncorr;
-	corridor **corrs;
-} splev;
+    int opcode;
+    struct opvar *opdat;
+} _opcode;
+
+typedef struct {
+    _opcode  *opcodes;
+    long     n_opcodes;
+} sp_lev;
+
+typedef struct {
+	xchar x, y, direction, count, lit;
+	char typ;
+} spill;
+
+
+/* only used by lev_comp */
+
+struct lc_funcdefs {
+    struct lc_funcdefs *next;
+    char *name;
+    long addr;
+    sp_lev code;
+    long n_called;
+};
+
+struct lc_vardefs {
+    struct lc_vardefs *next;
+    char *name;
+    long var_type; /* SPOVAR_foo */
+};
 
 #endif /* SP_LEV_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/system.h nethack/include/system.h
--- nh_orig/include/system.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/system.h	2009-09-07 09:52:30.877293621 -0400
@@ -474,5 +474,5 @@
 #ifdef NEED_VARARGS
 # if defined(USE_STDARG) || defined(USE_VARARGS)
-#  if !defined(SVR4) && !defined(apollo)
+#  if !defined(SVR4) && !defined(apollo) && !defined(OSX)
 #   if !(defined(ULTRIX_PROTO) && defined(__GNUC__))
 #    if !(defined(SUNOS4) && defined(__STDC__)) /* Solaris unbundled cc (acc) */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/trap.h nethack/include/trap.h
--- nh_orig/include/trap.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/trap.h	2009-09-28 07:52:26.134418460 -0400
@@ -73,5 +73,8 @@
 #define ANTI_MAGIC	21
 #define POLY_TRAP	22
-#define TRAPNUM 23
+#define SPEAR_TRAP 23
+#define COLLAPSE_TRAP 24
+#define MAGIC_BEAM_TRAP	25
+#define TRAPNUM 26
 
 #endif /* TRAP_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/unixconf.h nethack/include/unixconf.h
--- nh_orig/include/unixconf.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/unixconf.h	2010-04-26 14:16:44.817948018 -0400
@@ -33,10 +33,11 @@
 
 /* define any of the following that are appropriate */
-#define SVR4		/* use in addition to SYSV for System V Release 4 */
+/* #define SVR4		/* use in addition to SYSV for System V Release 4 */
 			/* including Solaris 2+ */
 #define NETWORK		/* if running on a networked system */
 			/* e.g. Suns sharing a playground through NFS */
 /* #define SUNOS4 */	/* SunOS 4.x */
-/* #define LINUX */	/* Another Unix clone */
+#define LINUX /* Another Unix clone */
+/* #define OSX	 /* Apple OS X */
 /* #define CYGWIN32 */	/* Unix on Win32 -- use with case sensitive defines */
 /* #define GENIX */	/* Yet Another Unix Clone */
@@ -110,9 +111,7 @@
  * If defined, it can be overridden by the environment variable PAGER.
  * Hack will use its internal pager if DEF_PAGER is not defined.
- * (This might be preferable for security reasons.)
- * #define DEF_PAGER	".../mydir/mypager"
- */
-
+ * (This might be preferable for security reasons.)*/
 
+/*#define DEF_PAGER	"/usr/bin/less"*/
 
 /*
@@ -133,5 +132,5 @@
  * a fine-grained timer.
  */
-/* #define TIMED_DELAY */	/* usleep() */
+#define TIMED_DELAY /* usleep() */
 #endif
 
@@ -144,5 +143,5 @@
  */
 
-#define MAIL			/* Deliver mail during the game */
+/* #define MAIL			/* Deliver mail during the game */
 
 /* The Andrew Message System does mail a little differently from normal
@@ -210,4 +209,10 @@
 #define FCMASK	0660	/* file creation mask */
 
+/* fcntl(2) is a POSIX-portable call for manipulating file descriptors.
+ * Comment out the USE_FCNTL if for some reason you have a strange
+ * os/filesystem combination for which fcntl(2) does not work. */
+#ifdef POSIX_TYPES
+# define USE_FCNTL
+#endif
 
 /*
@@ -271,5 +276,5 @@
 #define tgetch getchar
 
-#define SHELL		/* do not delete the '!' command */
+/* #define SHELL		do not delete the '!' command */
 
 #include "system.h"
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/unixconf.h.~1~ nethack/include/unixconf.h.~1~
--- nh_orig/include/unixconf.h.~1~	1969-12-31 19:00:00.000000000 -0500
+++ nethack/include/unixconf.h.~1~	2009-08-02 13:49:33.035408669 -0400
@@ -0,0 +1,356 @@
+/*	SCCS Id: @(#)unixconf.h 3.4	1999/07/02	*/
+/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
+/* NetHack may be freely redistributed.  See license for details. */
+
+#ifdef UNIX
+#ifndef UNIXCONF_H
+#define UNIXCONF_H
+
+/*
+ * Some include files are in a different place under SYSV
+ *	BSD		   SYSV
+ * <sys/time.h>		<time.h>
+ * <sgtty.h>		<termio.h>
+ *
+ * Some routines are called differently
+ * index		strchr
+ * rindex		strrchr
+ *
+ */
+
+/* define exactly one of the following four choices */
+/* #define BSD 1 */	/* define for 4.n/Free/Open/Net BSD  */
+			/* also for relatives like SunOS 4.x, DG/UX, and */
+			/* older versions of Linux */
+/* #define ULTRIX */	/* define for Ultrix v3.0 or higher (but not lower) */
+			/* Use BSD for < v3.0 */
+			/* "ULTRIX" not to be confused with "ultrix" */
+#define SYSV		/* define for System V, Solaris 2.x, newer versions */
+			/* of Linux */
+/* #define HPUX */	/* Hewlett-Packard's Unix, version 6.5 or higher */
+			/* use SYSV for < v6.5 */
+
+
+/* define any of the following that are appropriate */
+/* #define SVR4		/* use in addition to SYSV for System V Release 4 */
+			/* including Solaris 2+ */
+#define NETWORK		/* if running on a networked system */
+			/* e.g. Suns sharing a playground through NFS */
+/* #define SUNOS4 */	/* SunOS 4.x */
+#define LINUX /* Another Unix clone */
+/* #define OSX	 /* Apple OS X */
+/* #define CYGWIN32 */	/* Unix on Win32 -- use with case sensitive defines */
+/* #define GENIX */	/* Yet Another Unix Clone */
+/* #define HISX */	/* Bull Unix for XPS Machines */
+/* #define BOS */	/* Bull Open Software - Unix for DPX/2 Machines */
+/* #define UNIXPC */	/* use in addition to SYSV for AT&T 7300/3B1 */
+/* #define AIX_31 */	/* In AIX 3.1 (IBM RS/6000) use BSD ioctl's to gain
+			 * job control (note that AIX is SYSV otherwise)
+			 * Also define this for AIX 3.2 */
+
+#define TERMINFO	/* uses terminfo rather than termcap */
+			/* Should be defined for most SYSV, SVR4 (including
+			 * Solaris 2+), HPUX, and Linux systems.  In
+			 * particular, it should NOT be defined for the UNIXPC
+			 * unless you remove the use of the shared library in
+			 * the Makefile */
+#define TEXTCOLOR	/* Use System V r3.2 terminfo color support */
+			/* and/or ANSI color support on termcap systems */
+			/* and/or X11 color */
+#define POSIX_JOB_CONTROL /* use System V / Solaris 2.x / POSIX job control */
+			/* (e.g., VSUSP) */
+#define POSIX_TYPES	/* use POSIX types for system calls and termios */
+			/* Define for many recent OS releases, including
+			 * those with specific defines (since types are
+			 * changing toward the standard from earlier chaos).
+			 * For example, platforms using the GNU libraries,
+			 * Linux, Solaris 2.x
+			 */
+
+/* #define OPENWINBUG */	/* avoid a problem using OpenWindows 3.0 for
+				   X11 on SunOS 4.1.x, x>= 2.  Do not define
+				   for other X11 implementations. */
+/* #define PYRAMID_BUG */	/* avoid a bug on the Pyramid */
+/* #define BSD_43_BUG */	/* for real 4.3BSD cc's without schain botch fix */
+/* #define MICROPORT_BUG */	/* problems with large arrays in structs */
+/* #define MICROPORT_286_BUG */ /* changes needed in termcap.c to get it to
+				   run with Microport Sys V/AT version 2.4.
+				   By Jay Maynard */
+/* #define AIXPS_2BUG */	/* avoid a problem with little_to_big() optimization */
+
+/* #define RANDOM */		/* if neither random/srandom nor lrand48/srand48
+				   is available from your system */
+
+/* see sys/unix/snd86unx.shr for more information on these */
+/* #define UNIX386MUSIC */	/* play real music through speaker on systems
+				   with music driver installed */
+/* #define VPIX_MUSIC */	/* play real music through speaker on systems
+				   with built-in VPIX support */
+
+
+/*
+ * The next two defines are intended mainly for the Andrew File System,
+ * which does not allow hard links.  If NO_FILE_LINKS is defined, lock files
+ * will be created in LOCKDIR using open() instead of in the playground using
+ * link().
+ *		Ralf Brown, 7/26/89 (from v2.3 hack of 10/10/88)
+ */
+
+/* #define NO_FILE_LINKS */	/* if no hard links */
+/* #define LOCKDIR "/usr/games/lib/nethackdir" */	/* where to put locks */
+
+/*
+ * If you want the static parts of your playground on a read-only file
+ * system, define VAR_PLAYGROUND to be where the variable parts are kept.
+ */
+/* #define VAR_PLAYGROUND "/var/lib/games/nethack" */
+
+
+/*
+ * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more"
+ * If defined, it can be overridden by the environment variable PAGER.
+ * Hack will use its internal pager if DEF_PAGER is not defined.
+ * (This might be preferable for security reasons.)*/
+
+/*#define DEF_PAGER	"/usr/bin/less"*/
+
+/*
+ * Define PORT_HELP to be the name of the port-specfic help file.
+ * This file is found in HACKDIR.
+ * Normally, you shouldn't need to change this.
+ * There is currently no port-specific help for Unix systems.
+ */
+/* #define PORT_HELP "Unixhelp" */
+
+#ifdef TTY_GRAPHICS
+/*
+ * To enable the `timed_delay' option for using a timer rather than extra
+ * screen output when pausing for display effect.  Requires that `msleep'
+ * function be available (with time argument specified in milliseconds).
+ * Various output devices can produce wildly varying delays when the
+ * "extra output" method is used, but not all systems provide access to
+ * a fine-grained timer.
+ */
+#define TIMED_DELAY /* usleep() */
+#endif
+
+/*
+ * If you define MAIL, then the player will be notified of new mail
+ * when it arrives.  If you also define DEF_MAILREADER then this will
+ * be the default mail reader, and can be overridden by the environment
+ * variable MAILREADER; otherwise an internal pager will be used.
+ * A stat system call is done on the mailbox every MAILCKFREQ moves.
+ */
+
+/* #define MAIL			/* Deliver mail during the game */
+
+/* The Andrew Message System does mail a little differently from normal
+ * UNIX.  Mail is deposited in the user's own directory in ~/Mailbox
+ * (another directory).  MAILBOX is the element that will be added on to
+ * the user's home directory path to generate the Mailbox path - just in
+ * case other Andrew sites do it differently from CMU.
+ *
+ *		dan lovinger
+ *		dl2n+@andrew.cmu.edu (dec 19 1989)
+ */
+
+/* #define AMS */		/* use Andrew message system for mail */
+
+/* NO_MAILREADER is for kerberos authenticating filesystems where it is
+ * essentially impossible to securely exec child processes, like mail
+ * readers, when the game is running under a special token.
+ *
+ *	       dan
+ */
+
+/* #define NO_MAILREADER */	/* have mail daemon just tell player of mail */
+
+#ifdef	MAIL
+# if defined(BSD) || defined(ULTRIX)
+#  ifdef AMS
+#define AMS_MAILBOX	"/Mailbox"
+#  else
+#   if defined(__FreeBSD__) || defined(__OpenBSD__)
+#define DEF_MAILREADER	"/usr/bin/mail"
+#   else
+#define DEF_MAILREADER	"/usr/ucb/Mail"
+#   endif
+#  endif
+#else
+# if (defined(SYSV) || defined(DGUX) || defined(HPUX)) && !defined(LINUX)
+#  if defined(M_XENIX)
+#define DEF_MAILREADER	"/usr/bin/mail"
+#  else
+#   ifdef __sgi
+#define DEF_MAILREADER	"/usr/sbin/Mail"
+#   else
+#define DEF_MAILREADER	"/usr/bin/mailx"
+#   endif
+#  endif
+# else
+#define DEF_MAILREADER	"/bin/mail"
+# endif
+#endif
+
+#define MAILCKFREQ	50
+#endif	/* MAIL */
+
+
+
+#ifdef COMPRESS
+/* Some implementations of compress need a 'quiet' option.
+ * If you've got one of these versions, put -q here.
+ * You can also include any other strange options your compress needs.
+ * If you have a normal compress, just leave it commented out.
+ */
+/* #define COMPRESS_OPTIONS "-q" */
+#endif
+
+#define FCMASK	0660	/* file creation mask */
+
+/* fcntl(2) is a POSIX-portable call for manipulating file descriptors.
+ * Comment out the USE_FCNTL if for some reason you have a strange
+ * os/filesystem combination for which fcntl(2) does not work. */
+#ifdef POSIX_TYPES
+# define USE_FCNTL
+#endif
+
+/*
+ * The remainder of the file should not need to be changed.
+ */
+
+#ifdef _AUX_SOURCE
+# ifdef AUX /* gcc ? */
+#  define _SYSV_SOURCE
+#  define _BSD_SOURCE
+#else
+#  define AUX
+# endif
+#endif /* _AUX_SOURCE */
+
+#if defined(LINUX) || defined(bsdi)
+# ifndef POSIX_TYPES
+#  define POSIX_TYPES
+# endif
+# ifndef POSIX_JOB_CONTROL
+#  define POSIX_JOB_CONTROL
+# endif
+#endif
+
+/*
+ * BSD/ULTRIX systems are normally the only ones that can suspend processes.
+ * Suspending NetHack processes cleanly should be easy to add to other systems
+ * that have SIGTSTP in the Berkeley sense.  Currently the only such systems
+ * known to work are HPUX and AIX 3.1; other systems will probably require
+ * tweaks to unixtty.c and ioctl.c.
+ *
+ * POSIX defines a slightly different type of job control, which should be
+ * equivalent for NetHack's purposes.  POSIX_JOB_CONTROL should work on
+ * various recent SYSV versions (with possibly tweaks to unixtty.c again).
+ */
+#ifndef POSIX_JOB_CONTROL
+# if defined(BSD) || defined(ULTRIX) || defined(HPUX) || defined(AIX_31)
+#  define BSD_JOB_CONTROL
+# else
+#  if defined(SVR4)
+#   define POSIX_JOB_CONTROL
+#  endif
+# endif
+#endif
+#if defined(BSD_JOB_CONTROL) || defined(POSIX_JOB_CONTROL) || defined(AUX)
+#define SUSPEND		/* let ^Z suspend the game */
+#endif
+
+
+#if defined(BSD) || defined(ULTRIX)
+#include <sys/time.h>
+#else
+#include <time.h>
+#endif
+
+#define HLOCK	"perm"	/* an empty file used for locking purposes */
+
+#ifndef REDO
+#define Getchar nhgetch
+#endif
+#define tgetch getchar
+
+/* #define SHELL		do not delete the '!' command */
+
+#include "system.h"
+
+#if defined(POSIX_TYPES) || defined(__GNUC__)
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
+#if defined(POSIX_TYPES) || defined(__GNUC__) || defined(BSD) || defined(ULTRIX)
+#include <sys/wait.h>
+#endif
+
+#if defined(BSD) || defined(ULTRIX)
+# if !defined(DGUX) && !defined(SUNOS4)
+#define memcpy(d, s, n)		bcopy(s, d, n)
+#define memcmp(s1, s2, n)	bcmp(s2, s1, n)
+# endif
+# ifdef SUNOS4
+#include <memory.h>
+# endif
+#else	/* therefore SYSV */
+# ifndef index	/* some systems seem to do this for you */
+#define index	strchr
+# endif
+# ifndef rindex
+#define rindex	strrchr
+# endif
+#endif
+
+/* Use the high quality random number routines. */
+#if defined(BSD) || defined(LINUX) || defined(ULTRIX) || defined(CYGWIN32) || defined(RANDOM) || defined(__APPLE__)
+#define Rand()	random()
+#else
+#define Rand()	lrand48()
+#endif
+
+#ifdef TIMED_DELAY
+# if defined(SUNOS4) || defined(LINUX) || (defined(BSD) && !defined(ULTRIX))
+# define msleep(k) usleep((k)*1000)
+# endif
+# ifdef ULTRIX
+# define msleep(k) napms(k)
+# endif
+#endif
+
+#ifdef hc	/* older versions of the MetaWare High-C compiler define this */
+# ifdef __HC__
+#  undef __HC__
+# endif
+# define __HC__ hc
+# undef hc
+#endif
+
+#if defined(GNOME_GRAPHICS)
+#if defined(LINUX)
+# include <linux/unistd.h>
+# if defined(__NR_getresuid) && defined(__NR_getresgid)	/* ie., >= v2.1.44 */
+#  define GETRES_SUPPORT
+# endif
+#else
+# if defined(BSD) || defined(SVR4)
+/*
+ * [ALI] We assume that SVR4 means we can safely include syscall.h
+ * (although it's really a BSDism). This is certainly true for Solaris 2.5,
+ * Solaris 7, Solaris 8 and Compaq Tru64 5.1
+ * Later BSD systems will have the getresid system calls.
+ */
+# include <sys/syscall.h>
+# if (defined (SYS_getuid) || defined(SYS_getresuid)) && \
+  (defined(SYS_getgid) || defined(SYS_getresgid))
+#  define GETRES_SUPPORT
+# endif
+# endif	/* BSD || SVR4 */
+#endif /* LINUX */
+#endif	/* GNOME_GRAPHICS */
+
+#endif /* UNIXCONF_H */
+#endif /* UNIX */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/wincurs.h nethack/include/wincurs.h
--- nh_orig/include/wincurs.h	1969-12-31 19:00:00.000000000 -0500
+++ nethack/include/wincurs.h	2009-09-05 11:30:14.265303603 -0400
@@ -0,0 +1,250 @@
+#ifndef WINCURS_H
+#define WINCURS_H
+
+/* Global declarations for curses interface */
+
+int term_rows, term_cols; /* size of underlying terminal */
+
+WINDOW *base_term;    /* underlying terminal window */
+
+WINDOW *mapborderwin;
+
+
+#define TEXTCOLOR   /* Allow color */
+#define NHW_END 19
+#define OFF 0
+#define ON 1
+#define NONE -1
+#define KEY_ESC 0x1b
+#define DIALOG_BORDER_COLOR CLR_MAGENTA
+#define HIGHLIGHT_COLOR CLR_WHITE
+#define MORECOLOR CLR_ORANGE
+#define STAT_UP_COLOR CLR_GREEN
+#define STAT_DOWN_COLOR CLR_RED
+#define MESSAGE_WIN 1
+#define STATUS_WIN  2
+#define MAP_WIN     3
+#define HPOS_WIN    4
+#define MESG_HISTORY_MAX   200
+
+
+typedef enum orient_type
+{
+    CENTER,
+    UP,
+    DOWN,
+    RIGHT,
+    LEFT
+} orient;
+
+
+/* cursmain.c */
+
+extern struct window_procs curses_procs;
+
+extern void curses_init_nhwindows(int* argcp, char** argv);
+
+extern void curses_player_selection(void);
+
+extern void curses_askname(void);
+
+extern void curses_get_nh_event(void);
+
+extern void curses_exit_nhwindows(const char *str);
+
+extern void curses_suspend_nhwindows(const char *str);
+
+extern void curses_resume_nhwindows(void);
+
+extern winid curses_create_nhwindow(int type);
+
+extern void curses_clear_nhwindow(winid wid);
+
+extern void curses_display_nhwindow(winid wid, BOOLEAN_P block);
+
+extern void curses_destroy_nhwindow(winid wid);
+
+extern void curses_curs(winid wid, int x, int y);
+
+extern void curses_putstr(winid wid, int attr, const char *text);
+
+extern void curses_display_file(const char *filename,BOOLEAN_P must_exist);
+
+extern void curses_start_menu(winid wid);
+
+extern void curses_add_menu(winid wid, int glyph, const ANY_P * identifier,
+		CHAR_P accelerator, CHAR_P group_accel, int attr, 
+		const char *str, BOOLEAN_P presel);
+
+extern void curses_end_menu(winid wid, const char *prompt);
+
+extern int curses_select_menu(winid wid, int how, MENU_ITEM_P **selected);
+
+extern void curses_update_inventory(void);
+
+extern void curses_mark_synch(void);
+
+extern void curses_wait_synch(void);
+
+extern void curses_cliparound(int x, int y);
+
+extern void curses_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph);
+
+extern void curses_raw_print(const char *str);
+
+extern void curses_raw_print_bold(const char *str);
+
+extern int curses_nhgetch(void);
+
+extern int curses_nh_poskey(int *x, int *y, int *mod);
+
+extern void curses_nhbell(void);
+
+extern int curses_doprev_message(void);
+
+extern char curses_yn_function(const char *question, const char *choices, CHAR_P def);
+
+extern void curses_getlin(const char *question, char *input);
+
+extern int curses_get_ext_cmd(void);
+
+extern void curses_number_pad(int state);
+
+extern void curses_delay_output(void);
+
+extern void curses_start_screen(void);
+
+extern void curses_end_screen(void);
+
+extern void curses_outrip(winid wid, int how);
+
+extern void genl_outrip(winid tmpwin, int how);
+
+extern void curses_preference_update(const char *pref);
+
+
+/* curswins.c */
+
+extern WINDOW *curses_create_window(int width, int height, orient orientation);
+
+extern void curses_destroy_win(WINDOW *win);
+
+extern WINDOW *curses_get_nhwin(winid wid);
+
+extern void curses_add_nhwin(winid wid, int height, int width, int y,
+ int x, orient orientation, boolean border);
+
+extern void curses_refresh_nhwin(winid wid);
+
+extern void curses_refresh_nethack_windows(void);
+
+extern void curses_del_nhwin(winid wid);
+
+extern void curses_putch(winid wid, int x, int y, int ch, int color, int attrs);
+
+extern void curses_get_window_size(winid wid, int *height, int *width);
+
+extern boolean curses_window_has_border(winid wid);
+
+extern boolean curses_window_exists(winid wid);
+
+extern int curses_get_window_orientation(winid wid);
+
+extern void curses_get_window_xy(winid wid, int *x, int *y);
+
+extern void curses_puts(winid wid, int attr, const char *text);
+
+
+/* cursmisc.c */
+
+extern int curses_read_char(void);
+
+extern void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff);
+
+extern void curses_bail(const char *mesg);
+
+extern winid curses_get_wid(int type);
+
+extern char *curses_copy_of(const char *s);
+
+extern int curses_num_lines(const char *str, int width);
+
+extern char *curses_break_str(const char *str, int width, int line_num);
+
+extern char *curses_str_remainder(const char *str, int width, int line_num);
+
+extern boolean curses_is_menu(winid wid);
+
+extern boolean curses_is_text(winid wid);
+
+extern int curses_convert_glyph(int ch, int glyph);
+
+extern void curses_move_cursor(winid wid, int x, int y);
+
+extern void curses_prehousekeeping(void);
+
+extern void curses_posthousekeeping(void);
+
+extern void curses_view_file(const char *filename, boolean must_exist);
+
+extern char *curses_rtrim(char *str);
+
+
+/* cursdial.c */
+
+extern void curses_line_input_dialog(const char *prompt, char *answer, int buffer);
+
+extern int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def);
+
+extern int curses_ext_cmd(void);
+
+extern void curses_create_nhmenu(winid wid);
+
+extern void curses_add_nhmenu_item(winid wid, const ANY_P *identifier,
+ CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str,
+ BOOLEAN_P presel);
+
+extern void curses_finalize_nhmenu(winid wid, const char *prompt);
+
+extern int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected);
+
+extern boolean curses_menu_exists(winid wid);
+
+extern void curses_del_menu(winid wid);
+
+
+/* cursstat.c */
+
+extern void curses_update_stats(void);
+
+extern void curses_decrement_highlight(void);
+
+
+/* cursinit.c */
+
+extern void curses_create_main_windows(void);
+
+extern void curses_init_nhcolors(void);
+
+extern void curses_choose_character(void);
+
+extern int curses_character_dialog(const char** choices, const char *prompt);
+
+extern void curses_init_options(void);
+
+
+/* cursmesg.c */
+
+extern void curses_message_win_puts(const char *message, boolean recursed);
+
+extern void curses_more(void);
+
+extern void curses_clear_unhighlight_message_window(void);
+
+extern void curses_last_messages(void);
+
+extern void curses_init_mesg_history(void);
+
+
+#endif  /* WINCURS_H */
+
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/winprocs.h nethack/include/winprocs.h
--- nh_orig/include/winprocs.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/winprocs.h	2010-04-11 12:36:57.794750618 -0400
@@ -177,6 +177,7 @@
 #define WC2_FULLSCREEN		0x01L	/* 01 display full screen                    */
 #define WC2_SOFTKEYBOARD	0x02L	/* 02 software keyboard                      */
-#define WC2_WRAPTEXT		0x04L	/* 04 wrap long lines of text                */
-					/* 29 free bits */
+#define WC2_WRAPTEXT		0x04L	/* 03 wrap long lines of text                */
+#define WC2_DARKGRAY		0x08L	/* 04 try to use "bright black" color        */
+					/* 28 free bits */
 
 #define ALIGN_LEFT	1
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/you.h nethack/include/you.h
--- nh_orig/include/you.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/you.h	2010-03-24 12:55:58.963750958 -0400
@@ -89,9 +89,5 @@
 	      ldrnum,		/* PM_ of quest leader (questpgr.c) */
 	      guardnum,		/* PM_ of quest guardians (questpgr.c) */
-	      neminum,		/* PM_ of quest nemesis (questpgr.c) */
-	      enemy1num,	/* specific quest enemies (NON_PM == random) */
-	      enemy2num;
-	char  enemy1sym,	/* quest enemies by class (S_) */
-	      enemy2sym;
+	      neminum;		/* PM_ of quest nemesis (questpgr.c) */
 	short questarti;	/* index (ART_) of quest artifact (questpgr.c) */
 
@@ -264,4 +260,6 @@
 	struct prop uprops[LAST_PROP+1];
 
+    int u_telepathy_dist;
+
 	unsigned umconf;
 	char usick_cause[PL_PSIZ+20]; /* sizeof "unicorn horn named "+1 */
@@ -345,4 +343,5 @@
 	long	ucleansed;	/* to record moves when player was cleansed */
 	long	usleep;		/* sleeping; monstermove you last started */
+	long  udiseased;  /* diseased: are you diseased, and how badly? */
 	int uinvault;
 	struct monst *ustuck;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/include/youprop.h nethack/include/youprop.h
--- nh_orig/include/youprop.h	2003-12-07 18:39:13.000000000 -0500
+++ nethack/include/youprop.h	2009-08-02 13:49:33.040407823 -0400
@@ -61,4 +61,24 @@
 				 resists_drli(&youmonst))
 
+#define HVulnerable_fire  u.uprops[VULN_FIRE].intrinsic
+#define EVulnerable_fire  u.uprops[VULN_FIRE].extrinsic
+#define Vulnerable_fire	  (HVulnerable_fire || EVulnerable_fire || \
+		vulnerable_to(&youmonst,AD_FIRE))
+
+#define HVulnerable_cold  u.uprops[VULN_COLD].intrinsic
+#define EVulnerable_cold  u.uprops[VULN_COLD].extrinsic
+#define Vulnerable_cold	  (HVulnerable_cold || EVulnerable_cold || \
+		vulnerable_to(&youmonst,AD_COLD))
+
+#define HVulnerable_elec  u.uprops[VULN_ELEC].intrinsic
+#define EVulnerable_elec  u.uprops[VULN_ELEC].extrinsic
+#define Vulnerable_elec	  (HVulnerable_elec || EVulnerable_elec || \
+		vulnerable_to(&youmonst,AD_ELEC))
+
+#define HVulnerable_acid  u.uprops[VULN_ACID].intrinsic
+#define EVulnerable_acid  u.uprops[VULN_ACID].extrinsic
+#define Vulnerable_acid	  (HVulnerable_acid || EVulnerable_acid || \
+		vulnerable_to(&youmonst,AD_ACID))
+
 /* Intrinsics only */
 #define HSick_resistance	u.uprops[SICK_RES].intrinsic
@@ -80,4 +100,10 @@
 #define Stone_resistance	(EStone_resistance || resists_ston(&youmonst))
 
+#define EWere_resistance  u.uprops[WERE_RES].extrinsic
+#define Were_resistance	  (EWere_resistance)
+
+#define EBlind_resistance  u.uprops[BLIND_RES].extrinsic
+#define Blind_resistance	(EBlind_resistance || Vision)
+
 
 /*** Troubles ***/
@@ -87,10 +113,16 @@
 /* Those implemented solely as timeouts (we use just intrinsic) */
 #define HStun			u.uprops[STUNNED].intrinsic
-#define Stunned			(HStun || u.umonnum == PM_STALKER || \
-				 youmonst.data->mlet == S_BAT)
+#define Stunned			(!Stun_resistance && \
+							(HStun || u.umonnum == PM_STALKER || youmonst.data->mlet == S_BAT))
 		/* Note: birds will also be stunned */
 
 #define HConfusion		u.uprops[CONFUSION].intrinsic
-#define Confusion		HConfusion
+#define Confusion					  (HConfusion && !Confusion_resistance)
+
+/* cheap hack to avoid breaking save */
+#define EConfusion_resistance	  u.uprops[CONFUSION].extrinsic
+#define Confusion_resistance	  EConfusion_resistance
+#define EStun_resistance		  u.uprops[STUNNED].extrinsic
+#define Stun_resistance			  EStun_resistance
 
 #define Blinded			u.uprops[BLINDED].intrinsic
@@ -98,7 +130,10 @@
 		/* ...means blind because of a cover */
 #define Blind	((Blinded || Blindfolded || !haseyes(youmonst.data)) && \
-		 !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD))
+		 !(ublindf && ublindf->oartifact == ART_EYES_OF_THE_OVERWORLD) && \
+		 !(haseyes(youmonst.data) && Blind_resistance))
+
 		/* ...the Eyes operate even when you really are blind
-		    or don't have any eyes */
+		    or don't have any eyes, but blindness resistance won't
+			 grant sight to something that didn't have it... */
 
 #define Sick			u.uprops[SICK].intrinsic
@@ -112,5 +147,5 @@
 #define HHallucination		u.uprops[HALLUC].intrinsic
 #define EHalluc_resistance	u.uprops[HALLUC_RES].extrinsic
-#define Halluc_resistance	(EHalluc_resistance || \
+#define Halluc_resistance	(EHalluc_resistance || Vision || \
 				 (Upolyd && dmgtype(youmonst.data, AD_HALU)))
 #define Hallucination		(HHallucination && !Halluc_resistance)
@@ -138,11 +173,12 @@
 #define ESee_invisible		u.uprops[SEE_INVIS].extrinsic
 #define See_invisible		(HSee_invisible || ESee_invisible || \
-				 perceives(youmonst.data))
+				 perceives(youmonst.data) || Vision)
 
 #define HTelepat		u.uprops[TELEPAT].intrinsic
 #define ETelepat		u.uprops[TELEPAT].extrinsic
-#define Blind_telepat		(HTelepat || ETelepat || \
-				 telepathic(youmonst.data))
-#define Unblind_telepat		(ETelepat)
+#define Blind_telepat		((HTelepat || ETelepat || \
+				 telepathic(youmonst.data)) && !BTelepat)
+#define Unblind_telepat		(ETelepat && !BTelepat)
+#define BTelepat	 u.uprops[TELEPAT].blocked
 
 #define HWarning		u.uprops[WARNING].intrinsic
@@ -150,4 +186,10 @@
 #define Warning			(HWarning || EWarning)
 
+/* See invisible, infravision, protection from shape changers,
+ * blindness and hallucination resistance all rolled into one */
+#define EVision		 u.uprops[VISION].extrinsic
+#define Vision			 (EVision)
+
+
 /* Warning for a specific type of monster */
 #define HWarn_of_mon		u.uprops[WARN_OF_MON].intrinsic
@@ -171,5 +213,5 @@
 #define EInfravision		u.uprops[INFRAVISION].extrinsic
 #define Infravision		(HInfravision || EInfravision || \
-				  infravision(youmonst.data))
+				  infravision(youmonst.data) || Vision)
 
 #define HDetect_monsters	u.uprops[DETECT_MONSTERS].intrinsic
@@ -241,4 +283,5 @@
 	/* May touch surface; does not override any others */
 
+#define EWwalking	   u.uprops[WWALKING].extrinsic
 #define Wwalking		(u.uprops[WWALKING].extrinsic && \
 				 !Is_waterlevel(&u.uz))
@@ -310,5 +353,6 @@
 #define Protection_from_shape_changers \
 				(HProtection_from_shape_changers || \
-				 EProtection_from_shape_changers)
+				 EProtection_from_shape_changers || \
+				 Vision)
 
 #define HPolymorph		u.uprops[POLYMORPH].intrinsic
@@ -326,9 +370,14 @@
 #define HFast			u.uprops[FAST].intrinsic
 #define EFast			u.uprops[FAST].extrinsic
-#define Fast			(HFast || EFast)
-#define Very_fast		((HFast & ~INTRINSIC) || EFast)
+#define Fast			((HFast || EFast) && !Slow)
+#define Very_fast		(((HFast & ~INTRINSIC) || EFast) && !Slow)
+
+#define HSlow		   u.uprops[SLOW].intrinsic
+#define ESlow		   u.uprops[SLOW].extrinsic
+#define Slow			(HSlow || ESlow)
 
+#define HReflecting		u.uprops[REFLECTING].intrinsic
 #define EReflecting		u.uprops[REFLECTING].extrinsic
-#define Reflecting		(EReflecting || \
+#define Reflecting		(EReflecting || HReflecting || \
 				 (youmonst.data == &mons[PM_SILVER_DRAGON]))
 
@@ -339,4 +388,6 @@
 #define Lifesaved		u.uprops[LIFESAVED].extrinsic
 
+#define ELucky				u.uprops[LUCKY].extrinsic
+#define Lucky				(ELucky)
 
 #endif /* YOUPROP_H */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/nh343-curses-a2.patch nethack/nh343-curses-a2.patch
--- nh_orig/nh343-curses-a2.patch	1969-12-31 19:00:00.000000000 -0500
+++ nethack/nh343-curses-a2.patch	2009-09-05 10:31:56.532294000 -0400
@@ -0,0 +1,9003 @@
+diff -burN nethack-3.4.3/doc/window.doc nethack/doc/window.doc
+--- nethack-3.4.3/doc/window.doc	2003-12-07 18:39:13.000000000 -0500
++++ nethack/doc/window.doc	2009-03-11 13:33:19.000000000 -0400
+@@ -518,6 +518,9 @@
+   |  fullscreen        | WC2_FULLSCREEN     | wc2_fullscreen     |boolean |
+   |  softkeyboard      | WC2_SOFTKEYBOARD   | wc2_softkeyboard   |boolean |
+   |  wraptext          | WC2_WRAPTEXT       | wc2_wraptext       |boolean |
++  |  term_cols         | WC2_TERM_COLS      | wc2_term_cols      |int     |
++  |  term_rows         | WC2_TERM_ROWS      | wc2_term_rows      |int     |
++  |  windowborders     | WC2_WINDOWBORDERS  | wc2_windowborders  |int     |
+   +--------------------+--------------------+--------------------+--------+
+ 
+ align_message	-- where to place message window (top, bottom, left, right)
+@@ -548,6 +551,8 @@
+ 		   is this number of cells away from the edge of the window.
+ softkeyboard    -- handhelds should display an on-screen keyboard if possible.
+ splash_screen   -- port should/should not display an opening splashscreen.
++term_cols       -- Terminal should size itself to specified width, if possible.
++term_rows       -- Terminal should size itself to specified height, if possible.
+ tiled_map	-- port should display a tiled map if it can.
+ tile_width	-- port should display tiles with this width or round to closest
+ 		   if it can.
+@@ -558,6 +563,8 @@
+ use_inverse	-- port should display inverse when NetHack asks for it.
+ vary_msgcount	-- port should display this number of messages at a time in
+ 		   the message window.
++windowborders   -- port should display borders around main NetHack windows.
++                Can be set to (1) on, (2) off, or (3) auto.
+ windowcolors
+ 		-- port should use these colors for window foreground/background
+ 		   colors.  Syntax:
+diff -burN nethack-3.4.3/include/config.h nethack/include/config.h
+--- nethack-3.4.3/include/config.h	2003-12-07 18:39:13.000000000 -0500
++++ nethack/include/config.h	2009-03-05 13:50:37.000000000 -0500
+@@ -42,7 +42,8 @@
+  * Define all of those you want supported in your binary.
+  * Some combinations make no sense.  See the installation document.
+  */
+-#define TTY_GRAPHICS	/* good old tty based graphics */
++/* #define TTY_GRAPHICS */	/* good old tty based graphics */
++#define CURSES_GRAPHICS     /* Proper curses interface */
+ /* #define X11_GRAPHICS */	/* X11 interface */
+ /* #define QT_GRAPHICS */	/* Qt interface */
+ /* #define GNOME_GRAPHICS */	/* Gnome interface */
+@@ -113,6 +114,15 @@
+ # define HACKDIR "\\nethack"
+ #endif
+ 
++#ifdef CURSES_GRAPHICS
++# ifdef TTY_GRAPHICS
++# undef TTY_GRAPHICS
++# endif
++# ifndef DEFAULT_WINDOW_SYS
++#  define DEFAULT_WINDOW_SYS "curses"
++# endif
++#endif
++
+ #ifndef DEFAULT_WINDOW_SYS
+ # define DEFAULT_WINDOW_SYS "tty"
+ #endif
+@@ -169,11 +179,11 @@
+ 
+ #ifdef UNIX
+ /* path and file name extension for compression program */
+-#define COMPRESS "/usr/bin/compress"	/* Lempel-Ziv compression */
+-#define COMPRESS_EXTENSION ".Z"		/* compress's extension */
++/* #define COMPRESS "/usr/bin/compress" */	/* Lempel-Ziv compression */
++/* #define COMPRESS_EXTENSION ".Z"	*/	/* compress's extension */
+ /* An example of one alternative you might want to use: */
+-/* #define COMPRESS "/usr/local/bin/gzip" */	/* FSF gzip compression */
+-/* #define COMPRESS_EXTENSION ".gz" */		/* normal gzip extension */
++#define COMPRESS "/bin/gzip"	/* FSF gzip compression */
++#define COMPRESS_EXTENSION ".gz"		/* normal gzip extension */
+ #endif
+ 
+ #ifndef COMPRESS
+diff -burN nethack-3.4.3/include/flag.h nethack/include/flag.h
+--- nethack-3.4.3/include/flag.h	2003-12-07 18:39:13.000000000 -0500
++++ nethack/include/flag.h	2009-03-05 13:50:37.000000000 -0500
+@@ -156,6 +156,7 @@
+ 
+ struct instance_flags {
+ 	boolean  cbreak;	/* in cbreak mode, rogue format */
++    boolean  cursesgraphics;    /* Use portable curses extended characters */
+ 	boolean  DECgraphics;	/* use DEC VT-xxx extended character set */
+ 	boolean  echo;		/* 1 to echo characters */
+ 	boolean  IBMgraphics;	/* use IBM extended character set */
+@@ -181,6 +182,8 @@
+ #endif
+ #ifdef TTY_GRAPHICS
+ 	char prevmsg_window;	/* type of old message window to use */
++#endif
++#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
+ 	boolean  extmenu;	/* extended commands use menu interface */
+ #endif
+ #ifdef MFLOPPY
+@@ -263,6 +266,9 @@
+ 	boolean wc2_fullscreen;		/* run fullscreen */
+ 	boolean wc2_softkeyboard;	/* use software keyboard */
+ 	boolean wc2_wraptext;		/* wrap text */
++    int     wc2_term_cols;      /* terminal width, in characters */
++    int     wc2_term_rows;      /* terminal height, in characters */
++    int     wc2_windowborders;  /* display borders on NetHack windows */
+ 
+ 	boolean  cmdassist;	/* provide detailed assistance for some commands */
+ 	boolean	 obsolete;	/* obsolete options can point at this, it isn't used */
+diff -burN nethack-3.4.3/include/ntconf.h nethack/include/ntconf.h
+--- nethack-3.4.3/include/ntconf.h	2003-12-07 18:39:13.000000000 -0500
++++ nethack/include/ntconf.h	2009-03-11 13:27:04.000000000 -0400
+@@ -159,7 +159,9 @@
+ long _RTLENTRY _EXPFUNC lseek  (int __handle, long __offset, int __fromwhere);
+ int  _RTLENTRY _EXPFUNC read  (int __handle, void _FAR *__buf, unsigned __len);
+ #endif
+-#include <conio.h>
++#ifndef CURSES_GRAPHICS
++# include <conio.h>
++#endif
+ #undef kbhit		/* Use our special NT kbhit */
+ #define kbhit (*nt_kbhit)
+ 
+diff -burN nethack-3.4.3/include/rm.h nethack/include/rm.h
+--- nethack-3.4.3/include/rm.h	2003-12-07 18:39:13.000000000 -0500
++++ nethack/include/rm.h	2009-03-05 13:50:38.000000000 -0500
+@@ -234,6 +234,7 @@
+ #define IBM_GRAPHICS	1	/* PC graphic characters */
+ #define DEC_GRAPHICS	2	/* VT100 line drawing characters */
+ #define MAC_GRAPHICS	3	/* Macintosh drawing characters */
++#define CURS_GRAPHICS   4   /* Portable curses drawing characters */
+ 
+ /*
+  * The 5 possible states of doors
+diff -burN nethack-3.4.3/include/wincurs.h nethack/include/wincurs.h
+--- nethack-3.4.3/include/wincurs.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/include/wincurs.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,250 @@
++#ifndef WINCURS_H
++#define WINCURS_H
++
++/* Global declarations for curses interface */
++
++int term_rows, term_cols; /* size of underlying terminal */
++
++WINDOW *base_term;    /* underlying terminal window */
++
++WINDOW *mapborderwin;
++
++
++#define TEXTCOLOR   /* Allow color */
++#define NHW_END 19
++#define OFF 0
++#define ON 1
++#define NONE -1
++#define KEY_ESC 0x1b
++#define DIALOG_BORDER_COLOR CLR_MAGENTA
++#define HIGHLIGHT_COLOR CLR_WHITE
++#define MORECOLOR CLR_ORANGE
++#define STAT_UP_COLOR CLR_GREEN
++#define STAT_DOWN_COLOR CLR_RED
++#define MESSAGE_WIN 1
++#define STATUS_WIN  2
++#define MAP_WIN     3
++#define HPOS_WIN    4
++#define MESG_HISTORY_MAX   200
++
++
++typedef enum orient_type
++{
++    CENTER,
++    UP,
++    DOWN,
++    RIGHT,
++    LEFT
++} orient;
++
++
++/* cursmain.c */
++
++extern struct window_procs curses_procs;
++
++extern void curses_init_nhwindows(int* argcp, char** argv);
++
++extern void curses_player_selection(void);
++
++extern void curses_askname(void);
++
++extern void curses_get_nh_event(void);
++
++extern void curses_exit_nhwindows(const char *str);
++
++extern void curses_suspend_nhwindows(const char *str);
++
++extern void curses_resume_nhwindows(void);
++
++extern winid curses_create_nhwindow(int type);
++
++extern void curses_clear_nhwindow(winid wid);
++
++extern void curses_display_nhwindow(winid wid, BOOLEAN_P block);
++
++extern void curses_destroy_nhwindow(winid wid);
++
++extern void curses_curs(winid wid, int x, int y);
++
++extern void curses_putstr(winid wid, int attr, const char *text);
++
++extern void curses_display_file(const char *filename,BOOLEAN_P must_exist);
++
++extern void curses_start_menu(winid wid);
++
++extern void curses_add_menu(winid wid, int glyph, const ANY_P * identifier,
++		CHAR_P accelerator, CHAR_P group_accel, int attr, 
++		const char *str, BOOLEAN_P presel);
++
++extern void curses_end_menu(winid wid, const char *prompt);
++
++extern int curses_select_menu(winid wid, int how, MENU_ITEM_P **selected);
++
++extern void curses_update_inventory(void);
++
++extern void curses_mark_synch(void);
++
++extern void curses_wait_synch(void);
++
++extern void curses_cliparound(int x, int y);
++
++extern void curses_print_glyph(winid wid,XCHAR_P x,XCHAR_P y,int glyph);
++
++extern void curses_raw_print(const char *str);
++
++extern void curses_raw_print_bold(const char *str);
++
++extern int curses_nhgetch(void);
++
++extern int curses_nh_poskey(int *x, int *y, int *mod);
++
++extern void curses_nhbell(void);
++
++extern int curses_doprev_message(void);
++
++extern char curses_yn_function(const char *question, const char *choices, CHAR_P def);
++
++extern void curses_getlin(const char *question, char *input);
++
++extern int curses_get_ext_cmd(void);
++
++extern void curses_number_pad(int state);
++
++extern void curses_delay_output(void);
++
++extern void curses_start_screen(void);
++
++extern void curses_end_screen(void);
++
++extern void curses_outrip(winid wid, int how);
++
++extern void genl_outrip(winid tmpwin, int how);
++
++extern void curses_preference_update(const char *pref);
++
++
++/* curswins.c */
++
++extern WINDOW *curses_create_window(int width, int height, orient orientation);
++
++extern void curses_destroy_win(WINDOW *win);
++
++extern WINDOW *curses_get_nhwin(winid wid);
++
++extern void curses_add_nhwin(winid wid, int height, int width, int y,
++ int x, orient orientation, boolean border);
++
++extern void curses_refresh_nhwin(winid wid);
++
++extern void curses_refresh_nethack_windows(void);
++
++extern void curses_del_nhwin(winid wid);
++
++extern void curses_putch(winid wid, int x, int y, int ch, int color, int attrs);
++
++extern void curses_get_window_size(winid wid, int *height, int *width);
++
++extern boolean curses_window_has_border(winid wid);
++
++extern boolean curses_window_exists(winid wid);
++
++extern int curses_get_window_orientation(winid wid);
++
++extern void curses_get_window_xy(winid wid, int *x, int *y);
++
++extern void curses_puts(winid wid, int attr, const char *text);
++
++
++/* cursmisc.c */
++
++extern int curses_read_char(void);
++
++extern void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff);
++
++extern void curses_bail(const char *mesg);
++
++extern winid curses_get_wid(int type);
++
++extern char *curses_copy_of(const char *s);
++
++extern int curses_num_lines(const char *str, int width);
++
++extern char *curses_break_str(const char *str, int width, int line_num);
++
++extern char *curses_str_remainder(const char *str, int width, int line_num);
++
++extern boolean curses_is_menu(winid wid);
++
++extern boolean curses_is_text(winid wid);
++
++extern int curses_convert_glyph(int ch, int glyph);
++
++extern void curses_move_cursor(winid wid, int x, int y);
++
++extern void curses_prehousekeeping(void);
++
++extern void curses_posthousekeeping(void);
++
++extern void curses_view_file(const char *filename, boolean must_exist);
++
++extern char *curses_rtrim(char *str);
++
++
++/* cursdial.c */
++
++extern void curses_line_input_dialog(const char *prompt, char *answer, int buffer);
++
++extern int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def);
++
++extern int curses_ext_cmd(void);
++
++extern void curses_create_nhmenu(winid wid);
++
++extern void curses_add_nhmenu_item(winid wid, const ANY_P *identifier,
++ CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str,
++ BOOLEAN_P presel);
++
++extern void curses_finalize_nhmenu(winid wid, const char *prompt);
++
++extern int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected);
++
++extern boolean curses_menu_exists(winid wid);
++
++extern void curses_del_menu(winid wid);
++
++
++/* cursstat.c */
++
++extern void curses_update_stats(void);
++
++extern void curses_decrement_highlight(void);
++
++
++/* cursinit.c */
++
++extern void curses_create_main_windows(void);
++
++extern void curses_init_nhcolors(void);
++
++extern void curses_choose_character(void);
++
++extern int curses_character_dialog(const char** choices, const char *prompt);
++
++extern void curses_init_options(void);
++
++
++/* cursmesg.c */
++
++extern void curses_message_win_puts(const char *message, boolean recursed);
++
++extern void curses_more(void);
++
++extern void curses_clear_unhighlight_message_window(void);
++
++extern void curses_last_messages(void);
++
++extern void curses_init_mesg_history(void);
++
++
++#endif  /* WINCURS_H */
++
+diff -burN nethack-3.4.3/include/winprocs.h nethack/include/winprocs.h
+--- nethack-3.4.3/include/winprocs.h	2003-12-07 18:39:13.000000000 -0500
++++ nethack/include/winprocs.h	2009-03-05 13:50:38.000000000 -0500
+@@ -176,8 +176,11 @@
+ 
+ #define WC2_FULLSCREEN		0x01L	/* 01 display full screen                    */
+ #define WC2_SOFTKEYBOARD	0x02L	/* 02 software keyboard                      */
+-#define WC2_WRAPTEXT		0x04L	/* 04 wrap long lines of text                */
+-					/* 29 free bits */
++#define WC2_WRAPTEXT		0x04L	/* 03 wrap long lines of text                */
++#define WC2_TERM_COLS		0x08L	/* 04 supports setting terminal width        */
++#define WC2_TERM_ROWS		0x10L	/* 05 supports setting terminal height       */
++#define WC2_WINDOWBORDERS	0x20L	/* 06 display borders for NetHack windows    */
++					/* 26 free bits */
+ 
+ #define ALIGN_LEFT	1
+ #define ALIGN_RIGHT	2
+diff -burN nethack-3.4.3/src/cmd.c nethack/src/cmd.c
+--- nethack-3.4.3/src/cmd.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/src/cmd.c	2009-03-05 13:50:38.000000000 -0500
+@@ -322,7 +322,7 @@
+ 	return 0;
+ }
+ 
+-#ifdef TTY_GRAPHICS
++#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
+ #define MAX_EXT_CMD 40		/* Change if we ever have > 40 ext cmds */
+ /*
+  * This is currently used only by the tty port and is
+diff -burN nethack-3.4.3/src/drawing.c nethack/src/drawing.c
+--- nethack-3.4.3/src/drawing.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/src/drawing.c	2009-03-05 13:50:38.000000000 -0500
+@@ -4,7 +4,6 @@
+ 
+ #include "hack.h"
+ #include "tcap.h"
+-
+ /* Relevent header information in rm.h and objclass.h. */
+ 
+ #ifdef C
+@@ -314,6 +313,10 @@
+ void NDECL((*ibmgraphics_mode_callback)) = 0;	/* set in tty_start_screen() */
+ #endif /* PC9800 */
+ 
++#ifdef CURSES_GRAPHICS
++void NDECL((*cursesgraphics_mode_callback)) = 0;
++#endif
++
+ static uchar ibm_graphics[MAXPCHARS] = {
+ /* 0*/	g_FILLER(S_stone),
+ 	0xb3,	/* S_vwall:	meta-3, vertical rule */
+@@ -674,6 +677,9 @@
+  */
+ 	    iflags.IBMgraphics = TRUE;
+ 	    iflags.DECgraphics = FALSE;
++#ifdef CURSES_GRAPHICS
++        iflags.cursesgraphics = FALSE;
++#endif
+ 	    assign_graphics(ibm_graphics, SIZE(ibm_graphics), MAXPCHARS, 0);
+ #ifdef PC9800
+ 	    if (ibmgraphics_mode_callback) (*ibmgraphics_mode_callback)();
+@@ -687,6 +693,9 @@
+  */
+ 	    iflags.DECgraphics = TRUE;
+ 	    iflags.IBMgraphics = FALSE;
++#ifdef CURSES_GRAPHICS
++        iflags.cursesgraphics = FALSE;
++#endif
+ 	    assign_graphics(dec_graphics, SIZE(dec_graphics), MAXPCHARS, 0);
+ 	    if (decgraphics_mode_callback) (*decgraphics_mode_callback)();
+ 	    break;
+@@ -696,6 +705,12 @@
+ 	    assign_graphics(mac_graphics, SIZE(mac_graphics), MAXPCHARS, 0);
+ 	    break;
+ #endif
++#ifdef CURSES_GRAPHICS
++    case CURS_GRAPHICS:
++	    iflags.IBMgraphics = FALSE;
++	    iflags.DECgraphics = FALSE;
++        break;
++#endif
+ 	}
+     return;
+ }
+diff -burN nethack-3.4.3/src/options.c nethack/src/options.c
+--- nethack-3.4.3/src/options.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/src/options.c	2009-03-05 13:50:38.000000000 -0500
+@@ -69,19 +69,24 @@
+ 	{"checkspace", (boolean *)0, FALSE, SET_IN_FILE},
+ #endif
+ 	{"cmdassist", &iflags.cmdassist, TRUE, SET_IN_GAME},
+-# if defined(MICRO) || defined(WIN32)
++# if defined(MICRO) || defined(WIN32) || defined(CURSES_GRAPHICS)
+ 	{"color",         &iflags.wc_color,TRUE, SET_IN_GAME},		/*WC*/
+ # else	/* systems that support multiple terminals, many monochrome */
+ 	{"color",         &iflags.wc_color, FALSE, SET_IN_GAME},	/*WC*/
+ # endif
+ 	{"confirm",&flags.confirm, TRUE, SET_IN_GAME},
++#ifdef CURSES_GRAPHICS
++	{"cursesgraphics", &iflags.cursesgraphics, TRUE, SET_IN_GAME},
++#else
++	{"cursesgraphics", (boolean *)0, FALSE, SET_IN_FILE},
++#endif
+ #if defined(TERMLIB) && !defined(MAC_GRAPHICS_ENV)
+ 	{"DECgraphics", &iflags.DECgraphics, FALSE, SET_IN_GAME},
+ #else
+ 	{"DECgraphics", (boolean *)0, FALSE, SET_IN_FILE},
+ #endif
+ 	{"eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME},	/*WC*/
+-#ifdef TTY_GRAPHICS
++#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
+ 	{"extmenu", &iflags.extmenu, FALSE, SET_IN_GAME},
+ #else
+ 	{"extmenu", (boolean *)0, FALSE, SET_IN_FILE},
+@@ -2043,6 +2048,49 @@
+ 		return;
+ 	}
+ 
++	/* WINCAP2
++	 * term_cols:amount */
++	fullname = "term_cols";
++	if (match_optname(opts, fullname, sizeof("term_cols")-1, TRUE)) {
++		op = string_for_opt(opts, negated);
++		iflags.wc2_term_cols = atoi(op);
++		if (negated) bad_negation(fullname, FALSE);
++		return;
++	}
++
++	/* WINCAP2
++	 * term_rows:amount */
++	fullname = "term_rows";
++	if (match_optname(opts, fullname, sizeof("term_rows")-1, TRUE)) {
++		op = string_for_opt(opts, negated);
++		iflags.wc2_term_rows = atoi(op);
++		if (negated) bad_negation(fullname, FALSE);
++		return;
++	}
++
++
++	/* WINCAP2
++	 * windowborders:n */
++	fullname = "windowborders";
++	if (match_optname(opts, fullname, sizeof("windowborders")-1, TRUE)) {
++		op = string_for_opt(opts, negated);
++		if (negated && op) bad_negation(fullname, TRUE);
++		else {
++		    if (negated)
++		        iflags.wc2_windowborders = 2; /* Off */
++		    else if (!op)
++		        iflags.wc2_windowborders = 1; /* On */
++		    else    /* Value supplied */
++		        iflags.wc2_windowborders = atoi(op);
++		    if ((iflags.wc2_windowborders > 3) ||
++		     (iflags.wc2_windowborders < 1)) {
++		        iflags.wc2_windowborders = 0;
++		        badoption(opts);
++		    }
++		}
++		return;
++	}
++
+ 	/* menustyle:traditional or combo or full or partial */
+ 	if (match_optname(opts, "menustyle", 4, TRUE)) {
+ 		int tmp;
+@@ -2149,7 +2197,7 @@
+ 
+ 			duplicate_opt_detection(boolopt[i].name, 0);
+ 
+-#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV)
++#if defined(TERMLIB) || defined(ASCIIGRAPH) || defined(MAC_GRAPHICS_ENV) || defined(CURSES_GRAPHICS)
+ 			if (FALSE
+ # ifdef TERMLIB
+ 				 || (boolopt[i].addr) == &iflags.DECgraphics
+@@ -2160,6 +2208,9 @@
+ # ifdef MAC_GRAPHICS_ENV
+ 				 || (boolopt[i].addr) == &iflags.MACgraphics
+ # endif
++# ifdef CURSES_GRAPHICS
++				 || (boolopt[i].addr) == &iflags.cursesgraphics
++# endif
+ 				) {
+ # ifdef REINCARNATION
+ 			    if (!initial && Is_rogue_level(&u.uz))
+@@ -2181,6 +2232,11 @@
+ 				switch_graphics(iflags.MACgraphics ?
+ 						MAC_GRAPHICS : ASCII_GRAPHICS);
+ # endif
++# ifdef CURSES_GRAPHICS
++			    if ((boolopt[i].addr) == &iflags.cursesgraphics)
++				switch_graphics(iflags.cursesgraphics ?
++						CURS_GRAPHICS : ASCII_GRAPHICS);
++# endif
+ # ifdef REINCARNATION
+ 			    if (!initial && Is_rogue_level(&u.uz))
+ 				assign_rogue_graphics(TRUE);
+@@ -2226,6 +2282,11 @@
+ 					(boolopt[i].addr) == &iflags.hilite_pet) {
+ 			    need_redraw = TRUE;
+ 			}
++#ifdef CURSES_GRAPHICS
++			else if ((boolopt[i].addr) == &iflags.cursesgraphics) {
++			    need_redraw = TRUE;
++			}
++#endif
+ #ifdef TEXTCOLOR
+ 			else if ((boolopt[i].addr) == &iflags.use_color) {
+ 			    need_redraw = TRUE;
+@@ -3087,6 +3148,14 @@
+ 			FEATURE_NOTICE_VER_MIN,
+ 			FEATURE_NOTICE_VER_PATCH);
+ 	}
++	else if (!strcmp(optname, "term_cols")) {
++		if (iflags.wc2_term_cols) Sprintf(buf, "%d",iflags.wc2_term_cols);
++		else Strcpy(buf, defopt);
++	}
++	else if (!strcmp(optname, "term_rows")) {
++		if (iflags.wc2_term_rows) Sprintf(buf, "%d",iflags.wc2_term_rows);
++		else Strcpy(buf, defopt);
++	}
+ 	else if (!strcmp(optname, "tile_file"))
+ 		Sprintf(buf, "%s", iflags.wc_tile_file ? iflags.wc_tile_file : defopt);
+ 	else if (!strcmp(optname, "tile_height")) {
+@@ -3120,6 +3189,11 @@
+ 			ttycolors[CLR_BRIGHT_MAGENTA],
+ 			ttycolors[CLR_BRIGHT_CYAN]);
+ #endif /* VIDEOSHADES */
++	else if (!strcmp(optname,"windowborders"))
++		Sprintf(buf, "%s", iflags.wc2_windowborders == 1     ? "1=on" :
++				   iflags.wc2_windowborders == 2             ? "2=off" :
++				   iflags.wc2_windowborders == 3             ? "3=auto" :
++				   defopt);
+ 	else if (!strcmp(optname, "windowtype"))
+ 		Sprintf(buf, "%s", windowprocs.name);
+ 	else if (!strcmp(optname, "windowcolors"))
+@@ -3593,6 +3667,9 @@
+ 	{"fullscreen", WC2_FULLSCREEN},
+ 	{"softkeyboard", WC2_SOFTKEYBOARD},
+ 	{"wraptext", WC2_WRAPTEXT},
++	{"term_cols", WC2_TERM_COLS},
++	{"term_rows", WC2_TERM_ROWS},
++	{"windowborders", WC2_WINDOWBORDERS},
+ 	{(char *)0, 0L}
+ };
+ 
+diff -burN nethack-3.4.3/src/rip.c nethack/src/rip.c
+--- nethack-3.4.3/src/rip.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/src/rip.c	2009-03-05 13:50:38.000000000 -0500
+@@ -8,7 +8,7 @@
+ 
+ extern const char * const killed_by_prefix[];	/* from topten.c */
+ 
+-#if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) || defined(MSWIN_GRAPHICS)
++#if defined(TTY_GRAPHICS) || defined(X11_GRAPHICS) || defined(GEM_GRAPHICS) || defined(MSWIN_GRAPHICS) || defined(CURSES_GRAPHICS)
+ # define TEXT_TOMBSTONE
+ #endif
+ #if defined(mac) || defined(__BEOS__) || defined(WIN32_GRAPHICS)
+diff -burN nethack-3.4.3/src/windows.c nethack/src/windows.c
+--- nethack-3.4.3/src/windows.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/src/windows.c	2009-03-05 13:50:38.000000000 -0500
+@@ -6,6 +6,9 @@
+ #ifdef TTY_GRAPHICS
+ #include "wintty.h"
+ #endif
++#ifdef CURSES_GRAPHICS
++extern struct window_procs curses_procs;
++#endif
+ #ifdef X11_GRAPHICS
+ /* cannot just blindly include winX.h without including all of X11 stuff */
+ /* and must get the order of include files right.  Don't bother */
+@@ -53,6 +56,9 @@
+ #ifdef TTY_GRAPHICS
+     { &tty_procs, win_tty_init },
+ #endif
++#ifdef CURSES_GRAPHICS
++    { &curses_procs, 0 },
++#endif
+ #ifdef X11_GRAPHICS
+     { &X11_procs, win_X11_init },
+ #endif
+diff -burN nethack-3.4.3/sys/unix/Makefile.src nethack/sys/unix/Makefile.src
+--- nethack-3.4.3/sys/unix/Makefile.src	2003-12-07 18:39:13.000000000 -0500
++++ nethack/sys/unix/Makefile.src	2009-03-05 13:50:38.000000000 -0500
+@@ -61,7 +61,7 @@
+ #	if you get setcgtty() warnings during execution, you are feeding gcc
+ #		a non-ANSI <sys/ioctl.h> -- either run fixincludes on it or use
+ #		-traditional in CFLAGS
+-# CC = gcc
++CC = gcc
+ #
+ #	For Bull DPX/2 systems at B.O.S. 2.0 or higher use the following:
+ #
+@@ -141,6 +141,15 @@
+ #LINK = gcc
+ #LFLAGS = -Xlinker -soname=_APP_
+ 
++# Compile with PDCurses installed in a separate directory that doesn't
++# conflict with the system curses/ncurses library
++#CFLAGS = -O -I../include -I/usr/local/include/pdcurses
++# Same as above, but for XCurses
++#CFLAGS = -O -DXCURSES -I../include -I/usr/local/include/pdcurses
++# Compile against system curses library, such as ncurses
++CFLAGS = -O -I../include
++
++
+ # Only used for the Gnome interface.
+ # When including the Gnome interface, you need to include gnome specific
+ # directories.  The ones given below is the usual spot for linux systems.
+@@ -151,8 +160,8 @@
+ # flags for debugging:
+ # CFLAGS = -g -I../include
+ 
+-CFLAGS = -O -I../include
+-LFLAGS = 
++#CFLAGS = -O -I../include
++#LFLAGS = 
+ 
+ # The Qt and Be window systems are written in C++, while the rest of
+ # NetHack is standard C.  If using Qt, uncomment the LINK line here to get
+@@ -174,6 +183,14 @@
+ 	../win/tty/wintty.c
+ WINTTYOBJ = getline.o termcap.o topl.o wintty.o
+ #
++# Files for curses interface
++WINCURSESSRC = ../win/curses/cursmain.c ../win/curses/curswins.c \
++	../win/curses/cursmisc.c ../win/curses/cursdial.c \
++	../win/curses/cursstat.c ../win/curses/cursinit.c \
++	../win/curses/cursmesg.c
++WINCURSESOBJ = cursmain.o curswins.o cursmisc.o cursdial.o cursstat.o \
++	cursinit.o cursmesg.o
++#
+ # files for an X11 port
+ # (tile.c is a generated source file)
+ WINX11SRC = ../win/X11/Window.c ../win/X11/dialogs.c ../win/X11/winX.c \
+@@ -214,8 +231,8 @@
+ 
+ #
+ #
+-WINSRC = $(WINTTYSRC)
+-WINOBJ = $(WINTTYOBJ)
++WINSRC = $(WINCURSESSRC)
++WINOBJ = $(WINCURSESOBJ)
+ 
+ # on some systems the termcap library is in -ltermcap or -lcurses
+ # on 386 Xenix, the -ltermlib tputs() seems not to work; use -lcurses instead
+@@ -231,8 +248,15 @@
+ # WINTTYLIB = -lcurses
+ # WINTTYLIB = -lcurses16
+ # WINTTYLIB = -lncurses
+-WINTTYLIB = -ltermlib
++# WINTTYLIB = -ltermlib
+ #
++# libraries for curses port
++# link with ncurses
++WINCURSESLIB = -lncurses
++# link with pdcurses for SDL, installed in a separate directory
++#WINCURSESLIB = -L/usr/local/lib/pdcurses -lpdcurses -lSDL
++# same as above, for XCurses
++#WINCURSESLIB = -L/usr/local/lib/pdcurses -lXCurses -lXawM -lXmu -lXext -lXt -lX11
+ # libraries for X11
+ # If USE_XPM is defined in config.h, you will also need -lXpm here.
+ WINX11LIB = -lXaw -lXmu -lXext -lXt -lX11
+@@ -255,7 +279,7 @@
+ # libraries for BeOS 
+ WINBELIB = -lbe
+ 
+-WINLIB = $(WINTTYLIB)
++WINLIB = $(WINCURSESLIB)
+ 
+ # any other strange libraries your system needs (for Sysunix only -- the more
+ # specialized targets should already be right)
+@@ -605,6 +629,26 @@
+ wintty.o: ../win/tty/wintty.c $(HACK_H) ../include/dlb.h \
+ 		../include/patchlevel.h ../include/tcap.h
+ 	$(CC) $(CFLAGS) -c ../win/tty/wintty.c
++cursmain.o: ../win/curses/cursmain.c $(HACK_H) ../include/wincurs.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursmain.c
++curswins.o: ../win/curses/curswins.c $(HACK_H) ../include/func_tab.h \
++		../include/wincurs.h ../win/curses/curswins.h
++	$(CC) $(CFLAGS) -c ../win/curses/curswins.c
++cursmisc.o: ../win/curses/cursmisc.c $(HACK_H) ../include/wincurs.h \
++		../win/curses/cursmisc.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursmisc.c
++cursdial.o: ../win/curses/cursdial.c $(HACK_H) ../include/func_tab.h \
++		../include/wincurs.h ../win/curses/cursdial.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursdial.c
++cursstat.o: ../win/curses/cursstat.c $(HACK_H) ../include/wincurs.h \
++		../win/curses/cursstat.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursstat.c
++cursinit.o: ../win/curses/cursinit.c $(HACK_H) ../include/wincurs.h \
++		../win/curses/cursinit.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursinit.c
++cursmesg.o: ../win/curses/cursmesg.c $(HACK_H) ../include/wincurs.h \
++		../win/curses/cursmesg.h
++	$(CC) $(CFLAGS) -c ../win/curses/cursmesg.c
+ Window.o: ../win/X11/Window.c ../include/xwindowp.h ../include/xwindow.h \
+ 		$(CONFIG_H)
+ 	$(CC) $(CFLAGS) -c ../win/X11/Window.c
+diff -burN nethack-3.4.3/sys/winnt/cursmake.gcc nethack/sys/winnt/cursmake.gcc
+--- nethack-3.4.3/sys/winnt/cursmake.gcc	1969-12-31 19:00:00.000000000 -0500
++++ nethack/sys/winnt/cursmake.gcc	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,1357 @@
++#   SCCS Id: @(#)Makefile.gcc       3.4     $Date: 2003/11/16 04:50:57 $
++#   Copyright (c) NetHack PC Development Team 1993-2003
++#
++#   NetHack 3.4.x Makefile for MinGW
++#
++#   Win32 Compilers Tested:
++#                  - MinGW 1.0 (gcc version 2.95.3-6) (Console NetHack only)
++#                  - MinGW 2.0 (gcc version 3.2)
++#
++#   If you don't have this compiler, you can get it at:
++#       http://www.mingw.org/
++#
++#   This is used for building two versions of NetHack:
++#   A tty port utilizing the Win32 Console I/O subsystem, Console
++#       NetHack;
++#   A Win32 native port built on the Windows API, Graphical NetHack or
++#       NetHackW.
++#
++#   In addition to your C compiler,
++#
++#     if you want to change     you will need a
++#     files with suffix         workalike for
++#         .y                     yacc   (such as bison)
++#         .l                     lex    (such as flex)
++#
++#
++#   If you have any questions read the sys/winnt/Install.nt file included
++#   with the distribution.
++#
++#   --
++#   Dion Nicolaas
++#==============================================================================
++# Graphical interface
++# Set to Y for a graphical version
++# Set to anything else (or undefine) for a tty version
++
++GRAPHICAL = N
++
++# Debug
++# Set to Y for Debug support (to produce debug information)
++# Set to anything else (or undefine) for a "release" version
++# You can set your debug options below.
++
++DEBUG = Y
++
++cc     = gcc
++rc     = windres
++link   = gcc
++
++cflags = -mms-bitfields
++lflags  = 
++ifeq  "$(DEBUG)" "Y"
++cdebug = -g
++linkdebug = -g
++else
++cdebug =
++linkdebug =
++endif
++
++#
++#  Set the gamedir according to your preference.
++#  If not present prior to compilation it gets created.
++
++ifeq  "$(GRAPHICAL)" "Y"
++# Game Name
++GAME    = NetHackW
++else
++# Game Name
++GAME    = NetHackC
++endif
++# Game directory
++GAMEDIR = ../binary
++
++#
++#  Source directories.    Makedefs hardcodes these, don't change them.
++#
++
++# NetHack include files
++INCL  = ../include
++# NetHack data files
++DAT   = ../dat
++# NetHack documentation files
++DOC   = ../doc
++# Utility source
++UTIL  = ../util
++# Main source
++SRC   = ../src
++# Shared system files
++SSYS  = ../sys/share
++# NT Win32 specific files
++NTSYS = ../sys/winnt
++# window port files (tty)
++#TTY   = ../win/tty
++TTY   = ../win/curses
++# window port files (Win32)
++WIN32 = ../win/win32
++# Tile support files
++WSHR  = ../win/share
++
++#
++#  Object directory.
++#
++
++OBJ = o
++
++
++#
++#==========================================
++# Exe File Info.
++#==========================================
++
++# Yacc/Lex ... if you got 'em.
++#
++# If you have yacc and lex programs (or work-alike such as bison
++# and flex), comment out the upper two macros and uncomment
++# the lower two.
++#
++
++DO_YACC = YACC_MSG
++DO_LEX  = LEX_MSG
++#DO_YACC  = YACC_ACT
++#DO_LEX   = LEX_ACT
++
++# - Specify your yacc and lex programs (or work-alikes) here.
++
++#YACC   = bison -y
++YACC   = byacc
++#YACC   = yacc
++
++#LEX    = lex
++LEX     = flex
++
++#
++# - Specify your flex skeleton file (if needed).
++#
++
++FLEXSKEL =
++#FLEXSKEL = -S../tools/flex.ske
++
++YTABC   = y_tab.c
++YTABH   = y_tab.h
++LEXYYC  = lexyy.c
++
++#
++# Optional high-quality BSD random number generation routines
++# (see pcconf.h). Set to nothing if not used.
++#
++
++RANDOM  = $(OBJ)/random.o
++#RANDOM =
++
++#===============================================
++#======= End of Modification Section ===========
++#===============================================
++################################################
++#                                              #
++# Nothing below here should have to be changed.#
++#                                              #
++################################################
++
++ifeq  "$(GRAPHICAL)" "Y"
++WINPORT  = $(O)tile.o $(O)mhaskyn.o $(O)mhdlg.o \
++	$(O)mhfont.o $(O)mhinput.o $(O)mhmain.o $(O)mhmap.o \
++	$(O)mhmenu.o $(O)mhmsgwnd.o $(O)mhrip.o $(O)mhsplash.o \
++	$(O)mhstatus.o $(O)mhtext.o $(O)mswproc.o $(O)winhack.o
++WINPFLAG   = -DTILES -DMSWIN_GRAPHICS -D_WIN32_IE=0x0400
++NHRES   = $(O)winres.o
++WINPINC = -I$(WIN32)
++WINPHDR = $(WIN32)/mhaskyn.h $(WIN32)/mhdlg.h $(WIN32)/mhfont.h \
++	$(WIN32)/mhinput.h $(WIN32)/mhmain.h $(WIN32)/mhmap.h \
++	$(WIN32)/mhmenu.h $(WIN32)/mhmsg.h $(WIN32)/mhmsgwnd.h \
++	$(WIN32)/mhrip.h $(WIN32)/mhstatus.h \
++	$(WIN32)/mhtext.h $(WIN32)/resource.h $(WIN32)/winMS.h
++WINPLIBS =  -lcomctl32 -lwinmm
++else
++WINPORT = $(O)nttty.o
++#WINPFLAG= -DWIN32CON
++WINPHDR =
++NHRES   = $(O)console.o
++WINPINC =
++#WINPLIBS = ../lib/pdcurses.a -lwinmm
++WINPLIBS = ../lib/libpdcurses.a ../lib/libSDL.a -lwinmm
++endif
++
++TILEUTIL16  = $(UTIL)/tile2bmp.exe
++TILEBMP16   = $(SRC)/tiles.bmp
++
++TILEUTIL32  = $(UTIL)/til2bm32.exe
++TILEBMP32   = $(SRC)/tiles32.bmp
++
++SOUND = $(OBJ)/ntsound.o
++
++#SOUND =
++
++# To store all the level files,
++# help files, etc. in a single library file.
++# USE_DLB = Y is left uncommented
++
++USE_DLB = Y
++
++ifeq  "$(USE_DLB)" "Y"
++DLBFLG = -DDLB
++else
++DLBFLG =
++endif
++
++#==========================================
++# Setting up the compiler and linker
++# macros. All builds include the base ones.
++#==========================================
++
++CFLAGSBASE  = -c $(cflags) -I$(INCL) $(WINPINC) $(cdebug)
++LFLAGSBASEC = $(linkdebug) -mwindows
++LFLAGSBASEG = $(linkdebug) -mwindows
++
++#==========================================
++# Util builds
++#==========================================
++
++CFLAGSU = $(CFLAGSBASE) $(WINPFLAG)
++LFLAGSU = $(LFLAGSBASEC)
++
++#==========================================
++# - Game build
++#==========================================
++
++CFLAGS   = $(CFLAGSBASE) $(WINPFLAG) $(DLBFLG)
++lflags  = $(LFLAGSBASE)
++ifeq "$(GRAPHICAL)" "Y"
++lflags  = $(LFLAGSBASEG)
++else
++lflags  = $(LFLAGSBASEC)
++endif
++
++GAMEFILE = $(GAMEDIR)/$(GAME).exe # whole thing
++
++ifeq  "$(USE_DLB)" "Y"
++DLB = nhdat
++else
++DLB =
++endif
++
++#==========================================
++#================ RULES ==================
++#==========================================
++
++.SUFFIXES: .exe .o .til .uu .c .y .l
++
++#==========================================
++# Rules for files in src
++#==========================================
++
++$(OBJ)/%.o : /%.c
++	$(cc) $(CFLAGS)  -o$@ $<
++
++$(OBJ)/%.o : $(SRC)/%.c
++	$(cc) $(CFLAGS)   -o$@  $<
++
++#==========================================
++# Rules for files in sys/share
++#==========================================
++
++$(OBJ)/%.o : $(SSYS)/%.c
++	$(cc) $(CFLAGS)  -o$@  $<
++
++#==========================================
++# Rules for files in sys/winnt
++#==========================================
++
++$(OBJ)/%.o : $(NTSYS)/%.c
++	$(cc) $(CFLAGS)  -o$@  $<
++
++$(INCL)/%.h : $(NTSYS)/%.h
++	@copy $< $@
++
++#==========================================
++# Rules for files in util
++#==========================================
++
++$(OBJ)/%.o : $(UTIL)/%.c
++	$(cc) $(CFLAGSU) -o$@ $<
++
++#==========================================
++# Rules for files in win/share
++#==========================================
++
++$(OBJ)/%.o : $(WSHR)/%.c
++	$(cc) $(CFLAGS)  -o$@ $<
++
++$(INCL)/%.h : $(WSHR)/%.h
++	@copy $< $@
++
++#{$(WSHR)}.txt{$(DAT)}.txt:
++#	@copy $< $@
++
++#==========================================
++# Rules for files in win/tty
++#==========================================
++
++$(OBJ)/%.o : $(TTY)/%.c
++	$(cc) $(CFLAGS)  -o$@  $<
++
++#==========================================
++# Rules for files in win/win32
++#==========================================
++
++$(OBJ)/%.o : $(WIN32)/%.c
++	$(cc) $(CFLAGS)  -o$@  $<
++
++#==========================================
++#================ MACROS ==================
++#==========================================
++# This section creates shorthand macros for many objects
++# referenced later on in the Makefile.
++#
++
++DEFFILE = $(NTSYS)/$(GAME).def
++
++#
++# Shorten up the location for some files
++#
++
++O  = $(OBJ)/
++
++U  = $(UTIL)/
++
++#
++# Utility Objects.
++#
++
++MAKESRC        = $(U)makedefs.c
++
++SPLEVSRC       = $(U)lev_yacc.c  $(U)lev_$(LEX).c $(U)lev_main.c  $(U)panic.c
++
++DGNCOMPSRC     = $(U)dgn_yacc.c  $(U)dgn_$(LEX).c $(U)dgn_main.c
++
++MAKEOBJS       = $(O)makedefs.o $(O)monst.o $(O)objects.o
++
++SPLEVOBJS      = $(O)lev_yacc.o  $(O)lev_$(LEX).o $(O)lev_main.o \
++	$(O)alloc.o   $(O)decl.o      $(O)drawing.o \
++	$(O)monst.o   $(O)objects.o   $(O)panic.o
++
++DGNCOMPOBJS    = $(O)dgn_yacc.o  $(O)dgn_$(LEX).o $(O)dgn_main.o \
++	$(O)alloc.o   $(O)panic.o
++
++RECOVOBJS      = $(O)recover.o
++
++TILEFILES      = $(WSHR)/monsters.txt $(WSHR)/objects.txt $(WSHR)/other.txt
++
++#
++# These are not invoked during a normal game build in 3.4
++#
++TEXT_IO        = $(O)tiletext.o  $(O)tiletxt.o   $(O)drawing.o \
++	$(O)decl.o    $(O)monst.o     $(O)objects.o
++
++TEXT_IO32      = $(O)tilete32.o $(O)tiletx32.o $(O)drawing.o \
++	$(O)decl.o    $(O)monst.o     $(O)objects.o
++
++GIFREADERS     = $(O)gifread.o   $(O)alloc.o $(O)panic.o
++GIFREADERS32   = $(O)gifrd32.o $(O)alloc.o $(O)panic.o
++
++PPMWRITERS     = $(O)ppmwrite.o $(O)alloc.o $(O)panic.o
++
++#
++#  Object files for the game itself.
++#
++
++VOBJ01 = $(O)allmain.o  $(O)alloc.o    $(O)apply.o    $(O)artifact.o
++VOBJ02 = $(O)attrib.o   $(O)ball.o     $(O)bones.o    $(O)botl.o
++VOBJ03 = $(O)cmd.o      $(O)dbridge.o  $(O)decl.o     $(O)detect.o
++VOBJ04 = $(O)dig.o      $(O)display.o  $(O)do.o       $(O)do_name.o
++VOBJ05 = $(O)do_wear.o  $(O)dog.o      $(O)dogmove.o  $(O)dokick.o
++VOBJ06 = $(O)dothrow.o  $(O)drawing.o  $(O)dungeon.o  $(O)eat.o
++VOBJ07 = $(O)end.o      $(O)engrave.o  $(O)exper.o    $(O)explode.o
++VOBJ08 = $(O)extralev.o $(O)files.o    $(O)fountain.o $(O)hack.o
++VOBJ09 = $(O)hacklib.o  $(O)invent.o   $(O)light.o    $(O)lock.o
++VOBJ10 = $(O)mail.o     $(O)makemon.o  $(O)mapglyph.o $(O)mcastu.o
++VOBJ11 = $(O)mhitm.o    $(O)mhitu.o    $(O)minion.o   $(O)mklev.o
++VOBJ12 = $(O)mkmap.o    $(O)mkmaze.o   $(O)mkobj.o    $(O)mkroom.o
++VOBJ13 = $(O)mon.o      $(O)mondata.o  $(O)monmove.o  $(O)monst.o
++VOBJ14 = $(O)monstr.o   $(O)mplayer.o  $(O)mthrowu.o  $(O)muse.o
++VOBJ15 = $(O)music.o    $(O)o_init.o   $(O)objects.o  $(O)objnam.o
++VOBJ16 = $(O)options.o  $(O)pager.o    $(O)pickup.o   $(O)pline.o
++VOBJ17 = $(O)polyself.o $(O)potion.o   $(O)pray.o     $(O)priest.o
++VOBJ18 = $(O)quest.o    $(O)questpgr.o $(RANDOM)      $(O)read.o
++VOBJ19 = $(O)rect.o     $(O)region.o   $(O)restore.o  $(O)rip.o
++VOBJ20 = $(O)rnd.o      $(O)role.o     $(O)rumors.o   $(O)save.o
++VOBJ21 = $(O)shk.o      $(O)shknam.o   $(O)sit.o      $(O)sounds.o
++VOBJ22 = $(O)sp_lev.o   $(O)spell.o    $(O)steal.o    $(O)steed.o
++VOBJ23 = $(O)teleport.o $(O)timeout.o  $(O)topten.o   $(O)track.o
++VOBJ24 = $(O)trap.o     $(O)u_init.o   $(O)uhitm.o    $(O)vault.o
++VOBJ25 = $(O)vis_tab.o  $(O)vision.o   $(O)weapon.o   $(O)were.o
++VOBJ26 = $(O)wield.o    $(O)windows.o  $(O)wizard.o   $(O)worm.o
++VOBJ27 = $(O)worn.o     $(O)write.o    $(O)zap.o
++
++DLBOBJ = $(O)dlb.o
++
++#TTYOBJ = $(O)topl.o     $(O)getline.o  $(O)wintty.o
++TTYOBJ = $(O)cursmain.o $(O)curswins.o  $(O)cursmisc.o $(O)cursdial.o \
++	$(O)cursstat.o $(O)cursinit.o $(O)cursmesg.o 
++
++SOBJ   = $(O)winnt.o    $(O)pcsys.o      $(O)pcunix.o  \
++	$(SOUND) $(O)pcmain.o $(O)mapimail.o $(O)nhlan.o
++
++OBJS   = $(VOBJ01) $(VOBJ02) $(VOBJ03) $(VOBJ04) $(VOBJ05) \
++	$(VOBJ06) $(VOBJ07) $(VOBJ08) $(VOBJ09) $(VOBJ10) \
++	$(VOBJ11) $(VOBJ12) $(VOBJ13) $(VOBJ14) $(VOBJ15) \
++	$(VOBJ16) $(VOBJ17) $(VOBJ18) $(VOBJ19) $(VOBJ20) \
++	$(VOBJ21) $(VOBJ22) $(VOBJ23) $(VOBJ24) $(VOBJ25) \
++	$(VOBJ26) $(VOBJ27)
++
++WINPOBJ = $(WINPORT)
++
++VVOBJ  = $(O)version.o
++
++ALLOBJ  = $(WINPOBJ) $(SOBJ) $(DLBOBJ)  $(TTYOBJ) $(WOBJ) $(OBJS) $(VVOBJ)
++
++ifeq "$(GRAPHICAL)" "Y"
++OPTIONS_FILE = $(DAT)/guioptions
++else
++OPTIONS_FILE = $(DAT)/ttyoptions
++endif
++
++#==========================================
++# Header file macros
++#==========================================
++
++CONFIG_H = $(INCL)/config.h $(INCL)/config1.h $(INCL)/tradstdc.h \
++	       $(INCL)/global.h $(INCL)/coord.h $(INCL)/vmsconf.h \
++	       $(INCL)/system.h $(INCL)/unixconf.h $(INCL)/os2conf.h \
++	       $(INCL)/micro.h $(INCL)/pcconf.h $(INCL)/tosconf.h \
++	       $(INCL)/amiconf.h $(INCL)/macconf.h $(INCL)/beconf.h \
++	       $(INCL)/ntconf.h $(INCL)/nhlan.h
++
++HACK_H = $(INCL)/hack.h $(CONFIG_H) $(INCL)/align.h \
++	       $(INCL)/dungeon.h $(INCL)/monsym.h $(INCL)/mkroom.h \
++	       $(INCL)/objclass.h $(INCL)/youprop.h $(INCL)/prop.h \
++	       $(INCL)/permonst.h $(INCL)/monattk.h \
++	       $(INCL)/monflag.h $(INCL)/mondata.h $(INCL)/pm.h \
++	       $(INCL)/wintype.h $(INCL)/decl.h $(INCL)/quest.h \
++	       $(INCL)/spell.h $(INCL)/color.h $(INCL)/obj.h \
++	       $(INCL)/you.h $(INCL)/attrib.h $(INCL)/monst.h \
++	       $(INCL)/skills.h $(INCL)/onames.h $(INCL)/timeout.h \
++	       $(INCL)/trap.h $(INCL)/flag.h $(INCL)/rm.h \
++	       $(INCL)/vision.h $(INCL)/display.h $(INCL)/engrave.h \
++	       $(INCL)/rect.h $(INCL)/region.h $(INCL)/winprocs.h \
++	       $(INCL)/wintty.h $(INCL)/trampoli.h
++
++LEV_H       = $(INCL)/lev.h
++DGN_FILE_H  = $(INCL)/dgn_file.h
++LEV_COMP_H  = $(INCL)/lev_comp.h
++SP_LEV_H    = $(INCL)/sp_lev.h
++TILE_H      = ../win/share/tile.h
++
++#==========================================
++# Miscellaneous
++#==========================================
++
++DATABASE = $(DAT)/data.base
++
++#
++#  The name of the game.
++#
++
++GAMEFILE = $(GAMEDIR)/$(GAME).exe
++
++
++#==========================================
++#=============== TARGETS ==================
++#==========================================
++
++# Since DOS doesn't allow / as path separator, and GCC doesn't allow \ as
++# path separator, we must change all pathnames when performing DOS commands.
++# This is done by blindly applying $(subst /,\, ...) on every command.
++# Where any command contain / for another reason (switch char, or echoing
++# comment lines to lev/dungeon files) a little more care is taken.
++
++#
++#  The default make target (so just typing 'nmake' is useful).
++#
++default : $(GAMEFILE)
++
++#
++#  The main target.
++#
++
++$(GAME) : $(O)obj.tag $(O)utility.tag graphicschk $(GAMEFILE)
++	@echo $(GAME) is up to date.
++
++#
++#  Everything
++#
++
++all :   install
++
++install: graphicschk $(GAME) $(O)install.tag
++	@echo Done.
++
++
++$(O)install.tag:  $(DAT)/data    $(DAT)/rumors    $(DAT)/dungeon \
++	       $(DAT)/oracles $(DAT)/quest.dat $(O)sp_lev.tag $(DLB)
++ifeq  "$(USE_DLB)" "Y"
++	$(subst /,\,copy nhdat                $(GAMEDIR))
++	$(subst /,\,copy $(DAT)/license       $(GAMEDIR))
++	$(subst /,\,copy $(DAT)/opthelp       $(GAMEDIR))
++else
++	$(subst /,\,copy $(DAT)/*.            $(GAMEDIR))
++	$(subst /,\,copy $(DAT)/*.dat         $(GAMEDIR))
++	$(subst /,\,copy $(DAT)/*.lev         $(GAMEDIR))
++	$(subst /,\,if exist $(GAMEDIR)/makefile del $(GAMEDIR)/makefile)
++endif
++	$(subst /,\,if exist $(DOC)/guidebook.txt copy $(DOC)/guidebook.txt $(GAMEDIR)/Guidebook.txt)
++	$(subst /,\,if exist $(DOC)/nethack.txt copy $(DOC)/nethack.txt $(GAMEDIR)/NetHack.txt)
++	$(subst /,\,copy $(NTSYS)/defaults.nh   $(GAMEDIR)/defaults.nh)
++	$(subst /,\,echo install done > $@)
++
++#  copy $(NTSYS)/winnt.hlp    $(GAMEDIR)
++
++recover: $(U)recover.exe
++	$(subst /,\,if exist $(U)recover.exe copy $(U)recover.exe  $(GAMEDIR))
++	$(subst /,\,if exist $(DOC)/recover.txt copy $(DOC)/recover.txt $(GAMEDIR)/recover.txt)
++
++$(O)sp_lev.tag: $(O)utility.tag $(DAT)/bigroom.des  $(DAT)/castle.des \
++	 $(DAT)/endgame.des $(DAT)/gehennom.des $(DAT)/knox.des   \
++	 $(DAT)/medusa.des  $(DAT)/oracle.des   $(DAT)/tower.des  \
++	 $(DAT)/yendor.des  $(DAT)/arch.des     $(DAT)/barb.des   \
++	 $(DAT)/caveman.des $(DAT)/healer.des   $(DAT)/knight.des \
++	 $(DAT)/monk.des    $(DAT)/priest.des   $(DAT)/ranger.des \
++	 $(DAT)/rogue.des   $(DAT)/samurai.des  $(DAT)/sokoban.des \
++	 $(DAT)/tourist.des $(DAT)/valkyrie.des $(DAT)/wizard.des
++	$(subst /,\,$(U)lev_comp $(DAT)/bigroom.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/castle.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/endgame.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/gehennom.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/knox.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/mines.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/medusa.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/oracle.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/sokoban.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/tower.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/yendor.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/arch.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/barb.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/caveman.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/healer.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/knight.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/monk.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/priest.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/ranger.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/rogue.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/samurai.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/tourist.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/valkyrie.des)
++	$(subst /,\,$(U)lev_comp $(DAT)/wizard.des)
++	$(subst /,\,copy *.lev $(DAT))
++	$(subst /,\,del *.lev)
++	$(subst /,\,echo sp_levs done > $(O)sp_lev.tag)
++
++$(O)utility.tag: $(INCL)/date.h $(INCL)/onames.h $(INCL)/pm.h \
++	 $(SRC)/monstr.c $(SRC)/vis_tab.c $(U)lev_comp.exe $(INCL)/vis_tab.h \
++	 $(U)dgn_comp.exe $(TILEUTIL16)
++	$(subst /,\,@echo utilities made >$@)
++	@echo utilities made.
++
++tileutil: $(U)gif2txt.exe $(U)gif2tx32.exe $(U)txt2ppm.exe
++	@echo Optional tile development utilities are up to date.
++
++ifeq  "$(GRAPHICAL)" "Y"
++$(NHRES): $(TILEBMP16) $(WIN32)/winhack.rc $(WIN32)/mnsel.bmp \
++	 $(WIN32)/mnselcnt.bmp $(WIN32)/mnunsel.bmp \
++	 $(WIN32)/petmark.bmp $(WIN32)/NetHack.ico $(WIN32)/rip.bmp \
++	 $(WIN32)/splash.bmp
++	@$(rc) -o$@ --include-dir $(WIN32) -i $(WIN32)/winhack.rc
++else
++$(NHRES): $(NTSYS)/console.rc $(NTSYS)/NetHack.ico 
++	@$(rc) -o$@ --include-dir $(NTSYS) -i $(NTSYS)/console.rc
++endif
++
++#==========================================
++#  The main target.
++#==========================================
++$(O)gamedir.tag:
++	$(subst /,\,@if not exist $(GAMEDIR)/*.* echo creating directory $(GAMEDIR))
++	$(subst /,\,@if not exist $(GAMEDIR)/*.* mkdir $(GAMEDIR))
++	$(subst /,\,@echo directory created > $@)
++
++ifeq  "$(GRAPHICAL)" "Y"
++$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag
++else
++#$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag \
++#	 $(GAMEDIR)/nhdefkey.dll $(GAMEDIR)/nh340key.dll $(GAMEDIR)/nhraykey.dll
++$(GAMEFILE) : $(ALLOBJ) $(NHRES) $(O)gamedir.tag
++endif
++	@echo Linking....
++	$(link) $(lflags) -o$@ $(ALLOBJ) $(NHRES) $(WINPLIBS)
++	$(subst /,\,@if exist $(O)install.tag del $(O)install.tag)
++
++
++$(O)nhdefkey.o:
++	$(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nhdefkey.c 
++
++$(GAMEDIR)/nhdefkey.dll : $(O)nhdefkey.o $(O)gamedir.tag
++	@echo Linking $@
++	$(cc) -shared -Wl,--export-all-symbols \
++		-Wl,--add-stdcall-alias -o $@ $<
++
++$(O)nh340key.o:
++	$(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nh340key.c 
++
++$(GAMEDIR)/nh340key.dll : $(O)nh340key.o $(O)gamedir.tag
++	@echo Linking $@
++	$(cc) -shared -Wl,--export-all-symbols \
++		-Wl,--add-stdcall-alias -o $@ $<
++
++$(O)nhraykey.o:
++		$(cc) $(CFLAGS) -DBUILD_DLL -o$@ $(NTSYS)/nhraykey.c 
++
++$(GAMEDIR)/nhraykey.dll : $(O)nhraykey.o $(O)gamedir.tag
++	@echo Linking $@
++	$(cc) -shared -Wl,--export-all-symbols \
++		-Wl,--add-stdcall-alias -o $@ $<
++
++$(GAME)_.ico : $(NTSYS)/$(GAME).ico
++	$(subst /,\,@copy $(NTSYS)/$(GAME).ico $@)
++
++#==========================================
++# Create directory for holding object files
++#==========================================
++
++graphicschk:
++ifeq  "$(GRAPHICAL)" "Y"
++	@echo ----
++	@echo NOTE: This build will include tile support.
++	@echo ----
++endif
++	$(subst /,\,@echo graphicschk > graphicschk)
++
++#
++#  Secondary Targets.
++#
++
++#==========================================
++# Makedefs Stuff
++#==========================================
++
++$(U)makedefs.exe: $(MAKEOBJS)
++	@$(link) $(LFLAGSU) -o$@ $(MAKEOBJS)
++
++$(O)makedefs.o: $(CONFIG_H) $(INCL)/monattk.h $(INCL)/monflag.h \
++	 $(INCL)/objclass.h $(INCL)/monsym.h $(INCL)/qtext.h \
++	 $(INCL)/patchlevel.h $(U)makedefs.c $(O)obj.tag
++	$(cc) $(CFLAGSU) -o$@ $(U)makedefs.c
++
++#
++#  date.h should be remade every time any of the source or include
++#  files is modified.
++#
++
++$(INCL)/date.h $(OPTIONS_FILE): $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -v)
++
++#$(OPTIONS_FILE): $(U)makedefs.exe
++#	$(subst /,\,$(U)makedefs -v)
++
++$(INCL)/onames.h : $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -o)
++
++$(INCL)/pm.h : $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -p)
++
++#$(INCL)/trap.h : $(U)makedefs.exe
++#  $(U)makedefs -t
++
++$(SRC)/monstr.c: $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -m)
++
++$(INCL)/vis_tab.h: $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -z)
++
++$(SRC)/vis_tab.c: $(U)makedefs.exe
++	$(subst /,\,$(U)makedefs -z)
++
++#==========================================
++# uudecode utility and uuencoded targets
++#==========================================
++
++$(U)uudecode.exe: $(O)uudecode.o
++	@$(link) $(LFLAGSU) -o$@ $(O)uudecode.o
++
++$(O)uudecode.o: $(SSYS)/uudecode.c
++
++$(NTSYS)/NetHack.ico : $(U)uudecode.exe $(NTSYS)/nhico.uu
++	$(subst /,\,$(U)uudecode.exe $(NTSYS)/nhico.uu)
++	$(subst /,\,copy NetHack.ico $@)
++	del NetHack.ico
++
++$(WIN32)/NetHack.ico : $(NTSYS)/NetHack.ico
++	$(subst /,\,copy $< $@)
++
++$(WIN32)/mnsel.bmp: $(U)uudecode.exe $(WIN32)/mnsel.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/mnsel.uu)
++	$(subst /,\,copy mnsel.bmp $@)
++	del mnsel.bmp
++
++$(WIN32)/mnselcnt.bmp: $(U)uudecode.exe $(WIN32)/mnselcnt.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/mnselcnt.uu)
++	$(subst /,\,copy mnselcnt.bmp $@)
++	del mnselcnt.bmp
++
++$(WIN32)/mnunsel.bmp: $(U)uudecode.exe $(WIN32)/mnunsel.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/mnunsel.uu)
++	$(subst /,\,copy mnunsel.bmp $@)
++	del mnunsel.bmp
++
++$(WIN32)/petmark.bmp: $(U)uudecode.exe $(WIN32)/petmark.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/petmark.uu)
++	$(subst /,\,copy petmark.bmp $@)
++	del petmark.bmp
++
++$(WIN32)/rip.bmp: $(U)uudecode.exe $(WIN32)/rip.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/rip.uu)
++	$(subst /,\,copy rip.bmp $@)
++	del rip.bmp
++
++$(WIN32)/splash.bmp: $(U)uudecode.exe $(WIN32)/splash.uu
++	$(subst /,\,$(U)uudecode.exe $(WIN32)/splash.uu)
++	$(subst /,\,copy splash.bmp $@)
++	del splash.bmp
++
++
++#==========================================
++# Level Compiler Stuff
++#==========================================
++
++LEVCFLAGS=$(cflags) -c -DWIN32 -D_WIN32 -I../include $(cdebug) -DDLB
++
++$(U)lev_comp.exe: $(SPLEVOBJS)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(SPLEVOBJS)
++
++$(O)lev_yacc.o: $(HACK_H)   $(SP_LEV_H) $(INCL)/lev_comp.h $(U)lev_yacc.c
++	$(cc) $(LEVCFLAGS) -o$@ $(U)lev_yacc.c
++
++$(O)lev_$(LEX).o: $(HACK_H)   $(INCL)/lev_comp.h $(SP_LEV_H) \
++	$(U)lev_$(LEX).c
++	$(cc) $(LEVCFLAGS) -o$@ $(U)lev_$(LEX).c
++
++$(O)lev_main.o:   $(U)lev_main.c $(HACK_H)   $(SP_LEV_H)
++	$(cc) $(LEVCFLAGS) -o$@ $(U)lev_main.c
++
++
++$(U)lev_yacc.c $(INCL)/lev_comp.h : $(U)lev_comp.y
++ifeq  "$(DO_YACC)" "YACC_ACT"
++	$(subst /,\,$(YACC) -d $(U)lev_comp.y)
++	$(subst /,\,copy $(YTABC) $(U)lev_yacc.c)
++	$(subst /,\,copy $(YTABH) $(INCL)/lev_comp.h)
++	$(subst /,\,@del $(YTABC))
++	$(subst /,\,@del $(YTABH))
++
++else
++	@echo $(U)lev_comp.y has changed.
++	@echo To update $(U)lev_yacc.c and $(INCL)/lev_comp.h run $(YACC).
++	@echo ---
++	@echo For now, we will copy the prebuilt lev_yacc.c and
++	@echo lev_comp.h from $(SSYS) into $(UTIL) and use them.
++	$(subst /,\,@copy $(SSYS)/lev_yacc.c $(U)lev_yacc.c >nul)
++	$(subst /,\,@copy $(SSYS)/lev_comp.h $(INCL)/lev_comp.h >nul)
++	$(subst /,\,echo.>>$(U)lev_yacc.c)
++	$(subst /,\,echo.>>$(INCL)/lev_comp.h)
++endif
++
++$(U)lev_$(LEX).c: $(U)lev_comp.l
++ifeq  "$(DO_LEX)" "LEX_ACT"
++	$(subst /,\,$(LEX) $(FLEXSKEL) $(U)lev_comp.l)
++	$(subst /,\,copy $(LEXYYC) $@)
++	$(subst /,\,@del $(LEXYYC))
++else
++	@echo $(U)lev_comp.l has changed. To update $@ run $(LEX).
++	@echo ---
++	@echo For now, we will copy the prebuilt lev_lex.c
++	@echo from $(SSYS) into $(UTIL) and use it.
++	$(subst /,\,@copy $(SSYS)/lev_lex.c $@ >nul)
++	$(subst /,\,echo.>>$@)
++endif
++
++#==========================================
++# Dungeon Compiler Stuff
++#==========================================
++
++$(U)dgn_comp.exe: $(DGNCOMPOBJS)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(DGNCOMPOBJS)
++
++
++$(O)dgn_yacc.o:   $(HACK_H)   $(DGN_FILE_H) $(INCL)/dgn_comp.h $(U)dgn_yacc.c
++	$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_yacc.c
++
++$(O)dgn_$(LEX).o: $(HACK_H)   $(DGN_FILE_H)  $(INCL)/dgn_comp.h \
++	 $(U)dgn_$(LEX).c
++	$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_$(LEX).c
++
++$(O)dgn_main.o:   $(HACK_H) $(U)dgn_main.c
++	$(cc) $(LEVCFLAGS) -o$@ $(U)dgn_main.c
++
++$(U)dgn_yacc.c $(INCL)/dgn_comp.h : $(U)dgn_comp.y
++ifeq  "$(DO_YACC)" "YACC_ACT"
++	$(subst /,\,$(YACC) -d $(U)dgn_comp.y)
++	$(subst /,\,copy $(YTABC) $(U)dgn_yacc.c)
++	$(subst /,\,copy $(YTABH) $(INCL)/dgn_comp.h)
++	$(subst /,\,@del $(YTABC))
++	$(subst /,\,@del $(YTABH))
++else
++	@echo $(U)dgn_comp.y has changed. To update dgn_yacc.c and
++	@echo $(INCL)/dgn_comp.h run $(YACC).
++	@echo ---
++	@echo For now, we will copy the prebuilt $(U)dgn_yacc.c and
++	@echo dgn_comp.h from $(SSYS) into $(UTIL) and use them.
++	$(subst /,\,@copy $(SSYS)/dgn_yacc.c $(U)dgn_yacc.c >nul)
++	$(subst /,\,@copy $(SSYS)/dgn_comp.h $(INCL)/dgn_comp.h >nul)
++	$(subst /,\,echo.>>$(U)dgn_yacc.c)
++	$(subst /,\,echo.>>$(INCL)/dgn_comp.h)
++endif
++
++$(U)dgn_$(LEX).c: $(U)dgn_comp.l
++ifeq  "$(DO_LEX)" "LEX_ACT"
++	$(subst /,\,$(LEX) $(FLEXSKEL) $(U)dgn_comp.l)
++	$(subst /,\,copy $(LEXYYC) $@)
++	$(subst /,\,@del $(LEXYYC))
++else
++	@echo $(U)dgn_comp.l has changed. To update $@ run $(LEX).
++	@echo ---
++	@echo For now, we will copy the prebuilt dgn_lex.c
++	@echo from $(SSYS) into $(UTIL) and use it.
++	$(subst /,\,@copy $(SSYS)/dgn_lex.c $@ >nul)
++	$(subst /,\,echo.>>$@)
++endif
++
++#==========================================
++# Create directory for holding object files
++#==========================================
++
++$(O)obj.tag:
++	$(subst /,\,@if not exist $(OBJ)/*.* echo creating directory $(OBJ))
++	$(subst /,\,@if not exist $(OBJ)/*.* mkdir $(OBJ))
++	$(subst /,\,@echo directory created > $@)
++
++
++#==========================================
++#=========== SECONDARY TARGETS ============
++#==========================================
++
++#===========================================
++# Header files NOT distributed in ../include
++#===========================================
++
++$(INCL)/win32api.h: $(NTSYS)/win32api.h
++	$(subst /,\,copy $(NTSYS)/win32api.h $@)
++
++
++#==========================================
++# DLB utility and nhdat file creation
++#==========================================
++
++$(U)dlb_main.exe: $(DLBOBJ) $(O)dlb.o
++	@$(link) $(LFLAGSU) -o$@ $(O)dlb_main.o $(O)dlb.o $(O)alloc.o $(O)panic.o
++
++
++$(O)dlb.o:   $(O)dlb_main.o $(O)alloc.o $(O)panic.o $(INCL)/dlb.h
++	$(cc) $(CFLAGS) -o$@ $(SRC)/dlb.c
++
++$(O)dlb_main.o: $(UTIL)/dlb_main.c $(INCL)/config.h $(INCL)/dlb.h
++	$(cc) $(CFLAGS) -o$@ $(UTIL)/dlb_main.c
++
++$(DAT)/porthelp: $(NTSYS)/porthelp
++	$(subst /,\,@copy $(NTSYS)/porthelp $@ >nul)
++
++nhdat:  $(U)dlb_main.exe $(DAT)/data $(DAT)/oracles $(OPTIONS_FILE) \
++	 $(DAT)/quest.dat $(DAT)/rumors $(DAT)/help $(DAT)/hh $(DAT)/cmdhelp \
++	 $(DAT)/history $(DAT)/opthelp $(DAT)/wizhelp $(DAT)/dungeon \
++	 $(DAT)/porthelp $(DAT)/license $(O)sp_lev.tag
++	$(subst /,\,echo data >$(DAT)/dlb.lst)
++	$(subst /,\,echo oracles >>$(DAT)/dlb.lst)
++	$(subst /,\,if exist $(DAT)/options echo options >>$(DAT)/dlb.lst)
++	$(subst /,\,if exist $(DAT)/ttyoptions echo ttyoptions >>$(DAT)/dlb.lst)
++	$(subst /,\,if exist $(DAT)/guioptions echo guioptions >>$(DAT)/dlb.lst)
++	$(subst /,\,if exist $(DAT)/porthelp echo porthelp >>$(DAT)/dlb.lst)
++	$(subst /,\,echo quest.dat >>$(DAT)/dlb.lst)
++	$(subst /,\,echo rumors >>$(DAT)/dlb.lst)
++	$(subst /,\,echo help >>$(DAT)/dlb.lst)
++	$(subst /,\,echo hh >>$(DAT)/dlb.lst)
++	$(subst /,\,echo cmdhelp >>$(DAT)/dlb.lst)
++	$(subst /,\,echo history >>$(DAT)/dlb.lst)
++	$(subst /,\,echo opthelp >>$(DAT)/dlb.lst)
++	$(subst /,\,echo wizhelp >>$(DAT)/dlb.lst)
++	$(subst /,\,echo dungeon >>$(DAT)/dlb.lst)
++	$(subst /,\,echo license >>$(DAT)/dlb.lst)
++	dir /l /b /-p $(subst /,\,$(DAT)/*.lev >>$(DAT)/dlb.lst)
++	$(subst /,\,$(U)dlb_main CcIf $(DAT) dlb.lst $(SRC)/nhdat)
++
++#==========================================
++#  Recover Utility
++#==========================================
++
++$(U)recover.exe: $(RECOVOBJS)
++	$(link) $(LFLAGSU) -o$@ $(RECOVOBJS)
++
++$(O)recover.o: $(CONFIG_H) $(U)recover.c $(INCL)/win32api.h
++	$(cc) $(CFLAGSU) -o$@ $(U)recover.c
++
++#==========================================
++#  Tile Mapping
++#==========================================
++
++$(SRC)/tile.c: $(U)tilemap.exe
++	@echo A new $@ has been created
++	@$(U)tilemap
++
++$(U)tilemap.exe: $(O)tilemap.o
++	@$(link) $(LFLAGSU) -o$@ $(O)tilemap.o
++
++$(O)tilemap.o: $(WSHR)/tilemap.c $(HACK_H)
++	$(cc) $(CFLAGSU) -o$@ $(WSHR)/tilemap.c
++
++$(O)tiletx32.o: $(WSHR)/tilemap.c $(HACK_H)
++	$(cc) $(CFLAGS) -DTILETEXT -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/tilemap.c
++
++$(O)tiletxt.o: $(WSHR)/tilemap.c $(HACK_H)
++	$(cc) $(CFLAGS) -DTILETEXT -o$@ $(WSHR)/tilemap.c
++
++$(O)gifread.o: $(WSHR)/gifread.c  $(CONFIG_H) $(TILE_H)
++	$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/gifread.c
++
++$(O)gifrd32.o: $(WSHR)/gifread.c  $(CONFIG_H) $(TILE_H)
++	$(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/gifread.c
++
++$(O)ppmwrite.o: $(WSHR)/ppmwrite.c $(CONFIG_H) $(TILE_H)
++	$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/ppmwrite.c
++
++$(O)tiletext.o: $(WSHR)/tiletext.c  $(CONFIG_H) $(TILE_H)
++	$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tiletext.c
++
++$(O)tilete32.o: $(WSHR)/tiletext.c  $(CONFIG_H) $(TILE_H)
++	$(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/tiletext.c
++
++#==========================================
++# Optional Tile Utilities
++#==========================================
++
++$(U)gif2txt.exe: $(GIFREADERS) $(TEXT_IO)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(GIFREADERS) $(TEXT_IO)
++
++$(U)gif2tx32.exe: $(GIFREADERS32) $(TEXT_IO32)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(GIFREADERS32) $(TEXT_IO32)
++
++
++$(U)txt2ppm.exe: $(PPMWRITERS) $(TEXT_IO)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(PPMWRITERS) $(TEXT_IO)
++
++
++ifeq  "$(GRAPHICAL)" "Y"
++$(TILEBMP16): $(TILEUTIL16) $(TILEFILES)
++	@echo Creating 16x16 binary tile files (this may take some time)
++	$(subst /,\,@$(U)tile2bmp $(TILEBMP16))
++#$(TILEBMP32): $(TILEUTIL32) $(TILEFILES32)
++#	@echo Creating 32x32 binary tile files (this may take some time)
++#	$(subst /,\,@$(U)til2bm32 $(TILEBMP32))
++else
++$(TILEBMP16):
++$(TILEBMP32):
++endif
++
++$(U)tile2bmp.exe: $(O)tile2bmp.o $(TEXT_IO)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(O)tile2bmp.o $(TEXT_IO)
++
++$(U)til2bm32.exe: $(O)til2bm32.o $(TEXT_IO32)
++	@echo Linking $@...
++	@$(link) $(LFLAGSU) -o$@ $(O)til2bm32.o $(TEXT_IO32)
++
++$(O)tile2bmp.o: $(WSHR)/tile2bmp.c $(HACK_H) $(TILE_H) $(INCL)/win32api.h
++	$(cc) $(CFLAGS) -I$(WSHR) -o$@ $(WSHR)/tile2bmp.c
++
++$(O)til2bm32.o: $(WSHR)/til2bm32.c $(HACK_H) $(TILE_H) $(INCL)/win32api.h
++	$(cc) $(CFLAGS) -I$(WSHR) -DTILE_X=32 -DTILE_Y=32 -o$@ $(WSHR)/til2bm32.c
++
++#==========================================
++# Housekeeping
++#==========================================
++
++spotless: clean
++	$(subst /,\,if exist graphicschk       del graphicschk)
++	$(subst /,\,if exist $(INCL)/date.h    del $(INCL)/date.h)
++	$(subst /,\,if exist $(INCL)/onames.h  del $(INCL)/onames.h)
++	$(subst /,\,if exist $(INCL)/pm.h      del $(INCL)/pm.h)
++	$(subst /,\,if exist $(INCL)/vis_tab.h del $(INCL)/vis_tab.h)
++	$(subst /,\,if exist $(SRC)/vis_tab.c  del $(SRC)/vis_tab.c)
++	$(subst /,\,if exist $(SRC)/tile.c     del $(SRC)/tile.c)
++	$(subst /,\,if exist $(U)*.lnk         del $(U)*.lnk)
++	$(subst /,\,if exist $(U)*.map         del $(U)*.map)
++	$(subst /,\,if exist $(DAT)/data       del $(DAT)/data)
++	$(subst /,\,if exist $(DAT)/rumors     del $(DAT)/rumors)
++	$(subst /,\,if exist $(DAT)/???-fil?.lev      del $(DAT)/???-fil?.lev)
++	$(subst /,\,if exist $(DAT)/???-goal.lev      del $(DAT)/???-goal.lev)
++	$(subst /,\,if exist $(DAT)/???-loca.lev      del $(DAT)/???-loca.lev)
++	$(subst /,\,if exist $(DAT)/???-strt.lev      del $(DAT)/???-strt.lev)
++	$(subst /,\,if exist $(DAT)/air.lev      del $(DAT)/air.lev)
++	$(subst /,\,if exist $(DAT)/asmodeus.lev      del $(DAT)/asmodeus.lev)
++	$(subst /,\,if exist $(DAT)/astral.lev   del $(DAT)/astral.lev)
++	$(subst /,\,if exist $(DAT)/baalz.lev    del $(DAT)/baalz.lev)
++	$(subst /,\,if exist $(DAT)/bigrm-*.lev  del $(DAT)/bigrm-*.lev)
++	$(subst /,\,if exist $(DAT)/castle.lev   del $(DAT)/castle.lev)
++	$(subst /,\,if exist $(DAT)/data    del $(DAT)/data)
++	$(subst /,\,if exist $(DAT)/dungeon      del $(DAT)/dungeon)
++	$(subst /,\,if exist $(DAT)/dungeon.pdf  del $(DAT)/dungeon.pdf)
++	$(subst /,\,if exist $(DAT)/earth.lev    del $(DAT)/earth.lev)
++	$(subst /,\,if exist $(DAT)/fakewiz?.lev      del $(DAT)/fakewiz?.lev)
++	$(subst /,\,if exist $(DAT)/fire.lev     del $(DAT)/fire.lev)
++	$(subst /,\,if exist $(DAT)/juiblex.lev  del $(DAT)/juiblex.lev)
++	$(subst /,\,if exist $(DAT)/knox.lev     del $(DAT)/knox.lev)
++	$(subst /,\,if exist $(DAT)/medusa-?.lev      del $(DAT)/medusa-?.lev)
++	$(subst /,\,if exist $(DAT)/mine*.lev    del $(DAT)/mine*.lev)
++	$(subst /,\,if exist $(DAT)/options      del $(DAT)/options)
++	$(subst /,\,if exist $(DAT)/ttyoptions   del $(DAT)/ttyoptions)
++	$(subst /,\,if exist $(DAT)/guioptions   del $(DAT)/guioptions)
++	$(subst /,\,if exist $(DAT)/oracle.lev   del $(DAT)/oracle.lev)
++	$(subst /,\,if exist $(DAT)/oracles      del $(DAT)/oracles)
++	$(subst /,\,if exist $(DAT)/orcus.lev    del $(DAT)/orcus.lev)
++	$(subst /,\,if exist $(DAT)/rumors  del $(DAT)/rumors)
++	$(subst /,\,if exist $(DAT)/quest.dat    del $(DAT)/quest.dat)
++	$(subst /,\,if exist $(DAT)/sanctum.lev  del $(DAT)/sanctum.lev)
++	$(subst /,\,if exist $(DAT)/soko?-?.lev  del $(DAT)/soko?-?.lev)
++	$(subst /,\,if exist $(DAT)/tower?.lev   del $(DAT)/tower?.lev)
++	$(subst /,\,if exist $(DAT)/valley.lev   del $(DAT)/valley.lev)
++	$(subst /,\,if exist $(DAT)/water.lev    del $(DAT)/water.lev)
++	$(subst /,\,if exist $(DAT)/wizard?.lev  del $(DAT)/wizard?.lev)
++	$(subst /,\,if exist $(O)sp_lev.tag     del $(O)sp_lev.tag)
++	$(subst /,\,if exist $(SRC)/monstr.c    del $(SRC)/monstr.c)
++	$(subst /,\,if exist $(SRC)/vis_tab.c   del $(SRC)/vis_tab.c)
++	$(subst /,\,if exist $(U)recover.exe    del $(U)recover.exe)
++	$(subst /,\,if exist $(DAT)/dlb.lst      del $(DAT)/dlb.lst)
++	$(subst /,\,if exist nhdat.         del nhdat.)
++	$(subst /,\,if exist $(O)install.tag    del $(O)install.tag)
++	$(subst /,\,if exist $(O)obj.tag    del $(O)obj.tag)
++	$(subst /,\,if exist $(O)gamedir.tag    del $(O)gamedir.tag)
++ifneq "$(OBJ)" ""
++	$(subst /,\,rmdir $(OBJ)) /s /Q
++endif
++
++clean:
++	$(subst /,\,if exist $(O)*.o del $(O)*.o)
++	$(subst /,\,if exist $(O)utility.tag   del $(O)utility.tag)
++	$(subst /,\,if exist $(U)makedefs.exe  del $(U)makedefs.exe)
++	$(subst /,\,if exist $(U)lev_comp.exe  del $(U)lev_comp.exe)
++	$(subst /,\,if exist $(U)dgn_comp.exe  del $(U)dgn_comp.exe)
++	$(subst /,\,if exist $(SRC)/*.lnk      del $(SRC)/*.lnk)
++	$(subst /,\,if exist $(SRC)/*.map      del $(SRC)/*.map)
++	$(subst /,\,if exist $(TILEBMP16)      del $(TILEBMP16))
++	$(subst /,\,if exist $(TILEBMP32)      del $(TILEBMP32))
++
++#===================================================================
++# OTHER DEPENDENCIES
++#===================================================================
++
++#
++# dat dependencies
++#
++
++$(DAT)/data: $(O)utility.tag    $(DATABASE)
++	$(subst /,\,$(U)makedefs -d)
++
++$(DAT)/rumors: $(O)utility.tag    $(DAT)/rumors.tru   $(DAT)/rumors.fal
++	$(subst /,\,$(U)makedefs -r)
++
++$(DAT)/quest.dat: $(O)utility.tag  $(DAT)/quest.txt
++	$(subst /,\,$(U)makedefs -q)
++
++$(DAT)/oracles: $(O)utility.tag    $(DAT)/oracles.txt
++	$(subst /,\,$(U)makedefs -h)
++
++$(DAT)/dungeon: $(O)utility.tag  $(DAT)/dungeon.def
++	$(subst /,\,$(U)makedefs -e)
++	$(subst /,\,$(U)dgn_comp $(DAT)/dungeon.pdf)
++
++#
++# NT dependencies
++#
++
++$(O)nttty.o:   $(HACK_H) $(TILE_H) $(INCL)/win32api.h $(NTSYS)/nttty.c
++	$(cc) $(CFLAGS) -I$(WSHR) -o$@  $(NTSYS)/nttty.c
++$(O)winnt.o: $(HACK_H) $(INCL)/win32api.h $(NTSYS)/winnt.c
++	$(cc) $(CFLAGS) -o$@  $(NTSYS)/winnt.c
++$(O)ntsound.o: $(HACK_H) $(NTSYS)/ntsound.c
++	$(cc) $(CFLAGS)  -o$@ $(NTSYS)/ntsound.c
++$(O)mapimail.o: $(HACK_H) $(INCL)/nhlan.h $(NTSYS)/mapimail.c
++	$(cc) $(CFLAGS) -DMAPI_VERBOSE  -o$@ $(NTSYS)/mapimail.c
++
++#
++# util dependencies
++#
++
++$(O)panic.o:  $(U)panic.c $(CONFIG_H)
++	$(cc) $(CFLAGS) -o$@ $(U)panic.c
++
++#
++# The rest are stolen from sys/unix/Makefile.src,
++# with the following changes:
++#   * ../include changed to $(INCL)
++#   * -c (which is included in CFLAGS) substituted
++#	with -o$@
++#   * targets prefixed with $(O)
++#   * $(CC) changed to $(cc)
++# but otherwise untouched. 
++# That means that there is some irrelevant stuff
++# in here, but maintenance should be easier.
++#
++$(O)tos.o: ../sys/atari/tos.c $(HACK_H) $(INCL)/tcap.h
++	$(cc) $(CFLAGS) -o$@ ../sys/atari/tos.c
++$(O)pcmain.o: ../sys/share/pcmain.c $(HACK_H) $(INCL)/dlb.h \
++		$(INCL)/win32api.h
++	$(cc) $(CFLAGS) -o$@ ../sys/share/pcmain.c
++$(O)pcsys.o: ../sys/share/pcsys.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/share/pcsys.c
++$(O)pctty.o: ../sys/share/pctty.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/share/pctty.c
++$(O)pcunix.o: ../sys/share/pcunix.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/share/pcunix.c
++$(O)random.o: ../sys/share/random.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/share/random.c
++$(O)ioctl.o: ../sys/share/ioctl.c $(HACK_H) $(INCL)/tcap.h
++	$(cc) $(CFLAGS) -o$@ ../sys/share/ioctl.c
++$(O)unixtty.o: ../sys/share/unixtty.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/share/unixtty.c
++$(O)unixmain.o: ../sys/unix/unixmain.c $(HACK_H) $(INCL)/dlb.h
++	$(cc) $(CFLAGS) -o$@ ../sys/unix/unixmain.c
++$(O)unixunix.o: ../sys/unix/unixunix.c $(HACK_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/unix/unixunix.c
++$(O)unixres.o: ../sys/unix/unixres.c $(CONFIG_H)
++	$(cc) $(CFLAGS) -o$@ ../sys/unix/unixres.c
++$(O)bemain.o: ../sys/be/bemain.c $(HACK_H) $(INCL)/dlb.h
++	$(cc) $(CFLAGS) -o$@ ../sys/be/bemain.c
++$(O)getline.o: ../win/tty/getline.c $(HACK_H) $(INCL)/func_tab.h
++	$(cc) $(CFLAGS) -o$@ ../win/tty/getline.c
++$(O)termcap.o: ../win/tty/termcap.c $(HACK_H) $(INCL)/tcap.h
++	$(cc) $(CFLAGS) -o$@ ../win/tty/termcap.c
++$(O)topl.o: ../win/tty/topl.c $(HACK_H) $(INCL)/tcap.h
++	$(cc) $(CFLAGS) -o$@ ../win/tty/topl.c
++$(O)wintty.o: ../win/tty/wintty.c $(HACK_H) $(INCL)/dlb.h \
++		$(INCL)/patchlevel.h $(INCL)/tcap.h
++	$(cc) $(CFLAGS) -o$@ ../win/tty/wintty.c
++$(O)Window.o: ../win/X11/Window.c $(INCL)/xwindowp.h $(INCL)/xwindow.h \
++		$(CONFIG_H)
++	$(cc) $(CFLAGS) -o$@ ../win/X11/Window.c
++$(O)dialogs.o: ../win/X11/dialogs.c $(CONFIG_H)
++	$(cc) $(CFLAGS) -o$@ ../win/X11/dialogs.c
++$(O)winX.o: ../win/X11/winX.c $(HACK_H) $(INCL)/winX.h $(INCL)/dlb.h \
++		$(INCL)/patchlevel.h ../win/X11/nh72icon \
++		../win/X11/nh56icon ../win/X11/nh32icon
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winX.c
++$(O)winmap.o: ../win/X11/winmap.c $(INCL)/xwindow.h $(HACK_H) $(INCL)/dlb.h \
++		$(INCL)/winX.h $(INCL)/tile2x11.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winmap.c
++$(O)winmenu.o: ../win/X11/winmenu.c $(HACK_H) $(INCL)/winX.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winmenu.c
++$(O)winmesg.o: ../win/X11/winmesg.c $(INCL)/xwindow.h $(HACK_H) $(INCL)/winX.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winmesg.c
++$(O)winmisc.o: ../win/X11/winmisc.c $(HACK_H) $(INCL)/func_tab.h \
++		$(INCL)/winX.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winmisc.c
++$(O)winstat.o: ../win/X11/winstat.c $(HACK_H) $(INCL)/winX.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winstat.c
++$(O)wintext.o: ../win/X11/wintext.c $(HACK_H) $(INCL)/winX.h $(INCL)/xwindow.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/wintext.c
++$(O)winval.o: ../win/X11/winval.c $(HACK_H) $(INCL)/winX.h
++	$(cc) $(CFLAGS) -o$@ ../win/X11/winval.c
++$(O)tile.o: tile.c $(HACK_H)
++$(O)gnaskstr.o: ../win/gnome/gnaskstr.c ../win/gnome/gnaskstr.h \
++		../win/gnome/gnmain.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnaskstr.c
++$(O)gnbind.o: ../win/gnome/gnbind.c ../win/gnome/gnbind.h ../win/gnome/gnmain.h \
++		../win/gnome/gnaskstr.h ../win/gnome/gnyesno.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnbind.c
++$(O)gnglyph.o: ../win/gnome/gnglyph.c ../win/gnome/gnglyph.h $(INCL)/tile2x11.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnglyph.c
++$(O)gnmain.o: ../win/gnome/gnmain.c ../win/gnome/gnmain.h ../win/gnome/gnsignal.h \
++		../win/gnome/gnbind.h ../win/gnome/gnopts.h $(HACK_H) \
++		$(INCL)/date.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmain.c
++$(O)gnmap.o: ../win/gnome/gnmap.c ../win/gnome/gnmap.h ../win/gnome/gnglyph.h \
++		../win/gnome/gnsignal.h $(HACK_H)
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmap.c
++$(O)gnmenu.o: ../win/gnome/gnmenu.c ../win/gnome/gnmenu.h ../win/gnome/gnmain.h \
++		../win/gnome/gnbind.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmenu.c
++$(O)gnmesg.o: ../win/gnome/gnmesg.c ../win/gnome/gnmesg.h ../win/gnome/gnsignal.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnmesg.c
++$(O)gnopts.o: ../win/gnome/gnopts.c ../win/gnome/gnopts.h ../win/gnome/gnglyph.h \
++		../win/gnome/gnmain.h ../win/gnome/gnmap.h $(HACK_H)
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnopts.c
++$(O)gnplayer.o: ../win/gnome/gnplayer.c ../win/gnome/gnplayer.h \
++		../win/gnome/gnmain.h $(HACK_H)
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnplayer.c
++$(O)gnsignal.o: ../win/gnome/gnsignal.c ../win/gnome/gnsignal.h \
++		../win/gnome/gnmain.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnsignal.c
++$(O)gnstatus.o: ../win/gnome/gnstatus.c ../win/gnome/gnstatus.h \
++		../win/gnome/gnsignal.h ../win/gnome/gn_xpms.h \
++		../win/gnome/gnomeprv.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnstatus.c
++$(O)gntext.o: ../win/gnome/gntext.c ../win/gnome/gntext.h ../win/gnome/gnmain.h \
++		../win/gnome/gn_rip.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gntext.c
++$(O)gnworn.o: ../win/gnome/gnworn.c ../win/gnome/gnworn.h ../win/gnome/gnglyph.h \
++		../win/gnome/gnsignal.h ../win/gnome/gnomeprv.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnworn.c
++$(O)gnyesno.o: ../win/gnome/gnyesno.c ../win/gnome/gnbind.h ../win/gnome/gnyesno.h
++	$(cc) $(CFLAGS) $(GNOMEINC) -o$@ ../win/gnome/gnyesno.c
++$(O)wingem.o: ../win/gem/wingem.c $(HACK_H) $(INCL)/func_tab.h $(INCL)/dlb.h \
++		$(INCL)/patchlevel.h $(INCL)/wingem.h
++	$(cc) $(CFLAGS) -o$@ ../win/gem/wingem.c
++$(O)wingem1.o: ../win/gem/wingem1.c $(INCL)/gem_rsc.h $(INCL)/load_img.h \
++		$(INCL)/gr_rect.h $(INCL)/wintype.h $(INCL)/wingem.h
++	$(cc) $(CFLAGS) -o$@ ../win/gem/wingem1.c
++$(O)load_img.o: ../win/gem/load_img.c $(INCL)/load_img.h
++	$(cc) $(CFLAGS) -o$@ ../win/gem/load_img.c
++$(O)gr_rect.o: ../win/gem/gr_rect.c $(INCL)/gr_rect.h
++	$(cc) $(CFLAGS) -o$@ ../win/gem/gr_rect.c
++$(O)tile.o: tile.c $(HACK_H)
++$(O)qt_win.o: ../win/Qt/qt_win.cpp $(HACK_H) $(INCL)/func_tab.h \
++		$(INCL)/dlb.h $(INCL)/patchlevel.h $(INCL)/tile2x11.h \
++		$(INCL)/qt_win.h $(INCL)/qt_clust.h $(INCL)/qt_kde0.h \
++		$(INCL)/qt_xpms.h qt_win.moc qt_kde0.moc qttableview.moc
++	$(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_win.cpp
++$(O)qt_clust.o: ../win/Qt/qt_clust.cpp $(INCL)/qt_clust.h
++	$(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qt_clust.cpp
++$(O)qttableview.o: ../win/Qt/qttableview.cpp $(INCL)/qttableview.h
++	$(CXX) $(CXXFLAGS) -o$@ ../win/Qt/qttableview.cpp
++$(O)monstr.o: monstr.c $(CONFIG_H)
++$(O)vis_tab.o: vis_tab.c $(CONFIG_H) $(INCL)/vis_tab.h
++$(O)allmain.o: allmain.c $(HACK_H)
++$(O)alloc.o: alloc.c $(CONFIG_H)
++$(O)apply.o: apply.c $(HACK_H) $(INCL)/edog.h
++$(O)artifact.o: artifact.c $(HACK_H) $(INCL)/artifact.h $(INCL)/artilist.h
++$(O)attrib.o: attrib.c $(HACK_H)
++$(O)ball.o: ball.c $(HACK_H)
++$(O)bones.o: bones.c $(HACK_H) $(INCL)/lev.h
++$(O)botl.o: botl.c $(HACK_H)
++$(O)cmd.o: cmd.c $(HACK_H) $(INCL)/func_tab.h
++$(O)dbridge.o: dbridge.c $(HACK_H)
++$(O)decl.o: decl.c $(HACK_H)
++$(O)detect.o: detect.c $(HACK_H) $(INCL)/artifact.h
++$(O)dig.o: dig.c $(HACK_H) $(INCL)/edog.h
++$(O)display.o: display.c $(HACK_H)
++$(O)dlb.o: dlb.c $(CONFIG_H) $(INCL)/dlb.h
++$(O)do.o: do.c $(HACK_H) $(INCL)/lev.h
++$(O)do_name.o: do_name.c $(HACK_H)
++$(O)do_wear.o: do_wear.c $(HACK_H)
++$(O)dog.o: dog.c $(HACK_H) $(INCL)/edog.h
++$(O)dogmove.o: dogmove.c $(HACK_H) $(INCL)/mfndpos.h $(INCL)/edog.h
++$(O)dokick.o: dokick.c $(HACK_H) $(INCL)/eshk.h
++$(O)dothrow.o: dothrow.c $(HACK_H) $(INCL)/edog.h
++$(O)drawing.o: drawing.c $(HACK_H) $(INCL)/tcap.h
++$(O)dungeon.o: dungeon.c $(HACK_H) $(INCL)/dgn_file.h $(INCL)/dlb.h
++$(O)eat.o: eat.c $(HACK_H)
++$(O)end.o: end.c $(HACK_H) $(INCL)/eshk.h $(INCL)/dlb.h
++$(O)engrave.o: engrave.c $(HACK_H) $(INCL)/lev.h
++$(O)exper.o: exper.c $(HACK_H)
++$(O)explode.o: explode.c $(HACK_H)
++$(O)extralev.o: extralev.c $(HACK_H)
++$(O)files.o: files.c $(HACK_H) $(INCL)/dlb.h
++$(O)fountain.o: fountain.c $(HACK_H)
++$(O)hack.o: hack.c $(HACK_H)
++$(O)hacklib.o: hacklib.c $(HACK_H)
++$(O)invent.o: invent.c $(HACK_H)
++$(O)light.o: light.c $(HACK_H) $(INCL)/lev.h
++$(O)lock.o: lock.c $(HACK_H)
++$(O)mail.o: mail.c $(HACK_H) $(INCL)/mail.h
++$(O)makemon.o: makemon.c $(HACK_H) $(INCL)/epri.h $(INCL)/emin.h \
++		$(INCL)/edog.h
++$(O)mapglyph.o: mapglyph.c $(HACK_H)
++$(O)mcastu.o: mcastu.c $(HACK_H)
++$(O)mhitm.o: mhitm.c $(HACK_H) $(INCL)/artifact.h $(INCL)/edog.h
++$(O)mhitu.o: mhitu.c $(HACK_H) $(INCL)/artifact.h $(INCL)/edog.h
++$(O)minion.o: minion.c $(HACK_H) $(INCL)/emin.h $(INCL)/epri.h
++$(O)mklev.o: mklev.c $(HACK_H)
++$(O)mkmap.o: mkmap.c $(HACK_H) $(INCL)/sp_lev.h
++$(O)mkmaze.o: mkmaze.c $(HACK_H) $(INCL)/sp_lev.h $(INCL)/lev.h
++$(O)mkobj.o: mkobj.c $(HACK_H)
++$(O)mkroom.o: mkroom.c $(HACK_H)
++$(O)mon.o: mon.c $(HACK_H) $(INCL)/mfndpos.h $(INCL)/edog.h
++$(O)mondata.o: mondata.c $(HACK_H) $(INCL)/eshk.h $(INCL)/epri.h
++$(O)monmove.o: monmove.c $(HACK_H) $(INCL)/mfndpos.h $(INCL)/artifact.h \
++		$(INCL)/epri.h
++$(O)monst.o: monst.c $(CONFIG_H) $(INCL)/permonst.h $(INCL)/align.h \
++		$(INCL)/monattk.h $(INCL)/monflag.h $(INCL)/monsym.h \
++		$(INCL)/dungeon.h $(INCL)/eshk.h $(INCL)/vault.h \
++		$(INCL)/epri.h $(INCL)/color.h
++$(O)mplayer.o: mplayer.c $(HACK_H)
++$(O)mthrowu.o: mthrowu.c $(HACK_H)
++$(O)muse.o: muse.c $(HACK_H) $(INCL)/edog.h
++$(O)music.o: music.c $(HACK_H) #interp.c
++$(O)o_init.o: o_init.c $(HACK_H) $(INCL)/lev.h
++$(O)objects.o: objects.c $(CONFIG_H) $(INCL)/obj.h $(INCL)/objclass.h \
++		$(INCL)/prop.h $(INCL)/skills.h $(INCL)/color.h
++$(O)objnam.o: objnam.c $(HACK_H)
++$(O)options.o: options.c $(CONFIG_H) $(INCL)/objclass.h $(INCL)/flag.h \
++		$(HACK_H) $(INCL)/tcap.h
++$(O)pager.o: pager.c $(HACK_H) $(INCL)/dlb.h
++$(O)pickup.o: pickup.c $(HACK_H)
++$(O)pline.o: pline.c $(HACK_H) $(INCL)/epri.h $(INCL)/edog.h
++$(O)polyself.o: polyself.c $(HACK_H)
++$(O)potion.o: potion.c $(HACK_H)
++$(O)pray.o: pray.c $(HACK_H) $(INCL)/epri.h
++$(O)priest.o: priest.c $(HACK_H) $(INCL)/mfndpos.h $(INCL)/eshk.h \
++		$(INCL)/epri.h $(INCL)/emin.h
++$(O)quest.o: quest.c $(HACK_H) $(INCL)/qtext.h
++$(O)questpgr.o: questpgr.c $(HACK_H) $(INCL)/dlb.h $(INCL)/qtext.h
++$(O)read.o: read.c $(HACK_H)
++$(O)rect.o: rect.c $(HACK_H)
++$(O)region.o: region.c $(HACK_H) $(INCL)/lev.h
++$(O)restore.o: restore.c $(HACK_H) $(INCL)/lev.h $(INCL)/tcap.h
++$(O)rip.o: rip.c $(HACK_H)
++$(O)rnd.o: rnd.c $(HACK_H)
++$(O)role.o: role.c $(HACK_H)
++$(O)rumors.o: rumors.c $(HACK_H) $(INCL)/lev.h $(INCL)/dlb.h
++$(O)save.o: save.c $(HACK_H) $(INCL)/lev.h
++$(O)shk.o: shk.c $(HACK_H) $(INCL)/eshk.h
++$(O)shknam.o: shknam.c $(HACK_H) $(INCL)/eshk.h
++$(O)sit.o: sit.c $(HACK_H) $(INCL)/artifact.h
++$(O)sounds.o: sounds.c $(HACK_H) $(INCL)/edog.h
++$(O)sp_lev.o: sp_lev.c $(HACK_H) $(INCL)/dlb.h $(INCL)/sp_lev.h
++$(O)spell.o: spell.c $(HACK_H)
++$(O)steal.o: steal.c $(HACK_H)
++$(O)steed.o: steed.c $(HACK_H)
++$(O)teleport.o: teleport.c $(HACK_H)
++$(O)timeout.o: timeout.c $(HACK_H) $(INCL)/lev.h
++$(O)topten.o: topten.c $(HACK_H) $(INCL)/dlb.h $(INCL)/patchlevel.h
++$(O)track.o: track.c $(HACK_H)
++$(O)trap.o: trap.c $(HACK_H)
++$(O)u_init.o: u_init.c $(HACK_H)
++$(O)uhitm.o: uhitm.c $(HACK_H)
++$(O)vault.o: vault.c $(HACK_H) $(INCL)/vault.h
++$(O)version.o: version.c $(HACK_H) $(INCL)/date.h $(INCL)/patchlevel.h
++$(O)vision.o: vision.c $(HACK_H) $(INCL)/vis_tab.h
++$(O)weapon.o: weapon.c $(HACK_H)
++$(O)were.o: were.c $(HACK_H)
++$(O)wield.o: wield.c $(HACK_H)
++$(O)windows.o: windows.c $(HACK_H) $(INCL)/wingem.h $(INCL)/winGnome.h
++$(O)wizard.o: wizard.c $(HACK_H) $(INCL)/qtext.h $(INCL)/epri.h
++$(O)worm.o: worm.c $(HACK_H) $(INCL)/lev.h
++$(O)worn.o: worn.c $(HACK_H)
++$(O)write.o: write.c $(HACK_H)
++$(O)zap.o: zap.c $(HACK_H)
++
++# end of file
+diff -burN nethack-3.4.3/util/makedefs.c nethack/util/makedefs.c
+--- nethack-3.4.3/util/makedefs.c	2003-12-07 18:39:13.000000000 -0500
++++ nethack/util/makedefs.c	2009-03-11 13:35:46.000000000 -0400
+@@ -782,6 +782,9 @@
+ #ifdef TTY_GRAPHICS
+ 		"traditional tty-based graphics",
+ #endif
++#ifdef CURSES_GRAPHICS
++        "curses",
++#endif
+ #ifdef X11_GRAPHICS
+ 		"X11",
+ #endif
+diff -burN nethack-3.4.3/win/curses/Bugs.txt nethack/win/curses/Bugs.txt
+--- nethack-3.4.3/win/curses/Bugs.txt	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/Bugs.txt	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,13 @@
++Here is a list of known issues with the curses interface at the time of
++this writing.  Send any others you discover to me (Karl Garrison) at
++kgarrison@obox.com, along with how to reproduce the problem, if
++possible.  Missing features are listed in the file Todo.txt.
++
++ * Resizing a window to 80 columns or less causes a crash (PDCurses for
++ SDL and X11 only).  Windows starting at this size and below do not
++ cause a crash, however.
++ 
++ * Cursor position is wrong on map for smaller terminal windows in all
++ versions of PDCurses (smaller than 80 width or 24 height).  This is
++ due to an incomplete workaround for an issue with the wmove() function
++ in PDCurses.
+diff -burN nethack-3.4.3/win/curses/cursdial.c nethack/win/curses/cursdial.c
+--- nethack-3.4.3/win/curses/cursdial.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursdial.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,1182 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "cursdial.h"
++#include "func_tab.h"
++
++
++/* Dialog windows for curses interface */
++
++static nhmenu *nhmenus = NULL;  /* NetHack menu array */
++
++
++/* Get a line of text from the player, such as asking for a character name or a wish */
++
++void curses_line_input_dialog(const char *prompt, char *answer, int buffer)
++{
++    int map_height, map_width, maxwidth, remaining_buf, winx, winy, count;
++    WINDOW *askwin, *bwin;
++    char input[buffer];
++    char *tmpstr;
++    int prompt_width = strlen(prompt) + buffer + 1;
++    int prompt_height = 1;
++    int height = prompt_height;
++
++    maxwidth = term_cols - 2;
++
++    if (iflags.window_inited)
++    {
++        curses_get_window_size(MAP_WIN, &map_height, &map_width);
++        if ((prompt_width + 2) > map_width)
++            maxwidth = map_width - 2;
++    }
++    
++    if (prompt_width > maxwidth)
++    {
++        prompt_height = curses_num_lines(prompt, maxwidth);
++        height = prompt_height;
++        prompt_width = maxwidth;
++        tmpstr = curses_break_str(prompt, maxwidth, prompt_height);
++        remaining_buf = buffer - (strlen(tmpstr) - 1);
++        if (remaining_buf > 0 )
++        {
++            height += (remaining_buf / prompt_width);
++            if ((remaining_buf % prompt_width) > 0)
++            {
++                height++;
++            }
++        }
++    }
++    
++    if (iflags.window_inited)
++    {
++        bwin = curses_create_window(prompt_width, height, UP);
++        wrefresh(bwin);
++        getbegyx(bwin, winy, winx);
++        askwin = newwin(height, prompt_width, winy + 1, winx + 1);
++    }
++    else
++    {
++        bwin = curses_create_window(prompt_width, height, CENTER);
++        wrefresh(bwin);
++        getbegyx(bwin, winy, winx);
++        askwin = newwin(height, prompt_width, winy + 1, winx + 1);
++    }
++    for (count = 0; count < prompt_height; count++)
++    {
++        tmpstr = curses_break_str(prompt, maxwidth, count + 1);
++        if (count == (prompt_height - 1))    /* Last line */
++        {
++            mvwprintw(askwin, count, 0, "%s ", tmpstr);
++        }
++        else
++        {
++            mvwaddstr(askwin, count, 0, tmpstr);
++        }
++        free(tmpstr);
++    }
++    
++    echo();
++    curs_set(1);
++    wgetnstr(askwin, input, buffer-1);
++    curs_set(0);
++    strcpy(answer, input);
++    werase(bwin);
++    delwin(bwin);
++    curses_destroy_win(askwin);
++    noecho();
++}
++
++
++/* Get a single character response from the player, such as a y/n prompt */
++
++int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def)
++{
++    WINDOW *askwin;
++    int answer, count, maxwidth, map_height, map_width;
++    char *linestr;
++    char askstr[BUFSZ + QBUFSZ];
++    char choicestr[QBUFSZ];
++    int prompt_width = strlen(prompt);
++    int prompt_height = 1;
++    boolean any_choice = FALSE;
++
++    curses_get_window_size(MAP_WIN, &map_height, &map_width);
++    maxwidth = map_width - 2;
++    
++    if (choices != NULL)
++    {
++        choicestr[0] = ' ';
++        choicestr[1] = '[';
++        for (count = 0; choices[count] != '\0'; count++)
++        {
++            if (choices[count] == '\033')   /* Escape */
++            {
++                break;
++            }
++            choicestr[count + 2] = choices[count];
++        }
++        choicestr[count + 2] = ']';
++        if (((def >= 'A') && (def <= 'Z')) || ((def >= 'a') && (def <= 'z')))
++        {
++            choicestr[count + 3] = ' ';
++            choicestr[count + 4] = '(';
++            choicestr[count + 5] = def;
++            choicestr[count + 6] = ')';
++            choicestr[count + 7] = '\0';
++        }
++        else    /* No usable default choice */
++        {
++            choicestr[count + 3] = '\0';
++            def = '\0'; /* Mark as no default */
++        }
++        strcpy(askstr, prompt);
++        strcat(askstr, choicestr);
++    }
++    else
++    {
++        strcpy(askstr, prompt);
++        any_choice = TRUE;
++    }
++    
++    prompt_width = strlen(askstr);
++    
++    if ((prompt_width + 2) > maxwidth)
++    {
++        prompt_height = curses_num_lines(askstr, maxwidth);
++        prompt_width = map_width - 2;
++    }
++
++    if (iflags.wc_popup_dialog)
++    {
++        askwin = curses_create_window(prompt_width, prompt_height, UP);
++        for (count = 0; count < prompt_height; count++)
++        {
++            linestr = curses_break_str(askstr, maxwidth, count + 1);
++            mvwaddstr(askwin, count + 1, 1, linestr);
++            free(linestr);
++        }
++    
++        wrefresh(askwin);
++    }
++    else
++    {
++        linestr = curses_copy_of(askstr);
++        pline("%s", linestr);
++        free(linestr);
++        curs_set(1);
++    }
++
++    while (1)
++    {
++        answer = curses_read_char();
++        if (answer==KEY_ESC)
++        {
++            if (choices == NULL)
++            {
++                break;
++            }
++            answer = def;
++            for (count = 0; choices[count] != '\0'; count++)
++            {
++                if (choices[count] == 'q') /* q is preferred over n */
++                {
++                    answer = 'q';
++                }
++                else if ((choices[count] == 'n') && answer != 'q')
++                {
++                    answer = 'n';
++                }
++            }
++            break;
++        }
++        else if ((answer == '\n') || (answer == '\r'))
++        {
++            if ((choices != NULL) && (def != '\0'))
++            {
++                answer = def;
++            }
++            break;
++        }
++        if (any_choice)
++        {
++            break;
++        }
++        if (choices != NULL)
++        {
++            for (count = 0; count < strlen(choices); count++)
++            {
++                if (choices[count] == answer)
++                {
++                    break;
++                }
++            }
++            if (choices[count] == answer)
++            {
++                break;
++            }
++        }
++    }
++
++    if (iflags.wc_popup_dialog)
++    {
++        curses_destroy_win(askwin);
++    }
++    else
++    {
++        curses_clear_unhighlight_message_window();
++        curs_set(0);
++    }
++    
++    return answer;
++}
++
++
++/* Return an extended command from the user */
++
++int curses_ext_cmd()
++{
++    /* We should check the value of iflags.extmenu here, but there is
++    currently no non-menu alternative */
++
++    return extcmd_via_menu();
++}
++
++
++/* Initialize a menu from given NetHack winid */
++
++void curses_create_nhmenu(winid wid)
++{
++    nhmenu *new_menu = NULL;
++    nhmenu *menuptr = nhmenus;
++    nhmenu_item *menu_item_ptr = NULL;
++    nhmenu_item *tmp_menu_item = NULL;
++    
++    new_menu = get_menu(wid);
++    
++    if (new_menu != NULL)
++    {
++        /* Reuse existing menu, clearing out current entries */
++        menu_item_ptr = new_menu->entries;
++        
++        if (menu_item_ptr != NULL)
++        {
++            while (menu_item_ptr->next_item != NULL)
++            {
++                tmp_menu_item = menu_item_ptr->next_item;
++                free(menu_item_ptr);
++                menu_item_ptr = tmp_menu_item;
++            }
++            free(menu_item_ptr);    /* Last entry */
++            new_menu->entries = NULL;
++        }
++        if (new_menu->prompt != NULL)   /* Reusing existing menu */
++        {
++            free((char *)new_menu->prompt);
++        }    
++        return;
++    }
++    
++    new_menu = malloc(sizeof(nhmenu));
++    new_menu->wid = wid;
++    new_menu->prompt = NULL;
++    new_menu->entries = NULL;
++    new_menu->num_pages = 0;
++    new_menu->height = 0;
++    new_menu->width = 0;
++    new_menu->next_menu = NULL;
++    
++    if (nhmenus == NULL)    /* no menus in memory yet */
++    {
++        new_menu->prev_menu = NULL;
++        nhmenus = new_menu;
++    }
++    else
++    {
++        while (menuptr->next_menu != NULL)
++        {
++            menuptr = menuptr->next_menu;
++        }
++        new_menu->prev_menu = menuptr;
++        menuptr->next_menu = new_menu;
++    }
++}
++
++
++/* Add a menu item to the given menu window */
++
++void curses_add_nhmenu_item(winid wid, const ANY_P *identifier,
++ CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str,
++ BOOLEAN_P presel)
++{
++    char *new_str;
++    nhmenu_item *new_item, *current_items, *menu_item_ptr;
++    nhmenu *current_menu = get_menu(wid);
++    
++    if (str == NULL)
++    {
++        return;
++    }
++
++    new_str = curses_copy_of(str);
++    curses_rtrim((char *) new_str);
++    new_item = malloc(sizeof(nhmenu_item));
++    new_item->wid = wid;
++    new_item->identifier = *identifier;
++    new_item->accelerator = accelerator;
++    new_item->group_accel = group_accel;
++    new_item->attr = attr;
++    new_item->str = new_str;
++    new_item->presel = presel;
++    new_item->selected = FALSE;
++    new_item->page_num = 0;
++    new_item->line_num = 0;
++    new_item->num_lines = 0;
++    new_item->next_item = NULL;
++    
++    if (current_menu == NULL)
++    {
++        panic("curses_add_nhmenu_item: attempt to add item to nonexistant menu");
++    }
++
++    current_items = current_menu->entries;
++    menu_item_ptr = current_items;
++
++    if (current_items == NULL)
++    {
++        new_item->prev_item = NULL;
++        current_menu->entries = new_item;
++    }
++    else
++    {
++        while (menu_item_ptr->next_item != NULL)
++        {
++            menu_item_ptr = menu_item_ptr->next_item;
++        }
++        new_item->prev_item = menu_item_ptr;
++        menu_item_ptr->next_item = new_item;
++    }
++}
++
++
++/* No more entries are to be added to menu, so details of the menu can be
++ finalized in memory */
++
++void curses_finalize_nhmenu(winid wid, const char *prompt)
++{
++    int count = 0;
++    nhmenu *current_menu = get_menu(wid);
++    nhmenu_item *menu_item_ptr = current_menu->entries;
++
++    if (current_menu == NULL)
++    {
++        panic("curses_finalize_nhmenu: attempt to finalize nonexistant menu");
++    }
++
++    while (menu_item_ptr != NULL)
++    {
++        menu_item_ptr = menu_item_ptr->next_item;
++        count++;
++    }
++
++    current_menu->num_entries = count;
++    current_menu->prompt = curses_copy_of(prompt);
++}
++
++
++/* Display a nethack menu, and return a selection, if applicable */
++
++int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected)
++{
++    nhmenu *current_menu = get_menu(wid);
++    nhmenu_item *menu_item_ptr;
++    int num_choices, num_chosen, count;
++    WINDOW *win;
++    int curpage = 1;
++    MENU_ITEM_P *selected = NULL;
++
++	*_selected = NULL;
++    
++    if (current_menu == NULL)
++    {
++        panic("curses_display_nhmenu: attempt to display nonexistant menu");
++    }
++    
++    menu_item_ptr = current_menu->entries;
++    
++    if (menu_item_ptr == NULL)
++    {
++        panic("curses_display_nhmenu: attempt to display empty menu");
++    }
++    
++    /* Reset items to unselected to clear out selections from previous
++    invocations of this menu */
++    while (menu_item_ptr != NULL)
++    {
++        menu_item_ptr->selected = FALSE;
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++
++    menu_win_size(current_menu);
++    menu_determine_pages(current_menu);
++    win = curses_create_window(current_menu->width, current_menu->height, RIGHT);
++    num_choices = menu_get_choices(current_menu, how);
++    num_chosen = menu_get_selections(win, current_menu, num_choices, how);
++    curses_destroy_win(win);
++    
++    if (num_chosen > 0)
++    {
++        selected = (MENU_ITEM_P*) malloc(num_chosen * sizeof(MENU_ITEM_P));
++        count = 0;
++        
++        menu_item_ptr = current_menu->entries;
++
++        while (menu_item_ptr != NULL)
++        {
++            if (menu_item_ptr->selected)
++            {
++                if (count == num_chosen)
++                {
++                    panic("curses_display_nhmenu: Selected items exceeds expected number");
++                }
++                selected[count].item = menu_item_ptr->identifier;
++                selected[count].count = -1;
++                count++; 
++            }
++            menu_item_ptr = menu_item_ptr->next_item;
++        }
++        
++        if (count != num_chosen)
++        {
++            panic("curses_display_nhmenu: Selected items less than expected number");
++        }
++    }
++
++    *_selected = selected;
++    
++    return num_chosen;
++}
++
++
++boolean curses_menu_exists(winid wid)
++{
++    if (get_menu(wid) != NULL)
++    {
++        return TRUE;
++    }
++    else
++    {
++        return FALSE;
++    }
++}
++
++/* Delete the menu associated with the given NetHack winid from memory */
++
++void curses_del_menu(winid wid)
++{
++    nhmenu_item *tmp_menu_item;
++    nhmenu_item *menu_item_ptr;
++    nhmenu *tmpmenu;
++    nhmenu *current_menu = get_menu(wid);
++    
++    if (current_menu == NULL)
++    {
++       return;
++    }
++    
++    menu_item_ptr = current_menu->entries;
++    
++    /* First free entries associated with this menu from memory */
++    if (menu_item_ptr != NULL)
++    {
++        while (menu_item_ptr->next_item != NULL)
++        {
++            tmp_menu_item = menu_item_ptr->next_item;
++            free(menu_item_ptr);
++            menu_item_ptr = tmp_menu_item;
++        }
++        free(menu_item_ptr);    /* Last entry */
++        current_menu->entries = NULL;
++    }
++    
++    /* Now unlink the menu from the list and free it as well */
++    if (current_menu->prev_menu != NULL)
++    {
++        tmpmenu = current_menu->prev_menu;
++        tmpmenu->next_menu = current_menu->next_menu;
++    }
++    else
++    {
++        nhmenus = current_menu->next_menu;   /* New head mode or NULL */
++    }
++    if (current_menu->next_menu != NULL)
++    {
++        tmpmenu = current_menu->next_menu;
++        tmpmenu->prev_menu = current_menu->prev_menu;
++    }
++    free(current_menu);
++}
++
++
++/* return a pointer to the menu associated with the given NetHack winid */
++
++static nhmenu *get_menu(winid wid)
++{
++    nhmenu *menuptr = nhmenus;
++
++    while (menuptr != NULL)
++    {
++        if (menuptr->wid == wid)
++        {
++            return menuptr;
++        }
++        menuptr = menuptr->next_menu;
++    }
++    
++    
++    return NULL;    /* Not found */
++}
++
++
++static char menu_get_accel(boolean first)
++{
++    char ret;
++    static char next_letter = 'a';
++    
++    if (first)
++    {
++        next_letter = 'a';
++    }
++    
++    ret = next_letter;
++    
++    if (((next_letter < 'z') && (next_letter >= 'a')) || ((next_letter < 'Z')
++     && (next_letter >= 'A')))
++    {
++        next_letter++;
++    }
++    else if (next_letter == 'z')
++    {
++        next_letter = 'A';
++    }
++    
++    return ret;
++}
++
++
++/* Determine if menu will require multiple pages to display */
++
++static boolean menu_is_multipage(nhmenu *menu, int width, int height)
++{
++    int num_lines;
++    int curline = 0;
++    nhmenu_item *menu_item_ptr = menu->entries;
++
++    if (strlen(menu->prompt) > 0)
++    {
++        curline += curses_num_lines(menu->prompt, width) + 1;
++    }
++    
++    if (menu->num_entries <= (height - curline))
++    {   
++        while (menu_item_ptr != NULL)
++        {
++            menu_item_ptr->line_num = curline;
++            if (menu_item_ptr->identifier.a_void == NULL)
++            {
++                num_lines = curses_num_lines(menu_item_ptr->str, width);
++            }
++            else
++            {
++                /* Add space for accelerator */
++                num_lines = curses_num_lines(menu_item_ptr->str, width - 4);
++            }
++            menu_item_ptr->num_lines = num_lines;
++            curline += num_lines;
++            menu_item_ptr = menu_item_ptr->next_item;
++            if (curline > height)
++            {
++                break;
++            }
++        }
++        if (menu_item_ptr == NULL)
++        {
++            return FALSE;
++        }
++    }
++    return TRUE;
++}
++
++
++/* Determine which entries go on which page, and total number of pages */
++
++static void menu_determine_pages(nhmenu *menu)
++{
++    int tmpline, num_lines;
++    int curline = 0;
++    int page_num = 1;
++    nhmenu_item *menu_item_ptr = menu->entries;
++    int width = menu->width;
++    int height = menu->height;
++    int page_end = height;
++    
++    
++    if (strlen(menu->prompt) > 0)
++    {
++        curline += curses_num_lines(menu->prompt, width) + 1;
++    }
++        
++    tmpline = curline;
++    
++    if (menu_is_multipage(menu, width, height))
++    {
++        page_end -= 2;  /* Room to display current page number */
++    }
++
++    /* Determine what entries belong on which page */
++    menu_item_ptr = menu->entries;
++    
++    while (menu_item_ptr != NULL)
++    {
++        menu_item_ptr->page_num = page_num;
++        menu_item_ptr->line_num = curline;
++        if (menu_item_ptr->identifier.a_void == NULL)
++        {
++            num_lines = curses_num_lines(menu_item_ptr->str, width);
++        }
++        else
++        {
++            /* Add space for accelerator */
++            num_lines = curses_num_lines(menu_item_ptr->str, width - 4);
++        }
++        menu_item_ptr->num_lines = num_lines;
++        curline += num_lines;
++        if (curline > page_end)
++        {
++            page_num++;
++            curline = tmpline;
++            /* Move ptr back so entry will be reprocessed on new page */
++            menu_item_ptr = menu_item_ptr->prev_item;
++        }
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++    
++    menu->num_pages = page_num;
++}
++
++
++/* Determine dimensions of menu window based on term size and entries */
++
++static void menu_win_size(nhmenu *menu)
++{
++    int width, height, maxwidth, maxheight, curentrywidth, lastline,
++     map_height, map_width;
++    int maxentrywidth = strlen(menu->prompt);
++    int maxheaderwidth = 0;
++    nhmenu_item *menu_item_ptr = menu->entries;
++    
++    maxwidth = 38;  /* Reasonable minimum usable width */
++    
++    if ((term_cols / 2) > maxwidth)
++    {
++        maxwidth = (term_cols / 2); /* Half the screen */
++    }
++    
++    maxheight = term_rows - 2;
++    
++    /* First, determine the width of the longest menu entry */
++    while (menu_item_ptr != NULL)
++    {
++        if (menu_item_ptr->identifier.a_void == NULL)
++        {
++            curentrywidth=strlen(menu_item_ptr->str);
++
++            if (curentrywidth > maxheaderwidth)
++            {
++                maxheaderwidth = curentrywidth;
++            }
++        }
++        else
++        {
++            /* Add space for accelerator */
++            curentrywidth=strlen(menu_item_ptr->str) + 4;
++        }
++        if (curentrywidth > maxentrywidth)
++        {
++            maxentrywidth = curentrywidth;          
++        }
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++    
++    /* If the widest entry is smaller than maxwidth, reduce maxwidth accordingly */
++    if (maxentrywidth < maxwidth)
++    {
++        maxwidth = maxentrywidth;
++    }
++    
++    /* Try not to wrap headers/normal text lines if possible.  We can
++    go wider than half the screen for this purpose if need be */
++    
++    if ((maxheaderwidth > maxwidth) && (maxheaderwidth < (term_cols - 2)))
++    {
++        maxwidth = maxheaderwidth;
++    }
++    
++    width = maxwidth;
++    
++    /* Possibly reduce height if only 1 page */    
++    if (!menu_is_multipage(menu, maxwidth, maxheight))   
++    {
++        menu_item_ptr = menu->entries;
++        
++        while (menu_item_ptr->next_item != NULL)
++        {
++            menu_item_ptr = menu_item_ptr->next_item;
++        }
++        
++        lastline = (menu_item_ptr->line_num) + menu_item_ptr->num_lines;
++    
++        if (lastline < maxheight)
++        {
++            maxheight = lastline;
++        }
++    }
++    else    /* If multipage, make sure we have enough width for page footer */
++    {
++        if (width < 20)
++        {
++            width = 20;
++        }
++    }
++
++    height = maxheight;
++    menu->width = width;
++    menu->height = height;
++}
++
++
++/* Displays menu selections in the given window */
++
++static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num)
++{
++    nhmenu_item *menu_item_ptr;
++    int count, curletter, entry_cols, start_col, num_lines, footer_x;
++    boolean first_accel = TRUE;
++        
++    /* Cycle through entries until we are on the correct page */
++
++    menu_item_ptr = menu->entries;
++    
++    while (menu_item_ptr != NULL)
++    {
++        if (menu_item_ptr->page_num == page_num)
++        {
++            break;
++        }
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++    
++    if (menu_item_ptr == NULL)  /* Page not found */
++    {
++        panic("menu_display_page: attempt to display nonexistant page");
++    }
++
++    werase(win);
++
++    if (strlen(menu->prompt) > 0)
++    {
++        num_lines = curses_num_lines(menu->prompt, menu->width);
++        
++        for (count = 0; count < num_lines; count++)
++        {
++            mvwprintw(win, count + 1, 1, "%s",
++             curses_break_str(menu->prompt, menu->width, count + 1));
++        }
++    }
++
++    /* Display items for current page */
++    
++    while (menu_item_ptr != NULL)
++    {
++        if (menu_item_ptr->page_num != page_num)
++        {
++            break;
++        }
++        if (menu_item_ptr->identifier.a_void != NULL)
++        {
++            if (menu_item_ptr->accelerator != 0)
++            {
++                curletter = menu_item_ptr->accelerator;
++            }
++            else
++            {
++                if (first_accel)
++                {
++                    curletter = menu_get_accel(TRUE);
++                    first_accel = FALSE;
++                }
++                else
++                {
++                    curletter = menu_get_accel(FALSE);
++                }
++                menu_item_ptr->accelerator = curletter;
++            }
++            curses_toggle_color_attr(win, NONE, ATR_BOLD, ON);
++            mvwaddch(win, menu_item_ptr->line_num + 1, 2, curletter);
++            curses_toggle_color_attr(win, NONE, ATR_BOLD, OFF);
++            if (menu_item_ptr->selected)
++            {
++                curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON);
++                mvwaddch(win, menu_item_ptr->line_num + 1, 1, '<');
++                mvwaddch(win, menu_item_ptr->line_num + 1, 3, '>');
++                curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF);
++            }
++            else
++            {
++                mvwprintw(win, menu_item_ptr->line_num + 1, 3, ") ");
++            }
++        }
++        curses_toggle_color_attr(win, NONE, menu_item_ptr->attr, ON);
++        entry_cols = menu->width;
++        start_col = 1;
++
++        if (menu_item_ptr->identifier.a_void != NULL)
++        {
++            entry_cols -= 4;
++            start_col += 4;
++        }        
++        
++        num_lines = curses_num_lines(menu_item_ptr->str, entry_cols);
++        
++        for (count = 0; count < num_lines; count++)
++        {
++            if (strlen(menu_item_ptr->str) > 0)
++            {
++                mvwprintw(win, menu_item_ptr->line_num + count + 1,
++                 start_col, "%s", curses_break_str(menu_item_ptr->str,
++                 entry_cols, count + 1));
++             }
++        }
++        curses_toggle_color_attr(win, NONE, menu_item_ptr->attr, OFF);
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++
++    if (menu->num_pages > 1)
++    {
++        footer_x = menu->width - strlen("<- (Page X of Y) ->");
++        if (menu->num_pages > 9)    /* Unlikely */
++        {
++            footer_x -= 2;
++        }
++        mvwprintw(win, menu->height, footer_x + 3, "(Page %d of %d)",
++         page_num, menu->num_pages);
++        if (page_num != 1)
++        {
++            curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON);
++            mvwaddstr(win, menu->height, footer_x, "<=");
++            curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF);
++        }
++        if (page_num != menu->num_pages)
++        {
++            curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON);
++            mvwaddstr(win, menu->height, menu->width - 2, "=>");        
++            curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF);
++        }
++    }
++    curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
++    box(win, 0, 0);
++    curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
++    wrefresh(win);
++}
++
++
++/* Add valid selections to choices array, and return the number of choices */
++
++static int menu_get_choices(nhmenu *menu, int how)
++{
++    char curletter;
++    int count = 0;
++    int accel_idx = 0;
++    nhmenu_item *menu_item_ptr = menu->entries;
++    
++    if (how == PICK_NONE)
++        return 0;
++
++    while (menu_item_ptr != NULL)
++    {
++        if (menu_item_ptr->identifier.a_void != NULL)
++        {
++            if (menu_item_ptr->accelerator != 0)
++            {
++                curletter = menu_item_ptr->accelerator;
++            }
++            else
++            {
++                if (accel_idx == 0)
++                {
++                    curletter = menu_get_accel(TRUE);
++                }
++                else
++                {
++                    curletter = menu_get_accel(FALSE);
++                }
++                menu_item_ptr->accelerator = curletter;
++            }
++            accel_idx++;
++        }
++        menu_item_ptr = menu_item_ptr->next_item;
++        count++;
++    }
++    return count;
++}
++
++
++
++static int menu_get_selections(WINDOW *win, nhmenu *menu, int num_choices, int how)
++{
++    int count, curletter;
++    int curpage = 1;
++    int num_selected = 0;
++    boolean dismiss = FALSE;
++    nhmenu_item *menu_item_ptr = menu->entries;
++
++    menu_display_page(menu, win, 1);
++
++    while (!dismiss)
++    {
++        curletter = getch();
++        
++        switch (curletter)
++        {
++            case KEY_ESC:
++            {
++                num_selected = -1;
++                dismiss = TRUE;
++                break;
++            }
++            case '\n':
++            case '\r':
++            {
++                dismiss = TRUE;
++                break;
++            }
++            case KEY_RIGHT:
++            case KEY_NPAGE:
++            case MENU_NEXT_PAGE:
++            case ' ':
++            {
++                if (curpage < menu->num_pages)
++                {
++                    curpage++;
++                    menu_display_page(menu, win, curpage);
++                }
++                break;
++            }
++            case KEY_LEFT:
++            case KEY_PPAGE:
++            case MENU_PREVIOUS_PAGE:
++            {
++                if (curpage > 1)
++                {
++                    curpage--;
++                    menu_display_page(menu, win, curpage);
++                }
++                break;
++            }
++            case KEY_END:
++            case MENU_LAST_PAGE:
++            {
++                if (curpage != menu->num_pages)
++                {
++                    curpage = menu->num_pages;
++                    menu_display_page(menu, win, curpage);
++                }
++                break;
++            }
++            case KEY_HOME:
++            case MENU_FIRST_PAGE:
++            {
++                if (curpage != 1)
++                {
++                    curpage = 1;
++                    menu_display_page(menu, win, curpage);
++                }
++                break;
++            }
++        }
++        if (how == PICK_ANY)
++        {
++            switch (curletter)
++                {
++                case MENU_SELECT_PAGE:
++                {
++                    (void) menu_operation(win, menu, SELECT, curpage);
++                    break;
++                }
++                case MENU_SELECT_ALL:
++                {
++                    curpage = menu_operation(win, menu, SELECT, 0);
++                    break;
++                }
++                case MENU_UNSELECT_PAGE:
++                {
++                    (void) menu_operation(win, menu, DESELECT, curpage);
++                    break;
++                }
++                case MENU_UNSELECT_ALL:
++                {
++                    curpage = menu_operation(win, menu, DESELECT, 0);
++                    break;
++                }
++                case MENU_INVERT_PAGE:
++                {
++                    (void) menu_operation(win, menu, INVERT, curpage);
++                    break;
++                }
++                case MENU_INVERT_ALL:
++                {
++                    curpage = menu_operation(win, menu, INVERT, 0);
++                    break;
++                }
++            }
++        }
++        
++        menu_item_ptr = menu->entries;
++        
++        while ((menu_item_ptr != NULL) && (how != PICK_NONE))
++        {
++            if (menu_item_ptr->identifier.a_void != NULL)
++            {
++                if (curletter == menu_item_ptr->accelerator)
++                {
++                    if (curpage != menu_item_ptr->page_num)
++                    {
++                        curpage = menu_item_ptr->page_num;
++                        menu_display_page(menu, win, curpage);
++                    }
++                    menu_select_deselect(win, menu_item_ptr, INVERT);
++                    if (how == PICK_ONE)
++                    {
++                        num_selected = 1;
++                        dismiss = TRUE;
++                    }
++                    break;
++                }
++            }
++            menu_item_ptr = menu_item_ptr->next_item;
++        }
++    }
++    
++    if ((how == PICK_ANY) && (num_selected != -1))
++    {
++        num_selected = 0;
++        menu_item_ptr = menu->entries;
++        
++        while (menu_item_ptr != NULL)
++        {
++            if (menu_item_ptr->identifier.a_void != NULL)
++            {
++                if (menu_item_ptr->selected)
++                {
++                    num_selected++;
++                }
++            }
++            menu_item_ptr = menu_item_ptr->next_item;
++        }
++    }
++    
++    return num_selected;
++}
++
++
++/* Select, deselect, or toggle selected for the given menu entry */
++
++static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operation)
++{
++    if ((operation == DESELECT) || (item->selected && (operation ==
++     INVERT)))
++    {
++        item->selected = FALSE;
++        mvwaddch(win, item->line_num + 1, 1, ' ');
++        mvwaddch(win, item->line_num + 1, 3, ')');
++    }
++    else
++    {
++        item->selected = TRUE;
++        curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, ON);
++        mvwaddch(win, item->line_num + 1, 1, '<');
++        mvwaddch(win, item->line_num + 1, 3, '>');
++        curses_toggle_color_attr(win, HIGHLIGHT_COLOR, NONE, OFF);
++    }
++    
++    wrefresh(win);
++}
++
++
++/* Perform the selected operation (select, unselect, invert selection)
++on the given menu page.  If menu_page is 0, then perform opetation on
++all pages in menu.  Returns last page displayed.  */
++
++static int menu_operation(WINDOW *win, nhmenu *menu, menu_op
++ operation, int page_num)
++{
++    int first_page, last_page, current_page;
++    nhmenu_item *menu_item_ptr = menu->entries;    
++    
++    if (page_num == 0)  /* Operation to occur on all pages */
++    {
++        first_page = 1;
++        last_page = menu->num_pages;
++    }
++    else
++    {
++        first_page = page_num;
++        last_page = page_num;
++    }
++
++    /* Cycle through entries until we are on the correct page */
++
++    while (menu_item_ptr != NULL)
++    {
++        if (menu_item_ptr->page_num == first_page)
++        {
++            break;
++        }
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++    
++    current_page = first_page;
++    
++    if (page_num == 0)
++    {
++        menu_display_page(menu, win, current_page);
++    }
++    
++    if (menu_item_ptr == NULL)  /* Page not found */
++    {
++        panic("menu_display_page: attempt to display nonexistant page");
++    }
++    
++    while (menu_item_ptr != NULL)
++    {        
++        if (menu_item_ptr->page_num != current_page)
++        {
++            if (menu_item_ptr->page_num > last_page)
++            {
++                break;
++            }
++
++            current_page = menu_item_ptr->page_num;
++            menu_display_page(menu, win, current_page);
++        }
++        
++        if (menu_item_ptr->identifier.a_void != NULL)
++        {
++            menu_select_deselect(win, menu_item_ptr, operation);
++        }
++        
++        menu_item_ptr = menu_item_ptr->next_item;
++    }
++    
++    return current_page;
++}
+diff -burN nethack-3.4.3/win/curses/cursdial.h nethack/win/curses/cursdial.h
+--- nethack-3.4.3/win/curses/cursdial.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursdial.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,89 @@
++#ifndef CURSDIAL_H
++#define CURSDIAL_H
++
++
++/* Global declarations */
++
++void curses_line_input_dialog(const char *prompt, char *answer, int buffer);
++
++int curses_character_input_dialog(const char *prompt, const char *choices, CHAR_P def);
++
++int curses_ext_cmd(void);
++
++void curses_create_nhmenu(winid wid);
++
++void curses_add_nhmenu_item(winid wid, const ANY_P *identifier,
++ CHAR_P accelerator, CHAR_P group_accel, int attr, const char *str,
++ BOOLEAN_P presel);
++
++void curses_finalize_nhmenu(winid wid, const char *prompt);
++
++int curses_display_nhmenu(winid wid, int how, MENU_ITEM_P **_selected);
++
++boolean curses_menu_exists(winid wid);
++
++void curses_del_menu(winid wid);
++
++
++/* Private declarations */
++
++typedef struct nhmi
++{
++    winid wid;  /* NetHack window id */
++    anything identifier; /* Value returned if item selected */
++    CHAR_P accelerator;  /* Character used to select item from menu */
++    CHAR_P group_accel; /* Group accelerator for menu item, if any */
++    int attr;  /* Text attributes for item */
++    const char *str;  /* Text of menu item */
++    BOOLEAN_P presel; /* Whether menu item should be preselected */
++    boolean selected;   /* Whether item is currently selected */
++    int page_num;   /* Display page number for entry */
++    int line_num;   /* Line number on page where entry begins */
++    int num_lines;  /* Number of lines entry uses on page */
++    struct nhmi *prev_item;    /* Pointer to previous entry */
++    struct nhmi *next_item;    /* Pointer to next entry */
++} nhmenu_item;
++
++typedef struct nhm
++{
++    winid wid;  /* NetHack window id */
++    const char *prompt;  /* Menu prompt text */
++    nhmenu_item *entries;   /* Menu entries */
++    int num_entries;          /* Number of menu entries */
++    int num_pages;            /* Number of display pages for entry */
++    int height;               /* Window height of menu */
++    int width;                /* Window width of menu */
++    struct nhm *prev_menu;    /* Pointer to previous entry */
++    struct nhm *next_menu;    /* Pointer to next entry */
++} nhmenu;
++
++typedef enum menu_op_type
++{
++    SELECT,
++    DESELECT,
++    INVERT
++} menu_op;
++
++static nhmenu *get_menu(winid wid);
++
++static char menu_get_accel(boolean first);
++
++static void menu_determine_pages(nhmenu *menu);
++
++static boolean menu_is_multipage(nhmenu *menu, int width, int height);
++
++static void menu_win_size(nhmenu *menu);
++
++static void menu_display_page(nhmenu *menu, WINDOW *win, int page_num);
++
++static int menu_get_choices(nhmenu *menu, int how);
++
++static int menu_get_selections(WINDOW *win, nhmenu *menu, int num_choices, int how);
++
++static void menu_select_deselect(WINDOW *win, nhmenu_item *item, menu_op operation);
++
++static int menu_operation(WINDOW *win, nhmenu *menu, menu_op operation,
++ int page_num);
++
++
++#endif  /* CURSDIAL_H */
+diff -burN nethack-3.4.3/win/curses/cursinit.c nethack/win/curses/cursinit.c
+--- nethack-3.4.3/win/curses/cursinit.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursinit.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,792 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "cursinit.h"
++
++/* Initialization functions for curses interface */
++
++
++/* Create the "main" nonvolitile windows used by nethack */
++
++void curses_create_main_windows()
++{
++    int message_x, message_y, status_x, status_y, map_x, map_y;
++    int message_height, message_width, status_height, status_width,
++     map_height, map_width;
++    int min_message_height = 1;
++    int message_orientation = 0;
++    int status_orientation = 0;
++    int border_space = 0;
++    int hspace = term_cols - 80;
++    boolean borders = FALSE;
++
++    switch (iflags.wc2_windowborders)
++    {
++        case 1: /* On */
++        {
++            borders = TRUE;
++            break;
++        }
++        case 2: /* Off */
++        {
++            borders = FALSE;
++            break;
++        }
++        case 3: /* Auto */
++        {
++            if ((term_cols > 81) && (term_rows > 25))
++            {
++                borders = TRUE;
++            }
++            break;
++        }
++        default:
++        {
++            borders = FALSE;
++        }
++    }
++
++    
++    if (borders)
++    {
++        border_space = 2;
++        hspace -= border_space;
++    }
++    
++    if ((term_cols - border_space) < COLNO)
++    {
++        min_message_height++;
++    }
++    
++    /* Determine status window orientation */    
++    if (!iflags.wc_align_status || (iflags.wc_align_status == ALIGN_TOP)
++     || (iflags.wc_align_status == ALIGN_BOTTOM))
++    {
++        if (!iflags.wc_align_status)
++        {
++            iflags.wc_align_status = ALIGN_BOTTOM;
++        }
++        status_orientation = iflags.wc_align_status;
++    }
++    else    /* left or right alignment */
++    {
++        /* Max space for player name and title horizontally */
++        if ((hspace >= 26) && (term_rows >= 24))
++        {
++            status_orientation = iflags.wc_align_status;
++            hspace -= (26 + border_space);
++        }
++        else
++        {
++            status_orientation = ALIGN_BOTTOM;
++        }
++    }
++    
++    /* Determine message window orientation */    
++    if (!iflags.wc_align_message || (iflags.wc_align_message == ALIGN_TOP)
++     || (iflags.wc_align_message == ALIGN_BOTTOM))
++    {
++        if (!iflags.wc_align_message)
++        {
++            iflags.wc_align_message = ALIGN_TOP;
++        }
++        message_orientation = iflags.wc_align_message;
++    }
++    else    /* left or right alignment */
++    {
++        if ((hspace - border_space) >= 25)   /* Arbitrary */
++        {
++            message_orientation = iflags.wc_align_message;
++        }
++        else
++        {
++            message_orientation = ALIGN_TOP;
++        }
++    }
++    
++    /* Determine window placement and size - 16 possible combos
++       If anyone wants to try to generalize this, be my guest! */
++    if ((status_orientation == ALIGN_TOP) &&
++     (message_orientation == ALIGN_TOP))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_width = (term_cols - border_space);
++        status_height = 2;
++        message_x = 0;
++        message_y = status_y + (status_height + border_space);
++        message_width = (term_cols - border_space);
++        message_height = term_rows - (status_height + ROWNO + (border_space * 3));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_x = 0;
++        map_y = message_y + (message_height + border_space);
++        map_width = (term_cols - border_space);
++        map_height = term_rows - (status_height + message_height + (border_space * 3));
++    }
++    else if ((status_orientation == ALIGN_TOP) &&
++     (message_orientation == ALIGN_RIGHT))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_height = 2;
++        message_height = (term_rows - border_space);
++        message_width = term_cols - (COLNO + (border_space * 2));
++        status_width = term_cols - (message_width + (border_space * 2));
++        message_x = status_x + (status_width + border_space);
++        message_y = 0;
++        map_x = 0;
++        map_y = status_y + (status_height + border_space);
++        map_width = status_width;
++        map_height = term_rows - (status_height + (border_space * 2));
++    }
++    else if ((status_orientation == ALIGN_TOP) &&
++     (message_orientation == ALIGN_BOTTOM))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_width = (term_cols - border_space);
++        status_height = 2;
++        map_x = 0;
++        map_y = status_y + (status_height + border_space);
++        map_width = (term_cols - border_space);
++        message_height = term_rows - (status_height + ROWNO + (border_space * 3));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_height = term_rows - (status_height + message_height + (border_space * 3));
++        message_x = 0;
++        message_y = map_y + (map_height + border_space);
++        message_width = (term_cols - border_space);
++    }
++    else if ((status_orientation == ALIGN_TOP) &&
++     (message_orientation == ALIGN_LEFT))
++    {
++        message_x = 0;
++        message_y = 0;
++        message_height = (term_rows - border_space);
++        message_width = term_cols - (COLNO + (border_space * 2));
++        status_x = message_x + (message_width + border_space);
++        status_y = 0;
++        status_height = 2;
++        status_width = term_cols - (message_width + (border_space * 2));
++        map_x = status_x;
++        map_y = status_y + (status_height + border_space);
++        map_height = term_rows - (status_height + (border_space * 2));
++        map_width = status_width;
++    }
++    if ((status_orientation == ALIGN_RIGHT) &&
++     (message_orientation == ALIGN_TOP))
++    {
++        status_width = 26;
++        status_height = (term_rows - border_space);
++        status_x = term_cols - (status_width + border_space);
++        status_y = 0;
++        message_x = 0;
++        message_y = 0;
++        message_width = term_cols - (status_width + (border_space * 2));
++        message_height = term_rows - (ROWNO + (border_space * 2));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_x = 0;
++        map_y = message_y + (message_height + border_space);
++        map_width = term_cols - (status_width + (border_space * 2));
++        map_height = term_rows - (message_height + (border_space * 2));
++    }
++    else if ((status_orientation == ALIGN_RIGHT) &&
++     (message_orientation == ALIGN_RIGHT))
++    {
++        map_x = 0;
++        map_y = 0;
++        map_height = (term_rows - border_space);
++        status_width = 26;
++        message_width = term_cols - (COLNO + status_width + (border_space * 3));
++        map_width = term_cols - (status_width + message_width + (border_space * 3));
++        message_x = map_x + (map_width + border_space);
++        message_y = 0;
++        message_height = (term_rows - border_space);
++        status_x = message_x + (message_width + border_space);
++        status_y = 0;
++        status_height = (term_rows - border_space);
++    }
++    else if ((status_orientation == ALIGN_RIGHT) &&
++     (message_orientation == ALIGN_BOTTOM))
++    {
++        map_x = 0;
++        map_y = 0;
++        status_width = 26;
++        map_width = term_cols - (status_width + (border_space * 2));
++        message_height = term_rows - (ROWNO + (border_space * 2));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_height = term_rows - (message_height + (border_space * 2));
++        message_x = 0;
++        message_y = map_y + (map_height + border_space);
++        message_width = map_width;
++        status_x = map_x + (map_width + border_space);
++        status_y = 0;
++        status_height = (term_rows - border_space);
++    }
++    else if ((status_orientation == ALIGN_RIGHT) &&
++     (message_orientation == ALIGN_LEFT))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_height = (term_rows - border_space);
++        status_width = 26;
++        message_width = term_cols - (status_width + COLNO + (border_space * 3));
++        map_x = status_x + (status_width + border_space);
++        map_y = 0;
++        map_height = (term_rows - border_space);
++        map_width = term_cols - (status_width + message_width + (border_space * 3));
++        message_x = map_x + (map_width + border_space);
++        message_y = 0;
++        message_height = (term_rows - border_space);
++    }
++    if ((status_orientation == ALIGN_BOTTOM) &&
++     (message_orientation == ALIGN_TOP))
++    {
++        message_x = 0;
++        message_y = 0;
++        message_width = (term_cols - border_space);
++        status_height = 2;
++        message_height = term_rows - (status_height + ROWNO + (border_space * 3));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_x = 0;
++        map_y = message_y + (message_height + border_space);
++        map_width = (term_cols - border_space);
++        map_height = term_rows - (status_height + message_height + (border_space * 3));
++        status_x = 0;
++        status_y = map_y + (map_height + border_space);
++        status_width = (term_cols - border_space);
++    }
++    else if ((status_orientation == ALIGN_BOTTOM) &&
++     (message_orientation == ALIGN_RIGHT))
++    {
++        map_x = 0;
++        map_y = 0;
++        status_height = 2;
++        map_height = term_rows - (status_height + (border_space * 2));
++        message_width = term_cols - (COLNO + (border_space * 2));
++        map_width = term_cols - (message_width + (border_space * 2));
++        status_x = 0;
++        status_y = map_y + (map_height + border_space);
++        status_width = map_width;
++        message_x = map_x + (map_width + border_space);
++        message_y = 0;
++        message_height = (term_rows - border_space);
++    }
++    else if ((status_orientation == ALIGN_BOTTOM) &&
++     (message_orientation == ALIGN_BOTTOM))
++    {
++        map_x = 0;
++        map_y = 0;
++        message_x = 0;
++        status_x = 0;
++        message_width = (term_cols - border_space);
++        status_height = 2;
++        message_height = term_rows - (status_height + ROWNO + (border_space * 3));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_width = (term_cols - border_space);
++        map_height = term_rows - (status_height + message_height + (border_space * 3));
++        message_y = map_y + (map_height + border_space);
++        status_y = message_y + (message_height + border_space);
++        status_width = (term_cols - border_space);
++    }
++    else if ((status_orientation == ALIGN_BOTTOM) &&
++     (message_orientation == ALIGN_LEFT))
++    {
++        message_x = 0;
++        message_y = 0;
++        message_height = (term_rows - border_space);
++        message_width = term_cols - (COLNO + (border_space * 2));
++        status_height = 2;
++        map_x = message_x + (message_width + border_space);
++        map_y = 0;
++        map_height = term_rows - (status_height + (border_space * 2));
++        map_width = term_cols - (message_width + (border_space * 2));
++        status_x = map_x;
++        status_y = map_y + (map_height + border_space);
++        status_width = term_cols - (message_width + (border_space * 2));
++    }
++    if ((status_orientation == ALIGN_LEFT) &&
++     (message_orientation == ALIGN_TOP))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_height = (term_rows - border_space);
++        status_width = 26;
++        message_x = status_x + (status_width + border_space);
++        message_y = 0;
++        message_height = term_rows - (ROWNO + (border_space * 2));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        message_width = term_cols - (status_width + (border_space * 2));
++        map_x = message_x;
++        map_y = message_y + (message_height + border_space);
++        map_height = term_rows - (message_height + (border_space * 2));
++        map_width = term_cols - (status_width + (border_space * 2));
++    }
++    else if ((status_orientation == ALIGN_LEFT) &&
++     (message_orientation == ALIGN_RIGHT))
++    {
++        message_x = 0;
++        message_y = 0;
++        message_height = (term_rows - border_space);
++        status_width = 26;
++        message_width = term_cols - (status_width + COLNO + (border_space * 3));
++        map_x = message_x + (message_width + border_space);
++        map_y = 0;
++        map_height = (term_rows - border_space);
++        map_width = term_cols - (status_width + message_width + (border_space * 3));
++        status_x = map_x + (map_width + border_space);
++        status_y = 0;
++        status_height = (term_rows - border_space);
++    }
++    else if ((status_orientation == ALIGN_LEFT) &&
++     (message_orientation == ALIGN_BOTTOM))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_height = (term_rows - border_space);
++        status_width = 26;
++        map_x = status_x + (status_width + border_space);
++        map_y = 0;
++        message_height = term_rows - (ROWNO + (border_space * 2));
++        if (message_height < min_message_height)
++        {
++            message_height = min_message_height;
++        }
++        map_height = term_rows - (message_height + (border_space * 2));
++        map_width = term_cols - (status_width + (border_space * 2));
++        message_x = status_x + (status_width + border_space);
++        message_y = map_y + (map_height + border_space);
++        message_width = map_width;
++    }
++    else if ((status_orientation == ALIGN_LEFT) &&
++     (message_orientation == ALIGN_LEFT))
++    {
++        status_x = 0;
++        status_y = 0;
++        status_height = (term_rows - border_space);
++        status_width = 26;
++        message_x = status_x + (status_width + border_space);
++        message_y = 0;
++        message_height = status_height;
++        message_width = term_cols - (COLNO + status_width + (border_space * 3));
++        map_x = message_x + (message_width + border_space);
++        map_y = 0;
++        map_height = message_height;
++        map_width = term_cols - (status_width + message_width + (border_space * 3));
++    }
++    
++    if (map_width > COLNO)
++    {
++        map_width = COLNO;
++    }
++    
++    if (map_height > ROWNO)
++    {
++        map_height = ROWNO;
++    }
++    
++    if (curses_window_exists(STATUS_WIN))
++    {
++        curses_del_nhwin(STATUS_WIN);
++        curses_del_nhwin(MESSAGE_WIN);
++        curses_del_nhwin(MAP_WIN);
++        clear();
++    }
++    
++    curses_add_nhwin(STATUS_WIN, status_height, status_width, status_y,
++     status_x, status_orientation, borders);
++
++    curses_add_nhwin(MESSAGE_WIN, message_height, message_width, message_y,
++     message_x, message_orientation, borders);
++
++    if (borders)
++    {
++        mapborderwin = newwin(map_height + border_space, map_width
++         + border_space, map_y, map_x);
++        wrefresh(mapborderwin);
++        curses_add_nhwin(MAP_WIN, map_height, map_width, map_y + 1, map_x + 1,
++         0, borders);
++    }
++    else
++    {
++        curses_add_nhwin(MAP_WIN, map_height, map_width, map_y, map_x, 0,
++         borders);
++    }
++
++    refresh();
++    curses_refresh_nethack_windows();
++
++    if (iflags.window_inited)
++    {
++        curses_update_stats();
++    }
++    else
++    {
++        iflags.window_inited = TRUE;
++    }
++}
++
++
++/* Initialize curses colors to colors used by NetHack */
++
++void curses_init_nhcolors()
++{
++#ifdef TEXTCOLOR
++    if (has_colors())
++    {
++#ifdef NCURSES_VERSION
++        use_default_colors();
++        init_pair(1, COLOR_BLACK, -1);
++        init_pair(2, COLOR_RED, -1);
++        init_pair(3, COLOR_GREEN, -1);
++        init_pair(4, COLOR_YELLOW, -1);
++        init_pair(5, COLOR_BLUE, -1);
++        init_pair(6, COLOR_MAGENTA, -1);
++        init_pair(7, COLOR_CYAN, -1);
++        init_pair(8, -1, -1);
++        init_pair(9, COLOR_WHITE, -1);
++#else        
++        init_pair(1, COLOR_BLACK, COLOR_BLACK);
++        init_pair(2, COLOR_RED, COLOR_BLACK);
++        init_pair(3, COLOR_GREEN, COLOR_BLACK);
++        init_pair(4, COLOR_YELLOW, COLOR_BLACK);
++        init_pair(5, COLOR_BLUE, COLOR_BLACK);
++        init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
++        init_pair(7, COLOR_CYAN, COLOR_BLACK);
++        init_pair(8, COLOR_WHITE, COLOR_BLACK);
++#endif
++        if (can_change_color())
++        {
++            init_color(COLOR_YELLOW, 500, 300, 0);
++            init_color(COLOR_WHITE, 600, 600, 600);
++        }
++    }
++#endif
++}
++
++
++/* Allow player to pick character's role, race, gender, and alignment.
++Borrowed from the Gnome window port. */
++
++void curses_choose_character()
++{
++    int n, i, sel;
++    const char** choices;
++    int* pickmap;
++
++    /* prevent an unnecessary prompt */
++    rigid_role_checks();
++
++    if (!flags.randomall && flags.initrole < 0) {
++
++	/* select a role */
++	for (n = 0; roles[n].name.m; n++) continue;
++	choices = (const char **)alloc(sizeof(char *) * (n+1));
++	pickmap = (int*)alloc(sizeof(int) * (n+1));
++	for (;;) {
++	    for (n = 0, i = 0; roles[i].name.m; i++) {
++		if (ok_role(i, flags.initrace,
++			    flags.initgend, flags.initalign)) {
++		    if (flags.initgend >= 0 && flags.female && roles[i].name.f)
++			choices[n] = roles[i].name.f;
++		    else
++			choices[n] = roles[i].name.m;
++		    pickmap[n++] = i;
++		}
++	    }
++	    if (n > 0) break;
++	    else if (flags.initalign >= 0) flags.initalign = -1;    /* reset */
++	    else if (flags.initgend >= 0) flags.initgend = -1;
++	    else if (flags.initrace >= 0) flags.initrace = -1;
++	    else panic("no available ROLE+race+gender+alignment combinations");
++	}
++	choices[n] = (const char *) 0;
++	if (n > 1)
++        sel = curses_character_dialog(choices, "Choose one of the following roles:");
++	else sel = 0;
++	if (sel >= 0) sel = pickmap[sel];
++	else if (sel == ROLE_NONE) {		/* Quit */
++	    clearlocks();
++	    curses_bail(0);
++	}
++	free(choices);
++	free(pickmap);
++    } else if (flags.initrole < 0) sel = ROLE_RANDOM;
++    else sel = flags.initrole;
++  
++    if (sel == ROLE_RANDOM) {	/* Random role */
++	sel = pick_role(flags.initrace, flags.initgend,
++			  flags.initalign, PICK_RANDOM);
++	if (sel < 0) sel = randrole();
++    }
++
++    flags.initrole = sel;
++
++    /* Select a race, if necessary */
++    /* force compatibility with role, try for compatibility with
++     * pre-selected gender/alignment */
++    if (flags.initrace < 0 || !validrace(flags.initrole, flags.initrace)) {
++	if (flags.initrace == ROLE_RANDOM || flags.randomall) {
++	    flags.initrace = pick_race(flags.initrole, flags.initgend,
++				       flags.initalign, PICK_RANDOM);
++	    if (flags.initrace < 0) flags.initrace = randrace(flags.initrole);
++	} else {
++	    /* Count the number of valid races */
++	    n = 0;	/* number valid */
++	    for (i = 0; races[i].noun; i++) {
++		if (ok_race(flags.initrole, i, flags.initgend, flags.initalign))
++		    n++;
++	    }
++	    if (n == 0) {
++		for (i = 0; races[i].noun; i++) {
++		    if (validrace(flags.initrole, i)) n++;
++		}
++	    }
++
++	    choices = (const char **)alloc(sizeof(char *) * (n+1));
++	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
++	    for (n = 0, i = 0; races[i].noun; i++) {
++		if (ok_race(flags.initrole, i, flags.initgend,
++			    flags.initalign)) {
++		    choices[n] = races[i].noun;
++		    pickmap[n++] = i;
++		}
++	    }
++	    choices[n] = (const char *) 0;
++	    /* Permit the user to pick, if there is more than one */
++	    if (n > 1)
++		sel = curses_character_dialog(choices, "Choose one of the following races:");
++	    else sel = 0;
++	    if (sel >= 0) sel = pickmap[sel];
++	    else if (sel == ROLE_NONE) { /* Quit */
++		clearlocks();
++		curses_bail(0);
++	    }
++	    flags.initrace = sel;
++	    free(choices);
++	    free(pickmap);
++	}
++	if (flags.initrace == ROLE_RANDOM) {	/* Random role */
++	    sel = pick_race(flags.initrole, flags.initgend,
++			    flags.initalign, PICK_RANDOM);
++	    if (sel < 0) sel = randrace(flags.initrole);
++	    flags.initrace = sel;
++	}
++    }
++
++    /* Select a gender, if necessary */
++    /* force compatibility with role/race, try for compatibility with
++     * pre-selected alignment */
++    if (flags.initgend < 0 ||
++	!validgend(flags.initrole, flags.initrace, flags.initgend)) {
++	if (flags.initgend == ROLE_RANDOM || flags.randomall) {
++	    flags.initgend = pick_gend(flags.initrole, flags.initrace,
++				       flags.initalign, PICK_RANDOM);
++	    if (flags.initgend < 0)
++		flags.initgend = randgend(flags.initrole, flags.initrace);
++	} else {
++	    /* Count the number of valid genders */
++	    n = 0;	/* number valid */
++	    for (i = 0; i < ROLE_GENDERS; i++) {
++		if (ok_gend(flags.initrole, flags.initrace, i, flags.initalign))
++		    n++;
++	    }
++	    if (n == 0) {
++		for (i = 0; i < ROLE_GENDERS; i++) {
++		    if (validgend(flags.initrole, flags.initrace, i)) n++;
++		}
++	    }
++
++	    choices = (const char **)alloc(sizeof(char *) * (n+1));
++	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
++	    for (n = 0, i = 0; i < ROLE_GENDERS; i++) {
++		if (ok_gend(flags.initrole, flags.initrace, i,
++				flags.initalign)) {
++		    choices[n] = genders[i].adj;
++		    pickmap[n++] = i;
++		}
++	    }
++	    choices[n] = (const char *) 0;
++	    /* Permit the user to pick, if there is more than one */
++	    if (n > 1)
++		sel = curses_character_dialog(choices, "Choose one of the following genders:");
++	    else sel = 0;
++	    if (sel >= 0) sel = pickmap[sel];
++	    else if (sel == ROLE_NONE) { /* Quit */
++		clearlocks();
++		curses_bail(0);
++	    }
++	    flags.initgend = sel;
++	    free(choices);
++	    free(pickmap);
++	}
++	if (flags.initgend == ROLE_RANDOM) {	/* Random gender */
++	    sel = pick_gend(flags.initrole, flags.initrace,
++			    flags.initalign, PICK_RANDOM);
++	    if (sel < 0) sel = randgend(flags.initrole, flags.initrace);
++	    flags.initgend = sel;
++	}
++    }
++
++    /* Select an alignment, if necessary */
++    /* force compatibility with role/race/gender */
++    if (flags.initalign < 0 ||
++	!validalign(flags.initrole, flags.initrace, flags.initalign)) {
++	if (flags.initalign == ROLE_RANDOM || flags.randomall) {
++	    flags.initalign = pick_align(flags.initrole, flags.initrace,
++					 flags.initgend, PICK_RANDOM);
++	    if (flags.initalign < 0)
++		flags.initalign = randalign(flags.initrole, flags.initrace);
++	} else {
++	    /* Count the number of valid alignments */
++	    n = 0;	/* number valid */
++	    for (i = 0; i < ROLE_ALIGNS; i++) {
++		if (ok_align(flags.initrole, flags.initrace, flags.initgend, i))
++		    n++;
++	    }
++	    if (n == 0) {
++		for (i = 0; i < ROLE_ALIGNS; i++)
++		    if (validalign(flags.initrole, flags.initrace, i)) n++;
++	    }
++
++	    choices = (const char **)alloc(sizeof(char *) * (n+1));
++	    pickmap = (int*)alloc(sizeof(int) * (n + 1));
++	    for (n = 0, i = 0; i < ROLE_ALIGNS; i++) {
++		if (ok_align(flags.initrole,
++			     flags.initrace, flags.initgend, i)) {
++		    choices[n] = aligns[i].adj;
++		    pickmap[n++] = i;
++		}
++	    }
++	    choices[n] = (const char *) 0;
++	    /* Permit the user to pick, if there is more than one */
++	    if (n > 1)
++		sel = curses_character_dialog(choices, "Choose one of the following alignments:");
++	    else sel = 0;
++	    if (sel >= 0) sel = pickmap[sel];
++	    else if (sel == ROLE_NONE) { /* Quit */
++		clearlocks();
++		curses_bail(0);
++	    }
++	    flags.initalign = sel;
++	    free(choices);
++	    free(pickmap);
++	}
++	if (flags.initalign == ROLE_RANDOM) {
++	    sel = pick_align(flags.initrole, flags.initrace,
++			     flags.initgend, PICK_RANDOM);
++	    if (sel < 0) sel = randalign(flags.initrole, flags.initrace);
++	    flags.initalign = sel;
++	}
++    }
++}
++
++
++/* Prompt user for character race, role, alignment, or gender */
++
++int curses_character_dialog(const char** choices, const char *prompt)
++{
++    int count, count2, ret, curletter;
++    char used_letters[52];
++    anything identifier;
++    menu_item *selected = NULL;
++    winid wid = curses_get_wid(NHW_MENU);
++
++    identifier.a_void = 0;
++    curses_start_menu(wid);
++
++    for (count=0; choices[count]; count++)
++    {
++        curletter=tolower(choices[count][0]);
++        for (count2=0; count2<count; count2++)
++        {
++            if (curletter==used_letters[count2])
++            {
++                curletter=toupper(curletter);
++            }
++        }
++
++        identifier.a_int = (count + 1); /* Must be non-zero */
++        curses_add_menu(wid, NO_GLYPH, &identifier, curletter, 0,
++         A_NONE, choices[count], FALSE);
++        used_letters[count] = curletter;
++    }
++
++    /* Random Selection */
++    identifier.a_int = ROLE_RANDOM;
++    curses_add_menu(wid, NO_GLYPH, &identifier, '*', 0, A_NONE, "Random",
++     FALSE);    
++    
++    /* Quit prompt */
++    identifier.a_int = ROLE_NONE;
++    curses_add_menu(wid, NO_GLYPH, &identifier, 'q', 0, A_NONE, "Quit",
++     FALSE);    
++    curses_end_menu(wid, prompt);
++    ret = curses_select_menu(wid, PICK_ONE, &selected);
++    ret = (selected->item.a_int);
++
++    if (ret > 0)
++    {
++        ret--;
++    }
++    
++    free(selected);
++    return ret;
++}
++
++
++/* Initialize and display options appropriately */
++
++void curses_init_options()
++{
++	set_wc_option_mod_status(WC_ALIGN_MESSAGE|WC_ALIGN_STATUS|WC_COLOR|
++	 WC_HILITE_PET|WC_POPUP_DIALOG, SET_IN_GAME);
++	set_wc2_option_mod_status(WC2_TERM_COLS|WC2_TERM_ROWS|
++	 WC2_WINDOWBORDERS, SET_IN_GAME);
++	set_option_mod_status("DECgraphics", SET_IN_FILE);
++	set_option_mod_status("perm_invent", SET_IN_FILE);
++	set_option_mod_status("eight_bit_tty", SET_IN_FILE);
++#ifdef PDCURSES
++    /* PDCurses for SDL, win32 and OS/2 has the ability to set the
++     terminal size programatically.  If the user does not specify a
++     size in the config file, we will set it to a nice big 110x32 to
++     take advantage of some of the nice features of this windowport. */
++    if (iflags.wc2_term_cols == 0)
++    {
++        iflags.wc2_term_cols = 110;
++    }
++    
++    if (iflags.wc2_term_rows == 0)
++    {
++        iflags.wc2_term_rows = 32;
++    }
++    
++    resize_term(iflags.wc2_term_rows, iflags.wc2_term_cols);
++    getmaxyx(base_term, term_rows, term_cols);
++#endif
++    if (!iflags.wc2_windowborders)
++    {
++        iflags.wc2_windowborders = 3; /* Set to auto if not specified */
++    }
++}
++
+diff -burN nethack-3.4.3/win/curses/cursinit.h nethack/win/curses/cursinit.h
+--- nethack-3.4.3/win/curses/cursinit.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursinit.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,17 @@
++#ifndef CURSINIT_H
++#define CURSINIT_H
++
++/* Global declarations */
++
++void curses_create_main_windows(void);
++
++void curses_init_nhcolors(void);
++
++void curses_choose_character(void);
++
++int curses_character_dialog(const char** choices, const char *prompt);
++
++void curses_init_options(void);
++
++
++#endif  /* CURSINIT_H */
+diff -burN nethack-3.4.3/win/curses/cursmain.c nethack/win/curses/cursmain.c
+--- nethack-3.4.3/win/curses/cursmain.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursmain.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,650 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++
++/* Public functions for curses NetHack interface */
++
++/* Interface definition, for windows.c */
++struct window_procs curses_procs = {
++    "curses",
++    WC_ALIGN_MESSAGE|WC_ALIGN_STATUS|WC_COLOR|WC_HILITE_PET|
++    WC_POPUP_DIALOG,
++    WC2_TERM_COLS|WC2_TERM_ROWS|WC2_WINDOWBORDERS,
++    curses_init_nhwindows,
++    curses_player_selection,
++    curses_askname,
++    curses_get_nh_event,
++    curses_exit_nhwindows,
++    curses_suspend_nhwindows,
++    curses_resume_nhwindows,
++    curses_create_nhwindow,
++    curses_clear_nhwindow,
++    curses_display_nhwindow,
++    curses_destroy_nhwindow,
++    curses_curs,
++    curses_putstr,
++    curses_display_file,
++    curses_start_menu,
++    curses_add_menu,
++    curses_end_menu,
++    curses_select_menu,
++    genl_message_menu,
++    curses_update_inventory,
++    curses_mark_synch,
++    curses_wait_synch,
++#ifdef CLIPPING
++    curses_cliparound,
++#endif
++#ifdef POSITIONBAR
++    donull,
++#endif
++    curses_print_glyph,
++    curses_raw_print,
++    curses_raw_print_bold,
++    curses_nhgetch,
++    curses_nh_poskey,
++    curses_nhbell,
++    curses_doprev_message,
++    curses_yn_function,
++    curses_getlin,
++    curses_get_ext_cmd,
++    curses_number_pad,
++    curses_delay_output,
++#ifdef CHANGE_COLOR	/* only a Mac option currently */
++    donull,
++    donull,
++#endif
++    curses_start_screen,
++    curses_end_screen,
++    genl_outrip,
++    curses_preference_update,
++};
++
++/*  
++init_nhwindows(int* argcp, char** argv)
++                -- Initialize the windows used by NetHack.  This can also
++                   create the standard windows listed at the top, but does
++                   not display them.
++                -- Any commandline arguments relevant to the windowport
++                   should be interpreted, and *argcp and *argv should
++                   be changed to remove those arguments.
++                -- When the message window is created, the variable
++                   iflags.window_inited needs to be set to TRUE.  Otherwise
++                   all plines() will be done via raw_print().
++                ** Why not have init_nhwindows() create all of the "standard"
++                ** windows?  Or at least all but WIN_INFO?      -dean
++*/
++void curses_init_nhwindows(int* argcp, char** argv)
++{
++#ifdef XCURSES
++    base_term = Xinitscr(*argcp, argv);
++#else
++    base_term = initscr();
++#endif
++#ifdef TEXTCOLOR
++    if (has_colors())
++        start_color();
++    else
++        iflags.use_color = FALSE;
++    curses_init_nhcolors();
++#else
++    iflags.use_color = FALSE;
++#endif
++    noecho();
++    raw();
++    keypad(stdscr, TRUE);
++    meta(stdscr, TRUE);
++    curs_set(0);
++    getmaxyx(base_term, term_rows, term_cols);
++    curses_init_options();
++    if ((term_rows < 18) || (term_cols < 40))
++    {
++        panic("Terminal too small.  Must be minumum 40 width and 18 height");
++    }
++
++    curses_create_main_windows();
++    curses_init_mesg_history();
++}
++
++
++/* Do a window-port specific player type selection. If player_selection()
++   offers a Quit option, it is its responsibility to clean up and terminate
++   the process. You need to fill in pl_character[0].
++*/
++void curses_player_selection()
++{
++    curses_choose_character();
++}
++
++
++/* Ask the user for a player name. */
++void curses_askname()
++{
++    curses_line_input_dialog("Who are you?", plname, PL_NSIZ);
++}
++
++
++/* Does window event processing (e.g. exposure events).
++   A noop for the tty and X window-ports.
++*/
++void curses_get_nh_event()
++{
++#ifdef PDCURSES
++    if (is_termresized())
++    {
++        resize_term(0, 0);
++        getmaxyx(base_term, term_rows, term_cols);
++        curses_create_main_windows();
++        curses_last_messages();
++        doredraw();
++    }
++#endif
++#ifdef NCURSES_VERSION  /* Is there a better way to detect ncurses? */
++    if (is_term_resized(term_rows, term_cols))
++    {
++        if (!isendwin())
++        {
++            endwin();
++        }
++        
++        refresh();
++        getmaxyx(base_term, term_rows, term_cols);
++        curses_create_main_windows();
++        curses_last_messages();
++        doredraw();
++    }
++#endif
++}
++
++/* Exits the window system.  This should dismiss all windows,
++   except the "window" used for raw_print().  str is printed if possible.
++*/
++void curses_exit_nhwindows(const char *str)
++{
++    endwin();
++    iflags.window_inited = 0;
++    if (str != NULL)
++    {
++        raw_print(str);
++    }
++}
++
++/* Prepare the window to be suspended. */
++void curses_suspend_nhwindows(const char *str)
++{
++}
++
++
++/* Restore the windows after being suspended. */
++void curses_resume_nhwindows()
++{
++    curses_refresh_nethack_windows();
++}
++
++/*  Create a window of type "type" which can be 
++        NHW_MESSAGE     (top line)
++        NHW_STATUS      (bottom lines)
++        NHW_MAP         (main dungeon)
++        NHW_MENU        (inventory or other "corner" windows)
++        NHW_TEXT        (help/text, full screen paged window)
++*/
++winid curses_create_nhwindow(int type)
++{
++    winid wid = curses_get_wid(type);
++
++    if (curses_is_menu(wid) || curses_is_text(wid))
++    {
++        curses_start_menu(wid);
++        /* Add to window list just to keep track of the wid */
++        curses_add_nhwin(wid, 0, 0, 0, 0, 0, TRUE);
++    }
++    
++    return wid;
++}
++
++
++/* Clear the given window, when asked to. */
++void curses_clear_nhwindow(winid wid)
++{
++    if (wid != NHW_MESSAGE)
++    {
++        curses_clear_nhwin(wid);
++    }
++}
++
++/* -- Display the window on the screen.  If there is data
++                   pending for output in that window, it should be sent.
++                   If blocking is TRUE, display_nhwindow() will not
++                   return until the data has been displayed on the screen,
++                   and acknowledged by the user where appropriate.
++                -- All calls are blocking in the tty window-port.
++                -- Calling display_nhwindow(WIN_MESSAGE,???) will do a
++                   --more--, if necessary, in the tty window-port.
++*/
++void curses_display_nhwindow(winid wid, BOOLEAN_P block)
++{
++    menu_item *selected = NULL;
++    WINDOW *win = curses_get_nhwin(wid);
++    
++    if ((win != NULL) && (wid == MAP_WIN) && block)
++    {
++        curses_more();
++    }
++    else if (curses_is_menu(wid) || curses_is_text(wid))
++    {
++        curses_end_menu(wid, "");
++        curses_select_menu(wid, PICK_NONE, &selected);
++    }
++}
++
++
++/* Destroy will dismiss the window if the window has not 
++ * already been dismissed.
++*/
++void curses_destroy_nhwindow(winid wid)
++{
++    curses_del_nhwin(wid);
++}
++
++/* Next output to window will start at (x,y), also moves
++ displayable cursor to (x,y).  For backward compatibility,
++ 1 <= x < cols, 0 <= y < rows, where cols and rows are
++ the size of window.
++*/
++void curses_curs(winid wid, int x, int y)
++{
++    curses_move_cursor(wid, x, y);
++}
++
++/*
++putstr(window, attr, str)
++                -- Print str on the window with the given attribute.  Only
++                   printable ASCII characters (040-0126) must be supported.
++                   Multiple putstr()s are output on separate lines.
++Attributes
++                   can be one of
++                        ATR_NONE (or 0)
++                        ATR_ULINE
++                        ATR_BOLD
++                        ATR_BLINK
++                        ATR_INVERSE
++                   If a window-port does not support all of these, it may map
++                   unsupported attributes to a supported one (e.g. map them
++                   all to ATR_INVERSE).  putstr() may compress spaces out of
++                   str, break str, or truncate str, if necessary for the
++                   display.  Where putstr() breaks a line, it has to clear
++                   to end-of-line.
++                -- putstr should be implemented such that if two putstr()s
++                   are done consecutively the user will see the first and
++                   then the second.  In the tty port, pline() achieves this
++                   by calling more() or displaying both on the same line.
++*/
++void curses_putstr(winid wid, int attr, const char *text)
++{
++    curses_puts(wid, attr, text);
++}
++
++/* Display the file named str.  Complain about missing files
++                   iff complain is TRUE.
++*/
++void curses_display_file(const char *filename,BOOLEAN_P must_exist)
++{
++    curses_view_file(filename, must_exist);
++}
++
++/* Start using window as a menu.  You must call start_menu()
++   before add_menu().  After calling start_menu() you may not
++   putstr() to the window.  Only windows of type NHW_MENU may
++   be used for menus.
++*/
++void curses_start_menu(winid wid)
++{
++    curses_create_nhmenu(wid);
++}
++
++/*
++add_menu(winid wid, int glyph, const anything identifier,
++                                char accelerator, char groupacc,
++                                int attr, char *str, boolean preselected)
++                -- Add a text line str to the given menu window.  If identifier
++                   is 0, then the line cannot be selected (e.g. a title).
++                   Otherwise, identifier is the value returned if the line is
++                   selected.  Accelerator is a keyboard key that can be used
++                   to select the line.  If the accelerator of a selectable
++                   item is 0, the window system is free to select its own
++                   accelerator.  It is up to the window-port to make the
++                   accelerator visible to the user (e.g. put "a - " in front
++                   of str).  The value attr is the same as in putstr().
++                   Glyph is an optional glyph to accompany the line.  If
++                   window port cannot or does not want to display it, this
++                   is OK.  If there is no glyph applicable, then this
++                   value will be NO_GLYPH.
++                -- All accelerators should be in the range [A-Za-z].
++                -- It is expected that callers do not mix accelerator
++                   choices.  Either all selectable items have an accelerator
++                   or let the window system pick them.  Don't do both.
++                -- Groupacc is a group accelerator.  It may be any character
++                   outside of the standard accelerator (see above) or a
++                   number.  If 0, the item is unaffected by any group
++                   accelerator.  If this accelerator conflicts with
++                   the menu command (or their user defined alises), it loses.
++                   The menu commands and aliases take care not to interfere
++                   with the default object class symbols.
++                -- If you want this choice to be preselected when the
++                   menu is displayed, set preselected to TRUE.
++*/
++void curses_add_menu(winid wid, int glyph, const ANY_P * identifier,
++		CHAR_P accelerator, CHAR_P group_accel, int attr, 
++		const char *str, BOOLEAN_P presel)
++{
++    curses_add_nhmenu_item(wid, identifier, accelerator, group_accel, attr,
++     str, presel);
++}
++
++/*
++end_menu(window, prompt)
++                -- Stop adding entries to the menu and flushes the window
++                   to the screen (brings to front?).  Prompt is a prompt
++                   to give the user.  If prompt is NULL, no prompt will
++                   be printed.
++                ** This probably shouldn't flush the window any more (if
++                ** it ever did).  That should be select_menu's job.  -dean
++*/
++void curses_end_menu(winid wid, const char *prompt)
++{
++    curses_finalize_nhmenu(wid, prompt);
++}
++
++/*
++int select_menu(winid window, int how, menu_item **selected)
++                -- Return the number of items selected; 0 if none were chosen,
++                   -1 when explicitly cancelled.  If items were selected, then
++                   selected is filled in with an allocated array of menu_item
++                   structures, one for each selected line.  The caller must
++                   free this array when done with it.  The "count" field
++                   of selected is a user supplied count.  If the user did
++                   not supply a count, then the count field is filled with
++                   -1 (meaning all).  A count of zero is equivalent to not
++                   being selected and should not be in the list.  If no items
++                   were selected, then selected is NULL'ed out.  How is the
++                   mode of the menu.  Three valid values are PICK_NONE,
++                   PICK_ONE, and PICK_N, meaning: nothing is selectable,
++                   only one thing is selectable, and any number valid items
++                   may selected.  If how is PICK_NONE, this function should
++                   never return anything but 0 or -1.
++                -- You may call select_menu() on a window multiple times --
++                   the menu is saved until start_menu() or destroy_nhwindow()
++                   is called on the window.
++                -- Note that NHW_MENU windows need not have select_menu()
++                   called for them. There is no way of knowing whether
++                   select_menu() will be called for the window at
++                   create_nhwindow() time.
++*/
++int curses_select_menu(winid wid, int how, MENU_ITEM_P **selected)
++{
++    return curses_display_nhmenu(wid, how, selected);
++}
++
++/*
++    -- Indicate to the window port that the inventory has been changed.
++    -- Merely calls display_inventory() for window-ports that leave the 
++	window up, otherwise empty.
++*/
++void curses_update_inventory()
++{
++}
++
++/*
++mark_synch()    -- Don't go beyond this point in I/O on any channel until
++                   all channels are caught up to here.  Can be an empty call
++                   for the moment
++*/
++void curses_mark_synch()
++{
++}
++
++/*
++wait_synch()    -- Wait until all pending output is complete (*flush*() for
++                   streams goes here).
++                -- May also deal with exposure events etc. so that the
++                   display is OK when return from wait_synch().
++*/
++void curses_wait_synch()
++{
++}
++
++/*
++cliparound(x, y)-- Make sure that the user is more-or-less centered on the
++                   screen if the playing area is larger than the screen.
++                -- This function is only defined if CLIPPING is defined.
++*/
++void curses_cliparound(int x, int y)
++{
++}
++
++/*
++print_glyph(window, x, y, glyph)
++                -- Print the glyph at (x,y) on the given window.  Glyphs are
++                   integers at the interface, mapped to whatever the window-
++                   port wants (symbol, font, color, attributes, ...there's
++                   a 1-1 map between glyphs and distinct things on the map).
++*/
++void curses_print_glyph(winid wid, XCHAR_P x, XCHAR_P y, int glyph)
++{
++    int ch, color, special;
++    int attr = -1;
++
++    /* map glyph to character and color */
++    mapglyph(glyph, &ch, &color, &special, x, y);
++    if ((special & MG_PET) && iflags.hilite_pet)
++    {
++        attr = ATR_ULINE;
++    }
++    if ((special & MG_DETECT) && iflags.use_inverse)
++	{
++	    attr = ATR_INVERSE;
++	}
++	if (iflags.cursesgraphics)
++	{
++	    ch = curses_convert_glyph(ch, glyph);
++	}
++    curses_putch(wid, x, y, ch, color, attr);
++}
++
++/*
++raw_print(str)  -- Print directly to a screen, or otherwise guarantee that
++                   the user sees str.  raw_print() appends a newline to str.
++                   It need not recognize ASCII control characters.  This is
++                   used during startup (before windowing system initialization
++                   -- maybe this means only error startup messages are raw),
++                   for error messages, and maybe other "msg" uses.  E.g.
++                   updating status for micros (i.e, "saving").
++*/
++void curses_raw_print(const char *str)
++{
++    puts(str);
++}
++
++/*
++raw_print_bold(str)
++            -- Like raw_print(), but prints in bold/standout (if possible).
++*/
++void curses_raw_print_bold(const char *str)
++{
++    curses_raw_print(str);
++}
++
++/*
++int nhgetch()   -- Returns a single character input from the user.
++                -- In the tty window-port, nhgetch() assumes that tgetch()
++                   will be the routine the OS provides to read a character.
++                   Returned character _must_ be non-zero.
++*/
++int curses_nhgetch()
++{    
++    int ch;
++    
++    curses_prehousekeeping();
++    ch = curses_read_char();
++    curses_posthousekeeping();
++    
++    return ch;
++}
++
++/*
++int nh_poskey(int *x, int *y, int *mod)
++                -- Returns a single character input from the user or a
++                   a positioning event (perhaps from a mouse).  If the
++                   return value is non-zero, a character was typed, else,
++                   a position in the MAP window is returned in x, y and mod.
++                   mod may be one of
++
++                        CLICK_1         -- mouse click type 1 
++                        CLICK_2         -- mouse click type 2 
++
++                   The different click types can map to whatever the
++                   hardware supports.  If no mouse is supported, this
++                   routine always returns a non-zero character.
++*/
++int curses_nh_poskey(int *x, int *y, int *mod)
++{
++    return curses_nhgetch();
++}
++
++/*
++nhbell()        -- Beep at user.  [This will exist at least until sounds are
++                   redone, since sounds aren't attributable to windows anyway.]
++*/
++void curses_nhbell()
++{
++    beep();
++}
++
++/*
++doprev_message()
++                -- Display previous messages.  Used by the ^P command.
++                -- On the tty-port this scrolls WIN_MESSAGE back one line.
++*/
++int curses_doprev_message()
++{
++    curses_prev_mesg();
++}
++
++/*
++char yn_function(const char *ques, const char *choices, char default)
++                -- Print a prompt made up of ques, choices and default.
++                   Read a single character response that is contained in
++                   choices or default.  If choices is NULL, all possible
++                   inputs are accepted and returned.  This overrides
++                   everything else.  The choices are expected to be in
++                   lower case.  Entering ESC always maps to 'q', or 'n',
++                   in that order, if present in choices, otherwise it maps
++                   to default.  Entering any other quit character (SPACE,
++                   RETURN, NEWLINE) maps to default.
++                -- If the choices string contains ESC, then anything after
++                   it is an acceptable response, but the ESC and whatever
++                   follows is not included in the prompt.
++                -- If the choices string contains a '#' then accept a count.
++                   Place this value in the global "yn_number" and return '#'.
++                -- This uses the top line in the tty window-port, other
++                   ports might use a popup.
++*/
++char curses_yn_function(const char *question, const char *choices, CHAR_P def)
++{
++    curses_character_input_dialog(question, choices, def);
++}
++
++/*
++getlin(const char *ques, char *input)
++	    -- Prints ques as a prompt and reads a single line of text,
++	       up to a newline.  The string entered is returned without the
++	       newline.  ESC is used to cancel, in which case the string
++	       "\033\000" is returned.
++	    -- getlin() must call flush_screen(1) before doing anything.
++	    -- This uses the top line in the tty window-port, other
++	       ports might use a popup.
++*/
++void curses_getlin(const char *question, char *input)
++{
++    curses_line_input_dialog(question, input, BUFSZ);
++}
++
++/*
++int get_ext_cmd(void)
++	    -- Get an extended command in a window-port specific way.
++	       An index into extcmdlist[] is returned on a successful
++	       selection, -1 otherwise.
++*/
++int curses_get_ext_cmd()
++{
++    return curses_ext_cmd();
++}
++
++
++/*
++number_pad(state)
++	    -- Initialize the number pad to the given state.
++*/
++void curses_number_pad(int state)
++{
++}
++
++/*
++delay_output()  -- Causes a visible delay of 50ms in the output.
++	       Conceptually, this is similar to wait_synch() followed
++	       by a nap(50ms), but allows asynchronous operation.
++*/
++void curses_delay_output()
++{
++//    curses_refresh_nethack_windows();
++//    usleep(5000);
++}
++
++/*
++start_screen()  -- Only used on Unix tty ports, but must be declared for
++	       completeness.  Sets up the tty to work in full-screen
++	       graphics mode.  Look at win/tty/termcap.c for an
++	       example.  If your window-port does not need this function
++	       just declare an empty function.
++*/
++void curses_start_screen()
++{
++}
++
++/*
++end_screen()    -- Only used on Unix tty ports, but must be declared for
++	       completeness.  The complement of start_screen().
++*/
++void curses_end_screen()
++{
++}
++
++/*
++outrip(winid, int)
++	    -- The tombstone code.  If you want the traditional code use
++	       genl_outrip for the value and check the #if in rip.c.
++*/
++void curses_outrip(winid wid, int how)
++{
++}
++
++/*
++preference_update(preference)
++		-- The player has just changed one of the wincap preference
++		   settings, and the NetHack core is notifying your window
++		   port of that change.  If your window-port is capable of
++		   dynamically adjusting to the change then it should do so.
++		   Your window-port will only be notified of a particular
++		   change if it indicated that it wants to be by setting the 
++		   corresponding bit in the wincap mask.
++*/
++void curses_preference_update(const char *pref)
++{
++    if ((strcmp(pref, "align_status") == 0) ||
++     (strcmp(pref, "align_message") == 0))
++    {
++        curses_create_main_windows();
++        curses_last_messages();
++        doredraw();
++    }
++}
+diff -burN nethack-3.4.3/win/curses/cursmesg.c nethack/win/curses/cursmesg.c
+--- nethack-3.4.3/win/curses/cursmesg.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursmesg.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,365 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "cursmesg.h"
++
++/* Message window routines for curses interface */
++
++static int turn_lines = 1;
++static int mx = 0;
++static int my = 0;  /* message window text location */
++static nhprev_mesg *first_mesg = NULL;
++static nhprev_mesg *last_mesg = NULL;
++static int max_messages;
++static int num_messages = 0;
++
++
++
++/* Write a string to the message window.  Attributes set by calling function. */
++
++void curses_message_win_puts(const char *message, boolean recursed)
++{
++    int height, width, linespace, count;
++    char *tmpstr;
++    WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
++    boolean border = curses_window_has_border(MESSAGE_WIN);
++    int message_length = strlen(message);
++    int border_space = 0;
++    
++    if (!recursed)
++    {
++        strcpy(toplines, message);
++        mesg_add_line((char *) message);
++    }
++    
++    curses_get_window_size(MESSAGE_WIN, &height, &width);
++    if (border)
++    {
++        border_space = 1;
++        if (mx < 1)
++        {
++            mx = 1;
++        }
++        if (my < 1)
++        {
++            my = 1;
++        }
++    }
++    
++    linespace = ((width + border_space) - 3) - mx;
++    
++    if (linespace < message_length)
++    {
++        if (my >= (height - 1 + border_space)) /* bottom of message win */
++        {
++            if (turn_lines == height)
++            {
++                curses_more();
++            }
++            else
++            {
++                scroll_window(MESSAGE_WIN);
++                turn_lines++;
++            }
++        }
++        else
++        {
++            if (mx != border_space)
++            {
++                my++;
++                mx = border_space;
++            }
++        }
++    }
++
++    if (height > 1)
++    {
++        curses_toggle_color_attr(win, NONE, ATR_BOLD, ON);
++    }
++    
++    if ((mx == border_space) && ((message_length + 2) > width))
++    {
++        tmpstr = curses_break_str(message, (width - 2), 1);
++        mvwprintw(win, my, mx, tmpstr);
++        mx += strlen(tmpstr);
++        free(tmpstr);
++        if (height > 1)
++        {
++            curses_toggle_color_attr(win, NONE, ATR_BOLD, OFF);
++        }
++        wrefresh(win);
++        curses_message_win_puts(curses_str_remainder(message, (width - 2), 1),
++         TRUE);
++    }
++    else
++    {
++        mvwprintw(win, my, mx, message);
++        curses_toggle_color_attr(win, NONE, ATR_BOLD, OFF);
++    }
++    wrefresh(win);
++    mx += message_length + 1;
++}
++
++
++void curses_more()
++{
++    int height, width;
++    WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
++    
++    curses_get_window_size(MESSAGE_WIN, &height, &width);
++    curses_toggle_color_attr(win, MORECOLOR, NONE, ON);
++    mvwprintw(win, my, mx - 1, ">>");
++    curses_toggle_color_attr(win, MORECOLOR, NONE, OFF);
++    wrefresh(win);
++    wgetch(win);
++    if (height == 1)
++    {
++        curses_clear_unhighlight_message_window();
++    }
++    else
++    {
++        mvwprintw(win, my, mx - 1, "  ");
++        scroll_window(MESSAGE_WIN);
++        turn_lines = 1;
++    }
++}
++
++
++/* Clear the message window if one line; otherwise unhighlight old messages */
++
++void curses_clear_unhighlight_message_window()
++{
++    int mh, mw, count;
++    boolean border = curses_window_has_border(MESSAGE_WIN);
++    WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
++
++    turn_lines = 1;
++    
++    curses_get_window_size(MESSAGE_WIN, &mh, &mw); 
++    
++    mx = 0;
++    
++    if (border)
++    {
++        mx++;
++    }
++       
++    if (mh == 1)
++    {
++        curses_clear_nhwin(MESSAGE_WIN);
++    }
++    else
++    {
++        mx += mw;    /* Force new line on new turn */
++        
++        if (border)
++        {
++
++            for (count = 0; count < mh; count++)
++            {
++                mvwchgat(win, count+1, 1, mw, COLOR_PAIR(8), A_NORMAL, NULL);
++            }
++        }
++        else
++        {
++            for (count = 0; count < mh; count++)
++            {
++                mvwchgat(win, count, 0, mw, COLOR_PAIR(8), A_NORMAL, NULL);
++            }
++        }
++
++        wrefresh(win);
++    }
++}
++
++
++/* Reset message window cursor to starting position, and display most
++recent messages. */
++
++void curses_last_messages()
++{
++    boolean border = curses_window_has_border(MESSAGE_WIN);
++
++    if (border)
++    {
++        mx = 1;
++        my = 1;
++    }
++    else
++    {
++        mx = 0;
++        my = 0;
++    }
++    
++    pline(toplines);
++}
++
++
++/* Initialize list for message history */
++
++void curses_init_mesg_history()
++{
++    max_messages = iflags.msg_history;
++    
++    if (max_messages < 1)
++    {
++        max_messages = 1;
++    }
++
++    if (max_messages > MESG_HISTORY_MAX)
++    {
++        max_messages = MESG_HISTORY_MAX;
++    }
++}
++
++
++/* Display previous message window messages in reverse chron order */
++
++void curses_prev_mesg()
++{
++    int count;
++    winid wid;
++    long turn = 0;
++    anything *identifier;
++    nhprev_mesg *mesg;
++    menu_item *selected = NULL;
++
++    wid = curses_get_wid(NHW_MENU);
++    curses_create_nhmenu(wid);
++    identifier = malloc(sizeof(anything));
++    identifier->a_void = NULL;
++    
++    for (count = 0; count < num_messages; count++)
++    {
++        mesg = get_msg_line(TRUE, count);
++        if ((turn != mesg->turn) && (count != 0))
++        {
++            curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NONE,
++             "---", FALSE);
++        }
++        curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NONE,
++         mesg->str, FALSE);
++        turn = mesg->turn;
++    }
++    
++    curses_end_menu(wid, "");
++    curses_select_menu(wid, PICK_NONE, &selected);
++}
++
++
++/* Scroll lines upward in given window, or clear window if only one line. */
++
++static void scroll_window(winid wid)
++{
++    int wh, ww, s_top, s_bottom;
++    boolean border = curses_window_has_border(wid);
++    WINDOW *win = curses_get_nhwin(wid);
++    
++    curses_get_window_size(wid, &wh, &ww);
++    if (wh == 1)
++    {
++        curses_clear_nhwin(wid);
++        return;
++    }
++    if (border)
++    {
++        s_top = 1;
++        s_bottom = wh;
++    }
++    else
++    {
++        s_top = 0;
++        s_bottom = wh - 1;
++    }
++    scrollok(win, TRUE);
++    wsetscrreg(win, s_top, s_bottom);
++    scroll(win);
++    scrollok(win, FALSE);
++    if (wid == MESSAGE_WIN)
++    {
++        if (border)
++            mx = 1;
++        else
++            mx = 0;
++    }
++    if (border)
++    {
++        box(win, 0, 0);
++    }
++    wrefresh(win);
++}
++
++
++/* Add given line to message history */
++
++static void mesg_add_line(char *mline)
++{
++    nhprev_mesg *tmp_mesg = NULL;
++    nhprev_mesg *current_mesg = malloc(sizeof(nhprev_mesg));
++
++    current_mesg->str = curses_copy_of(mline);
++    current_mesg->turn = moves;
++    current_mesg->next_mesg = NULL;
++
++    if (num_messages == 0)
++    {
++        first_mesg = current_mesg;
++    }
++    
++    if (last_mesg != NULL)
++    {
++        last_mesg->next_mesg = current_mesg;
++    }
++    current_mesg->prev_mesg = last_mesg;
++    last_mesg = current_mesg;
++
++
++    if (num_messages < max_messages)
++    {
++        num_messages++;
++    }
++    else
++    {
++        tmp_mesg = first_mesg->next_mesg;
++        free(first_mesg);
++        first_mesg = tmp_mesg;
++    }
++}
++
++
++/* Returns specified line from message history, or NULL if out of bounds */
++
++static nhprev_mesg *get_msg_line(boolean reverse, int mindex)
++{
++    int count;
++    char *line;
++    nhprev_mesg *current_mesg;
++
++    if (reverse)
++    {
++        current_mesg = last_mesg;
++        for (count = 0; count < mindex; count++)
++        {
++            if (current_mesg == NULL)
++            {
++                return NULL;
++            }
++            current_mesg = current_mesg->prev_mesg;
++        }
++        return current_mesg;
++    }
++    else
++    {
++        current_mesg = first_mesg;
++        for (count = 0; count < mindex; count++)
++        {
++            if (current_mesg == NULL)
++            {
++                return NULL;
++            }
++            current_mesg = current_mesg->next_mesg;
++        }
++        return current_mesg;
++    }
++}
++
+diff -burN nethack-3.4.3/win/curses/cursmesg.h nethack/win/curses/cursmesg.h
+--- nethack-3.4.3/win/curses/cursmesg.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursmesg.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,37 @@
++#ifndef CURSMESG_H
++#define CURSMESG_H
++
++
++/* Global declarations */
++
++void curses_message_win_puts(const char *message, boolean recursed);
++
++void curses_more(void);
++
++void curses_clear_unhighlight_message_window(void);
++
++void curses_last_messages(void);
++
++void curses_init_mesg_history(void);
++
++void curses_prev_mesg(void);
++
++
++/* Private declatations */
++
++typedef struct nhpm
++{
++    char *str;  /* Message text */
++    long turn;  /* Turn number for message */
++    struct nhpm *prev_mesg;    /* Pointer to previous message */
++    struct nhpm *next_mesg;    /* Pointer to next message */
++} nhprev_mesg;
++
++static void scroll_window(winid wid);
++
++static void mesg_add_line(char *mline);
++
++static nhprev_mesg *get_msg_line(boolean reverse, int mindex);
++
++
++#endif  /* CURSMESG_H */
+diff -burN nethack-3.4.3/win/curses/cursmisc.c nethack/win/curses/cursmisc.c
+--- nethack-3.4.3/win/curses/cursmisc.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursmisc.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,647 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "cursmisc.h"
++#include "func_tab.h"
++#include "dlb.h"
++
++/* Misc. curses interface functions */
++
++static int curs_x = -1;
++static int curs_y = -1;
++static winid curs_win = 0;
++
++
++/* Read a character of input from the user */
++
++int curses_read_char()
++{
++    int ch;
++
++    ch = getch();
++    if (!ch)
++    {
++        ch = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */
++    }
++    
++    if ((ch >= 0x197) && (ch <= 0x1ba)) /* Alt/Meta key handling */
++    {
++        ch = (ch - 0x140) | 0x80;
++    }
++
++#ifdef KEY_RESIZE
++    /* Handle resize events via get_nh_event, not this code */
++    if (ch == KEY_RESIZE)
++    {
++        ch = '\033'; /* NetHack doesn't know what to do with KEY_RESIZE */
++    }
++#endif
++
++    /* Handle arrow keys */
++    
++    switch (ch)
++    {
++        case KEY_LEFT:
++        {
++            if (iflags.num_pad)
++            {
++                ch = '4';
++            }
++            else
++            {
++                ch = 'h';
++            }
++            break;
++        }
++        case KEY_RIGHT:
++        {
++            if (iflags.num_pad)
++            {
++                ch = '6';
++            }
++            else
++            {
++                ch = 'l';
++            }
++            break;
++        }
++        case KEY_UP:
++        {
++            if (iflags.num_pad)
++            {
++                ch = '8';
++            }
++            else
++            {
++                ch = 'k';
++            }
++            break;
++        }
++        case KEY_DOWN:
++        {
++            if (iflags.num_pad)
++            {
++                ch = '2';
++            }
++            else
++            {
++                ch = 'j';
++            }
++            break;
++        }
++    }
++
++    return ch;
++}
++
++/* Turn on or off the specified color and / or attribute */
++
++void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff)
++{
++#ifdef TEXTCOLOR
++    int curses_color, curses_attr;
++
++    switch (attr)
++    {
++        case ATR_NONE:
++        {
++            curses_attr = A_NORMAL;
++            break;
++        }
++        case ATR_ULINE:
++        {
++            curses_attr = A_UNDERLINE;
++            break;
++        }
++        case ATR_BOLD:
++        {
++            curses_attr = A_BOLD;
++            break;
++        }
++        case ATR_BLINK:
++        {
++            curses_attr = A_BLINK;
++            break;
++        }
++        case ATR_INVERSE:
++        {
++            curses_attr = A_REVERSE;
++            break;
++        }
++        default:
++        {
++            curses_attr = A_NORMAL;
++        }
++    }
++    if (color == 0) /* make black fg visible */
++#ifdef CURSES_VERSION
++        color = 16;
++#else
++        color = 8;
++#endif
++    curses_color = color + 1;
++    if (curses_color > 8)
++        curses_color -= 8;
++    if (onoff == ON)    /* Turn on color/attributes */
++    {
++        if ((attr != NONE) && iflags.use_color)
++            wattron(win, curses_attr);
++        if ((color != NONE) && iflags.use_color)
++        {
++            if ((color > 7) && iflags.use_color)  /* high-intensity color */
++                wattron(win, A_BOLD);
++            if (iflags.use_color)
++                wattron(win, COLOR_PAIR(curses_color));
++        }
++    }
++    else                /* Turn off color/attributes */
++    {
++        if ((attr != NONE) && iflags.use_color)
++            wattroff(win, curses_attr);
++        if ((color != NONE) && iflags.use_color)
++        {
++            if ((color > 7) && iflags.use_color)  /* high-intensity color */
++                wattroff(win, A_BOLD);
++            if (iflags.use_color)
++                wattroff(win, COLOR_PAIR(curses_color));
++        }
++    }
++#endif
++}
++
++
++/* clean up and quit - taken from tty port */
++
++void curses_bail(const char *mesg)
++{
++    clearlocks();
++    curses_exit_nhwindows(mesg);
++    terminate(EXIT_SUCCESS);
++}
++
++
++/* Return a winid for a new window of the given type */
++
++winid curses_get_wid(int type)
++{
++	winid ret;
++    static winid menu_wid = 20; /* Always even */
++    static winid text_wid = 21; /* Always odd */
++
++	switch (type)
++	{
++		case NHW_MESSAGE:
++		{
++			return MESSAGE_WIN;
++			break;
++		}
++		case NHW_MAP:
++		{
++			return MAP_WIN;
++			break;
++		}
++		case NHW_STATUS:
++		{
++			return STATUS_WIN;
++			break;
++		}
++		case NHW_MENU:
++		{
++			ret = menu_wid;
++			break;
++		}
++		case NHW_TEXT:
++		{
++			ret = text_wid;
++			break;
++		}
++		default:
++		{
++			panic("curses_get_wid: unsupported window type");
++		}
++	}
++
++	while (curses_window_exists(ret))
++	{
++	    ret += 2;
++	    if ((ret + 2) > 10000)    /* Avoid "wid2k" problem */
++	    {
++	        ret -= 9900;
++	    }
++	}
++	
++	if (type == NHW_MENU)
++	{
++	    menu_wid += 2;
++	}
++	else
++	{
++	    text_wid += 2;
++	}
++
++	return ret;
++}
++
++
++/*
++ * Allocate a copy of the given string.  If null, return a string of
++ * zero length.
++ *
++ * This is taken from copy_of() in tty/wintty.c.
++ */
++
++char *curses_copy_of(const char *s)
++{
++    if (!s) s = "";
++    return strcpy((char *) alloc((unsigned) (strlen(s) + 1)), s);
++}
++
++
++/* Determine the number of lines needed for a string for a dialog window
++of the given width */
++
++int curses_num_lines(const char *str, int width)
++{
++    int last_space, count;
++    int curline = 1;
++    char substr[BUFSZ];
++    char tmpstr[BUFSZ];
++    
++    strcpy(substr, str);
++    
++    while (strlen(substr) > width)
++    {
++        last_space = 0;
++        
++        for (count = 0; count <= width; count++)
++        {
++            if (substr[count] == ' ')
++            last_space = count;
++        }
++        if (last_space == 0)    /* No spaces found */
++        {
++            last_space = count - 1;
++        }
++        for (count = (last_space + 1); count < strlen(substr); count++)
++        {
++            tmpstr[count - (last_space + 1)] = substr[count];
++        }
++        tmpstr[count - (last_space + 1)] = '\0';
++        strcpy(substr, tmpstr);
++        curline++;
++    }
++    
++    return curline;
++}
++
++
++/* Break string into smaller lines to fit into a dialog window of the
++given width */
++
++char *curses_break_str(const char *str, int width, int line_num)
++{
++    int last_space, count;
++    char *retstr;
++    int curline = 0;
++    int strsize = strlen(str);
++    char substr[strsize];
++    char curstr[strsize];
++    char tmpstr[strsize];
++    
++    strcpy(substr, str);
++    
++    while (curline < line_num)
++    {
++        if (strlen(substr) == 0 )
++        {
++            break;
++        }
++        curline++;
++        last_space = 0;       
++        for (count = 0; count <= width; count++)
++        {
++            if (substr[count] == ' ')
++            {
++                last_space = count;
++            }
++            else if (substr[count] == '\0')           
++            {
++                last_space = count;
++                break;
++            }
++        }
++        if (last_space == 0)    /* No spaces found */
++        {
++            last_space = count - 1;
++        }
++        for (count = 0; count < last_space; count++)
++        {
++            curstr[count] = substr[count];
++        }
++        curstr[count] = '\0';
++        if (substr[count] == '\0')
++        {
++            break;
++        }
++        for (count = (last_space + 1); count < strlen(substr); count++)
++        {
++            tmpstr[count - (last_space + 1)] = substr[count];
++        }
++        tmpstr[count - (last_space + 1)] = '\0';
++        strcpy(substr, tmpstr);
++    }
++    
++    if (curline < line_num)
++    {
++        return NULL;
++    }
++    
++    retstr = curses_copy_of(curstr);
++    
++    return retstr;
++}
++
++
++/* Return the remaining portion of a string after hacking-off line_num lines */
++
++char *curses_str_remainder(const char *str, int width, int line_num)
++{
++    int last_space, count;
++    char *retstr;
++    int curline = 0;
++    int strsize = strlen(str);
++    char substr[strsize];
++    char curstr[strsize];
++    char tmpstr[strsize];
++    
++    strcpy(substr, str);
++    
++    while (curline < line_num)
++    {
++        if (strlen(substr) == 0 )
++        {
++            break;
++        }
++        curline++;
++        last_space = 0;       
++        for (count = 0; count <= width; count++)
++        {
++            if (substr[count] == ' ')
++            {
++                last_space = count;
++            }
++            else if (substr[count] == '\0')           
++            {
++                last_space = count;
++                break;
++            }
++        }
++        if (last_space == 0)    /* No spaces found */
++        {
++            last_space = count - 1;
++        }
++        for (count = 0; count < last_space; count++)
++        {
++            curstr[count] = substr[count];
++        }
++        curstr[count] = '\0';
++        if (substr[count] == '\0')
++        {
++            break;
++        }
++        for (count = (last_space + 1); count < strlen(substr); count++)
++        {
++            tmpstr[count - (last_space + 1)] = substr[count];
++        }
++        tmpstr[count - (last_space + 1)] = '\0';
++        strcpy(substr, tmpstr);
++    }
++    
++    if (curline < line_num)
++    {
++        return NULL;
++    }
++    
++    retstr = curses_copy_of(substr);
++    
++    return retstr;
++}
++
++
++/* Determine if the given NetHack winid is a menu window */
++
++boolean curses_is_menu(winid wid)
++{
++    if ((wid > 19) && !(wid % 2))   /* Even number */
++    {
++        return TRUE;
++    }
++    else
++    {
++        return FALSE;
++    }
++}
++
++
++/* Determine if the given NetHack winid is a text window */
++
++boolean curses_is_text(winid wid)
++{
++    if ((wid > 19) && (wid % 2))   /* Odd number */
++    {
++        return TRUE;
++    }
++    else
++    {
++        return FALSE;
++    }
++}
++
++
++/* Replace certain characters with portable drawing characters if
++cursesgraphics option is enabled */
++
++int curses_convert_glyph(int ch, int glyph)
++{
++    int symbol;
++    
++    /* Save some processing time by returning if the glyph represents
++    an object that we don't have custom characters for */
++    if (!glyph_is_cmap(glyph))
++    {
++        return ch;
++    }
++    
++    symbol = glyph_to_cmap(glyph);
++    
++    /* If user selected a custom character for this object, don't
++    override this. */
++    if (((glyph_is_cmap(glyph)) && (ch != showsyms[symbol])))
++    {
++        return ch;
++    }
++
++    switch (symbol)
++    {
++        case S_vwall:
++            return ACS_VLINE;
++        case S_hwall:
++            return ACS_HLINE;
++        case S_tlcorn:
++            return ACS_ULCORNER;
++        case S_trcorn:
++            return ACS_URCORNER;
++        case S_blcorn:
++            return ACS_LLCORNER;
++        case S_brcorn:
++            return ACS_LRCORNER;
++        case S_crwall:
++            return ACS_PLUS;
++        case S_tuwall:
++            return ACS_TTEE;
++        case S_tdwall:
++            return ACS_BTEE;
++        case S_tlwall:
++            return ACS_LTEE;
++        case S_trwall:
++            return ACS_RTEE;
++        case S_tree:
++            return ACS_PLMINUS;
++        case S_corr:
++            return ACS_CKBOARD;
++        case S_litcorr:
++            return ACS_CKBOARD;
++    }
++
++	return ch;
++}
++
++
++/* Move text cursor to specified coordinates in the given NetHack window */
++
++void curses_move_cursor(winid wid, int x, int y)
++{
++    WINDOW *win = curses_get_nhwin(curs_win);
++
++    if (wid != MAP_WIN)
++    {
++        return;
++    }
++
++#ifdef PDCURSES
++    /* PDCurses seems to not handle wmove correctly, so we use move and
++    physical screen coordinates instead */
++    curses_get_window_xy(wid, &curs_x, &curs_y);
++    curs_x += x;
++    curs_y += y;
++#else
++    curs_x = x;
++    curs_y = y;
++#endif    
++    curs_win = wid;
++#ifdef PDCURSES
++    move(curs_y, curs_x);
++#else
++    wmove(win, curs_y, curs_x);
++#endif
++}
++
++
++/* Perform actions that should be done every turn before nhgetch() */
++
++void curses_prehousekeeping()
++{
++    WINDOW *win = curses_get_nhwin(curs_win);
++
++    if ((curs_x > -1) && (curs_y > -1))
++    {
++        curs_set(1);
++#ifdef PDCURSES
++        /* PDCurses seems to not handle wmove correctly, so we use move
++        and physical screen coordinates instead */
++        move(curs_y, curs_x);
++#else
++        wmove(win, curs_y, curs_x);
++#endif
++        curses_refresh_nhwin(curs_win);
++    }
++}
++
++
++/* Perform actions that should be done every turn after nhgetch() */
++
++void curses_posthousekeeping()
++{
++    curs_set(0);
++    curses_decrement_highlight();
++    curses_clear_unhighlight_message_window();
++}
++
++
++void curses_view_file(const char *filename, boolean must_exist)
++{
++    winid wid;
++    anything *identifier;
++    char buf[BUFSZ];
++    menu_item *selected = NULL;
++    dlb *fp = dlb_fopen(filename, "r");
++    
++    if ((fp == NULL) && (must_exist))
++    {
++        pline("Cannot open %s for reading!", filename);
++    }
++
++    if (fp == NULL)
++    {
++        return;
++    }
++    
++    wid = curses_get_wid(NHW_MENU);
++    curses_create_nhmenu(wid);
++    identifier = malloc(sizeof(anything));
++    identifier->a_void = NULL;
++    
++    while (dlb_fgets(buf, BUFSZ, fp) != NULL)
++    {
++        curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, A_NONE, buf,
++         FALSE);
++    }
++    
++    dlb_fclose(fp);
++    curses_end_menu(wid, "");
++    curses_select_menu(wid, PICK_NONE, &selected);
++}
++
++
++char *curses_rtrim(char *str)
++{
++    char *s;
++
++    for(s = str; *s != '\0'; ++s);
++    for(--s;isspace(*s) && s > str; --s);
++    if(s == str) *s = '\0';
++    else *(++s) = '\0';
++}
++
++/* Use nethack wall symbols for drawing unless cursesgraphics is
++defined, in which case we use the standard curses ones.  Not sure if
++this is desirable behavior since one may prefer regular lines for
++borders but traditional symbols to draw rooms.  Commenting it out for
++now. */
++
++/*
++ * void curses_border(WINDOW *win)
++ * {
++ *     if (iflags.cursesgraphics)
++ *     {
++ *         box(win, 0, 0);
++ *     }
++ *     else
++ *     {
++ *         wborder(win, showsyms[S_vwall], showsyms[S_vwall],
++ *          showsyms[S_hwall], showsyms[S_hwall], showsyms[S_tlcorn],
++ *          showsyms[S_trcorn], showsyms[S_blcorn], showsyms[S_brcorn]);
++ *     }
++ * }
++ */
++
+diff -burN nethack-3.4.3/win/curses/cursmisc.h nethack/win/curses/cursmisc.h
+--- nethack-3.4.3/win/curses/cursmisc.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursmisc.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,38 @@
++#ifndef CURSMISC_H
++#define CURSMISC_H
++
++/* Global declarations */
++
++int curses_read_char(void);
++
++void curses_toggle_color_attr(WINDOW *win, int color, int attr, int onoff);
++
++void curses_bail(const char *mesg);
++
++winid curses_get_wid(int type);
++
++char *curses_copy_of(const char *s);
++
++int curses_num_lines(const char *str, int width);
++
++char *curses_break_str(const char *str, int width, int line_num);
++
++char *curses_str_remainder(const char *str, int width, int line_num);
++
++boolean curses_is_menu(winid wid);
++
++boolean curses_is_text(winid wid);
++
++int curses_convert_glyph(int ch, int glyph);
++
++void curses_move_cursor(winid wid, int x, int y);
++
++void curses_prehousekeeping(void);
++
++void curses_posthousekeeping(void);
++
++void curses_view_file(const char *filename, boolean must_exist);
++
++char *curses_rtrim(char *str);
++
++#endif  /* CURSMISC_H */
+diff -burN nethack-3.4.3/win/curses/cursstat.c nethack/win/curses/cursstat.c
+--- nethack-3.4.3/win/curses/cursstat.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursstat.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,2145 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "cursstat.h"
++
++/* Status window functions for curses interface */
++
++static nhstat prevname;
++static nhstat prevdepth;
++static nhstat prevstr;
++static nhstat prevint;
++static nhstat prevwis;
++static nhstat prevdex;
++static nhstat prevcon;
++static nhstat prevcha;
++static nhstat prevalign;  
++static nhstat prevau;
++static nhstat prevhp;
++static nhstat prevmhp;
++static nhstat prevlevel;
++static nhstat prevpow;
++static nhstat prevmpow;
++static nhstat prevac;
++static nhstat prevexp;
++static nhstat prevtime;
++static nhstat prevscore;
++static nhstat prevhunger;
++static nhstat prevconf;
++static nhstat prevblind;
++static nhstat prevstun;
++static nhstat prevhallu;
++static nhstat prevsick;
++static nhstat prevslime;
++static nhstat prevencumb;
++
++extern const char *hu_stat[]; /* from eat.c */
++extern const char *enc_stat[]; /* from botl.c */
++
++/* Update the status win - this is called when NetHack would normally
++write to the status window, so we know somwthing has changed.  We
++override the write and update what needs to be updated ourselves. */
++
++void curses_update_stats()
++{
++    char buf[BUFSZ];
++    int count, enc, orient, sx_start;
++    WINDOW *win = curses_get_nhwin(STATUS_WIN);
++    static boolean first = TRUE;
++    boolean horiz;
++    int sx = 0;
++    int sy = 0;
++    boolean border = curses_window_has_border(STATUS_WIN);
++    
++    if (border)
++    {
++        sx++;
++        sy++;
++    }
++    
++    sx_start = sx;
++        
++    if (first)
++    {
++        init_stats();
++        first = FALSE;
++    }
++    
++    orient = curses_get_window_orientation(STATUS_WIN);
++
++    if ((orient == ALIGN_RIGHT) || (orient == ALIGN_LEFT))
++    {
++        horiz = FALSE;
++    }
++    else
++    {
++        horiz = TRUE;
++    }
++
++    curses_clear_nhwin(STATUS_WIN);
++    
++    /* Line 1 */
++    
++    /* Player name and title */
++    strcpy(buf, plname);
++    if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
++    strcat(buf, " the ");
++    if (u.mtimedone) {
++        char mname[BUFSZ];
++        int k = 0;
++
++        strcpy(mname, mons[u.umonnum].mname);
++        while(mname[k] != 0) {
++            if ((k == 0 || (k > 0 && mname[k-1] == ' '))
++             && 'a' <= mname[k] && mname[k] <= 'z')
++            {
++                mname[k] += 'A' - 'a';
++            }
++            k++;
++        }
++        strcat(buf, mname);
++    } else {
++        strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
++    }
++    
++    if (strcmp(buf, prevname.txt) != 0) /* Title changed */
++    {
++        prevname.highlight_turns = 5;
++        prevname.highlight_color = HIGHLIGHT_COLOR;
++        free(prevname.txt);
++        prevname.txt = curses_copy_of(buf);
++    }
++    
++    if (prevname.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevname.label);
++        sx += strlen(prevname.label);
++    }
++    
++    if (prevname.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevname.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevname.txt);
++        curses_toggle_color_attr(win, prevname.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevname.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevname.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++    
++    /* Strength */
++    if (ACURR(A_STR) != prevstr.value)  /* Strength changed */
++    {
++        
++        if (ACURR(A_STR) > prevstr.value)
++        {
++            prevstr.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevstr.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevstr.value = ACURR(A_STR);
++        if (ACURR(A_STR) > 118)
++        {
++            sprintf(buf, "%d", ACURR(A_STR) - 100);
++        }
++        else if (ACURR(A_STR)==118)
++        {
++            sprintf(buf, "18/**");
++        }
++        else if(ACURR(A_STR) > 18)
++        {
++            sprintf(buf, "18/%02d", ACURR(A_STR) - 18);
++        }
++        else
++        {
++            sprintf(buf, "%d", ACURR(A_STR));
++        }
++        free(prevstr.txt);
++        prevstr.txt = curses_copy_of(buf);
++        prevstr.highlight_turns = 5;
++    }
++
++    if (prevstr.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevstr.label);
++        sx += strlen(prevstr.label);
++    }
++    
++    if (prevstr.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevstr.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevstr.txt);
++        curses_toggle_color_attr(win, prevstr.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevstr.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevstr.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Intelligence */
++    if (ACURR(A_INT) != prevint.value)  /* Intelligence changed */
++    {
++        
++        if (ACURR(A_INT) > prevint.value)
++        {
++            prevint.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevint.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevint.value = ACURR(A_INT);
++        sprintf(buf, "%d", ACURR(A_INT)); 
++        free(prevint.txt);
++        prevint.txt = curses_copy_of(buf);
++        prevint.highlight_turns = 5;
++    }
++
++    if (prevint.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevint.label);
++        sx += strlen(prevint.label);
++    }
++    
++    if (prevint.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevint.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevint.txt);
++        curses_toggle_color_attr(win, prevint.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevint.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevint.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Wisdom */
++    if (ACURR(A_WIS) != prevwis.value)  /* Wisdom changed */
++    {
++        
++        if (ACURR(A_WIS) > prevwis.value)
++        {
++            prevwis.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevwis.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevwis.value = ACURR(A_WIS);
++        sprintf(buf, "%d", ACURR(A_WIS)); 
++        free(prevwis.txt);
++        prevwis.txt = curses_copy_of(buf);
++        prevwis.highlight_turns = 5;
++    }
++
++    if (prevwis.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevwis.label);
++        sx += strlen(prevwis.label);
++    }
++    
++    if (prevwis.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevwis.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevwis.txt);
++        curses_toggle_color_attr(win, prevwis.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevwis.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevwis.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Dexterity */
++    if (ACURR(A_DEX) != prevdex.value)  /* Dexterity changed */
++    {
++        
++        if (ACURR(A_DEX) > prevdex.value)
++        {
++            prevdex.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevdex.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevdex.value = ACURR(A_DEX);
++        sprintf(buf, "%d", ACURR(A_DEX));
++        free(prevdex.txt);
++        prevdex.txt = curses_copy_of(buf);
++        prevdex.highlight_turns = 5;
++    }
++
++    if (prevdex.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevdex.label);
++        sx += strlen(prevdex.label);
++    }
++    
++    if (prevdex.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevdex.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevdex.txt);
++        curses_toggle_color_attr(win, prevdex.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevdex.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevdex.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Constitution */
++    if (ACURR(A_CON) != prevcon.value)  /* Constitution changed */
++    {
++        
++        if (ACURR(A_CON) > prevcon.value)
++        {
++            prevcon.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevcon.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevcon.value = ACURR(A_CON);
++        sprintf(buf, "%d", ACURR(A_CON));
++        free(prevcon.txt);
++        prevcon.txt = curses_copy_of(buf);
++        prevcon.highlight_turns = 5;
++    }
++
++    if (prevcon.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevcon.label);
++        sx += strlen(prevcon.label);
++    }
++    
++    if (prevcon.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevcon.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevcon.txt);
++        curses_toggle_color_attr(win, prevcon.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevcon.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevcon.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Charisma */
++    if (ACURR(A_CHA) != prevcha.value)  /* Charisma changed */
++    {
++        if (ACURR(A_CHA) > prevcha.value)
++        {
++            prevcha.highlight_color = STAT_UP_COLOR;
++        }
++        else
++        {
++            prevcha.highlight_color = STAT_DOWN_COLOR;
++        }
++        prevcha.value = ACURR(A_CHA);
++        sprintf(buf, "%d", ACURR(A_CHA));
++        free(prevcha.txt);
++        prevcha.txt = curses_copy_of(buf);
++        prevcha.highlight_turns = 5;
++    }
++
++    if (prevcha.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevcha.label);
++        sx += strlen(prevcha.label);
++    }
++    
++    if (prevcha.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevcha.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevcha.txt);
++        curses_toggle_color_attr(win, prevcha.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevcha.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevcha.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++    
++    /* Alignment */
++    if (prevalign.alignment != u.ualign.type)   /* Alignment changed */
++    {
++        prevalign.highlight_color = HIGHLIGHT_COLOR;
++        prevalign.highlight_turns = 10; /* This is a major change! */
++        prevalign.alignment = u.ualign.type;
++        free(prevalign.txt);
++        switch (u.ualign.type)
++        {
++            case A_LAWFUL:
++            {
++                prevalign.txt = curses_copy_of("Lawful");
++                break;
++            }
++            case A_NEUTRAL:
++            {
++                prevalign.txt = curses_copy_of("Neutral");
++                break;
++            }
++            case A_CHAOTIC:
++            {
++                prevalign.txt = curses_copy_of("Chaotic");
++                break;
++            }
++        }
++    }
++
++    if (prevalign.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevalign.label);
++        sx += strlen(prevalign.label);
++    }
++    
++    if (prevalign.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevalign.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevalign.txt);
++        curses_toggle_color_attr(win, prevalign.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevalign.txt);
++    }
++    
++    /* Line 2 */
++    
++    sx = sx_start;
++    sy++;
++    
++    /* Dungeon Level */
++    if (depth(&u.uz) != prevdepth.value)    /* Dungeon level changed */
++    {
++        prevdepth.highlight_color = HIGHLIGHT_COLOR;
++        prevdepth.highlight_turns = 5;
++        prevdepth.value = depth(&u.uz);
++        free(prevdepth.txt);
++        if (In_endgame(&u.uz))
++        {
++            strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
++        }
++        else
++        {
++            sprintf(buf, "%d", depth(&u.uz));
++        }
++        prevdepth.txt = curses_copy_of(buf);
++    }
++    
++    if (prevdepth.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevdepth.label);
++        sx += strlen(prevdepth.label);
++    }
++    
++    if (prevdepth.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevdepth.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevdepth.txt);
++        curses_toggle_color_attr(win, prevdepth.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevdepth.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevdepth.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++    
++    /* Gold */
++#ifndef GOLDOBJ
++    if (prevau.value != u.ugold)    /* Gold changed */
++    {
++        if (u.ugold > prevau.value)
++        {
++#else
++    if (prevau.value != money_cnt(invent))  /* Gold changed */
++    {
++        if (money_cnt(invent) > prevau.value)
++        {
++#endif
++            prevau.highlight_color = HI_GOLD;
++        }
++        else
++        {
++            prevau.highlight_color = STAT_DOWN_COLOR;
++        }
++#ifndef GOLDOBJ
++        prevau.value = u.ugold;
++        sprintf(buf,"%ld", u.ugold);
++#else
++        prevau.value = money_cnt(invent);
++        sprintf(buf,"%ld", money_cnt(invent));
++#endif
++        free(prevau.txt);
++        prevau.txt = curses_copy_of(buf);
++        prevau.highlight_turns = 5;
++    }
++    
++    if (prevau.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevau.label);
++        sx += strlen(prevau.label);
++    }
++    
++    if (prevau.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevau.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevau.txt);
++        curses_toggle_color_attr(win, prevau.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevau.txt);
++    }
++
++    if (horiz)
++    {
++        sx += strlen(prevau.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++    
++    /* Hit Points */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
++    {
++	    if (u.mh != prevhp.value)
++	    {
++	        if (u.mh > prevhp.value)
++	        {
++	            prevhp.highlight_color = STAT_UP_COLOR;
++	        }
++	        else
++	        {
++	            prevhp.highlight_color = STAT_DOWN_COLOR;
++	        }
++            prevhp.highlight_turns = 3;
++            prevhp.value = u.mh;
++            sprintf(buf, "%d", u.mh);
++            free(prevhp.txt);
++            prevhp.txt = curses_copy_of(buf);
++	    }
++	}
++	else if (u.uhp != prevhp.value)  /* Not polymorphed */
++	{
++	    if (u.uhp > prevhp.value)
++	    {
++	        prevhp.highlight_color = STAT_UP_COLOR;
++	    }
++	    else
++	    {
++            prevhp.highlight_color = STAT_DOWN_COLOR;
++	    }
++        prevhp.value = u.uhp;
++        sprintf(buf, "%d", u.uhp);
++        free(prevhp.txt);
++        prevhp.txt = curses_copy_of(buf);
++        prevhp.highlight_turns = 3;
++	}
++
++    if (prevhp.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevhp.label);
++        sx += strlen(prevhp.label);
++    }
++
++    if (prevhp.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevhp.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevhp.txt);
++        curses_toggle_color_attr(win, prevhp.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevhp.txt);
++    }
++    
++    sx += strlen(prevhp.txt);
++
++    /* Max Hit Points */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
++    {
++	    if (u.mhmax != prevmhp.value)
++	    {
++	        if (u.mhmax > prevmhp.value)
++	        {
++	            prevmhp.highlight_color = STAT_UP_COLOR;
++	        }
++	        else
++	        {
++	            prevmhp.highlight_color = STAT_DOWN_COLOR;
++	        }
++            prevmhp.value = u.mhmax;
++            sprintf(buf, "%d", u.mhmax);
++            free(prevmhp.txt);
++            prevmhp.txt = curses_copy_of(buf);
++            prevmhp.highlight_turns = 3;
++	    }
++	}
++	else if (u.uhpmax != prevmhp.value)  /* Not polymorphed */
++	{
++	    if (u.uhpmax > prevmhp.value)
++	    {
++	        prevmhp.highlight_color = STAT_UP_COLOR;
++	    }
++	    else
++	    {
++            prevmhp.highlight_color = STAT_DOWN_COLOR;
++	    }
++        prevmhp.value = u.uhpmax;
++        sprintf(buf, "%d", u.uhpmax);
++        free(prevmhp.txt);
++        prevmhp.txt = curses_copy_of(buf);
++        prevmhp.highlight_turns = 3;
++	}
++
++    if (prevmhp.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevmhp.label);
++        sx += strlen(prevmhp.label);
++    }
++
++    if (prevmhp.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevmhp.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevmhp.txt);
++        curses_toggle_color_attr(win, prevmhp.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevmhp.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevmhp.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Power */
++    if (u.uen != prevpow.value)
++	{
++	    if (u.uen > prevpow.value)
++	    {
++	        prevpow.highlight_color = STAT_UP_COLOR;
++	    }
++	    else
++	    {
++            prevpow.highlight_color = STAT_DOWN_COLOR;
++	    }
++        prevpow.value = u.uen;
++        sprintf(buf, "%d", u.uen);
++        free(prevpow.txt);
++        prevpow.txt = curses_copy_of(buf);
++        prevpow.highlight_turns = 3;
++	}
++
++    if (prevpow.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevpow.label);
++        sx += strlen(prevpow.label);
++    }
++
++    if (prevpow.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevpow.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevpow.txt);
++        curses_toggle_color_attr(win, prevpow.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevpow.txt);
++    }
++    
++    sx += strlen(prevpow.txt);
++
++    /* Max Power */
++    if (u.uenmax != prevmpow.value)
++	{
++	    if (u.uenmax > prevmpow.value)
++	    {
++	        prevmpow.highlight_color = STAT_UP_COLOR;
++	    }
++	    else
++	    {
++            prevmpow.highlight_color = STAT_DOWN_COLOR;
++	    }
++        prevmpow.value = u.uenmax;
++        sprintf(buf, "%d", u.uenmax);
++        free(prevmpow.txt);
++        prevmpow.txt = curses_copy_of(buf);
++        prevmpow.highlight_turns = 3;
++	}
++
++    if (prevmpow.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevmpow.label);
++        sx += strlen(prevmpow.label);
++    }
++
++    if (prevmpow.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevmpow.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevmpow.txt);
++        curses_toggle_color_attr(win, prevmpow.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevmpow.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevmpow.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++
++    /* Armor Class */
++    if (u.uac != prevac.value)
++	{
++	    if (u.uac > prevac.value)   /* Lower is better for AC */
++	    {
++	        prevac.highlight_color = STAT_DOWN_COLOR;
++	    }
++	    else
++	    {
++            prevac.highlight_color = STAT_UP_COLOR;
++	    }
++        prevac.value = u.uac;
++        sprintf(buf, "%d", u.uac);
++        free(prevac.txt);
++        prevac.txt = curses_copy_of(buf);
++        prevac.highlight_turns = 5;
++	}
++
++    if (prevac.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevac.label);
++        sx += strlen(prevac.label);
++    }
++
++    if (prevac.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevac.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevac.txt);
++        curses_toggle_color_attr(win, prevac.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevac.txt);
++    }
++    
++    if (horiz)
++    {
++        sx += strlen(prevac.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Experience */
++#ifdef EXP_ON_BOTL
++    if (prevexp.display != flags.showexp)   /* Setting has changed */
++    {
++        prevexp.display = flags.showexp;
++        free(prevlevel.label);
++        if (prevexp.display)
++        {
++            prevlevel.label = curses_copy_of("/");
++        }
++        else
++        {
++            prevlevel.label = curses_copy_of("Lvl:");
++        }
++    }
++
++    if (prevexp.display && !u.mtimedone)
++    {
++        if (u.uexp != prevexp.value)
++	    {
++	        if (u.uexp > prevexp.value)
++	        {
++	            prevexp.highlight_color = STAT_UP_COLOR;
++	        }
++	        else
++	        {
++                prevexp.highlight_color = STAT_DOWN_COLOR;
++	        }
++            sprintf(buf, "%d", u.uexp);
++            free(prevexp.txt);
++            prevexp.txt = curses_copy_of(buf);
++            prevexp.highlight_turns = 3;
++	    }
++
++        if (prevexp.label != NULL)
++        {
++            mvwaddstr(win, sy, sx, prevexp.label);
++            sx += strlen(prevexp.label);
++        }
++
++        if (prevexp.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevexp.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevexp.txt);
++            curses_toggle_color_attr(win, prevexp.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevexp.txt);
++        }
++
++        sx += strlen(prevexp.txt);
++    }
++    
++    prevexp.value = u.uexp; /* Track it even when it's not displayed */
++#endif  /* EXP_ON_BOTL */
++
++    /* Level */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HD */
++    {
++        if (strncmp(prevlevel.label, "HD:", 3) != 0)
++        {
++            free(prevlevel.label);
++            prevlevel.label = curses_copy_of("HD:");
++        }
++        if (mons[u.umonnum].mlevel != prevlevel.value)
++        {
++            if (mons[u.umonnum].mlevel > prevlevel.value)
++            {
++                prevlevel.highlight_color = STAT_UP_COLOR;
++            }
++            else
++            {
++                prevlevel.highlight_color = STAT_DOWN_COLOR;
++            }
++            prevlevel.highlight_turns = 5;
++        }
++        prevlevel.value = mons[u.umonnum].mlevel;
++        sprintf(buf, "%d", mons[u.umonnum].mlevel);
++        free(prevlevel.txt);
++        prevlevel.txt = curses_copy_of(buf);
++    }
++    else    /* Not polymorphed */
++    {
++        if (strncmp(prevlevel.label, "HD:", 3) == 0)
++        {
++            free(prevlevel.label);
++            if (prevexp.display)
++            {
++                prevlevel.label = curses_copy_of("/");
++            }
++            else
++            {
++                prevlevel.label = curses_copy_of("Lvl:");
++            }
++        }
++        if (u.ulevel > prevlevel.value)
++        {
++            prevlevel.highlight_color = STAT_UP_COLOR;
++            prevlevel.highlight_turns = 5;
++        }
++        else if (u.ulevel < prevlevel.value)
++        {
++            prevlevel.highlight_color = STAT_DOWN_COLOR;
++            prevlevel.highlight_turns = 5;
++        }
++        prevlevel.value = u.ulevel;
++        sprintf(buf, "%d", u.ulevel);
++        free(prevlevel.txt);
++        prevlevel.txt = curses_copy_of(buf);
++    }
++
++    if (prevlevel.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevlevel.label);
++        sx += strlen(prevlevel.label);
++    }
++
++    if (prevlevel.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevlevel.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevlevel.txt);
++        curses_toggle_color_attr(win, prevlevel.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevlevel.txt);
++    }
++
++    if (horiz)
++    {
++        sx += strlen(prevlevel.txt) + 1;
++    }
++    else
++    {
++        sx = sx_start;
++        sy++;
++    }
++
++    /* Time */
++    if (prevtime.display != flags.time)   /* Setting has changed */
++    {
++        prevtime.display = flags.time;
++    }
++    if (prevtime.display)
++    {
++        if (moves != prevtime.value)
++	    {
++            sprintf(buf, "%ld", moves);
++            free(prevtime.txt);
++            prevtime.txt = curses_copy_of(buf);
++	    }
++
++        if (prevtime.label != NULL)
++        {
++            mvwaddstr(win, sy, sx, prevtime.label);
++            sx += strlen(prevtime.label);
++        }
++
++        mvwaddstr(win, sy, sx, prevtime.txt);
++
++        if (horiz)
++        {
++            sx += strlen(prevtime.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++    
++    /* Score */
++#ifdef SCORE_ON_BOTL
++    if (prevscore.display != flags.showscore)   /* Setting has changed */
++    {
++        prevscore.display = flags.showscore;
++    }
++    if (prevscore.display)
++    {
++        if (botl_score() != prevscore.value)
++	    {
++	        if (botl_score() > prevscore.value)
++	        {
++	            prevscore.highlight_color = STAT_UP_COLOR;
++	        }
++	        else    /* Not sure this is possible */
++	        {
++                prevscore.highlight_color = STAT_DOWN_COLOR;
++	        }
++            sprintf(buf, "%ld", botl_score());
++            free(prevscore.txt);
++            prevscore.txt = curses_copy_of(buf);
++            prevscore.highlight_turns = 3;
++	    }
++
++        if (prevscore.label != NULL)
++        {
++            mvwaddstr(win, sy, sx, prevscore.label);
++            sx += strlen(prevscore.label);
++        }
++
++        if (prevscore.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevscore.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevscore.txt);
++            curses_toggle_color_attr(win, prevscore.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevscore.txt);
++        }
++
++        if (horiz)
++        {
++            sx += strlen(prevscore.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++    
++    prevscore.value = botl_score(); /* Track it even when it's not displayed */
++#endif  /* SCORE_ON_BOTL */
++
++    /* Hunger */
++    if (u.uhs != prevhunger.value)
++	{
++	    if ((u.uhs > prevhunger.value) || (u.uhs > 3))
++	    {
++	        prevhunger.highlight_color = STAT_DOWN_COLOR;
++	    }
++	    else
++	    {
++            prevhunger.highlight_color = STAT_UP_COLOR;
++	    }
++        prevhunger.value = u.uhs;
++        for (count = 0; count < strlen(hu_stat[u.uhs]); count++)
++        {
++            if ((hu_stat[u.uhs][count]) == ' ')
++            {
++                break;
++            }
++            buf[count] = hu_stat[u.uhs][count];
++        }
++
++        buf[count] = '\0';
++        free(prevhunger.txt);
++        prevhunger.txt = curses_copy_of(buf);
++        prevhunger.highlight_turns = 5;
++	}
++
++    if (prevhunger.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevhunger.label);
++        sx += strlen(prevhunger.label);
++    }
++
++    if (prevhunger.highlight_turns > 0)
++    {
++        curses_toggle_color_attr(win, prevhunger.highlight_color, NONE, ON);
++        mvwaddstr(win, sy, sx, prevhunger.txt);
++        curses_toggle_color_attr(win, prevhunger.highlight_color, NONE, OFF);
++    }
++    else
++    {
++        mvwaddstr(win, sy, sx, prevhunger.txt);
++    }
++    
++    if (strlen(prevhunger.txt) > 0)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevhunger.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Confusion */
++    if (Confusion != prevconf.value)
++	{
++	    prevconf.highlight_color = STAT_DOWN_COLOR;
++        if (prevconf.txt != NULL)
++        {
++            free(prevconf.txt);
++        }
++        if (Confusion)
++        {
++            prevconf.txt = curses_copy_of("Conf");
++        }
++        else
++        {
++            prevconf.txt = NULL;
++        }
++        if (prevconf.value == 0)
++        {
++            prevconf.highlight_turns = 5;
++	    }
++        prevconf.value = Confusion;
++	}
++
++    if (prevconf.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevconf.label);
++        sx += strlen(prevconf.label);
++    }
++
++    if (prevconf.txt != NULL)
++    {
++        if (prevconf.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevconf.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevconf.txt);
++            curses_toggle_color_attr(win, prevconf.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevconf.txt);
++        }
++    }
++
++    if (prevconf.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevconf.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Blindness */
++    if (Blind != prevblind.value)
++	{
++	    prevblind.highlight_color = STAT_DOWN_COLOR;
++        if (prevblind.txt != NULL)
++        {
++            free(prevblind.txt);
++        }
++        if (Blind)
++        {
++            prevblind.txt = curses_copy_of("Blind");
++        }
++        else
++        {
++            prevblind.txt = NULL;
++        }
++        if (prevblind.value == 0)
++        {
++            prevblind.highlight_turns = 5;
++	    }
++        prevblind.value = Blind;
++	}
++
++    if (prevblind.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevblind.label);
++        sx += strlen(prevblind.label);
++    }
++
++    if (prevblind.txt != NULL)
++    {
++        if (prevblind.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevblind.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevblind.txt);
++            curses_toggle_color_attr(win, prevblind.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevblind.txt);
++        }
++    }
++
++    if (prevblind.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevblind.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Stun */
++    if (Stunned != prevstun.value)
++	{
++	    prevstun.highlight_color = STAT_DOWN_COLOR;
++        if (prevstun.txt != NULL)
++        {
++            free(prevstun.txt);
++        }
++        if (Stunned)
++        {
++            prevstun.txt = curses_copy_of("Stun");
++        }
++        else
++        {
++            prevstun.txt = NULL;
++        }
++        if (prevstun.value == 0)
++        {
++            prevstun.highlight_turns = 5;
++	    }
++        prevstun.value = Stunned;
++	}
++
++    if (prevstun.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevstun.label);
++        sx += strlen(prevstun.label);
++    }
++
++    if (prevstun.txt != NULL)
++    {
++        if (prevstun.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevstun.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevstun.txt);
++            curses_toggle_color_attr(win, prevstun.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevstun.txt);
++        }
++    }
++
++    if (prevstun.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevstun.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Hallucination */
++    if (Hallucination != prevhallu.value)
++	{
++	    prevhallu.highlight_color = STAT_DOWN_COLOR;
++        if (prevhallu.txt != NULL)
++        {
++            free(prevhallu.txt);
++        }
++        if (Hallucination)
++        {
++            prevhallu.txt = curses_copy_of("Hallu");
++        }
++        else
++        {
++            prevhallu.txt = NULL;
++        }
++        if (prevhallu.value == 0)
++        {
++            prevhallu.highlight_turns = 5;
++	    }
++        prevhallu.value = Hallucination;
++	}
++
++    if (prevhallu.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevhallu.label);
++        sx += strlen(prevhallu.label);
++    }
++
++    if (prevhallu.txt != NULL)
++    {
++        if (prevhallu.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevhallu.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevhallu.txt);
++            curses_toggle_color_attr(win, prevhallu.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevhallu.txt);
++        }
++    }
++
++    if (prevhallu.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevhallu.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Sick */
++    if (Sick != prevsick.value)
++	{
++	    prevsick.highlight_color = STAT_DOWN_COLOR;
++        if (prevsick.txt != NULL)
++        {
++            free(prevsick.txt);
++        }
++        if (Sick)
++        {
++            if (u.usick_type & SICK_VOMITABLE)
++            {
++                prevsick.txt = curses_copy_of("FoodPois");
++            }
++            else      
++            {
++                prevsick.txt = curses_copy_of("Ill");
++            }
++        }
++        else
++        {
++            prevsick.txt = NULL;
++        }
++        if (prevsick.value == 0)
++        {
++            prevsick.highlight_turns = 5;
++	    }
++        prevsick.value = Sick;
++	}
++
++    if (prevsick.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevsick.label);
++        sx += strlen(prevsick.label);
++    }
++
++    if (prevsick.txt != NULL)
++    {
++        if (prevsick.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevsick.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevsick.txt);
++            curses_toggle_color_attr(win, prevsick.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevsick.txt);
++        }
++    }
++
++    if (prevsick.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevsick.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Slime */
++    if (Slimed != prevslime.value)
++	{
++	    prevslime.highlight_color = STAT_DOWN_COLOR;
++        if (prevslime.txt != NULL)
++        {
++            free(prevslime.txt);
++        }
++        if (Slimed)
++        {
++            prevslime.txt = curses_copy_of("Slime");
++        }
++        else
++        {
++            prevslime.txt = NULL;
++        }
++        if (prevslime.value == 0)
++        {
++            prevslime.highlight_turns = 5;
++	    }
++        prevslime.value = Slimed;
++	}
++
++    if (prevslime.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevslime.label);
++        sx += strlen(prevslime.label);
++    }
++
++    if (prevslime.txt != NULL)
++    {
++        if (prevslime.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevslime.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevslime.txt);
++            curses_toggle_color_attr(win, prevslime.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevslime.txt);
++        }
++    }
++
++    if (prevslime.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevslime.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    /* Encumberance */
++    enc = near_capacity();
++    
++    if (enc != prevencumb.value)
++	{
++	    if (enc < prevencumb.value)
++	    {
++	        prevencumb.highlight_color = STAT_UP_COLOR;
++	    }
++	    else
++	    {
++	        prevencumb.highlight_color = STAT_DOWN_COLOR;
++        }
++        if (prevencumb.txt != NULL)
++        {
++            free(prevencumb.txt);
++        }
++        if (enc > UNENCUMBERED)
++        {
++            sprintf(buf, "%s", enc_stat[enc]);
++            prevencumb.txt = curses_copy_of(buf);
++            prevencumb.highlight_turns = 5;
++        }
++        else
++        {
++            prevencumb.txt = NULL;
++        }
++        prevencumb.value = enc;
++	}
++
++    if (prevencumb.label != NULL)
++    {
++        mvwaddstr(win, sy, sx, prevencumb.label);
++        sx += strlen(prevencumb.label);
++    }
++
++    if (prevencumb.txt != NULL)
++    {
++        if (prevencumb.highlight_turns > 0)
++        {
++            curses_toggle_color_attr(win, prevencumb.highlight_color, NONE, ON);
++            mvwaddstr(win, sy, sx, prevencumb.txt);
++            curses_toggle_color_attr(win, prevencumb.highlight_color, NONE, OFF);
++        }
++        else
++        {
++            mvwaddstr(win, sy, sx, prevencumb.txt);
++        }
++    }
++
++    if (prevencumb.txt != NULL)
++    {
++        if (horiz)
++        {
++            sx += strlen(prevencumb.txt) + 1;
++        }
++        else
++        {
++            sx = sx_start;
++            sy++;
++        }
++    }
++
++    wrefresh(win);
++}
++
++
++/* Decrement the highlight_turns for all stats.  Call curses_update_stats
++if needed to unhighlight a stat */
++
++void curses_decrement_highlight()
++{
++    boolean unhighlight = FALSE;
++    
++    if (prevname.highlight_turns > 0)
++    {
++        prevname.highlight_turns--;
++        if (prevname.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevdepth.highlight_turns > 0)
++    {
++        prevdepth.highlight_turns--;
++        if (prevdepth.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevstr.highlight_turns > 0)
++    {
++        prevstr.highlight_turns--;
++        if (prevstr.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevint.highlight_turns > 0)
++    {
++        prevint.highlight_turns--;
++        if (prevint.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevwis.highlight_turns > 0)
++    {
++        prevwis.highlight_turns--;
++        if (prevwis.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevdex.highlight_turns > 0)
++    {
++        prevdex.highlight_turns--;
++        if (prevdex.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevcon.highlight_turns > 0)
++    {
++        prevcon.highlight_turns--;
++        if (prevcon.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevcha.highlight_turns > 0)
++    {
++        prevcha.highlight_turns--;
++        if (prevcha.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevalign.highlight_turns > 0)
++    {
++        prevalign.highlight_turns--;
++        if (prevalign.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevau.highlight_turns > 0)
++    {
++        prevau.highlight_turns--;
++        if (prevau.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevhp.highlight_turns > 0)
++    {
++        prevhp.highlight_turns--;
++        if (prevhp.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevmhp.highlight_turns > 0)
++    {
++        prevmhp.highlight_turns--;
++        if (prevmhp.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevlevel.highlight_turns > 0)
++    {
++        prevlevel.highlight_turns--;
++        if (prevlevel.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevpow.highlight_turns > 0)
++    {
++        prevpow.highlight_turns--;
++        if (prevpow.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevmpow.highlight_turns > 0)
++    {
++        prevmpow.highlight_turns--;
++        if (prevmpow.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevac.highlight_turns > 0)
++    {
++        prevac.highlight_turns--;
++        if (prevac.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++#ifdef EXP_ON_BOTL
++    if (prevexp.highlight_turns > 0)
++    {
++        prevexp.highlight_turns--;
++        if (prevexp.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++#endif
++    if (prevtime.highlight_turns > 0)
++    {
++        prevtime.highlight_turns--;
++        if (prevtime.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++#ifdef SCORE_ON_BOTL
++    if (prevscore.highlight_turns > 0)
++    {
++        prevscore.highlight_turns--;
++        if (prevscore.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++#endif
++    if (prevhunger.highlight_turns > 0)
++    {
++        prevhunger.highlight_turns--;
++        if (prevhunger.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevconf.highlight_turns > 0)
++    {
++        prevconf.highlight_turns--;
++        if (prevconf.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevblind.highlight_turns > 0)
++    {
++        prevblind.highlight_turns--;
++        if (prevblind.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevstun.highlight_turns > 0)
++    {
++        prevstun.highlight_turns--;
++        if (prevstun.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevhallu.highlight_turns > 0)
++    {
++        prevhallu.highlight_turns--;
++        if (prevhallu.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevsick.highlight_turns > 0)
++    {
++        prevsick.highlight_turns--;
++        if (prevsick.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevslime.highlight_turns > 0)
++    {
++        prevslime.highlight_turns--;
++        if (prevslime.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    if (prevencumb.highlight_turns > 0)
++    {
++        prevencumb.highlight_turns--;
++        if (prevencumb.highlight_turns == 0)
++        {
++            unhighlight = TRUE;
++        }
++    }
++    
++    if (unhighlight)
++    {
++        curses_update_stats();
++    }
++}
++
++
++/* Initialize the stats with beginning values. */
++
++static void init_stats()
++{
++    char buf[BUFSZ];
++    int count;
++
++    /* Player name and title */
++    strcpy(buf, plname);
++    if ('a' <= buf[0] && buf[0] <= 'z') buf[0] += 'A'-'a';
++    strcat(buf, " the ");
++    if (u.mtimedone) {
++        char mname[BUFSZ];
++        int k = 0;
++
++        strcpy(mname, mons[u.umonnum].mname);
++        while(mname[k] != 0) {
++            if ((k == 0 || (k > 0 && mname[k-1] == ' '))
++             && 'a' <= mname[k] && mname[k] <= 'z')
++            {
++                mname[k] += 'A' - 'a';
++            }
++            k++;
++        }
++        strcat(buf, mname);
++    } else {
++        strcat(buf, rank_of(u.ulevel, pl_character[0], flags.female));
++    }
++
++    prevname.txt = curses_copy_of(buf);
++    prevname.display = TRUE;
++    prevname.highlight_turns = 0;
++    prevname.label = NULL;
++    
++    /* Strength */
++    if (ACURR(A_STR) > 118)
++    {
++        sprintf(buf, "%d", ACURR(A_STR) - 100);
++    }
++    else if (ACURR(A_STR)==118)
++    {
++        sprintf(buf, "18/**");
++    }
++    else if(ACURR(A_STR) > 18)
++    {
++        sprintf(buf, "18/%02d", ACURR(A_STR) - 18);
++    }
++    else
++    {
++        sprintf(buf, "%d", ACURR(A_STR));
++    }
++
++    prevstr.value = ACURR(A_STR);
++    prevstr.txt = curses_copy_of(buf);
++    prevstr.display = TRUE;
++    prevstr.highlight_turns = 0;
++    prevstr.label = curses_copy_of("Str:");
++
++    /* Intelligence */
++    sprintf(buf, "%d", ACURR(A_INT));
++    prevint.value = ACURR(A_INT);
++    prevint.txt = curses_copy_of(buf);
++    prevint.display = TRUE;
++    prevint.highlight_turns = 0;
++    prevint.label = curses_copy_of("Int:");
++
++    /* Wisdom */
++    sprintf(buf, "%d", ACURR(A_WIS));
++    prevwis.value = ACURR(A_WIS);
++    prevwis.txt = curses_copy_of(buf);
++    prevwis.display = TRUE;
++    prevwis.highlight_turns = 0;
++    prevwis.label = curses_copy_of("Wis:");
++
++    /* Dexterity */
++    sprintf(buf, "%d", ACURR(A_DEX));
++    prevdex.value = ACURR(A_DEX);
++    prevdex.txt = curses_copy_of(buf);
++    prevdex.display = TRUE;
++    prevdex.highlight_turns = 0;
++    prevdex.label = curses_copy_of("Dex:");
++
++    /* Constitution */
++    sprintf(buf, "%d", ACURR(A_CON));
++    prevcon.value = ACURR(A_CON);
++    prevcon.txt = curses_copy_of(buf);
++    prevcon.display = TRUE;
++    prevcon.highlight_turns = 0;
++    prevcon.label = curses_copy_of("Con:");
++
++    /* Charisma */
++    sprintf(buf, "%d", ACURR(A_CHA));
++    prevcha.value = ACURR(A_CHA);
++    prevcha.txt = curses_copy_of(buf);
++    prevcha.display = TRUE;
++    prevcha.highlight_turns = 0;
++    prevcha.label = curses_copy_of("Cha:");
++
++    /* Alignment */
++    switch (u.ualign.type)
++    {
++        case A_LAWFUL:
++        {
++            prevalign.txt = curses_copy_of("Lawful");
++            break;
++        }
++        case A_NEUTRAL:
++        {
++            prevalign.txt = curses_copy_of("Neutral");
++            break;
++        }
++        case A_CHAOTIC:
++        {
++            prevalign.txt = curses_copy_of("Chaotic");
++            break;
++        }
++    }
++    
++    prevalign.alignment = u.ualign.type;
++    prevalign.display = TRUE;
++    prevalign.highlight_turns = 0;
++    prevalign.label = NULL;
++    
++    /* Dungeon level */
++    if (In_endgame(&u.uz))
++    {
++        strcpy(buf, (Is_astralevel(&u.uz) ? "Astral Plane":"End Game"));
++    }
++    else
++    {
++        sprintf(buf, "%d", depth(&u.uz));
++    }
++
++    prevdepth.value = depth(&u.uz);
++    prevdepth.txt = curses_copy_of(buf);
++    prevdepth.display = TRUE;
++    prevdepth.highlight_turns = 0;
++    prevdepth.label = curses_copy_of("Dlvl:");
++    
++    /* Gold */
++#ifndef GOLDOBJ
++    sprintf(buf,"%ld", u.ugold);
++    prevau.value = u.ugold;
++#else
++    sprintf(buf,"%ld", money_cnt(invent));
++    prevau.value = money_cnt(invent);
++#endif
++    prevau.txt = curses_copy_of(buf);
++    prevau.display = TRUE;
++    prevau.highlight_turns = 0;
++    sprintf(buf, "%c:", GOLD_SYM);
++    prevau.label = curses_copy_of(buf);
++
++    /* Hit Points */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
++    {
++        prevhp.value = u.mh;
++        sprintf(buf, "%d", u.mh);
++        prevhp.txt = curses_copy_of(buf);
++	}
++	else if (u.uhp != prevhp.value)  /* Not polymorphed */
++	{
++	    prevhp.value = u.uhp;
++        sprintf(buf, "%d", u.uhp);
++        prevhp.txt = curses_copy_of(buf);
++	}
++	prevhp.display = TRUE;
++	prevhp.highlight_turns = 0;
++    prevhp.label = curses_copy_of("HP:");
++
++    /* Max Hit Points */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
++    {
++        prevmhp.value = u.mhmax;
++        sprintf(buf, "%d", u.mhmax);
++        prevmhp.txt = curses_copy_of(buf);
++	}
++	else    /* Not polymorphed */
++	{
++	    prevmhp.value = u.uhpmax;
++        sprintf(buf, "%d", u.uhpmax);
++        prevmhp.txt = curses_copy_of(buf);
++	}
++	prevmhp.display = TRUE;
++	prevmhp.highlight_turns = 0;
++    prevmhp.label = curses_copy_of("/");
++
++    /* Power */
++    prevpow.value = u.uen;
++    sprintf(buf, "%d", u.uen);
++    prevpow.txt = curses_copy_of(buf);
++	prevpow.display = TRUE;
++	prevpow.highlight_turns = 0;
++    prevpow.label = curses_copy_of("Pw:");
++
++    /* Max Power */
++    prevmpow.value = u.uenmax;
++    sprintf(buf, "%d", u.uenmax);
++    prevmpow.txt = curses_copy_of(buf);
++	prevmpow.display = TRUE;
++	prevmpow.highlight_turns = 0;
++    prevmpow.label = curses_copy_of("/");
++
++    /* Armor Class */
++    prevac.value = u.uac;
++    sprintf(buf, "%d", u.uac);
++    prevac.txt = curses_copy_of(buf);
++	prevac.display = TRUE;
++	prevac.highlight_turns = 0;
++    prevac.label = curses_copy_of("AC:");
++
++    /* Experience */
++#ifdef EXP_ON_BOTL
++    prevexp.value = u.uexp;
++    sprintf(buf, "%ld", u.uexp);
++    prevexp.txt = curses_copy_of(buf);
++	prevexp.display = flags.showexp;
++	prevexp.highlight_turns = 0;
++    prevexp.label = curses_copy_of("Xp:");
++#endif
++
++    /* Level */
++    if (u.mtimedone)    /* Currently polymorphed - show monster HP */
++    {
++        prevlevel.value = mons[u.umonnum].mlevel;
++        sprintf(buf, "%d", mons[u.umonnum].mlevel);
++        prevlevel.txt = curses_copy_of(buf);
++        prevlevel.label = curses_copy_of("HD:");
++	}
++	else if (u.ulevel != prevlevel.value)  /* Not polymorphed */
++	{
++	    prevlevel.value = u.ulevel;
++        sprintf(buf, "%d", u.ulevel);
++        prevlevel.txt = curses_copy_of(buf);
++        if (prevexp.display)
++        {
++            prevlevel.label = curses_copy_of("/");
++        }
++        else
++        {    
++            prevlevel.label = curses_copy_of("Lvl:");
++        }
++	}
++	prevlevel.display = TRUE;
++	prevlevel.highlight_turns = 0;
++
++    /* Time */
++    prevtime.value = moves;
++    sprintf(buf, "%ld", moves);
++    prevtime.txt = curses_copy_of(buf);
++	prevtime.display = flags.time;
++	prevtime.highlight_turns = 0;
++    prevtime.label = curses_copy_of("T:");
++
++    /* Score */
++#ifdef SCORE_ON_BOTL
++    prevscore.value = botl_score();
++    sprintf(buf, "%ld", botl_score());
++    prevscore.txt = curses_copy_of(buf);
++	prevscore.display = flags.showscore;
++	prevscore.highlight_turns = 0;
++    prevscore.label = curses_copy_of("S:");
++#endif
++
++    /* Hunger */
++    prevhunger.value = u.uhs;
++    for (count = 0; count < strlen(hu_stat[u.uhs]); count++)
++    {
++        if ((hu_stat[u.uhs][count]) == ' ')
++        {
++            break;
++        }
++        buf[count] = hu_stat[u.uhs][count];
++    }
++
++    buf[count] = '\0';
++    prevhunger.txt = curses_copy_of(buf);
++    prevhunger.display = TRUE;
++    prevhunger.highlight_turns = 0;
++    prevhunger.label = NULL;
++
++    /* Confusion */
++    prevconf.value = Confusion;
++    if (Confusion)
++    {
++        prevconf.txt = curses_copy_of("Conf");
++    }
++    else
++    {
++        prevconf.txt = NULL;
++    }
++    prevconf.display = TRUE;
++    prevconf.highlight_turns = 0;
++    prevconf.label = NULL;
++
++    /* Blindness */
++    prevblind.value = Blind;
++    if (Blind)
++    {
++        prevblind.txt = curses_copy_of("Blind");
++    }
++    else
++    {
++        prevblind.txt = NULL;
++    }
++    prevblind.display = TRUE;
++    prevblind.highlight_turns = 0;
++    prevblind.label = NULL;
++
++    /* Stun */
++    prevstun.value = Stunned;
++    if (Stunned)
++    {
++        prevstun.txt = curses_copy_of("Stun");
++    }
++    else
++    {
++        prevstun.txt = NULL;
++    }
++    prevstun.display = TRUE;
++    prevstun.highlight_turns = 0;
++    prevstun.label = NULL;
++
++    /* Hallucination */
++    prevhallu.value = Hallucination;
++    if (Hallucination)
++    {
++        prevhallu.txt = curses_copy_of("Hallu");
++    }
++    else
++    {
++        prevhallu.txt = NULL;
++    }
++    prevhallu.display = TRUE;
++    prevhallu.highlight_turns = 0;
++    prevhallu.label = NULL;
++
++    /* Sick */
++    prevsick.value = Sick;
++    if (Sick)
++    {
++        if (u.usick_type & SICK_VOMITABLE)
++        {
++            prevsick.txt = curses_copy_of("Sick");
++        }
++        else     
++        {
++            prevsick.txt = curses_copy_of("Ill");
++        }
++    }
++    else
++    {
++        prevsick.txt = NULL;
++    }
++    prevsick.display = TRUE;
++    prevsick.highlight_turns = 0;
++    prevsick.label = NULL;
++
++    /* Slimed */
++    prevslime.value = Slimed;
++    if (Slimed)
++    {
++        prevslime.txt = curses_copy_of("Slime");
++    }
++    else
++    {
++        prevslime.txt = NULL;
++    }
++    prevslime.display = TRUE;
++    prevslime.highlight_turns = 0;
++    prevslime.label = NULL;
++
++    /* Encumberance */
++    prevencumb.value = near_capacity();
++    if (prevencumb.value > UNENCUMBERED)
++    {
++        sprintf(buf, "%s", enc_stat[prevencumb.value]);
++        prevencumb.txt = curses_copy_of(buf);
++    }
++    else
++    {
++        prevencumb.txt = NULL;
++    }
++    prevencumb.display = TRUE;
++    prevencumb.highlight_turns = 0;
++    prevencumb.label = NULL;
++}
++
+diff -burN nethack-3.4.3/win/curses/cursstat.h nethack/win/curses/cursstat.h
+--- nethack-3.4.3/win/curses/cursstat.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/cursstat.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,29 @@
++#ifndef CURSSTAT_H
++#define CURSSTAT_H
++
++
++/* Global declarations */
++
++void curses_update_stats(void);
++
++void curses_decrement_highlight(void);
++
++
++/* Private declarations */
++
++typedef struct nhs
++{
++    long value;
++    char *txt;
++    aligntyp alignment;
++    boolean display;
++    int highlight_turns;
++    int highlight_color;
++    int x;
++    int y;
++    char *label;
++} nhstat;
++
++static void init_stats(void);
++
++#endif  /* CURSSTAT_H */
+diff -burN nethack-3.4.3/win/curses/curswins.c nethack/win/curses/curswins.c
+--- nethack-3.4.3/win/curses/curswins.c	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/curswins.c	2009-03-11 15:08:53.000000000 -0400
+@@ -0,0 +1,462 @@
++#include "curses.h"
++#include "hack.h"
++#include "wincurs.h"
++#include "curswins.h"
++
++/* Window handling for curses interface */
++
++static nethack_window *nhwins = NULL;  /* NetHack window array */
++
++
++
++/* Create a window with the specified size and orientation */
++
++WINDOW *curses_create_window(int width, int height, orient orientation)
++{
++    int mapx, mapy, maph, mapw = 0;
++    int startx = 0;
++    int starty = 0;
++    WINDOW *win;
++    boolean map_border = FALSE;
++        
++    if ((orientation == UP) || (orientation == DOWN) ||
++     (orientation == LEFT))
++    {
++        map_border = curses_window_has_border(MAP_WIN);
++        curses_get_window_xy(MAP_WIN, &mapx, &mapy);
++        curses_get_window_size(MAP_WIN, &maph, &mapw);
++    }
++    width += 2;    /* leave room for bounding box */
++    height += 2;
++    if ((width > term_cols) || (height > term_rows))
++        panic("curses_create_window: Terminal too small for dialog window");
++    switch (orientation)
++    {
++        case CENTER:
++        {
++            startx = (term_cols / 2) - (width / 2);
++            starty = (term_rows / 2) - (height / 2);
++            break;
++        }
++        case UP:
++        {
++            startx = (mapw / 2) - (width / 2) + mapx;
++            starty = mapy;
++            break;
++        }
++        case DOWN:
++        {
++            startx = (mapw / 2) - (width / 2) + mapx;
++            starty = height - mapy - 1;
++            break;
++        }
++        case LEFT:
++        {
++            if (map_border && (width < term_cols))
++                startx = 1;
++            else
++                startx = 0;
++            starty = term_rows - height;
++            break;
++        }
++        case RIGHT:
++        {
++            startx = term_cols - width;
++            starty = 0;
++            break;
++        }
++        default:
++        {
++            panic("curses_create_window: Bad orientation");
++        }
++    }
++    win = newwin(height, width, starty, startx);
++    curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, ON);
++    box(win, 0, 0);
++    curses_toggle_color_attr(win, DIALOG_BORDER_COLOR, NONE, OFF);
++    return win;
++}
++
++
++/* Erase and delete curses window, and refresh standard windows */
++
++void curses_destroy_win(WINDOW *win)
++{
++    werase(win);
++    wrefresh(win);
++    delwin(win);
++    curses_refresh_nethack_windows();
++}
++
++
++/* Refresh nethack windows if they exist, or base window if not */
++
++void curses_refresh_nethack_windows()
++{
++    WINDOW *status_window, *message_window;
++    
++    status_window = curses_get_nhwin(STATUS_WIN);
++    message_window = curses_get_nhwin(MESSAGE_WIN);
++    
++    if (!iflags.window_inited)
++    {
++        /* Main windows not yet displayed; refresh base window instead */
++        touchwin(stdscr);
++        refresh();
++    }
++    else
++    {
++        touchwin(status_window);
++        wnoutrefresh(status_window);
++        box(mapborderwin, 0, 0);
++        wrefresh(mapborderwin);
++        touchwin(message_window);
++        wnoutrefresh(message_window);
++        doupdate();
++        refresh_map_window();
++    }
++}
++
++
++/* Return curses window pointer for given NetHack winid */
++
++WINDOW *curses_get_nhwin(winid wid)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++            return winptr->curwin;
++        winptr = winptr->next_window;
++    }
++    
++    return NULL;    /* Not found */
++}
++
++
++/* Add curses window pointer and window info to list for given NetHack winid */
++
++void curses_add_nhwin(winid wid, int height, int width, int y, int x,
++  orient orientation, boolean border)
++{
++    WINDOW *win;
++    nethack_window *new_win;
++    nethack_window *winptr = nhwins;
++    int real_width = width;
++    int real_height = height;
++    
++    new_win = malloc(sizeof(nethack_window));
++    new_win->nhwin = wid;
++    new_win->border = border;
++    new_win->width = width;
++    new_win->height = height;
++    new_win->x = x;
++    new_win->y = y;
++    new_win->orientation = orientation;
++    if (border)
++    {
++        real_width += 2;    /* leave room for bounding box */
++        real_height += 2;
++    }
++    new_win->next_window = NULL;
++    if (winptr == NULL)
++    {
++        new_win->prev_window = NULL;
++        nhwins = new_win;
++    }
++    else
++    {
++        while (winptr->next_window != NULL)
++            winptr = winptr->next_window;
++        new_win->prev_window = winptr;
++        winptr->next_window = new_win;
++    }
++    if (wid != MAP_WIN)
++    {
++        win = newwin(real_height, real_width, y, x);
++        if (border)
++        {
++            box(win, 0, 0);
++        }
++    }
++    else
++    {
++        if (border)
++        {
++            box(mapborderwin, 0, 0);
++        }
++        win = newpad(ROWNO, COLNO);
++    }
++    new_win->curwin = win;
++}
++
++
++/* refresh a curses window via given nethack winid */
++
++void curses_refresh_nhwin(winid wid)
++{
++    if (wid != MAP_WIN)
++        wrefresh(curses_get_nhwin(wid));
++    else
++        refresh_map_window();
++}
++
++
++/* Delete curses window via given NetHack winid and remove entry from list */
++
++void curses_del_nhwin(winid wid)
++{
++    nethack_window *tmpwin;
++    nethack_window *winptr = nhwins;
++    
++    if (curses_is_menu(wid) || curses_is_text(wid))
++    {
++        curses_del_menu(wid);
++    }
++    
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            if (winptr->prev_window != NULL)
++            {
++                tmpwin = winptr->prev_window;
++                tmpwin->next_window = winptr->next_window;
++            }
++            else
++            {
++                nhwins = winptr->next_window;   /* New head mode, or NULL */
++            }
++            if (winptr->next_window != NULL)
++            {
++                tmpwin = winptr->next_window;
++                tmpwin->prev_window = winptr->prev_window;
++            }
++            free(winptr);
++            break;
++        }
++        winptr = winptr->next_window;
++    }
++}
++
++
++/* Print a single character in the given window at the given coordinates */
++
++void curses_putch(winid wid, int x, int y, int ch, int color, int attr)
++{
++    WINDOW *win;
++    boolean border = curses_window_has_border(wid);
++    
++    if (border && (wid != MAP_WIN))
++    {
++        x++;
++        y++;
++    }
++    win = curses_get_nhwin(wid);
++    curses_toggle_color_attr(win, color, attr, ON);
++#ifdef PDCURSES
++    mvwaddrawch(win, y, x, ch);
++#else
++    mvwaddch(win, y, x, ch);
++#endif
++    if (wid == MAP_WIN)
++    {
++        refresh_map_window();
++    }
++else
++    {
++        wrefresh(win);
++    }
++    
++    curses_toggle_color_attr(win, color, attr, OFF);
++}
++
++
++/* Get x, y coordinates of curses window on the physical terminal window */
++
++void curses_get_window_xy(winid wid, int *x, int *y)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            *x = winptr->x;
++            *y = winptr->y;
++            break;
++        }
++        winptr = winptr->next_window;
++    }
++}
++
++
++/* Get usable width and height curses window on the physical terminal window */
++
++void curses_get_window_size(winid wid, int *height, int *width)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            *height = winptr->height;
++            *width = winptr->width;
++            break;
++        }
++        winptr = winptr->next_window;
++    }
++}
++
++
++/* Determine if given window has a visible border */
++
++boolean curses_window_has_border(winid wid)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            return winptr->border;
++        }
++        winptr = winptr->next_window;
++    }
++}
++
++
++/* Determine if window for given winid exists */
++
++boolean curses_window_exists(winid wid)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            return TRUE;
++        }
++        winptr = winptr->next_window;
++    }
++    
++    return FALSE;
++}
++
++
++/* Return the orientation of the specified window */
++
++int curses_get_window_orientation(winid wid)
++{
++    nethack_window *winptr = nhwins;
++ 
++    while (winptr != NULL)
++    {
++        if (winptr->nhwin == wid)
++        {
++            return winptr->orientation;
++        }
++        winptr = winptr->next_window;
++    }
++}
++
++
++/* Output a line of text to specified NetHack window with given coordinates
++and text attributes */
++
++void curses_puts(winid wid, int attr, const char *text)
++{
++    anything *identifier;
++    WINDOW *win = curses_get_nhwin(wid);
++    
++    curses_toggle_color_attr(win, NONE, attr, ON);
++    if (wid == MESSAGE_WIN)
++    {
++        curses_message_win_puts(text, FALSE);
++        return;
++    }
++    
++    if (wid == STATUS_WIN)
++    {
++        curses_update_stats();  /* We will do the write ourselves */
++        return;
++    }
++    
++    if (curses_is_menu(wid) || curses_is_text(wid))
++    {
++        if (!curses_menu_exists(wid))
++        {
++            panic("curses_puts: Attempted write to nonexistant window!"); 
++        }
++        identifier = malloc(sizeof(anything));
++        identifier->a_void = NULL;
++        curses_add_menu(wid, NO_GLYPH, identifier, 0, 0, attr, text,
++         FALSE);
++    }
++    else
++    {
++        waddstr(win, text);
++        wrefresh(win);
++    }
++    curses_toggle_color_attr(win, NONE, attr, OFF);
++}
++
++
++/* Clear the contents of a window via the given NetHack winid */
++
++void curses_clear_nhwin(winid wid)
++{
++    WINDOW *win = curses_get_nhwin(wid);
++    boolean border = curses_window_has_border(wid);
++    
++    werase(win);
++    if (border && (wid != MAP_WIN))
++        box(win, 0, 0);
++    if (wid != MAP_WIN)
++    {
++        wrefresh(win);
++    }
++    else
++    {
++        refresh_map_window();
++    }
++}
++
++
++/* Refresh visible portion of map window */
++
++static void refresh_map_window()
++{
++    int mapwinx, mapwiny, maph, mapw, mapwinw, mapwinh, mapx, mapy;
++    WINDOW *map_window = curses_get_nhwin(MAP_WIN);
++    boolean border = curses_window_has_border(MAP_WIN);
++    
++    curses_get_window_xy(MAP_WIN, &mapwinx, &mapwiny);
++    curses_get_window_size(MAP_WIN, &mapwinh, &mapwinw);
++    maph = ROWNO;
++    mapw = COLNO;
++    mapx = u.ux - (mapwinw / 2);
++    if ((mapx + mapwinw) > mapw)
++    {
++        mapx = mapw - mapwinw;
++    }
++    if (mapx < 0)
++    {
++        mapx = 0;
++    }
++    mapy = u.uy - (mapwinh / 2);
++    if ((mapy + mapwinh) > maph)
++    {
++        mapy = maph - mapwinh;
++    }
++    if (mapy < 0)
++    {
++        mapy = 0;
++    }
++    prefresh(map_window, mapy, mapx, mapwiny, mapwinx, mapwiny + mapwinh - 1, 
++     mapwinx + mapwinw - 1);
++}
++
+diff -burN nethack-3.4.3/win/curses/curswins.h nethack/win/curses/curswins.h
+--- nethack-3.4.3/win/curses/curswins.h	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/curswins.h	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,55 @@
++#ifndef CURSWIN_H
++#define CURSWIN_H
++
++
++/* Global declarations */
++
++WINDOW *curses_create_window(int width, int height, orient orientation);
++
++void curses_destroy_win(WINDOW *win);
++
++void curses_refresh_nethack_windows(void);
++
++WINDOW *curses_get_nhwin(winid wid);
++
++void curses_add_nhwin(winid wid, int height, int width, int y, int x,
++ orient orientation, boolean border);
++
++void curses_refresh_nhwin(winid wid);
++
++void curses_del_nhwin(winid wid);
++
++void curses_putch(winid wid, int x, int y, int ch, int color, int attrs);
++
++void curses_get_window_xy(winid wid, int *x, int *y);
++
++boolean curses_window_has_border(winid wid);
++
++boolean curses_window_exists(winid wid);
++
++int curses_get_window_orientation(winid wid);
++
++void curses_puts(winid wid, int attr, const char *text);
++
++void curses_clear_nhwin(winid wid);
++
++
++/* Private declarations */
++
++typedef struct nhw
++{
++    winid nhwin;  /* NetHack window id */
++    WINDOW *curwin; /* Curses window pointer */
++    int width;  /* Usable width not counting border */
++    int height; /* Usable height not counting border */
++    int x;  /* start of window on terminal (left) */
++    int y;  /* start of window on termial (top) */
++    int orientation;    /* Placement of window relative to map */
++    boolean border; /* Whether window has a visible border */
++    struct nhw *prev_window;    /* Pointer to previous entry */
++    struct nhw *next_window;    /* Pointer to next entry */
++} nethack_window;
++
++static void refresh_map_window(void);
++
++#endif  /* CURSWIN_H */
+diff -burN nethack-3.4.3/win/curses/Readme.txt nethack/win/curses/Readme.txt
+--- nethack-3.4.3/win/curses/Readme.txt	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/Readme.txt	2009-03-05 13:50:38.000000000 -0500
+@@ -0,0 +1,116 @@
++INTRO
++=====
++
++The "curses" windowport is a new text-based interface for NetHack,
++using high-level curses routines to control the display.  Currently, it
++has been compiled and tested on Linux and Windows, but it should also
++be portable to a number of other systems, such as other forms of UNIX,
++Mac OS X, MSDOS, and OS/2.
++
++Some features of this interface compared to the traditional tty
++interface include:
++
++ * Dynamic window resizing (e.g. maximizing a terminal window)
++ * Dynamic configurable placement of status and message windows,
++ relative to the map
++ * Makes better use of larger terminal windows
++ * Fancier display (e.g. window borders, optional popup dialogs)
++ * "cursesgraphics" option for fancier line-drawing characters for
++ drawing the dungeon - this should work on most terminals/platforms
++
++
++BUILDING
++========
++
++As of this writing code has been compiled on Linux and Windows.
++
++UNIX/Linux build instructions: Follow the instructions in
++sys/unix/Install.unx.  By default, the Makefile is setup to compile
++against ncurses.  Edit Makefile.src if you wish to compile against a
++different curses library, such as PDCurses for SDL.
++
++Windows build instructions: If you are using Mingw32 as your compiler,
++then follow the instructions in sys/winnt/Install.nt with the following
++changes:
++
++ * After running nhsetup, manually copy the file cursmake.gcc to the
++ src/ subdirectory
++ * Instead of typing "mingw32-make -f Makefile.gcc install" you will
++ type "mingw32-make -f cursmake.gcc install"
++
++If you are using a different compiler, you will have to manually modify
++the appropriate Makefile to include the curses windowport files.
++
++
++GAMEPLAY
++========
++
++Gameplay should be similar to the tty interface for NetHack; the 
++differences are primarily visual.  This windowport supports dymanic
++resizing of the terminal window, so you can play with it to see how it
++looks best to you during a game.  Also, the align_status and
++align_message options may be set during the game, so you can experiment
++to see what arraingement looks best to you.
++
++For menus, in addition to the normal configurable keybindings for menu
++navigation descrived in the Guidebook, you can use the right and left
++arrows to to forward or backward one page, respectively, and the home
++and end keys to go to the first and last pages, respectively.
++
++Some configuration options that are specific to or relevant to the
++curses windowport are shown below.  Copy any of these that you like to
++your nethack configuration file (e.g. .nethackrc for UNIX or
++NetHack.cnf for Windows):
++#
++# Use this if the binary was compiled with multiple window interfaces,
++# and curses is not the default
++OPTIONS=windowtype:curses
++#
++# Set this for Windows systems, or for PDCurses for SDL on any system.
++# The latter uses a cp437 font, which works with this option
++#OPTIONS=IBMgraphics
++#
++# Set this if IBMgraphics above won't work for your system.  Mutually
++# exclusive with the above option, and should work on nearly any
++# system.
++OPTIONS=cursesgraphics
++#
++# Optionally specify the alignment of the message and status windows
++# relative to the map window.  If not specified, the code will default
++# to the locations used in the tty interface: message window on top,
++# and status window on bottom.  Placing either of these on the right or
++# left really only works well for winder terminal windows.
++OPTIONS=align_message:bottom,align_status:right
++#
++# Use a small popup "window" for short prompts, e.g. "Really save?".
++# If this is not set, the message window will be used for these as is
++# done for the tty interface.
++OPTIONS=popup_dialog
++#
++# Specify the initial window size for NetHack in units of characters.
++# This is supported on PDCurses for SDL as well as PDCurses for
++# Windows.
++OPTIONS=term_cols:110,term_rows:32
++#
++# Controls the usage of window borders for the main NetHack windows
++# (message, map, and status windows).  A value of 1 forces the borders
++# to be drawn, a value of 2 forces them to be off, and a value of 3
++# allows the code to decide if they should be drawn based on the size
++# of the terminal window.
++OPTIONS=windowborders:3
++
++
++CONTACT
++=======
++
++Please send any bug reports, suggestions, patches, or miscellaneous
++feedback to me (Karl Garrison) at: kgarrison@pobox.com.  Note that as
++of this writing, I only have sporatic Internet access, so I may not get
++back to you right away.
++
++Happy Hacking!
++
++Karl Garrison
++March, 2009
++
++
+diff -burN nethack-3.4.3/win/curses/Todo.txt nethack/win/curses/Todo.txt
+--- nethack-3.4.3/win/curses/Todo.txt	1969-12-31 19:00:00.000000000 -0500
++++ nethack/win/curses/Todo.txt	2009-03-11 14:32:27.000000000 -0400
+@@ -0,0 +1,146 @@
++Below are some things I would like to see
++
++NETHACK INTERFACE
++=================
++
++(These are the functions in cursmain.c called by the core NetHack code)
++
++ * Implement curses_rip for optional fancier color tombstone, as well
++ as one that will display correctly on smaller terminals.
++ 
++ * I am confused as to how mark_synch, wait_synch, and delay_output
++ should work.  Help, please?
++ 
++ * Both PDCurses and Ncurses have mouse support, so the poskey function
++ could probably be implemented easily enough.
++ 
++ * raw_print is supposed to be able to work before the windowing system
++ has been initialized, as well as after, so I am unsure if curses
++ functions should be used here.  Maybe check to see if initscr() has
++ been called, and use curses functions if so, and call initscr() from
++ there is not?  Right now it is just a call to puts() with no support
++ for bold text.
++
++
++DISPLAY
++=======
++
++ * Consolidate refreshes of the display for smoother output.
++
++ * Horizontal scrollbar to show position for displays < 80 columns.
++ 
++ * Calls to getch() should probably be turned into wgetch() for the
++ appropriate window.  This causes quirty cursor behavior under
++ PDCurses, however.
++
++ * Animation effects do not display properly - this could probably be
++ fixed with a correct implementation of the delay_output function.
++
++ * Support option to set forground and background colors for individual
++ windows
++
++
++MENUS
++=====
++
++(cursdial.c)
++
++ * Menus need to be able to accept a count as input, e.g. to specifiy
++ how many items to drop.
++ 
++ * Currently the "preselected" flag for an individual menu item is
++ ignored.  This should eventually be implemented.
++ 
++ * Menus probably should never overlap with the message window, since
++ the user sometmes needs to be able to see the messages while the menu
++ is active, e.g. when identifying multiple items one at a time.
++ 
++ * Perhaps allow for keyboard navigation of individual items, e.g.
++ using the up and down arrows to move among the selectable items, and
++ selecting individual items with the spacebar.  Perhaps the tab key
++ could jump to the first selectable item after the next heading, and
++ shift-tab could jump to the first item of the previous heading.
++
++
++MESSAGE WINDOW
++==============
++
++(cursmesg.c)
++
++ * Hitting Esc at the more prompt (which is '>>' for the curses
++ interface) should suppress the display of any further messages for
++ that turn like the tty interface does.
++
++
++MAP WINDOW
++==========
++
++(curswins.c)
++
++ * The map window would probably benefit from a total redesign.  Right
++ now, it uses a pad instead of a regular curses window, which causes a
++ number of special cases in the code to account for it, and a seperate
++ window behind it just to draw the border.  It feels kludgy and
++ annoying!
++
++
++STATUS WINDOW
++=============
++
++(cursstat.c)
++
++ * If the status window is on the right or left, then we have much more
++ room to work with for each item horizontally.  Expand out some of the
++ labels for clarity.  We can also list the current dungeon (e.g.
++ Gnomish Mines) and perhaps show thermometer bars for hit points and
++ magical power.
++ 
++ * Conversely, if we have a narrower dislay, compress some of the
++ labels to save space, and do not display some items that never or
++ rarely change (e.g. name, level and title, and alignment).  Perhaps
++ display changes to these fields in the message window if they do
++ happen to change (e.g. converting to a new alignment).
++ 
++ * Maybe add some configuration options for what colors are used and
++ the like.
++
++OTHER DIALOGS
++=============
++
++(cursdial.c)
++
++ * curses_yn_function needs to accept a count if a '#' is present in
++ choices string.
++ 
++ * Extended commands should be enterable letter-by-letter via a '#'
++ prompt if user does not have the extmenu command set to TRUE.
++ 
++ * Character selection should allow for a random selection of any or
++ all choices.
++
++
++OTHER PLATFORMS
++===============
++
++ * PDCurses also work on DOS and OS/2.  PDCurses for SDL and ncurses
++ exist for Mac OS X.  Porting the curses interface to these platforms
++ should not be too difficult.
++
++
++MISC
++====
++
++ * Update documentation and in-game help to describe the newly-added
++ options: cursesgraphics, term_rows, term_cols, and windowborders.
++
++ * Recognize "Alt" key in a platform-independant way to allow its use
++ to select extended commands.  Currently this works for PDCurses.  For
++ Ncurses, the Alt key works in an xterm or rxvt if the -meta8 flag is
++ passed, but I'd like to see a general way of detecting it.
++ 
++ * PDCurses has a function named "addrawch" to output the visual
++ representation of a control character to the screen without having the
++ control character affect the display otherwise.  I would like to find
++ a way to accomplish the same thing via Ncurses to e.g. be able to use
++ a font like nh10 with the correct symbol mappings in an xterm or the
++ like.
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/README.statuscolors nethack/README.statuscolors
--- nh_orig/README.statuscolors	1969-12-31 19:00:00.000000000 -0500
+++ nethack/README.statuscolors	2007-12-27 09:01:28.000000000 -0500
@@ -0,0 +1,62 @@
+Statuscolors is a patch for Nethack (version 3.4.3) that attempts to generalize
+the hpmon patch to be more like the menucolor patch. As of v1.2, the
+statuscolors patch may be applied after the menucolor patch (but not before
+it). Unlike menucolor, it does not use regexps. Instead, it provides the
+following options:
+
+To enable statuscolors:
+    OPTIONS=statuscolors
+
+To specify statuscolor options, write:
+    STATUSCOLOR=<option>,<option>
+
+Numeric options have the format <field>%<max-percent>:<color-option>. For
+example:
+    STATUSCOLOR=hp%15:red&bold,pw%100=green
+
+Text options have the format <text>:<color-option>. Text is case-insensitive.
+For example:
+    STATUSCOLOR=hallu:orange,foodpois:red&inverse&blink
+
+A color option is a <color> followed by an optional sequence of &<attr>. Color
+and attribute names are case insensitive. Valid colors are:
+    black blue brown cyan gray green lightblue lightcyan lightgreen
+    lightmagenta magenta none orange red white yellow
+
+Valid attributes are:
+    blink bold dim inverse none underline
+
+A reasonable set of defaults might be:
+    # HP
+    STATUSCOLOR=hp%100=green,hp%66=yellow,hp%50=orange
+    STATUSCOLOR=hp%33=red&bold,hp%15:red&inverse,hp%0:red&inverse&blink
+    # Pw
+    STATUSCOLOR=pw%100=green,pw%66=yellow,pw%50:orange,pw%33=red&bold
+    # Carry
+    STATUSCOLOR=burdened:yellow,stressed:orange,strained:red&bold
+    STATUSCOLOR=overtaxed:red&inverse,overloaded:red&inverse&blink
+    # Hunger
+    STATUSCOLOR=satiated:yellow,hungry:orange,weak:red&bold
+    STATUSCOLOR=fainting:red&inverse,fainted:red&inverse&blink
+    # Mental
+    STATUSCOLOR=hallu:yellow,conf:orange,stun:red&bold
+    # Health
+    STATUSCOLOR=ill:red&inverse,foodpois:red&inverse,slime:red&inverse
+    # Other
+    STATUSCOLOR=held:red&inverse,blind:red&inverse
+
+Changelog:
+
+    v1.2:
+      - Menucolor compatibility.
+
+    v1.1:
+      - Fixed several shameful bugs.
+
+    v1.0:
+      - Initial release.
+
+---
+Shachaf & Oren Ben-Kiki
+shachaf+nethack@gmail.com
+nethack-oren@ben-kiki.org
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/shrced.php.txt nethack/shrced.php.txt
--- nh_orig/shrced.php.txt	1969-12-31 19:00:00.000000000 -0500
+++ nethack/shrced.php.txt	2009-11-11 07:37:48.960274338 -0500
@@ -0,0 +1,138 @@
+<?php
+
+$logindb = "/var/lib/dgamelaunch/dgldir/dgamelaunch.db";
+$rcpath = "/var/lib/dgamelaunch/dgldir/rcfiles/";
+$default_rc = "/var/lib/dgamelaunch/default.nethackrc";
+
+/*
+$logindb = '/opt/nethack/nethack.alt.org/dgldir/dgamelaunch.db';
+$rcpath = '/opt/nethack/nethack.alt.org/dgldir/userdata/';
+$default_rc = "/opt/nethack/nethack.alt.org/dgl-default-rcfile.nh343";
+*/
+
+function plr_rcfile($plr)
+{
+  global $rcpath;
+  /*return $rcpath.$plr."/".$plr.".nh343rc";*/
+  return $rcpath.$plr.".nethackrc";
+}
+
+
+function dgl_auth_user($username = NULL, $passwd = NULL)
+{
+  global $logindb;
+  if (!isset($username))
+    $username = $_SERVER['PHP_AUTH_USER'];
+  if (!isset($passwd))
+    $passwd = $_SERVER['PHP_AUTH_PW'];
+
+  if (!isset($username) || !isset($passwd) ||
+      ($username == "") || ($passwd == "")) return 0;
+
+  if (!preg_match("/^[0-9a-zA-Z]+$/", $username)) return 0;
+
+  $passwd_crypt = crypt($passwd, substr($passwd, 0, 2));
+
+  $db = sqlite3_open($logindb);
+
+  $username = strtolower($username);
+
+  $result = sqlite3_query($db, "select * from dglusers where lower(username)='".$username."'");
+
+  $dat = sqlite3_fetch_array($result);
+  sqlite3_query_close($result);
+
+  if (strtolower($dat['username']) == $username && $dat['password'] == $passwd_crypt) return 1;
+  return 0;
+} //dgl_auth_user()
+
+
+function edit_form($plr,$passwd)
+{
+  global $default_rc;
+  $cansave = 1;
+
+  $rcfname = plr_rcfile($plr);
+
+  $fp = @fopen($rcfname, "r");
+  if (!$fp) {
+    $cansave = 0;
+    echo '<P>NOTE: You don\'t seem to have an rcfile. <B>You cannot save these changes.</B> You need to log in to nethack.alt.org first!';
+    $fp = @fopen($default_rc, "r");
+  }
+  /*echo '<P><B>NOTE:</B> If you get warnings that the changes could not be written, please wait an hour.';*/
+
+  echo '<P>For more help, see <A HREF="http://nethack.org/v343/Guidebook.html#_TOCentry_43">the Options-section in The Guidebook</A>';
+  echo ' or see <a href="http://nethack.wikia.com/wiki/Options">this page on the NetHack Wiki</a>.';
+
+  echo '<P><form method="POST" action="'.$_SERVER['PHP_SELF'].'">';
+  echo '<input type="hidden" name="plr" value="'.$plr.'">';
+  echo '<input type="hidden" name="passwd" value="'.$passwd.'">';
+  echo '<textarea name="rcdata" rows=24 cols=80>'; fpassthru($fp); echo '</textarea>';
+  echo '<br>';
+  if ($cansave)
+    echo '<input type="submit" value="Save" name="submit">';
+  echo '<input type="reset">';
+  echo '</form>';
+} //edit_form()
+
+
+function update_rcfile($plr, $passwd)
+{
+  if ($_POST['submit']) {
+    $rcdata = str_replace("\\\"", "\"", $_POST['rcdata']);
+    $rcdata = str_replace("\\'", "'", $rcdata);
+    $rcdata = str_replace("\\\\", "\\", $rcdata);
+    $rcdata = str_replace("\r", "", $rcdata);
+
+    $rcfname = plr_rcfile($plr);
+
+    $fp = @fopen($rcfname, "w");
+    if (!$fp) {
+      echo '<P><em>Could not write rc file. Sorry.</em>';
+    } else {
+      $rcdata = "\n".$rcdata;  // what eats the first empty line away?
+      if (fwrite($fp, $rcdata) === FALSE) {
+        echo '<P><em>There was some error when writing the rc file. Sorry.</em>';
+      } else {
+        echo '<P><em>Your rc file was saved.</em>';
+      }
+      fclose($fp);
+    }
+  }
+} //update_rcfile()
+
+
+
+
+
+print '<html><head></head><body>';
+
+print '<h1>Config file editor</h1>';
+
+if ($_SERVER['REQUEST_METHOD'] == 'POST') {
+  $passwd = $_POST['passwd'];
+  $plr = $_POST['plr'];
+  if (dgl_auth_user($plr, $passwd)) {
+    if ($_POST['submit'] == "Login") {
+      edit_form($plr, $passwd);
+    } else if ($_POST['submit'] == "Save") {
+      update_rcfile($plr, $passwd);
+    }
+  } else {
+    echo '<p>wrong username/password combination.';
+  }
+} else {
+  print '<pre>';
+  print '<form method="post" action="'.$_SERVER['PHP_SELF'].'" name="login">';
+  print 'Username: <input type="text" name="plr">';
+  print "\n";
+  print 'Password: <input type="password" name="passwd">';
+  print '<input type="submit" value="Login" name="submit">';
+  print '</form>';
+  print '</pre>';
+}
+
+print '</body></html>';
+
+?>
\ No newline at end of file
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/allmain.c nethack/src/allmain.c
--- nh_orig/src/allmain.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/allmain.c	2010-05-02 09:11:33.831736581 -0400
@@ -25,5 +25,11 @@
 #endif
     int moveamt = 0, wtcap = 0, change = 0;
+	 int regen_frequency;
     boolean didmove = FALSE, monscanmove = FALSE;
+	 /* don't make it obvious when monsters will start speeding up */
+	 int monclock;
+	 int timeout_start = rnd(10000)+15000;
+	 int clock_base = 70000L-timeout_start;
+	 int past_clock;
 
     flags.moonphase = phase_of_the_moon();
@@ -59,4 +65,7 @@
     u.uz0.dlevel = u.uz.dlevel;
     youmonst.movement = NORMAL_SPEED;	/* give the hero some movement points */
+#ifdef WHEREIS_FILE
+	 touch_whereis();
+#endif
 
     for(;;) {
@@ -92,7 +101,49 @@
 			mtmp->movement += mcalcmove(mtmp);
 
-		    if(!rn2(u.uevent.udemigod ? 25 :
-			    (depth(&u.uz) > depth(&stronghold_level)) ? 50 : 70))
+			 /* Vanilla generates a critter every 70-ish turns.
+			  * The rate accelerates to every 50 or so below the Castle,
+			  * and 'round every 25 turns once you've done the Invocation.
+			  *
+			  * We will push it even further.  Monsters post-Invocation
+			  * will almost always appear on the stairs (if present), and 
+			  * much more frequently; this, along with the extra intervene()
+			  * calls, should certainly make it seem like you're wading back
+			  * through the teeming hordes.
+			  *
+			  * Aside from that, a more general clock should be put on things;
+			  * after about 30,000 turns, the frequency rate of appearance
+			  * and (TODO) difficulty of monsters generated will slowly increase until
+			  * it reaches the point it will be at as if you were post-Invocation.
+			  *
+			  * 80,000 turns should be adequate as a target mark for this effect;
+			  * if you haven't ascended in 80,000 turns, you're intentionally
+			  * fiddling around somewhere and will certainly be strong enough
+			  * to handle anything that comes your way, so this won't be 
+			  * dropping newbies off the edge of the planet.  -- DSR 12/2/07
+			  */
+
+			 monclock = 70;
+			 if (u.uevent.udemigod) {
+				 monclock = 10;
+			 } else {
+				 if (depth(&u.uz) > depth(&stronghold_level)) {
+					 monclock = 50;
+				 }
+				 past_clock = moves - timeout_start;
+				 if (past_clock > 0) {
+					 monclock -= past_clock*60/clock_base;
+				 }
+			 }
+			 /* make sure we don't fall off the bottom */
+			 if (monclock < 10) { monclock = 10; }
+
+			 /* TODO: adj difficulty in makemon */
+		    if(!rn2(monclock)) {
+				 if (u.uevent.udemigod && xupstair && rn2(10)) {
+					(void) makemon((struct permonst *)0, xupstair, yupstair, MM_ADJACENTOK);
+				 } else {
 			(void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS);
+				 }
+			 }
 
 		    /* calculate how much time passed. */
@@ -113,4 +164,7 @@
 			    /* average movement is 1.33 times normal */
 			    if (rn2(3) != 0) moveamt += NORMAL_SPEED / 2;
+				} else if (Slow) {
+					/* average movement noticeably slower */
+					if (rn2(3) != 0) moveamt -= NORMAL_SPEED / 2;
 			}
 		    }
@@ -207,13 +261,23 @@
 		    }
 
-		    if ((u.uen < u.uenmax) &&
-			((wtcap < MOD_ENCUMBER &&
-			  (!(moves%((MAXULEV + 8 - u.ulevel) *
-				    (Role_if(PM_WIZARD) ? 3 : 4) / 6))))
-			 || Energy_regeneration)) {
+			 /* wizards regen slightly faster than others; energy regeneration is
+			  * faster than both; wizards + energy regeneration (Eye) is fastest of all */
+		    if (u.uen < u.uenmax && wtcap < MOD_ENCUMBER) {
+				if (Energy_regeneration) {
+					regen_frequency = (MAXULEV - (Role_if(PM_WIZARD) ? 5 : 0) - u.ulevel) * (Role_if(PM_WIZARD) ? 2 : 3) / 6;
+				} else {
+					regen_frequency = (MAXULEV + 8 - u.ulevel) * (Role_if(PM_WIZARD) ? 3 : 4) / 6;
+				}
+				/* regen_freq should never hit 0 or negative, but let's cover it here just in case
+				 * since we saw a crash earlier at this line -- this is the only thing it could be */
+				if (regen_frequency < 1) { regen_frequency = 1; }
+				if (!(moves % regen_frequency)) {
 			u.uen += rn1((int)(ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1,1);
-			if (u.uen > u.uenmax)  u.uen = u.uenmax;
+					if (u.uen > u.uenmax) {
+						u.uen = u.uenmax;
+					}
 			flags.botl = 1;
 		    }
+		    }
 
 		    if(!u.uinvulnerable) {
@@ -246,5 +310,5 @@
 				    stop_occupation();
 				else
-				    nomul(0);
+				    nomul(0, 0);
 				if (change == 1) polyself(FALSE);
 				else you_were();
@@ -268,5 +332,5 @@
 			if (!u.udg_cnt) {
 			    intervene();
-			    u.udg_cnt = rn1(200, 50);
+			    u.udg_cnt = rn1(100, 50);
 			}
 		    }
@@ -295,4 +359,22 @@
 	    /******************************************/
 
+		 /* move this here so player can check inventory safely in lava
+		  * but any actual action will cause time to pass */
+		if (u.utrap && u.utraptype == TT_LAVA) {
+			if(!is_lava(u.ux,u.uy))
+				u.utrap = 0;
+			else if (!u.uinvulnerable) {
+				u.utrap -= 1<<8;
+				if (u.utrap < 1<<8) {
+					killer_format = KILLED_BY;
+					killer = "molten lava";
+					You("sink below the surface and die.");
+					done(DISSOLVED);
+				} else if(didmove && !u.umoved) {
+					Norep("You sink deeper into the lava.");
+					u.utrap += rnd(4);
+				}
+			}
+		}
 
 	} /* actual time passed */
@@ -317,4 +399,14 @@
 	    if (vision_full_recalc) vision_recalc(0);	/* vision! */
 	}
+
+#ifdef REALTIME_ON_BOTL
+        if(iflags.showrealtime) {
+            /* Update the bottom line if the number of minutes has
+             * changed */
+            if(get_realtime() / 60 != realtime_data.last_displayed_time / 60)
+                flags.botl = 1;
+        }
+#endif
+  
 	if(flags.botl || flags.botlx) bot();
 
@@ -357,21 +449,4 @@
 		do_vicinity_map();
 
-	if(u.utrap && u.utraptype == TT_LAVA) {
-	    if(!is_lava(u.ux,u.uy))
-		u.utrap = 0;
-	    else if (!u.uinvulnerable) {
-		u.utrap -= 1<<8;
-		if(u.utrap < 1<<8) {
-		    killer_format = KILLED_BY;
-		    killer = "molten lava";
-		    You("sink below the surface and die.");
-		    done(DISSOLVED);
-		} else if(didmove && !u.umoved) {
-		    Norep("You sink deeper into the lava.");
-		    u.utrap += rnd(4);
-		}
-	    }
-	}
-
 #ifdef WIZARD
 	if (iflags.sanity_check)
@@ -403,4 +478,5 @@
 	    }
 	} else if (multi == 0) {
+	    ck_server_admin_msg();
 #ifdef MAIL
 	    ckmailstatus();
@@ -439,5 +515,5 @@
 */
 #ifdef REDO
-		nomul(0);
+		nomul(0, 0);
 		pushch(0);
 #endif
@@ -538,4 +614,17 @@
 	program_state.something_worth_saving++;	/* useful data now exists */
 
+#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)
+
+        /* Start the timer here */
+        realtime_data.realtime = (time_t)0L;
+
+#if defined(BSD) && !defined(POSIX_TYPES)
+        (void) time((long *)&realtime_data.restoretime);
+#else
+        (void) time(&realtime_data.restoretime);
+#endif
+
+#endif /* RECORD_REALTIME || REALTIME_ON_BOTL */
+
 	/* Success! */
 	welcome(TRUE);
@@ -567,6 +656,6 @@
 	Sprintf(eos(buf), " %s", genders[currentgend].adj);
 
-    pline(new_game ? "%s %s, welcome to NetHack!  You are a%s %s %s."
-		   : "%s %s, the%s %s %s, welcome back to NetHack!",
+    pline(new_game ? "%s %s, welcome to SporkHack!  You are a%s %s %s."
+		   : "%s %s, the%s %s %s, welcome back to SporkHack!",
 	  Hello((struct monst *) 0), plname, buf, urace.adj,
 	  (currentgend && urole.name.f) ? urole.name.f : urole.name.m);
@@ -629,4 +718,31 @@
 #endif
 
+#if defined(REALTIME_ON_BOTL) || defined (RECORD_REALTIME)
+time_t
+get_realtime(void)
+{
+    time_t curtime;
+
+    /* Get current time */
+#if defined(BSD) && !defined(POSIX_TYPES)
+    (void) time((long *)&curtime);
+#else
+    (void) time(&curtime);
+#endif
+
+    /* Since the timer isn't set until the game starts, this prevents us
+     * from displaying nonsense on the bottom line before it does. */
+    if(realtime_data.restoretime == 0) {
+        curtime = realtime_data.realtime;
+    } else {
+        curtime -= realtime_data.restoretime;
+        curtime += realtime_data.realtime;
+    }
+ 
+    return curtime;
+}
+#endif /* REALTIME_ON_BOTL || RECORD_REALTIME */
+
+
 #endif /* OVLB */
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/apply.c nethack/src/apply.c
--- nh_orig/src/apply.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/apply.c	2009-11-22 07:39:48.196273101 -0500
@@ -16,5 +16,5 @@
 #endif
 STATIC_DCL int FDECL(use_towel, (struct obj *));
-STATIC_DCL boolean FDECL(its_dead, (int,int,int *));
+STATIC_DCL boolean FDECL(its_dead, (int,int,int *,struct obj*));
 STATIC_DCL int FDECL(use_stethoscope, (struct obj *));
 STATIC_DCL void FDECL(use_whistle, (struct obj *));
@@ -27,4 +27,5 @@
 STATIC_DCL void FDECL(use_lamp, (struct obj *));
 STATIC_DCL void FDECL(light_cocktail, (struct obj *));
+STATIC_DCL void FDECL(light_poo, (struct obj *));
 STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
 STATIC_DCL void FDECL(use_figurine, (struct obj **));
@@ -32,4 +33,5 @@
 STATIC_DCL void FDECL(use_trap, (struct obj *));
 STATIC_DCL void FDECL(use_stone, (struct obj *));
+STATIC_DCL void FDECL(apply_flint, (struct obj *));
 STATIC_PTR int NDECL(set_trap);		/* occupation callback */
 STATIC_DCL int FDECL(use_whip, (struct obj *));
@@ -160,6 +162,7 @@
 /* maybe give a stethoscope message based on floor objects */
 STATIC_OVL boolean
-its_dead(rx, ry, resp)
+its_dead(rx, ry, resp, tobj)
 int rx, ry, *resp;
+struct obj* tobj;
 {
 	struct obj *otmp;
@@ -192,4 +195,28 @@
 	    return TRUE;
 	}
+
+	/* listening to eggs is a little fishy, but so is stethoscopes detecting alignment
+	 * The overcomplex wording is because all the monster-naming functions operate
+	 * on actual instances of the monsters, and we're dealing with just an index
+	 * so we can avoid things like "a owlbear", etc. */
+	if (otmp = sobj_at(EGG,rx,ry)) {
+		if (Hallucination) {
+			pline("You listen to the egg and guess... %s?",rndmonnam());
+		} else {
+			if (stale_egg(otmp) || otmp->corpsenm == NON_PM) {
+				pline("The egg doesn't make much noise at all.");
+			} else {
+				pline("You listen to the egg and guess... %s?",mons[otmp->corpsenm].mname);
+			}
+		}
+		return TRUE;
+	}
+
+	/* using a stethoscope on a safe?  You safe-cracker, you. */
+	if (otmp = sobj_at(IRON_SAFE,rx,ry)) {
+		pick_lock(tobj,rx,ry);
+		return TRUE;
+	}
+
 	return FALSE;
 }
@@ -250,5 +277,5 @@
 		    You_cant("reach the %s.",
 			(u.dz > 0) ? surface(u.ux,u.uy) : ceiling(u.ux,u.uy));
-		else if (its_dead(u.ux, u.uy, &res))
+		else if (its_dead(u.ux, u.uy, &res, obj))
 		    ;	/* message already given */
 		else if (Is_stronghold(&u.uz))
@@ -303,5 +330,5 @@
 	}
 
-	if (!its_dead(rx, ry, &res))
+	if (!its_dead(rx, ry, &res, obj))
 	    You("hear nothing special.");	/* not You_hear()  */
 	return res;
@@ -562,6 +589,5 @@
 		    ;	/* still close enough */
 		} else if (otmp->cursed && !breathless(mtmp->data)) {
-		    if (um_dist(mtmp->mx, mtmp->my, 5) ||
-			    (mtmp->mhp -= rnd(2)) <= 0) {
+		    if (um_dist(mtmp->mx, mtmp->my, 5) || damage_mon(mtmp,rnd(2),AD_PHYS)) {
 			long save_pacifism = u.uconduct.killer;
 
@@ -625,5 +651,5 @@
 			      "Yow!  The mirror stares back!" :
 			      "Yikes!  You've frozen yourself!");
-			nomul(-rnd((MAXULEV+6) - u.ulevel));
+			nomul(-rnd((MAXULEV+6) - u.ulevel), "gazing into a mirror");
 			} else You("stiffen momentarily under your gaze.");
 		    } else if (youmonst.data->mlet == S_VAMPIRE)
@@ -789,5 +815,5 @@
 			case 2: /* no explanation; it just happens... */
 				nomovemsg = "";
-				nomul(-rnd(2));
+				nomul(-rnd(2), 0);
 				break;
 		}
@@ -895,5 +921,5 @@
 			(Blind ? "." : " brightly!"));
 	}
-	if (!invocation_pos(u.ux, u.uy)) {
+	if (!invocation_pos(u.ux, u.uy) && u.uevent.invoked) {
 		pline_The("%s %s being rapidly consumed!", s, vtense(s, "are"));
 		obj->age /= 2;
@@ -910,4 +936,34 @@
 }
 
+
+STATIC_OVL void
+light_poo(obj)
+struct obj* obj;
+{
+	char buf[BUFSZ];
+
+	makeknown(obj->otyp);
+	if(Underwater) {
+		pline("Not even -that- will burn here.");
+		return;
+	}
+	if(obj->lamplit) {
+		You("snuff out %s and breathe a little more deeply.", yname(obj));
+		BStealth = 0;
+		end_burn(obj, TRUE);
+		return;
+	}
+	if (obj->age == 0) {
+		pline("This %s is (mostly) empty; what's left won't burn anymore.", xname(obj));
+		return;
+	}
+	check_unpaid(obj);
+	pline("%s %s burns with a dim flame and vile stench.", Shk_Your(buf, obj), xname(obj));
+	begin_burn(obj, FALSE);
+	BStealth = (size_t)obj;
+
+}
+
+
 STATIC_OVL void
 use_candle(optr)
@@ -1009,5 +1065,6 @@
 	if (obj->lamplit) {
 	    if (obj->otyp == OIL_LAMP || obj->otyp == MAGIC_LAMP ||
-		    obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL) {
+		    obj->otyp == BRASS_LANTERN || obj->otyp == POT_OIL ||
+			 obj->otyp == BAG_OF_POO) {
 		(void) get_obj_location(obj, &x, &y, 0);
 		if (obj->where == OBJ_MINVENT ? cansee(x,y) : !Blind)
@@ -1359,7 +1416,12 @@
 
 	    teleds(cc.x, cc.y, TRUE);
-	    nomul(-1);
+	    nomul(-1, "jumping around");
 	    nomovemsg = "";
+		 /* Knights get it for cheaper */
+		 if (Role_if(PM_KNIGHT)) {
+			 morehungry(rnd(10));
+		 } else {
 	    morehungry(rnd(25));
+		 }
 	    return 1;
 	}
@@ -1447,8 +1509,16 @@
 {
 #define PROP_COUNT 6		/* number of properties we're dealing with */
-#define ATTR_COUNT (A_MAX*3)	/* number of attribute points we might fix */
+#define ATTR_COUNT 0	 	/* number of attribute points we might fix */
+
+	/* Changing this to 0 is going to cause people's hair to stand on end.
+	 * The problem is, the spellbook and potion of restore ability are
+	 * absolutely junk at the moment, because the unicorn horn handles 
+	 * it all.  So we can fix that; let the unicorn horn handle
+	 * transitional troubles, and make the player find restore ability
+	 * potions and whatnot for stat abuse/stat drop.  -- DSR 12/02/07 */
+
 	int idx, val, val_limit,
-	    trouble_count, unfixable_trbl, did_prop, did_attr;
-	int trouble_list[PROP_COUNT + ATTR_COUNT];
+	    trouble_count, unfixable_trbl, did_prop;
+	int trouble_list[PROP_COUNT];
 
 	if (obj && obj->cursed) {
@@ -1484,5 +1554,5 @@
 #define attr_trouble(Y) trouble_list[trouble_count++] = attr2trbl(Y)
 
-	trouble_count = unfixable_trbl = did_prop = did_attr = 0;
+	trouble_count = unfixable_trbl = did_prop = 0;
 
 	/* collect property troubles */
@@ -1496,4 +1566,7 @@
 	unfixable_trbl = unfixable_trouble_count(TRUE);
 
+#if 0
+	/*... don't need to fix these anymore */
+
 	/* collect attribute troubles */
 	for (idx = 0; idx < A_MAX; idx++) {
@@ -1509,4 +1582,5 @@
 	    unfixable_trbl += (AMAX(idx) - val_limit);
 	}
+#endif
 
 	if (trouble_count == 0) {
@@ -1563,4 +1637,5 @@
 		break;
 	    default:
+#if 0
 		if (idx >= 0 && idx < A_MAX) {
 		    ABASE(idx) += 1;
@@ -1568,16 +1643,22 @@
 		} else
 		    panic("use_unicorn_horn: bad trouble? (%d)", idx);
+#endif
 		break;
 	    }
 	}
 
+#if 0
 	if (did_attr)
 	    pline("This makes you feel %s!",
 		  (did_prop + did_attr) == (trouble_count + unfixable_trbl) ?
 		  "great" : "better");
-	else if (!did_prop)
+	else
+#endif
+
+	if (!did_prop)
 	    pline("Nothing seems to happen.");
 
-	flags.botl = (did_attr || did_prop);
+	flags.botl = (did_prop);
+
 #undef PROP_COUNT
 #undef ATTR_COUNT
@@ -1703,5 +1784,5 @@
 		if (!quietly)
 		    You("cannot place a figurine in %s!",
-			IS_TREE(levl[x][y].typ) ? "a tree" : "solid rock");
+			IS_TREE(levl[x][y].typ) ? christmas() ? "a christmas tree" : "a tree" : "solid rock");
 		return FALSE;
 	}
@@ -1832,4 +1913,49 @@
 }
 
+/* creating flint arrows - DSR */
+
+STATIC_OVL void
+apply_flint(flint)
+struct obj* flint;
+{
+	struct obj* obj;
+	char szwork[QBUFSZ];
+	int flints, arrows, i;
+	static const char menulist[2] = {WEAPON_CLASS,0};
+
+	flints = flint->quan;
+
+	Sprintf(szwork, "affix the stone%s to", plur(flints));
+	if ((obj = getobj(menulist,szwork)) == 0) {
+		return;
+	}
+
+	/* can only stick flint to arrows */
+	if (obj->otyp < ARROW || obj->otyp > YA) {
+		You("aren't really sure what good that will do.");
+		return;
+	}
+
+	/* can't make MIRV arrows; if they're +1, leave it be */
+	if (obj->spe > 0) {
+		You("don't think you can make these any better than they are.");
+		return;
+	}
+
+	arrows = obj->quan;
+
+	/* One flint stone will do 10 arrows. */
+	if (flints*10 > arrows) {
+		(obj->spe)++;
+		You("lash flint tips to the arrows.");
+		for (i = 0;i <= arrows/10;i++) {
+			useup(flint);
+		}
+	} else {
+		You("don't have enough flint to re-tip all of these.");
+	}
+	return;
+}
+
 /* touchstones - by Ken Arnold */
 STATIC_OVL void
@@ -1839,4 +1965,7 @@
     struct obj *obj;
     boolean do_scratch;
+	 boolean make_sparks;
+	 int i, j;
+	 struct monst* mtmp;
     const char *streak_color, *choices;
     char stonebuf[QBUFSZ];
@@ -1897,4 +2026,5 @@
 
     do_scratch = FALSE;
+	 make_sparks = FALSE;
     streak_color = 0;
 
@@ -1903,4 +2033,7 @@
     case RING_CLASS:
 	if (tstone->otyp != TOUCHSTONE) {
+				if (tstone->otyp == FLINT && objects[obj->otyp].oc_material == IRON) {
+					make_sparks = TRUE;	/* we'll catch it later */
+				} 
 	    do_scratch = TRUE;
 	} else if (obj->oclass == GEM_CLASS && (tstone->blessed ||
@@ -1946,4 +2079,8 @@
 	    streak_color = "silvery";
 	    break;
+				case IRON:
+					if (tstone->otyp == FLINT) {
+						make_sparks = TRUE;
+					}
 	default:
 	    /* Objects passing the is_flimsy() test will not
@@ -1960,9 +2097,59 @@
 
     Sprintf(stonebuf, "stone%s", plur(tstone->quan));
-    if (do_scratch)
+    if (do_scratch) {
+	 	if (!make_sparks) {
 	pline("You make %s%sscratch marks on the %s.",
 	      streak_color ? streak_color : (const char *)"",
 	      streak_color ? " " : "", stonebuf);
-    else if (streak_color)
+		} else if (tstone->otyp == FLINT) {
+			/* Iron and flint make sparks. Non-intelligent creatures
+			 * fear fire.  So anything next to Our Hero(tm) that isn't
+			 * intelligent should have a chance of becoming afraid. */
+			 makeknown(tstone->otyp);
+			 if (u.uinwater) {
+			 	pline("You'd need a flamethrower to make fire here.");
+				return;
+			 }
+			 You("strike a few sparks from the flint stone!");
+			 if (u.uswallow) {
+				/* Not even the thing you're inside can see your piddly spark. */
+			 	pline("That's not going to make it any brighter in here.");
+				if (!rn2(3)) {
+					Your("flint stone crumbles!");
+					useup(tstone);
+				}
+				return;
+			 }
+
+			 for (i = u.ux-1;i < u.ux+2;i++) {
+			 	for (j = u.uy-1;j < u.uy+2;j++) {
+					if (!isok(i,j)) {
+						continue;
+					}
+					mtmp = m_at(i,j);
+					/* blind monsters can't see it */
+					if (!mtmp || mtmp->mblinded || !haseyes(mtmp->data)) {
+						continue;
+					}
+					/* only some things will be scared:
+					 * animals and undead fear fire, but
+					 * not if they're fire resistant, sufficiently powerful,
+					 * gigantic (purple worm), or currently in water */
+					if ((is_animal(mtmp->data) || is_undead(mtmp->data)) &&
+						!(resists_fire(mtmp) || mtmp->data->mcolor == CLR_MAGENTA ||
+							mtmp->data->msize == MZ_GIGANTIC || is_pool(i,j))) {
+						if (rn2(3)) {
+							monflee(mtmp,rnd(10), TRUE, TRUE);
+						}
+					}	
+				}
+			}
+			if (!rn2(3)) {
+				Your("flint stone crumbles!");
+				useup(tstone);
+			}
+			return;
+		}
+	 } else if (streak_color)
 	pline("You see %s streaks on the %s.", streak_color, stonebuf);
     else
@@ -2247,4 +2434,18 @@
 	   map_invisible(rx, ry);
 	}
+	/* Disciplining your pets? */
+	if (mtmp->mtame) {
+		pline("You severely beat %s!",y_monnam(mtmp));
+		abuse_dog(mtmp);
+		return 1;
+	}
+	/* invitation to a little S&M perhaps? */
+	if (mtmp->data == &mons[PM_SUCCUBUS] || mtmp->data == &mons[PM_INCUBUS]) {
+		pline("As you crack the whip, %s winks at you.",mon_nam(mtmp));
+		if (!Upolyd && mtmp->female != flags.female) {
+			mattacku(mtmp);
+		}
+		return 1;
+	}
 	otmp = MON_WEP(mtmp);	/* can be null */
 	if (otmp) {
@@ -2386,6 +2587,12 @@
 	/* Prompt for a location */
 	pline(where_to_hit);
+	if (polemonst && !DEADMONSTER(polemonst)) {
+		cc.x = polemonst->mx;
+		cc.y = polemonst->my;
+	} else {
+		polemonst = 0;	 /* reset this since it's either already 0 or should be */
 	cc.x = u.ux;
 	cc.y = u.uy;
+	}
 	if (getpos(&cc, TRUE, "the spot to hit") < 0)
 	    return 0;	/* user pressed ESC */
@@ -2416,4 +2623,5 @@
 	    int oldhp = mtmp->mhp;
 
+		 polemonst = mtmp;
 	    bhitpos = cc;
 	    check_caitiff(mtmp);
@@ -2425,4 +2633,5 @@
 	    if (mtmp->mhp < oldhp)
 		u.uconduct.weaphit++;
+		 if (DEADMONSTER(mtmp)) polemonst = 0;	 /* clean up pre-emptively */
 	} else
 	    /* Now you know that nothing is there... */
@@ -2680,4 +2889,5 @@
     case WAN_TELEPORTATION:
     case WAN_UNDEAD_TURNING:
+	 case WAN_WIND:
 	affects_objects = TRUE;
 	break;
@@ -2751,5 +2961,5 @@
     if (obj)
 	delobj(obj);
-    nomul(0);
+    nomul(0, 0);
     return 1;
 }
@@ -2782,9 +2992,11 @@
 	struct obj *obj;
 	register int res = 1;
+	int breakchance;
+	char eroded[256];
 	char class_list[MAXOCLASSES+2];
 
 	if(check_capacity((char *)0)) return (0);
 
-	if (carrying(POT_OIL) || uhave_graystone())
+	if (carrying(FLINT) || carrying(POT_OIL) || uhave_graystone())
 		Strcpy(class_list, tools_too);
 	else
@@ -2827,7 +3039,9 @@
 	case CHEST:
 	case ICE_BOX:
+	case SMALL_SACK:
 	case SACK:
 	case BAG_OF_HOLDING:
 	case OILSKIN_SACK:
+	case IRON_SAFE:
 		res = use_container(obj, 1);
 		break;
@@ -2835,4 +3049,7 @@
 		bagotricks(obj);
 		break;
+	case BAG_OF_POO:
+		light_poo(obj);
+		break;
 	case CAN_OF_GREASE:
 		use_grease(obj);
@@ -2843,5 +3060,5 @@
 #endif
 	case SKELETON_KEY:
-		(void) pick_lock(obj);
+		(void) pick_lock(obj,0,0);
 		break;
 	case PICK_AXE:
@@ -2997,7 +3214,14 @@
 		break;
 	case FLINT:
+		if (Role_if(PM_CAVEMAN)) {
+			apply_flint(obj);
+		} else {
+			use_stone(obj);
+		}
+		break;
 	case LUCKSTONE:
 	case LOADSTONE:
 	case TOUCHSTONE:
+	case SALT_CHUNK:
 		use_stone(obj);
 		break;
@@ -3013,9 +3237,38 @@
 		pline("Sorry, I don't know how to use that.");
 	xit:
-		nomul(0);
+		nomul(0, 0);
 		return 0;
 	}
 	if (res && obj && obj->oartifact) arti_speak(obj);
-	nomul(0);
+	nomul(0, 0);
+	
+	/* Tools that aren't in perfect condition might break... 
+	 * ...but only tools, not the weapons */
+	if (obj && !obj->oerodeproof && obj->otyp != BULLWHIP && 
+			!is_pole(obj) && !is_pick(obj) && !obj->oartifact) {	 /* don't break the Key */
+		breakchance = obj->blessed ? 100 : obj->cursed ? 5 : 10;
+		if (rn2(breakchance) < greatest_erosion(obj)) {
+			Strcpy(eroded,"");
+			add_erosion_words(obj,(char*)eroded);
+			Strcat(eroded,xname(obj));
+			pline("Your %s breaks!",eroded);
+			if (Has_contents(obj)) {
+				struct obj* octmp;
+				struct obj* tobj;
+				pline("The contents spill out everywhere!");
+				for (octmp = obj->cobj; octmp; octmp = tobj) {
+					tobj = octmp->nobj;
+					obj_extract_self(octmp);
+					if (!flooreffects(octmp,u.ux,u.uy,"falls")) {
+						place_object(octmp,u.ux,u.uy);
+						stackobj(octmp);
+					}
+				}
+			}
+			useup(obj);
+			return res;
+		}
+	}
+
 	return res;
 }
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/artifact.c nethack/src/artifact.c
--- nh_orig/src/artifact.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/artifact.c	2009-11-22 07:19:36.314397844 -0500
@@ -17,4 +17,7 @@
  */
 
+/*#define DEBUG*/
+/* Uncomment for some complaint messages */
+
 extern boolean notonhead;	/* for long worms */
 
@@ -64,7 +67,16 @@
 		art->alignment = alignmnt;
 
-	/* Excalibur can be used by any lawful character, not just knights */
-	if (!Role_if(PM_KNIGHT))
+	/* Excalibur can be used by any lawful character, not just knights
+		So can Dirge, for that matter */
+	if (!Role_if(PM_KNIGHT)) {
 	    artilist[ART_EXCALIBUR].role = NON_PM;
+		 artilist[ART_DIRGE].role = NON_PM;
+	 }
+
+	/* Demonbane should always be in the Priest's list of available toys
+	 * even though this might look a little odd when it comes out Chaotic */
+	if (Role_if(PM_PRIEST)) {
+		artilist[ART_DEMONBANE].alignment = alignmnt;
+	}
 
 	/* Fix up the quest artifact */
@@ -283,4 +295,10 @@
 #ifdef OVLB
 
+/*
+ * ...Side effect of allowing Sting produces the famous artinaming bug.
+ * We can fix this; naming something an artifact name for an artifact that is
+ * SPFX_RESTR should produce an outright failure.
+ */
+
 boolean
 restrict_name(otmp, name)  /* returns 1 if name is restricted for otmp->otyp */
@@ -299,10 +317,9 @@
 		 */
 	for (a = artilist+1; a->otyp; a++) {
-	    if (a->otyp != otmp->otyp) continue;
 	    aname = a->name;
 	    if (!strncmpi(aname, "the ", 4)) aname += 4;
-	    if (!strcmp(aname, name))
-		return ((boolean)((a->spfx & (SPFX_NOGEN|SPFX_RESTR)) != 0 ||
-			otmp->quan > 1L));
+	    if (!strcmp(aname, name)) {
+			return ((boolean)((a->spfx & (SPFX_NOGEN|SPFX_RESTR)) != 0 || otmp->quan > 1L));
+		 }
 	}
 
@@ -328,7 +345,60 @@
 {
 	register const struct artifact *weap;
+	unsigned long mask;
 
-	if ((weap = get_artifact(otmp)) != 0)
-		return((boolean)(weap->defn.adtyp == adtyp));
+	if ((weap = get_artifact(otmp)) != 0) {
+		switch (adtyp) {
+			case AD_FIRE:
+				mask = (weap->defn & SPDF_FIRE);
+				break;
+			case AD_COLD:
+				mask = (weap->defn & SPDF_COLD);
+				break;
+			case AD_ELEC:
+				mask = (weap->defn & SPDF_ELEC);
+				break;
+			case AD_SLEE:
+				mask = (weap->defn & SPDF_SLEEP);
+				break;
+			case AD_DISN:
+				mask = (weap->defn & SPDF_DISINT);
+				break;
+			case AD_DRST:
+				mask = (weap->defn & SPDF_POISON);
+				break;
+			case AD_ACID:
+				mask = (weap->defn & SPDF_ACID);
+				break;
+			case AD_MAGM:
+				mask = (weap->defn & SPDF_MAGIC);
+				break;
+			case AD_BLND:
+				mask = (weap->defn & SPDF_BLIND);
+				break;
+			case AD_WERE:
+				mask = (weap->defn & SPDF_WERE);
+				break;
+			case AD_DRLI:
+				mask = (weap->defn & SPDF_DRAIN);
+				break;
+			case AD_STUN:
+				mask = (weap->defn & SPDF_STUN);
+				break;
+			case AD_CONF:
+				mask = (weap->defn & SPDF_CONFUSE);
+				break;
+			case AD_DISE:
+			case AD_DRIN:
+				mask = 0;	/* none yet */
+				break;
+			default:
+#ifdef DEBUG
+				/* Don't whine about this unless we really want to */
+				pline("strange attack type in defends(): %d",adtyp);
+#endif
+				return FALSE;
+		}
+		return (mask > 0);  /* straight cast will fail */
+	}
 	return FALSE;
 }
@@ -364,6 +434,6 @@
 	if (!oart) return;
 
-	/* effects from the defn field */
-	dtyp = (wp_mask != W_ART) ? oart->defn.adtyp : oart->cary.adtyp;
+	/* effects from the cary field */
+	dtyp = (wp_mask != W_ART) ? 0 : oart->cary.adtyp;
 
 	if (dtyp == AD_FIRE)
@@ -398,4 +468,59 @@
 	}
 
+	/* effects from the defn field; could be more than one
+		...Note that we don't have to check for other stuff, because
+		this uses wp_mask directly and you can only have one of 
+		any given thing in the appropriate slot */
+	if (wp_mask & (W_WEP | W_ARMOR | W_AMUL | W_RING | W_TOOL)) {
+		if (oart->defn & SPDF_FIRE) {
+			if (on) EFire_resistance |= wp_mask;
+			else EFire_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_COLD) {
+			if (on) ECold_resistance |= wp_mask;
+			else ECold_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_ELEC) {
+			if (on) EShock_resistance |= wp_mask;
+			else EShock_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_SLEEP) {
+			if (on) ESleep_resistance |= wp_mask;
+			else ESleep_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_POISON) {
+			if (on) EPoison_resistance |= wp_mask;
+			else EPoison_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_ACID) {
+			if (on) EAcid_resistance |= wp_mask;
+			else EAcid_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_DISINT) {
+			if (on) EDisint_resistance |= wp_mask;
+			else EDisint_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_DRAIN) {
+			if (on) EDrain_resistance |= wp_mask;
+			else EDrain_resistance &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_MAGIC) {
+			if (on) EAntimagic |= wp_mask;
+			else EAntimagic &= ~wp_mask;
+		}
+		if (oart->defn & SPDF_WERE) {
+			/* Doesn't have a specific resistance in the table */
+		}
+		if (oart->defn & SPDF_BLIND) {
+			/* Doesn't have a specific resistance in the table */
+		}
+		if (oart->defn & SPDF_CONFUSE) {
+			/* Doesn't have a specific resistance in the table */
+		}
+		if (oart->defn & SPDF_STUN) {
+			/* Doesn't have a specific resistance in the table */
+		}
+	}
+
 	/* intrinsics from the spfx field; there could be more than one */
 	spfx = (wp_mask != W_ART) ? oart->spfx : oart->cspfx;
@@ -414,4 +539,8 @@
 	    else ESearching &= ~wp_mask;
 	}
+	if (spfx & SPFX_POLYC) {
+		if (on) EPolymorph_control |= wp_mask;
+		else EPolymorph_control &= ~wp_mask;
+	}
 	if (spfx & SPFX_HALRES) {
 	    /* make_hallucinated must (re)set the mask itself to get
@@ -441,11 +570,21 @@
 	}
 	if (spfx & SPFX_WARN) {
-	    if (spec_m2(otmp)) {
+		/* right now the only things that warn against a specific monster type
+		 * are wielded artifacts.  this may change in the future but for now
+		 * this is probably the smallest change to clean things up without
+		 * screwing around adding more M2 flags */
+		if (spfx & (SPFX_DCLAS | SPFX_DFLAG2)) {
 	    	if (on) {
-			EWarn_of_mon |= wp_mask;
+				if (spfx & SPFX_DCLAS)
+					flags.warntype = oart->mtype;
+				else
 			flags.warntype |= spec_m2(otmp);
+				EWarn_of_mon |= wp_mask;
 	    	} else {
-			EWarn_of_mon &= ~wp_mask;
+				if (spfx & SPFX_DCLAS)
+					flags.warntype = 0L;
+				else
 	    		flags.warntype &= ~spec_m2(otmp);
+				EWarn_of_mon &= ~wp_mask;
 		}
 		see_monsters();
@@ -473,8 +612,17 @@
 	    vision_full_recalc = 1;
 	}
-	if ((spfx & SPFX_REFLECT) && (wp_mask & W_WEP)) {
+	if (spfx & SPFX_REFLECT) {
+		/* Knights only have to carry the mirror; everyone else must wield it */
+		if (Role_if(PM_KNIGHT)) {
+			if (on) {
+				EReflecting |= wp_mask;
+			} else {
+				EReflecting &= ~wp_mask;
+			}
+		} else if (wp_mask & W_WEP) {
 	    if (on) EReflecting |= wp_mask;
 	    else EReflecting &= ~wp_mask;
 	}
+	}
 
 	if(wp_mask == W_ART && !on && oart->inv_prop) {
@@ -595,14 +743,14 @@
 	    switch(weap->attk.adtyp) {
 		case AD_FIRE:
-			return !(yours ? Fire_resistance : resists_fire(mtmp));
+			return !(!yours ? resists_fire(mtmp) : (how_resistant(FIRE_RES) > 99) ? TRUE : FALSE);
 		case AD_COLD:
-			return !(yours ? Cold_resistance : resists_cold(mtmp));
+			return !(!yours ? resists_cold(mtmp) : (how_resistant(COLD_RES) > 99) ? TRUE : FALSE);
 		case AD_ELEC:
-			return !(yours ? Shock_resistance : resists_elec(mtmp));
+			return !(!yours ? resists_elec(mtmp) : (how_resistant(SHOCK_RES) > 99) ? TRUE : FALSE);
 		case AD_MAGM:
 		case AD_STUN:
 			return !(yours ? Antimagic : (rn2(100) < ptr->mr));
 		case AD_DRST:
-			return !(yours ? Poison_resistance : resists_poison(mtmp));
+			return !(!yours ? resists_poison(mtmp) : (how_resistant(POISON_RES) > 99) ? TRUE : FALSE);
 		case AD_DRLI:
 			return !(yours ? Drain_resistance : resists_drli(mtmp));
@@ -651,4 +799,8 @@
 	register const struct artifact *weap = get_artifact(otmp);
 
+	if (otmp->oclass == GEM_CLASS && uwep && uwep->oartifact == ART_GIANTSLAYER) {
+		weap = get_artifact(uwep);
+	}
+
 	if (!weap || (weap->attk.adtyp == AD_PHYS && /* check for `NO_ATTK' */
 			weap->attk.damn == 0 && weap->attk.damd == 0))
@@ -857,5 +1009,5 @@
 		resisted = TRUE;
 	    } else {
-		nomul(-3);
+		nomul(-3, "being scared stiff");
 		nomovemsg = "";
 		if (magr && magr == u.ustuck && sticks(youmonst.data)) {
@@ -949,4 +1101,6 @@
 	static const char you[] = "you";
 	char hittee[BUFSZ];
+	struct artifact* atmp;
+	int j;
 
 	Strcpy(hittee, youdefend ? you : mon_nam(mdef));
@@ -1006,4 +1160,12 @@
 	    return realizes_damage;
 	}
+	/* the fifth basic attack: poison */
+	if (attacks(AD_DRST, otmp)) {
+		if (realizes_damage) {
+			pline_The("venomous blade %s %s%c",spec_dbon_applies ? "strikes" : "nicks",
+				hittee, spec_dbon_applies ? '!' : '.');
+			return realizes_damage;
+		}
+	}
 
 	if (attacks(AD_STUN, otmp) && dieroll <= MB_MAX_DIEROLL) {
@@ -1018,4 +1180,79 @@
 	}
 
+	/* Are we about to do something special vs. a monster type? */
+	atmp = &artilist[otmp->oartifact];
+	if (otmp->oclass == GEM_CLASS && uwep && uwep->oartifact == ART_GIANTSLAYER) {
+		atmp = &artilist[ART_GIANTSLAYER];
+		otmp->oartifact = ART_GIANTSLAYER;	/* really miserable hack */
+	}
+	if (atmp->spfx & (SPFX_DFLAG2 | SPFX_DCLAS)) {
+		j = rn2(2);	  /* 50% chance of instakill for some artifacts */
+		switch (otmp->oartifact) {
+			case ART_DRAGONBANE:
+				if (youattack && j) {
+					You("pierce the heart of %s!", mon_nam(mdef));
+					*dmgptr = (2 * mdef->mhp + FATAL_DAMAGE_MODIFIER);
+				} else if (youdefend && j) {
+					pline("The deadly spear pierces your heart!");
+					*dmgptr = (2 * Upolyd ? u.mh : u.uhp + FATAL_DAMAGE_MODIFIER);
+				} else {
+					return FALSE;
+				}
+				return TRUE;
+			case ART_WEREBANE:
+				if (youattack && j) {
+					*dmgptr = (2 * mdef->mhp + FATAL_DAMAGE_MODIFIER);
+				} else if (youdefend && j) {
+					*dmgptr = (2 * Upolyd ? u.mh : u.uhp + FATAL_DAMAGE_MODIFIER);
+				} else {
+					return FALSE;
+				}
+				return TRUE;
+			case ART_GIANTSLAYER:
+				if (otmp->oclass == GEM_CLASS) {	 /* second part of miserable hack */
+					otmp->oartifact = 0L;
+				}
+				if (youattack) {
+					You("strike %s in the forehead!",mon_nam(mdef));
+					*dmgptr = (2 * mdef->mhp + FATAL_DAMAGE_MODIFIER);
+				} else if (youdefend) {
+					*dmgptr = (2 * Upolyd ? u.mh : u.uhp + FATAL_DAMAGE_MODIFIER);
+					You("are hit in the center of your forehead!");
+				}
+				return TRUE;
+			case ART_OGRESMASHER:
+				if (youattack && j) {
+					You("crush the skull of %s!", mon_nam(mdef));
+					*dmgptr = (2 * mdef->mhp + FATAL_DAMAGE_MODIFIER);
+				} else if (youdefend && j) {
+					pline("The monstrous hammer crushes your skull!");
+					*dmgptr = (2 * Upolyd ? u.mh : u.uhp + FATAL_DAMAGE_MODIFIER);
+				} else {
+					return FALSE;
+				}
+				return TRUE;
+			case ART_TROLLSBANE:
+				if (youattack && j) {
+					pline("As you strike %s, it bursts into flame!", mon_nam(mdef));
+					*dmgptr = (2 * mdef->mhp + FATAL_DAMAGE_MODIFIER);
+				} else if (youdefend && j) {
+					You("burst into flame as you are hit!");
+					*dmgptr = (2 * Upolyd ? u.mh : u.uhp + FATAL_DAMAGE_MODIFIER);
+				} else {
+					return FALSE;
+				}
+				return TRUE;
+			/* below this we don't get any additional handling, so drop through
+			* just listed here for potential future reference */
+			case ART_DEMONBANE:
+			case ART_SUNSWORD:
+			case ART_ORCRIST:
+			case ART_STING:
+			default:
+				break;
+		}
+
+	}
+
 	/* We really want "on a natural 20" but Nethack does it in */
 	/* reverse from AD&D. */
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/attrib.c nethack/src/attrib.c
--- nh_orig/src/attrib.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/attrib.c	2009-11-23 12:02:47.602313145 -0500
@@ -6,4 +6,6 @@
 
 #include "hack.h"
+#include "artifact.h"
+#include "artilist.h"
 
 /* #define DEBUG */	/* uncomment for debugging info */
@@ -187,9 +189,8 @@
 	    if (Upolyd) {
 		u.mh -= 6;
-		u.mhmax -= 6;
 	    } else {
 		u.uhp -= 6;
-		u.uhpmax -= 6;
 	    }
+		 gainmaxhp(-6);
 	}
 	(void) adjattrib(A_STR, -num, TRUE);
@@ -539,4 +540,5 @@
 	register const struct innate *abil, *rabil;
 	long mask = FROMEXPER;
+	int bShowMsgAnyway = 0;
 
 
@@ -571,4 +573,5 @@
 	while (abil || rabil) {
 	    long prevabil;
+		 bShowMsgAnyway = 0;
 	    /* Have we finished with the intrinsics list? */
 	    if (!abil || !abil->ability) {
@@ -581,4 +584,11 @@
 		prevabil = *(abil->ability);
 		if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
+			// Must do this check before we set the FROMEXPER flag
+			if ((*(abil->ability) & TIMEOUT) < 100)
+			{
+				bShowMsgAnyway = 1;
+			}
+
+			if (abil->ulevel == 1)
 			/* Abilities gained at level 1 can never be lost
 			 * via level loss, only via means that remove _any_
@@ -587,9 +597,8 @@
 			 * FROMOUTSIDE to avoid such gains.
 			 */
-			if (abil->ulevel == 1)
 				*(abil->ability) |= (mask|FROMOUTSIDE);
 			else
 				*(abil->ability) |= mask;
-			if(!(*(abil->ability) & INTRINSIC & ~mask)) {
+			if(bShowMsgAnyway || !(*(abil->ability) & INTRINSIC & ~mask)) {
 			    if(*(abil->gainstr))
 				You_feel("%s!", abil->gainstr);
@@ -621,6 +630,5 @@
 newhp()
 {
-	int	hp, conplus;
-
+	int	hp, conplus, tempnum;
 
 	if (u.ulevel == 0) {
@@ -645,4 +653,23 @@
 	    	if (urace.hpadv.hirnd > 0) hp += rnd(urace.hpadv.hirnd);
 	    }
+
+		/* Cavemen get a tiny HP boost if they've remained illiterate,
+			as well as a tiny wisdom boost.  The longer they remain illit,
+			the bigger the HP boost gets (capped at d3) */
+
+		if (Role_if(PM_CAVEMAN)) {
+			tempnum = 0;
+			if (u.uconduct.literate < 1) {
+				if (u.ulevel < 4) {
+					tempnum += 1;
+				} else if (u.ulevel < 8) {
+					tempnum += rnd(2);
+				} else {
+					tempnum += rnd(3);
+				}
+				exercise(A_WIS,TRUE);
+			}
+			hp += tempnum;
+		}
 	}
 
@@ -670,4 +697,8 @@
 	if (x == A_STR) {
 		if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
+		if ((uwep && (artilist[uwep->oartifact].spfx & SPFX_STR)) ||
+				(uswapwep && (artilist[uswapwep->oartifact].spfx & SPFX_STR))) {
+			return (118);
+		}
 #ifdef WIN32_BUG
 		else return(x=((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
@@ -675,4 +706,6 @@
 		else return((schar)((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp));
 #endif
+	} else if (x == A_CON) {
+		if (uwep && (artilist[uwep->oartifact].spfx & SPFX_CON)) return (25);
 	} else if (x == A_CHA) {
 		if (tmp < 18 && (youmonst.data->mlet == S_NYMPH ||
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/ball.c nethack/src/ball.c
--- nh_orig/src/ball.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/ball.c	2009-11-22 07:19:36.355272024 -0500
@@ -558,5 +558,5 @@
 	    You("cannot %sdrag the heavy iron ball.",
 			    invent ? "carry all that and also " : "");
-	    nomul(0);
+	    nomul(0, 0);
 	    return FALSE;
 	}
@@ -596,5 +596,5 @@
 		    newsym(u.ux0, u.uy0);
 		}
-		nomul(0);
+		nomul(0, 0);
 
 		*bc_control = BC_BALL;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/bones.c nethack/src/bones.c
--- nh_orig/src/bones.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/bones.c	2009-08-02 13:49:38.692407855 -0400
@@ -65,9 +65,11 @@
 		    resetobjs(otmp->cobj,restore);
 
-		if (((otmp->otyp != CORPSE || otmp->corpsenm < SPECIAL_PM)
-			&& otmp->otyp != STATUE)
-			&& (!otmp->oartifact ||
-			   (restore && (exist_artifact(otmp->otyp, ONAME(otmp))
-					|| is_quest_artifact(otmp))))) {
+		if (
+			 ((otmp->otyp != CORPSE || otmp->corpsenm < SPECIAL_PM) && 
+				otmp->otyp != STATUE && otmp->otyp != SKULL) && 
+					(!otmp->oartifact || (restore && 
+						(exist_artifact(otmp->otyp, ONAME(otmp)) || 
+							 is_quest_artifact(otmp))))
+				) {
 			otmp->oartifact = 0;
 			otmp->onamelth = 0;
@@ -156,4 +158,9 @@
 #endif
 	if (cont) cont->owt = weight(cont);
+
+	/* should we leave a skull behind? */
+	if (rn2(3) && has_head(youmonst.data) && !unsolid(youmonst.data)) {
+		otmp = mk_named_object(SKULL,youmonst.data,u.ux,u.uy,plname);
+	}
 }
 
@@ -230,7 +237,8 @@
 	    if (mtmp->iswiz || mptr == &mons[PM_MEDUSA] ||
 		    mptr->msound == MS_NEMESIS || mptr->msound == MS_LEADER ||
-		    mptr == &mons[PM_VLAD_THE_IMPALER])
+		    mptr == &mons[PM_VLAD_THE_IMPALER]) {
 		mongone(mtmp);
 	}
+	}
 #ifdef STEED
 	if (u.usteed) dismount_steed(DISMOUNT_BONES);
@@ -246,4 +254,12 @@
 	if (uball) uball->owornmask = uchain->owornmask = 0;
 
+	/* extinguish armor */
+	if(uarm && (uarm->otyp == GOLD_DRAGON_SCALE_MAIL || uarm->otyp == GOLD_DRAGON_SCALES))
+		end_burn(uarm,FALSE);
+
+	if(uarms && uarms->otyp == SHIELD_OF_LIGHT) {
+		end_burn(uarms,FALSE);
+	}
+
 	/* dispose of your possessions, usually cursed */
 	if (u.ugrave_arise == (NON_PM - 1)) {
@@ -261,6 +277,43 @@
 		drop_upon_death((struct monst *)0, (struct obj *)0);
 		/* trick makemon() into allowing monster creation
-		 * on your location
+		 * on your location */
+		if (ukiller) {
+		   /* If you don't rise from your grave (and are thus carrying your stuff),
+			 * the critter that killed you gets some special handling here.
+			 *
+			 * First, he gets to loot your body; if he's a demon lord or prince,
+			 * he will tend to take all the "good stuff".
+			 *
+			 * He also gets a chance to be removed as well -- hitting Yeenybones
+			 * once is not a big deal, but a persistent upper-dungeon Yeeny from 
+			 * an unlucky fountain quaffer would be a bit much.
 		 */
+			struct obj* otmp;
+			struct obj* otmp2;
+			boolean greedy = FALSE;
+
+			/* For now the only actively mean monsters are demon lords/princes */
+			if (is_dlord(ukiller->data) || is_dprince(ukiller->data)) {
+				greedy = TRUE;
+			}
+
+			for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) {
+				otmp2 = otmp->nexthere; /* mpickobj might free otmp */
+				if (!rn2(8) || 
+						(greedy && rn2(2) && (otmp->oartifact || Is_dragon_armor(otmp) ||
+							otmp->otyp == AMULET_OF_LIFE_SAVING || otmp->otyp == AMULET_OF_POWER ||
+							otmp->otyp == MAGIC_MARKER || otmp->otyp == UNICORN_HORN))) {
+					if (!touch_artifact(otmp,ukiller)) continue;
+					if (!can_carry(ukiller,otmp)) continue;
+					obj_extract_self(otmp);
+					mpickobj(ukiller,otmp);
+				}
+			}
+			m_dowear(ukiller, TRUE); /* Let him put them on :) */
+			if (greedy && !rn2(2)) {
+				mongone(ukiller);
+				dmonsfree();		  /* have to call this again */
+			}
+		}
 		in_mklev = TRUE;
 		mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, MM_NONAME);
@@ -293,4 +346,5 @@
 		mtmp->msleeping = 1;
 	}
+
 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
 		resetobjs(mtmp->minvent,FALSE);
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/botl.c nethack/src/botl.c
--- nh_orig/src/botl.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/botl.c	2009-09-07 11:26:05.050309303 -0400
@@ -35,4 +35,87 @@
 #endif
 
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+
+extern const struct percent_color_option *hp_colors;
+extern const struct percent_color_option *pw_colors;
+extern const struct text_color_option *text_colors;
+
+struct color_option
+text_color_of(text, color_options)
+const char *text;
+const struct text_color_option *color_options;
+{
+	if (color_options == NULL) {
+		struct color_option result = {NO_COLOR, 0};
+		return result;
+	}
+	if (strstri(color_options->text, text)
+	 || strstri(text, color_options->text))
+		return color_options->color_option;
+	return text_color_of(text, color_options->next);
+}
+
+struct color_option
+percentage_color_of(value, max, color_options)
+int value, max;
+const struct percent_color_option *color_options;
+{
+	if (color_options == NULL) {
+		struct color_option result = {NO_COLOR, 0};
+		return result;
+	}
+	if (100 * value <= color_options->percentage * max)
+		return color_options->color_option;
+	return percentage_color_of(value, max, color_options->next);
+}
+
+void
+start_color_option(color_option)
+struct color_option color_option;
+{
+	int i;
+	if (color_option.color != NO_COLOR)
+		term_start_color(color_option.color);
+	for (i = 0; (1 << i) <= color_option.attr_bits; ++i)
+		if (i != ATR_NONE && color_option.attr_bits & (1 << i))
+			term_start_attr(i);
+}
+
+void
+end_color_option(color_option)
+struct color_option color_option;
+{
+	int i;
+	if (color_option.color != NO_COLOR)
+		term_end_color(color_option.color);
+	for (i = 0; (1 << i) <= color_option.attr_bits; ++i)
+		if (i != ATR_NONE && color_option.attr_bits & (1 << i))
+			term_end_attr(i);
+}
+
+void
+apply_color_option(color_option, str, x)
+struct color_option color_option;
+const char *str;
+int x;
+{
+	if (x >= CO) return;
+	curs(WIN_STATUS, x, 1);
+	if (iflags.use_status_colors) start_color_option(color_option);
+	putstr(WIN_STATUS, 0, str);
+	if (iflags.use_status_colors) end_color_option(color_option);
+}
+
+void
+add_colored_text(text, x)
+const char *text;
+int x;
+{
+	if (*text == '\0') return;
+	apply_color_option(text_color_of(text, text_colors), text, x);
+}
+
+#endif
+
 #ifndef OVLB
 STATIC_DCL int mrank_sz;
@@ -72,5 +155,4 @@
 	register int i;
 
-
 	/* Find the role */
 	for (role = (struct Role *) roles; role->name.m; role++)
@@ -80,4 +162,9 @@
 	    role = &urole;
 
+	/* Gratuitous hack */
+	if (u.ualign.type == A_CHAOTIC && Role_if(PM_KNIGHT)) {
+		role = &urole;
+	}
+
 	/* Find the rank */
 	for (i = xlev_to_rank((int)lev); i >= 0; i--) {
@@ -166,8 +253,14 @@
 #endif
 
+#ifdef DUMP_LOG
+void bot1str(char *newbot1)
+#else
 STATIC_OVL void
 bot1()
+#endif
 {
+#ifndef DUMP_LOG
 	char newbot1[MAXCO];
+#endif
 	register char *nb;
 	register int i,j;
@@ -216,4 +309,13 @@
 	    Sprintf(nb = eos(nb), " S:%ld", botl_score());
 #endif
+#ifdef DUMP_LOG
+}
+STATIC_OVL void
+bot1()
+{
+	char newbot1[MAXCO];
+
+	bot1str(newbot1);
+#endif
 	curs(WIN_STATUS, 1, 0);
 	putstr(WIN_STATUS, 0, newbot1);
@@ -221,4 +323,15 @@
 
 /* provide the name of the current level for display by various ports */
+const char* short_dgn_names[] = {
+	"Dungeons of Doom",
+	"Gehennom",
+	"Gnomish Mines",
+	"Quest Levels",	 /* Placeholder; this is overridden below */
+	"Sokoban",
+	"Fort Ludios",		 /* this too */
+	"Vlad's Tower",
+	"End Game"			 /* and this */
+};
+
 int
 describe_level(buf)
@@ -237,5 +350,7 @@
 	else {
 		/* ports with more room may expand this one */
-		Sprintf(buf, "Dlvl:%-2d ", depth(&u.uz));
+		Sprintf(buf, "%s:%-2d ", 
+				iflags.show_dgn_name ? short_dgn_names[u.uz.dnum] : "Dlvl",
+				depth(&u.uz));
 		ret = 0;
 	}
@@ -243,11 +358,24 @@
 }
 
+#ifdef DUMP_LOG
+void bot2str(newbot2)
+char* newbot2;
+#else
 STATIC_OVL void
 bot2()
+#endif
 {
+#ifndef DUMP_LOG
 	char  newbot2[MAXCO];
+#endif
 	register char *nb;
 	int hp, hpmax;
 	int cap = near_capacity();
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	struct color_option color_option;
+	int save_botlx = flags.botlx;
+#endif
+
+	int x = 1;
 
 	hp = Upolyd ? u.mh : u.uhp;
@@ -256,43 +384,154 @@
 	if(hp < 0) hp = 0;
 	(void) describe_level(newbot2);
-	Sprintf(nb = eos(newbot2),
-		"%c:%-2ld HP:%d(%d) Pw:%d(%d) AC:%-2d", oc_syms[COIN_CLASS],
+	Sprintf(nb = eos(newbot2), "%c:%-2ld", oc_syms[COIN_CLASS],
 #ifndef GOLDOBJ
-		u.ugold,
+		u.ugold
 #else
-		money_cnt(invent),
+		money_cnt(invent)
 #endif
-		hp, hpmax, u.uen, u.uenmax, u.uac);
+	       );
 
-	if (Upolyd)
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	Strcat(nb = eos(newbot2), " HP:");
+	curs(WIN_STATUS, x, 1);
+	putstr(WIN_STATUS, 0, newbot2);
+	x += strlen(newbot2);
+
+	Sprintf(nb = eos(nb), "%d(%d)", hp, hpmax);
+
+	apply_color_option(percentage_color_of(hp, hpmax, hp_colors), nb, x);
+	x += strlen(nb);
+#else
+	Sprintf(nb = eos(nb), " HP:%d(%d)", hp, hpmax);
+#endif
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	Strcat(nb = eos(nb), " Pw:");
+	curs(WIN_STATUS, x, 1);
+	putstr(WIN_STATUS, 0, nb);
+
+	x += strlen(nb);
+
+	Sprintf(nb = eos(nb), "%d(%d)", u.uen, u.uenmax);
+	apply_color_option(percentage_color_of(u.uen, u.uenmax, pw_colors), nb, x);
+	x += strlen(nb);
+#else
+	Sprintf(nb = eos(nb), " Pw:%d(%d)", u.uen, u.uenmax);
+#endif
+	Sprintf(nb = eos(nb), " AC:%-2d", u.uac);
+	curs(WIN_STATUS, x, 1);
+	putstr(WIN_STATUS, 0, nb);
+	x += strlen(nb);
+	if (Upolyd) {
 		Sprintf(nb = eos(nb), " HD:%d", mons[u.umonnum].mlevel);
+		curs(WIN_STATUS, x, 1);
+		putstr(WIN_STATUS, 0, nb);
+		x += strlen(nb);
+	}
 #ifdef EXP_ON_BOTL
-	else if(flags.showexp)
+	else if(flags.showexp) {
 		Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel,u.uexp);
+		curs(WIN_STATUS, x, 1);
+		putstr(WIN_STATUS, 0, nb);
+		x += strlen(nb);
+	}
 #endif
-	else
+	else {
 		Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
-
-	if(flags.time)
+		curs(WIN_STATUS, x, 1);
+		putstr(WIN_STATUS, 0, nb);
+		x += strlen(nb);
+	}
+	if(flags.time) {
 	    Sprintf(nb = eos(nb), " T:%ld", moves);
+	    curs(WIN_STATUS, x, 1);
+	    putstr(WIN_STATUS, 0, nb);
+	    x += strlen(nb);
+	}
+#ifdef REALTIME_ON_BOTL
+  if(iflags.showrealtime) {
+    time_t currenttime = get_realtime();
+    Sprintf(nb = eos(nb), " %d:%2.2d", currenttime / 3600, (currenttime % 3600) / 60);
+  }
+#endif
+	x++;
 	if(strcmp(hu_stat[u.uhs], "        ")) {
-		Sprintf(nb = eos(nb), " ");
-		Strcat(newbot2, hu_stat[u.uhs]);
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text(hu_stat[u.uhs], x);
+#endif
+	    Sprintf(nb = eos(nb), " %s", hu_stat[u.uhs]);
+	    x += strlen(nb);
+	}
+ 	if(Confusion) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text("Conf", x);
+#endif
+	    Strcat(nb = eos(nb), " Conf");
+	    x += strlen(nb);
 	}
-	if(Confusion)	   Sprintf(nb = eos(nb), " Conf");
 	if(Sick) {
-		if (u.usick_type & SICK_VOMITABLE)
-			   Sprintf(nb = eos(nb), " FoodPois");
-		if (u.usick_type & SICK_NONVOMITABLE)
-			   Sprintf(nb = eos(nb), " Ill");
+	    if (u.usick_type & SICK_VOMITABLE) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+		add_colored_text("FoodPois", x);
+#endif
+		Strcat(nb = eos(nb), " FoodPois");
+		x += strlen(nb);
 	}
-	if(Blind)	   Sprintf(nb = eos(nb), " Blind");
-	if(Stunned)	   Sprintf(nb = eos(nb), " Stun");
-	if(Hallucination)  Sprintf(nb = eos(nb), " Hallu");
-	if(Slimed)         Sprintf(nb = eos(nb), " Slime");
-	if(cap > UNENCUMBERED)
+	    if (u.usick_type & SICK_NONVOMITABLE) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+		add_colored_text("Ill", x);
+#endif
+		Strcat(nb = eos(nb), " Ill");
+		x += strlen(nb);
+	    }
+	}
+	if(Slow) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text("Slow", x);
+#endif
+	    Strcat(nb = eos(nb)," Slow");
+	    x += strlen(nb);
+	}
+	if(Blind) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text("Blind", x);
+#endif
+	    Strcat(nb = eos(nb), " Blind");
+	    x += strlen(nb);
+	}
+	if(Stunned) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text("Stun", x);
+#endif
+	    Strcat(nb = eos(nb), " Stun");
+	    x += strlen(nb);
+	}
+	if(Slimed) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text("Slime", x);
+#endif
+	    Strcat(nb = eos(nb), " Slime");
+	    x += strlen(nb);
+	}
+	if(cap > UNENCUMBERED) {
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	    add_colored_text(enc_stat[cap], x);
+	    flags.botlx = save_botlx;
+#endif
 		Sprintf(nb = eos(nb), " %s", enc_stat[cap]);
+	    x += strlen(nb);
+	}
+#ifdef DUMP_LOG
+}
+STATIC_OVL void
+bot2()
+{
+	char newbot2[MAXCO];
+	bot2str(newbot2);
+#endif
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+#else
 	curs(WIN_STATUS, 1, 1);
 	putstr(WIN_STATUS, 0, newbot2);
+#endif
 }
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/cmd.c nethack/src/cmd.c
--- nh_orig/src/cmd.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/cmd.c	2010-05-13 09:22:21.980839635 -0400
@@ -96,4 +96,5 @@
 extern int NDECL(dowield); /**/
 extern int NDECL(dowieldquiver); /**/
+extern int NDECL(dowieldlauncher); /**/
 extern int NDECL(dozap); /**/
 extern int NDECL(doorganize); /**/
@@ -110,4 +111,5 @@
 STATIC_PTR int NDECL(dotravel);
 # ifdef WIZARD
+int NDECL(wiz_show_rooms);
 STATIC_PTR int NDECL(wiz_wish);
 STATIC_PTR int NDECL(wiz_identify);
@@ -124,4 +126,6 @@
 STATIC_PTR int NDECL(wiz_mon_polycontrol);
 STATIC_PTR int NDECL(wiz_show_wmodes);
+STATIC_PTR int NDECL(wiz_mazewalkmap);
+extern char SpLev_Map[COLNO][ROWNO];
 #if defined(__BORLANDC__) && !defined(_WIN32)
 extern void FDECL(show_borlandc_stats, (winid));
@@ -479,4 +483,8 @@
 enter_explore_mode()
 {
+	/* Solely changed due to public-serverness. */
+	pline("Explore mode has been deactivated.  Sorry.");
+	return 0;
+
 	if(!discover && !wizard) {
 		pline("Beware!  From explore mode there will be no return to normal game.");
@@ -496,4 +504,51 @@
 #ifdef WIZARD
 
+int
+wiz_fliplevel()
+{
+    int f = rnd(3);
+    flip_level(f);
+    if (f & 1) u.uy = (ROWNO-1) - u.uy;
+    if (f & 2) u.ux = (COLNO-1) - u.ux;
+    clear_nhwindow(WIN_MAP);
+    vision_recalc(2);
+    vision_reset();
+    vision_full_recalc = 1;
+    vision_recalc(0);
+    docrt();
+    return 0;
+}
+
+int
+wiz_show_rooms()
+{
+    winid win;
+    int x,y;
+    char row[COLNO+1];
+    struct rm*lev;
+
+    win = create_nhwindow(NHW_TEXT);
+    for (y = 0; y < ROWNO; y++) {
+	for (x = 0; x < COLNO; x++) {
+	    int rno = levl[x][y].roomno;
+	    if (rno == NO_ROOM)
+		row[x] = '.';
+	    else if (rno == SHARED)
+		row[x] = '+';
+	    else if (rno == SHARED_PLUS)
+		row[x] = '*';
+	    else {
+		int i = (rno - ROOMOFFSET) % 52;
+		row[x] = (i < 26) ? ('a'+i) : ('A'+i-26);
+	    }
+	}
+	row[COLNO] = '\0';
+	putstr(win, 0, row);
+    }
+    display_nhwindow(win, TRUE);
+    destroy_nhwindow(win);
+    return 0;
+}
+
 /* ^W command - wish for something */
 STATIC_PTR int
@@ -527,13 +582,75 @@
 	if (wizard) {
 	    struct trap *t;
+	    winid win;
+	    menu_item *pick_list = (menu_item *)0;
+	    anything any;
+	    int n;
 	    long save_Hconf = HConfusion,
 		 save_Hhallu = HHallucination;
 
 	    HConfusion = HHallucination = 0L;
+
+	    win = create_nhwindow(NHW_MENU);
+	    start_menu(win);
+
+	    any.a_void = 0;
+	    any.a_int = 'm'; add_menu(win, NO_GLYPH, &any, 'm', 0, ATR_NONE, "Show map", MENU_UNSELECTED);
+	    any.a_int = 's'; add_menu(win, NO_GLYPH, &any, 's', 0, ATR_NONE, "Show secret doors", MENU_UNSELECTED);
+	    any.a_int = 't'; add_menu(win, NO_GLYPH, &any, 't', 0, ATR_NONE, "Show traps", MENU_UNSELECTED);
+	    any.a_int = 'i'; add_menu(win, NO_GLYPH, &any, 'i', 0, ATR_NONE, "Show items", MENU_UNSELECTED);
+	    any.a_int = 'M'; add_menu(win, NO_GLYPH, &any, 'M', 0, ATR_NONE, "Show monsters", MENU_UNSELECTED);
+	    any.a_int = 'A'; add_menu(win, NO_GLYPH, &any, 'A', 0, ATR_NONE, "All of the above", MENU_UNSELECTED);
+
+	    end_menu(win, "Reveal what");
+
+	    n = select_menu(win, PICK_ANY, &pick_list);
+	    destroy_nhwindow(win);
+	    if (n > 0) {
+		int idx;
+		for (idx = 0; idx < n; idx++) {
+		    if (pick_list[idx].item.a_int == 'm') {
+			do_mapping();
+		    } else if (pick_list[idx].item.a_int == 's') {
+			int x,y;
+			for (x = 0; x < COLNO; x++)
+			    for (y = 0; y < ROWNO; y++)
+				if (levl[x][y].typ == SDOOR) {
+				    cvt_sdoor_to_door(&levl[x][y]);
+				    magic_map_background(x, y, 0);
+				    newsym(x, y);
+				}
+		    } else if (pick_list[idx].item.a_int == 't') {
 	    for (t = ftrap; t != 0; t = t->ntrap) {
 		t->tseen = 1;
 		map_trap(t, TRUE);
 	    }
+		    } else if (pick_list[idx].item.a_int == 'i') {
+			object_detect(NULL, 0);
+		    } else if (pick_list[idx].item.a_int == 'M') {
+			if (HDetect_monsters < 1) incr_itimeout(&HDetect_monsters, 10);
+			see_monsters();
+		    } else if (pick_list[idx].item.a_int == 'A') {
+			int x,y;
 	    do_mapping();
+			for (x = 0; x < COLNO; x++)
+			    for (y = 0; y < ROWNO; y++)
+				if (levl[x][y].typ == SDOOR) {
+				    cvt_sdoor_to_door(&levl[x][y]);
+				    magic_map_background(x, y, 0);
+				    newsym(x, y);
+				}
+			for (t = ftrap; t != 0; t = t->ntrap) {
+			    t->tseen = 1;
+			    map_trap(t, TRUE);
+			}
+			object_detect(NULL, 0);
+			if (HDetect_monsters < 1) incr_itimeout(&HDetect_monsters, 10);
+			see_monsters();
+		    }
+		}
+	    }
+
+            free((genericptr_t)pick_list);
+
 	    HConfusion = save_Hconf;
 	    HHallucination = save_Hhallu;
@@ -593,5 +710,5 @@
 wiz_level_change()
 {
-    char buf[BUFSZ];
+    char buf[BUFSZ] = "";
     int newlevel;
     int ret;
@@ -633,6 +750,37 @@
 wiz_panic()
 {
+	/*
+	 * Hijacked temporarily to sanity-check the new rnd.c code.
+	 * Uncomment to test on your own machine.
+	 *
+
+	int x;
+	int z[20];
+	double q;
+	FILE* testfile;
+
+	for(x=0;x<20;x++)
+	{
+		z[x] = 0;
+	}
+
+	for(x=0;x<=9999999;x++)
+	{
+		z[rn2(20)]++;
+	}
+
+	testfile = fopen("randtest","w");
+	for(x=0;x<20;x++)
+	{
+		q = ((double)z[x] / (double)9999999) * 100;
+		fprintf(testfile,"%2d: %d (%2.3f%%)\n",x,z[x],q);
+	}
+	fclose(testfile);
+
+	*/
+
 	if (yn("Do you want to call panic() and end your game?") == 'y')
 		panic("crash test.");
+
         return 0;
 }
@@ -859,5 +1007,6 @@
 	else if (u.ualign.record >= -3)	you_have("strayed");
 	else if (u.ualign.record >= -8)	you_have("sinned");
-	else you_have("transgressed");
+	else if (u.ualign.record >= -15) you_have("transgressed");
+	else you_are("a filthy heretic");
 #ifdef WIZARD
 	if (wizard) {
@@ -868,20 +1017,31 @@
 
 	/*** Resistances to troubles ***/
-	if (Fire_resistance) you_are("fire resistant");
-	if (Cold_resistance) you_are("cold resistant");
-	if (Sleep_resistance) you_are("sleep resistant");
-	if (Disint_resistance) you_are("disintegration-resistant");
-	if (Shock_resistance) you_are("shock resistant");
-	if (Poison_resistance) you_are("poison resistant");
+	Sprintf(buf,"%d%% fire resistant",how_resistant(FIRE_RES));
+	if (Fire_resistance) you_are(buf);
+	Sprintf(buf,"%d%% cold resistant",how_resistant(COLD_RES));
+	if (Cold_resistance) you_are(buf);
+	Sprintf(buf,"%d%% sleep resistant",how_resistant(SLEEP_RES));
+	if (Sleep_resistance) you_are(buf);
+	Sprintf(buf,"%d%% disintegration-resistant",how_resistant(DISINT_RES));
+	if (Disint_resistance) you_are(buf);
+	Sprintf(buf,"%d%% shock resistant",how_resistant(SHOCK_RES));
+	if (Shock_resistance) you_are(buf);
+	Sprintf(buf,"%d%% poison resistant",how_resistant(POISON_RES));
+	if (Poison_resistance) you_are(buf);
 	if (Drain_resistance) you_are("level-drain resistant");
 	if (Sick_resistance) you_are("immune to sickness");
 	if (Antimagic) you_are("magic-protected");
 	if (Acid_resistance) you_are("acid resistant");
-	if (Stone_resistance)
-		you_are("petrification resistant");
+	if (Stone_resistance) you_are("petrification resistant");
+	if (Confusion_resistance) you_are("confusion resistant");
+	if (Stun_resistance) you_are("stun resistant");
 	if (Invulnerable) you_are("invulnerable");
 	if (u.uedibility) you_can("recognize detrimental food");
 
 	/*** Troubles ***/
+	if (Vulnerable_fire) you_are("vulnerable to fire");
+	if (Vulnerable_cold) you_are("vulnerable to cold");
+	if (Vulnerable_elec) you_are("vulnerable to electricity");
+	if (Vulnerable_acid) you_are("vulnerable to acid");
 	if (Halluc_resistance)
 		enl_msg("You resist", "", "ed", " hallucinations");
@@ -936,4 +1096,5 @@
 		you_are(buf);
 	}
+	if (Blind_resistance) enl_msg(You_,"resist","resisted"," blindness");
 	if (Undead_warning) you_are("warned of undead");
 	if (Searching) you_have("automatic searching");
@@ -1006,4 +1167,5 @@
 	if (Slow_digestion) you_have("slower digestion");
 	if (Regeneration) enl_msg("You regenerate", "", "d", "");
+	if (Energy_regeneration) you_have("faster energy regeneration");
 	if (u.uspellprot || Protection) {
 	    int prot = 0;
@@ -1037,5 +1199,22 @@
 	if (Unchanging) you_can("not change from your current form");
 	if (Fast) you_are(Very_fast ? "very fast" : "fast");
-	if (Reflecting) you_have("reflection");
+	if (Slow) {
+		Strcpy(buf,"slow");
+#ifdef WIZARD
+		if (wizard)
+			if (ESlow) Sprintf(eos(buf)," (from an item)");
+			else Sprintf(eos(buf)," (%d turns)",HSlow);
+#endif
+		you_are(buf);
+	}
+	if (Reflecting) {
+		Strcpy(buf,"reflection");
+#ifdef WIZARD
+		if (wizard)
+			if (EReflecting) Sprintf(eos(buf)," (from an item)");
+			else Sprintf(eos(buf)," (%d turns)",HReflecting);
+#endif
+		you_have(buf);
+	}
 	if (Free_action) you_have("free action");
 	if (Fixed_abil) you_have("fixed abilities");
@@ -1127,4 +1306,318 @@
 }
 
+#ifdef DUMP_LOG
+void
+dump_enlightenment(final)
+int final;
+{
+	int ltmp;
+	char buf[BUFSZ];
+	char buf2[BUFSZ];
+	const char *enc_stat[] = { /* copied from botl.c */
+	     "",
+	     "burdened",
+	     "stressed",
+	     "strained",
+	     "overtaxed",
+	     "overloaded"
+	};
+	char *youwere = "  You were ";
+	char *youhave = "  You have ";
+	char *youhad  = "  You had ";
+	char *youcould = "  You could ";
+
+	dump("", "Final attributes");
+
+#ifdef ELBERETH
+	if (u.uevent.uhand_of_elbereth) {
+	    static const char * const hofe_titles[3] = {
+				"the Hand of Elbereth",
+				"the Envoy of Balance",
+				"the Glory of Arioch"
+	    };
+	    dump(youwere,
+		(char *)hofe_titles[u.uevent.uhand_of_elbereth - 1]);
+	}
+#endif
+
+	if (u.ualign.record >= 20)
+		dump(youwere, "piously aligned");
+	else if (u.ualign.record > 13)
+	    dump(youwere, "devoutly aligned");
+	else if (u.ualign.record > 8)
+	    dump(youwere, "fervently aligned");
+	else if (u.ualign.record > 3)
+	    dump(youwere, "stridently aligned");
+	else if (u.ualign.record == 3)
+	    dump(youwere, "aligned");
+	else if (u.ualign.record > 0)
+	    dump(youwere, "haltingly aligned");
+	else if (u.ualign.record == 0)
+	    dump(youwere, "nominally aligned");
+	else if (u.ualign.record >= -3)	dump(youhave, "strayed");
+	else if (u.ualign.record >= -8)	dump(youhave, "sinned");
+	else if (u.ualign.record >= -15) dump(youhave, "transgressed");
+	else dump("  You are ", "a filthy heretic");
+	Sprintf(buf, " %d", u.ualign.record);
+	dump("  Your alignment was ", buf);
+
+
+	/*** Resistances to troubles ***/
+	Sprintf(buf,"%d%% fire resistant",how_resistant(FIRE_RES));
+	if (Fire_resistance) dump(youwere,buf);
+	Sprintf(buf,"%d%% cold resistant",how_resistant(COLD_RES));
+	if (Cold_resistance) dump(youwere,buf);
+	Sprintf(buf,"%d%% sleep resistant",how_resistant(SLEEP_RES));
+	if (Sleep_resistance) dump(youwere,buf);
+	Sprintf(buf,"%d%% disintegration-resistant",how_resistant(DISINT_RES));
+	if (Disint_resistance) dump(youwere,buf);
+	Sprintf(buf,"%d%% shock resistant",how_resistant(SHOCK_RES));
+	if (Shock_resistance) dump(youwere,buf);
+	Sprintf(buf,"%d%% poison resistant",how_resistant(POISON_RES));
+	if (Poison_resistance) dump(youwere,buf);
+	if (Drain_resistance) dump(youwere, "level-drain resistant");
+	if (Sick_resistance) dump(youwere, "immune to sickness");
+	if (Antimagic) dump(youwere, "magic-protected");
+	if (Acid_resistance) dump(youwere, "acid resistant");
+	if (Stone_resistance) dump(youwere, "petrification resistant");
+	if (Confusion_resistance) dump(youwere, "confusion resistant");
+	if (Stun_resistance) dump(youwere, "stun resistant");
+	if (Invulnerable) dump(youwere, "invulnerable");
+	if (u.uedibility) dump(youcould, "recognize detrimental food");
+
+	/*** Troubles ***/
+	if (Halluc_resistance) 	dump("  ", "You resisted hallucinations");
+	if (Vulnerable_fire) dump(youwere,"vulnerable to fire");
+	if (Vulnerable_cold) dump(youwere,"vulnerable to cold");
+	if (Vulnerable_elec) dump(youwere,"vulnerable to electricity");
+	if (Vulnerable_acid) dump(youwere,"vulnerable to acid");
+	if (Hallucination) dump(youwere, "hallucinating");
+	if (Stunned) dump(youwere, "stunned");
+	if (Confusion) dump(youwere, "confused");
+	if (Blinded) dump(youwere, "blinded");
+	if (Sick) {
+		if (u.usick_type & SICK_VOMITABLE)
+			dump(youwere, "sick from food poisoning");
+		if (u.usick_type & SICK_NONVOMITABLE)
+			dump(youwere, "sick from illness");
+	}
+	if (Stoned) dump(youwere, "turning to stone");
+	if (Slimed) dump(youwere, "turning into slime");
+	if (Strangled)
+		dump(youwere, (u.uburied) ? "buried" : "being strangled");
+	if (Glib) {
+		Sprintf(buf, "slippery %s", makeplural(body_part(FINGER)));
+		dump(youhad, buf);
+	}
+	if (Fumbling) dump("  ", "You fumbled");
+	if (Wounded_legs
+#ifdef STEED
+	    && !u.usteed
+#endif
+			  ) {
+		Sprintf(buf, "wounded %s", makeplural(body_part(LEG)));
+		dump(youhad, buf);
+	}
+#ifdef STEED
+	if (Wounded_legs && u.usteed) {
+	    Strcpy(buf, x_monnam(u.usteed, ARTICLE_YOUR, (char *)0, 
+		    SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION, FALSE));
+	    *buf = highc(*buf);
+	    Strcat(buf, " had wounded legs");
+	    dump("  ", buf);
+	}
+#endif
+	if (Sleeping) dump("  ", "You fell asleep");
+	if (Hunger) dump("  ", "You hungered rapidly");
+
+	/*** Vision and senses ***/
+	if (See_invisible) dump("  ", "You saw invisible");
+	if (Blind_telepat) dump(youwere, "telepathic");
+	if (Warning) dump(youwere, "warned");
+	if (Warn_of_mon && flags.warntype) {
+		Sprintf(buf, "aware of the presence of %s",
+			(flags.warntype & M2_ORC) ? "orcs" :
+			(flags.warntype & M2_DEMON) ? "demons" :
+			something); 
+		dump(youwere, buf);
+	}
+	if (Blind_resistance) dump("  ", "You resisted blindness");
+	if (Undead_warning) dump(youwere, "warned of undead");
+	if (Searching) dump(youhad, "automatic searching");
+	if (Clairvoyant) dump(youwere, "clairvoyant");
+	if (Infravision) dump(youhad, "infravision");
+	if (Detect_monsters)
+	  dump(youwere, "sensing the presence of monsters");
+	if (u.umconf) dump(youwere, "going to confuse monsters");
+
+	/*** Appearance and behavior ***/
+	if (Adornment) {
+	    int adorn = 0;
+	    if(uleft && uleft->otyp == RIN_ADORNMENT) adorn += uleft->spe;
+	    if(uright && uright->otyp == RIN_ADORNMENT) adorn += uright->spe;
+	    if (adorn < 0)
+		dump(youwere, "poorly adorned");
+	    else
+		dump(youwere, "adorned");
+	}
+	if (Invisible) dump(youwere, "invisible");
+	else if (Invis) dump(youwere, "invisible to others");
+	/* ordinarily "visible" is redundant; this is a special case for
+	   the situation when invisibility would be an expected attribute */
+	else if ((HInvis || EInvis || pm_invisible(youmonst.data)) && BInvis)
+	    dump(youwere, "visible");
+	if (Displaced) dump(youwere, "displaced");
+	if (Stealth) dump(youwere, "stealthy");
+	if (Aggravate_monster) dump("  ", "You aggravated monsters");
+	if (Conflict) dump("  ", "You caused conflict");
+
+	/*** Transportation ***/
+	if (Jumping) dump(youcould, "jump");
+	if (Teleportation) dump(youcould, "teleport");
+	if (Teleport_control) dump(youhad, "teleport control");
+	if (Lev_at_will) dump(youwere, "levitating, at will");
+	else if (Levitation)
+	  dump(youwere, "levitating");	/* without control */
+	else if (Flying) dump(youcould, "fly");
+	if (Wwalking) dump(youcould, "walk on water");
+	if (Swimming) dump(youcould, "swim");
+	if (Breathless) dump(youcould, "survive without air");
+	else if (Amphibious) dump(youcould, "breathe water");
+	if (Passes_walls) dump(youcould, "walk through walls");
+#ifdef STEED
+	if (u.usteed && (final < 2 || strcmp(killer, "riding accident"))) {
+	    Sprintf(buf, "riding %s", y_monnam(u.usteed));
+	    dump(youwere, buf);
+	}
+#endif
+	if (u.uswallow) {
+	    Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck));
+#ifdef WIZARD
+	    if (wizard) Sprintf(eos(buf), " (%u)", u.uswldtim);
+#endif
+	    dump(youwere, buf);
+	} else if (u.ustuck) {
+	    Sprintf(buf, "%s %s",
+		    (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",
+		    a_monnam(u.ustuck));
+	    dump(youwere, buf);
+	}
+
+	/*** Physical attributes ***/
+	if (u.uhitinc)
+	    dump(youhad,
+		enlght_combatinc("to hit", u.uhitinc, final, buf));
+	if (u.udaminc)
+	    dump(youhad,
+		enlght_combatinc("damage", u.udaminc, final, buf));
+	if (Slow_digestion) dump(youhad, "slower digestion");
+	if (Regeneration) dump("  ", "You regenerated");
+	if (Energy_regeneration) dump(youhad, "faster energy regeneration");
+	if (u.uspellprot || Protection) {
+	    int prot = 0;
+
+	    if(uleft && uleft->otyp == RIN_PROTECTION) prot += uleft->spe;
+	    if(uright && uright->otyp == RIN_PROTECTION) prot += uright->spe;
+	    if (HProtection & INTRINSIC) prot += u.ublessed;
+	    prot += u.uspellprot;
+	    
+	    if (prot < 0)
+		dump(youwere, "ineffectively protected");
+	    else
+		dump(youwere, "protected");
+	}
+	if (Protection_from_shape_changers)
+		dump(youwere, "protected from shape changers");
+	if (Polymorph) dump(youwere, "polymorphing");
+	if (Polymorph_control) dump(youhad, "polymorph control");
+	if (u.ulycn >= LOW_PM) {
+		Strcpy(buf, an(mons[u.ulycn].mname));
+		dump(youwere, buf);
+	}
+	if (Upolyd) {
+	    if (u.umonnum == u.ulycn) Strcpy(buf, "in beast form");
+	    else Sprintf(buf, "polymorphed into %s",
+			 an(youmonst.data->mname));
+#ifdef WIZARD
+	    if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone);
+#endif
+	    dump(youwere, buf);
+	}
+	if (Unchanging)
+	  dump(youcould, "not change from your current form");
+	if (Fast) dump(youwere, Very_fast ? "very fast" : "fast");
+	if (Reflecting) dump(youhad, "reflection");
+	if (Free_action) dump(youhad, "free action");
+	if (Fixed_abil) dump(youhad, "fixed abilities");
+	if (Lifesaved)
+		dump("  ", "Your life would have been saved");
+	if (u.twoweap) dump(youwere, "wielding two weapons at once");
+
+	/*** Miscellany ***/
+	if (Luck) {
+	    ltmp = abs((int)Luck);
+	    Sprintf(buf, "%s%slucky (%d)",
+		    ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",
+		    Luck < 0 ? "un" : "", Luck);
+	    dump(youwere, buf);
+	}
+#ifdef WIZARD
+	 else if (wizard) dump("  ", "Your luck was zero");
+#endif
+	if (u.moreluck > 0) dump(youhad, "extra luck");
+	else if (u.moreluck < 0) dump(youhad, "reduced luck");
+	if (carrying(LUCKSTONE) || stone_luck(TRUE)) {
+	    ltmp = stone_luck(FALSE);
+	    if (ltmp <= 0)
+		dump("  ", "Bad luck did not time out for you");
+	    if (ltmp >= 0)
+		dump("  ", "Good luck did not time out for you");
+	}
+
+	if (u.ugangr) {
+	    Sprintf(buf, " %sangry with you",
+		u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : "");
+#ifdef WIZARD
+	    if (wizard) Sprintf(eos(buf), " (%d)", u.ugangr);
+#endif
+	    Sprintf(buf2, "%s was %s", u_gname(), buf);
+	    dump("  ", buf2);
+	}
+
+    {
+	const char *p;
+
+	buf[0] = '\0';
+	if (final < 2) {    /* quit/escaped/ascended */
+	    p = "survived after being killed ";
+	    switch (u.umortality) {
+	    case 0:  p = "survived";  break;
+	    case 1:  Strcpy(buf, "once");  break;
+	    case 2:  Strcpy(buf, "twice");  break;
+	    case 3:  Strcpy(buf, "thrice");  break;
+	    default: Sprintf(buf, "%d times", u.umortality);
+		     break;
+	    }
+	} else {		/* game ended in character's death */
+	    p = "are dead";
+	    switch (u.umortality) {
+	    case 0:  impossible("dead without dying?");
+	    case 1:  break;			/* just "are dead" */
+	    default: Sprintf(buf, " (%d%s time!)", u.umortality,
+			     ordin(u.umortality));
+		     break;
+	    }
+	}
+	if (p) {
+	  Sprintf(buf2, "You %s %s", p, buf);
+	  dump("  ", buf2);
+	}
+    }
+	dump("", "");
+	return;
+
+} /* dump_enlightenment */
+#endif
+
 /*
  * Courtesy function for non-debug, non-explorer mode players
@@ -1342,4 +1835,97 @@
 }
 
+#ifdef DUMP_LOG
+void
+dump_conduct(final)
+int final;
+{
+	char buf[BUFSZ];
+	int ngenocided;
+
+	dump("", "Voluntary challenges");
+
+	if (!u.uconduct.food)
+	    dump("", "  You went without food");
+	    /* But beverages are okay */
+	else if (!u.uconduct.unvegan)
+	    dump("", "  You followed a strict vegan diet");
+	else if (!u.uconduct.unvegetarian)
+	    dump("", "  You were a vegetarian");
+	else if (Role_if(PM_MONK) && u.uconduct.unvegetarian < 10) {
+	    sprintf(buf, "  You ate non-vegetarian food %ld time%s.", 
+		u.uconduct.unvegetarian, plur(u.uconduct.unvegetarian));
+	    dump("", buf);
+	}
+
+	if (!u.uconduct.gnostic)
+	    dump("", "  You were an atheist");
+
+	if (!u.uconduct.weaphit)
+	    dump("", "  You never hit with a wielded weapon");
+	else if (Role_if(PM_MONK) && u.uconduct.weaphit < 10) {
+	    Sprintf(buf, "  You hit with a wielded weapon %ld time%s",
+		    u.uconduct.weaphit, plur(u.uconduct.weaphit));
+	    dump("", buf);
+	}
+#ifdef WIZARD
+	else if (wizard) {
+	    Sprintf(buf, "hit with a wielded weapon %ld time%s",
+		    u.uconduct.weaphit, plur(u.uconduct.weaphit));
+	    dump("  You ", buf);
+	}
+#endif
+	if (!u.uconduct.killer)
+	    dump("", "  You were a pacifist");
+
+	if (!u.uconduct.literate)
+	    dump("", "  You were illiterate");
+#ifdef WIZARD
+	else if (wizard) {
+	    Sprintf(buf, "read items or engraved %ld time%s",
+		    u.uconduct.literate, plur(u.uconduct.literate));
+	    dump("  You ", buf);
+	}
+#endif
+
+	ngenocided = num_genocides();
+	if (ngenocided == 0) {
+	    dump("", "  You never genocided any monsters");
+	} else {
+	    Sprintf(buf, "genocided %d type%s of monster%s",
+		    ngenocided, plur(ngenocided), plur(ngenocided));
+	    dump("  You ", buf);
+	}
+
+	if (!u.uconduct.polypiles)
+	    dump("", "  You never polymorphed an object");
+	else {
+	    Sprintf(buf, "polymorphed %ld item%s",
+		    u.uconduct.polypiles, plur(u.uconduct.polypiles));
+	    dump("  You ", buf);
+	}
+
+	if (!u.uconduct.polyselfs)
+	    dump("", "  You never changed form");
+	else {
+	    Sprintf(buf, "changed form %ld time%s",
+		    u.uconduct.polyselfs, plur(u.uconduct.polyselfs));
+	    dump("  You ", buf);
+	}
+
+	if (!u.uconduct.wishes)
+	    dump("", "  You used no wishes");
+	else {
+	    Sprintf(buf, "used %ld wish%s",
+		    u.uconduct.wishes, (u.uconduct.wishes > 1L) ? "es" : "");
+	    dump("  You ", buf);
+
+	    if (!u.uconduct.wisharti)
+		dump("", "  You did not wish for any artifacts");
+	}
+
+	dump("", "");
+}
+#endif /* DUMP_LOG */
+
 #endif /* OVLB */
 #ifdef OVL1
@@ -1470,4 +2056,5 @@
 	{GOLD_SYM, TRUE, doprgold},
 	{SPBOOK_SYM, TRUE, dovspell},			/* Mike Stephenson */
+	{'%', FALSE, dowieldlauncher},
 	{'#', TRUE, doextcmd},
 	{'_', TRUE, dotravel},
@@ -1510,4 +2097,5 @@
 	{(char *)0, (char *)0, donull, TRUE},
 	{(char *)0, (char *)0, donull, TRUE},
+	{(char *)0, (char *)0, donull, TRUE},
 #ifdef DEBUG_MIGRATING_MONS
 	{(char *)0, (char *)0, donull, TRUE},
@@ -1516,4 +2104,5 @@
 	{(char *)0, (char *)0, donull, TRUE},
 	{(char *)0, (char *)0, donull, TRUE},
+	{(char *)0, (char *)0, donull, TRUE},
 #ifdef PORT_DEBUG
 	{(char *)0, (char *)0, donull, TRUE},
@@ -1523,4 +2112,5 @@
 	{(char *)0, (char *)0, donull, TRUE},
 	{(char *)0, (char *)0, donull, TRUE},
+	{(char *)0, (char *)0, donull, TRUE},
 #ifdef DEBUG
 	{(char *)0, (char *)0, donull, TRUE},
@@ -1533,6 +2123,8 @@
 #if defined(WIZARD)
 static const struct ext_func_tab debug_extcmdlist[] = {
+	{"flip_level", "flip level horizontally and/or vertically", wiz_fliplevel, TRUE},
 	{"levelchange", "change experience level", wiz_level_change, TRUE},
 	{"lightsources", "show mobile light sources", wiz_light_sources, TRUE},
+	{"mazewalkmap", "show MAZEWALK paths", wiz_mazewalkmap, TRUE},
 #ifdef DEBUG_MIGRATING_MONS
 	{"migratemons", "migrate n random monsters", wiz_migrate_mons, TRUE},
@@ -1544,4 +2136,5 @@
 	{"portdebug", "wizard port debug command", wiz_port_debug, TRUE},
 #endif
+	{"rooms", "show room numbers", wiz_show_rooms, TRUE},
 	{"seenv", "show seen vectors", wiz_show_seenv, TRUE},
 	{"stats", "show memory statistics", wiz_show_stats, TRUE},
@@ -1698,4 +2291,27 @@
 }
 
+static int
+wiz_mazewalkmap()
+{
+	winid win;
+	int x, y;
+	char row[COLNO+1];
+
+	win = create_nhwindow(NHW_TEXT);
+
+	for (y = 0; y < ROWNO; y++) {
+	    for (x = 0; x < COLNO; x++)
+		row[x] = SpLev_Map[x][y] ? '1' : '.';
+	    if (y == u.uy)
+		row[u.ux] = '@';
+	    row[x] = '\0';
+	    putstr(win, 0, row);
+	}
+	display_nhwindow(win, TRUE);
+	destroy_nhwindow(win);
+	return 0;
+}
+
+
 /*
  * Display memory usage of all monsters and objects on the level.
@@ -1771,5 +2387,5 @@
 {
 	int mcount = 0;
-	char inbuf[BUFSZ];
+	char inbuf[BUFSZ] = "";
 	struct permonst *ptr;
 	struct monst *mtmp;
@@ -2081,5 +2697,7 @@
 {
 	char dirsym;
+	boolean validselection = FALSE;
 
+	while (!validselection) {
 #ifdef REDO
 	if(in_doagain || *readchar_queue)
@@ -2092,7 +2710,8 @@
 	savech(dirsym);
 #endif
-	if(dirsym == '.' || dirsym == 's')
+		if (dirsym == '.' || dirsym == 's') {
 		u.dx = u.dy = u.dz = 0;
-	else if(!movecmd(dirsym) && !u.dz) {
+			validselection = TRUE;
+		} else if(!movecmd(dirsym) && !u.dz) {
 		boolean did_help = FALSE;
 		if(!index(quitchars, dirsym)) {
@@ -2102,7 +2721,12 @@
 		    }
 		    if (!did_help) pline("What a strange direction!");
+			} else {
+				return 0;	/* selected a valid quitchar */
 		}
-		return 0;
+		} else {
+			validselection = TRUE;
 	}
+	}	/* while */
+
 	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir();
 	return 1;
@@ -2243,5 +2867,5 @@
                 cmd[0]=mod == CLICK_1 ? 'q' : M('d');
                 return cmd;
-            } else if(IS_THRONE(levl[u.ux][u.uy].typ)) {
+            } else if(sobj_at(FUR_THRONE,u.ux,u.uy)) {
                 cmd[0]=M('s');
                 return cmd;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dbridge.c nethack/src/dbridge.c
--- nh_orig/src/dbridge.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dbridge.c	2009-08-02 13:49:38.690407629 -0400
@@ -364,9 +364,9 @@
 				Flying || Levitation)) ||
 			is_swimmer(etmp->edata) || is_flyer(etmp->edata) ||
-			is_floater(etmp->edata));
+			is_floater(etmp->edata) || is_flying(etmp->emon));
 	/* must force call to lava_effects in e_died if is_u */
 	if (is_lava(x, y))
 		return (boolean)((is_u(etmp) && (Levitation || Flying)) ||
-			    likes_lava(etmp->edata) || is_flyer(etmp->edata));
+			    likes_lava(etmp->edata) || is_flyer(etmp->edata) || is_flying(etmp->emon));
 	if (is_db_wall(x, y))
 		return((boolean)(is_u(etmp) ? Passes_walls :
@@ -466,5 +466,5 @@
 		return(TRUE);
 
-	if (is_flyer(etmp->edata) &&
+	if ((is_flyer(etmp->edata) || is_flying(etmp->emon)) &&
 	    (is_u(etmp)? !Sleeping :
 	     (etmp->emon->mcanmove && !etmp->emon->msleeping)))
@@ -709,5 +709,5 @@
 		if (e_survives_at(etmp, etmp->ex, etmp->ey)) {
 			if (e_inview && !is_flyer(etmp->edata) &&
-			    !is_floater(etmp->edata))
+			    !is_floater(etmp->edata) && !is_flying(etmp->emon))
 				pline("%s from the bridge.",
 				      E_phrase(etmp, "fall"));
@@ -755,4 +755,8 @@
 	lev1 = &levl[x][y];
 	if (lev1->typ != DRAWBRIDGE_DOWN) return;
+	if (rn2(4)) {
+		pline("The mechanism seems to have something stuck in it and won't close.");
+		return;
+	}
 	x2 = x; y2 = y;
 	get_wall_for_db(&x2,&y2);
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/decl.c nethack/src/decl.c
--- nh_orig/src/decl.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/decl.c	2009-11-22 07:19:36.373272935 -0500
@@ -21,4 +21,5 @@
 
 NEARDATA int multi = 0;
+char multi_txt[BUFSZ] = DUMMY;
 #if 0
 NEARDATA int warnlevel = 0;		/* used by movemon and dochugw */
@@ -138,4 +139,6 @@
 struct mkroom *upstairs_room, *dnstairs_room, *sstairs_room;
 
+struct engr *head_engr;
+
 dlevel_t level;		/* level map */
 struct trap *ftrap = (struct trap *)0;
@@ -144,4 +147,6 @@
 NEARDATA struct instance_flags iflags = DUMMY;
 NEARDATA struct you u = DUMMY;
+NEARDATA struct monst* polemonst = (struct monst*)0;	/* last monster we tried to polearm */
+NEARDATA struct monst* ukiller = (struct monst*)0;		/* The one that got ya */
 
 NEARDATA struct obj *invent = (struct obj *)0,
@@ -149,4 +154,5 @@
 	*uswapwep = (struct obj *)0,
 	*uquiver = (struct obj *)0, /* quiver */
+	*ulauncher = (struct obj *)0, /* def. ranged weapon */
 #ifdef TOURIST
 	*uarmu = (struct obj *)0, /* under-wear, so to speak */
@@ -210,4 +216,13 @@
 NEARDATA struct mvitals mvitals[NUMMONS];
 
+/* originally from end.c */
+#ifdef DUMP_LOG
+#ifdef DUMP_FN
+char dump_fn[] = DUMP_FN;
+#else
+char dump_fn[PL_PSIZ] = DUMMY;
+#endif
+#endif /* DUMP_LOG */
+
 NEARDATA struct c_color_names c_color_names = {
 	"black", "amber", "golden",
@@ -236,4 +251,8 @@
 };
 
+#ifdef MENU_COLOR
+struct menucoloring *menu_colorings = 0;
+#endif
+
 struct c_common_strings c_common_strings = {
 	"Nothing happens.",		"That's enough tries!",
@@ -272,4 +291,12 @@
 #endif
 
+#ifdef RECORD_ACHIEVE
+struct u_achieve achieve = DUMMY;
+#endif
+
+#if defined(RECORD_REALTIME) || defined(REALTIME_ON_BOTL)
+struct realtime_data realtime_data = { 0, 0, 0 };
+#endif
+
 /* dummy routine used to force linkage */
 void
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/detect.c nethack/src/detect.c
--- nh_orig/src/detect.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/detect.c	2010-04-25 13:07:29.306716603 -0400
@@ -298,5 +298,5 @@
     register struct monst *mtmp;
     register int ct = 0, ctu = 0;
-    boolean confused = (Confusion || (sobj && sobj->cursed)), stale;
+    boolean confused = Confusion, stale;
     char oclass = confused ? POTION_CLASS : FOOD_CLASS;
     const char *what = confused ? something : "food";
@@ -695,5 +695,6 @@
     }
     for (obj = fobj; obj; obj = obj->nobj) {
-	if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped) {
+	if ((obj->otyp == LARGE_BOX || obj->otyp == CHEST || obj->otyp == IRON_SAFE) && 
+			obj->otrapped) {
 	    if (obj->ox != u.ux || obj->oy != u.uy)
 		goto outtrapmap;
@@ -726,5 +727,6 @@
 
     for (obj = fobj; obj; obj = obj->nobj)
-	if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
+	if ((obj->otyp == LARGE_BOX || obj->otyp == CHEST || obj->otyp == IRON_SAFE) && 
+			obj->otrapped)
 	sense_trap((struct trap *)0, obj->ox, obj->oy, sobj && sobj->cursed);
 
@@ -862,5 +864,5 @@
     }
     You("peer into %s...", the(xname(obj)));
-    nomul(-rnd(10));
+    nomul(-rnd(10), "gazing into a crystal ball");
     nomovemsg = "";
     if (obj->spe <= 0)
@@ -1104,5 +1106,5 @@
 
 	if(u.uswallow) return(0);
-	do_clear_area(u.ux, u.uy, BOLT_LIM, findone, (genericptr_t) &num);
+	do_clear_area(u.ux, u.uy, 8, findone, (genericptr_t) &num);
 	return(num);
 }
@@ -1122,5 +1124,5 @@
 	}
 
-	do_clear_area(u.ux, u.uy, BOLT_LIM, openone, (genericptr_t) &num);
+	do_clear_area(u.ux, u.uy, 8, openone, (genericptr_t) &num);
 	return(num);
 }
@@ -1192,5 +1194,5 @@
 			cvt_sdoor_to_door(&levl[x][y]);	/* .typ = DOOR */
 			exercise(A_WIS, TRUE);
-			nomul(0);
+			nomul(0, 0);
 			if (Blind && !aflag)
 			    feel_location(x,y);	/* make sure it shows up */
@@ -1202,5 +1204,5 @@
 			unblock_point(x,y);	/* vision */
 			exercise(A_WIS, TRUE);
-			nomul(0);
+			nomul(0, 0);
 			newsym(x,y);
 		    } else {
@@ -1247,5 +1249,5 @@
 
 			if ((trap = t_at(x,y)) && !trap->tseen && !rnl(8)) {
-			    nomul(0);
+			    nomul(0, 0);
 
 			    if (trap->ttyp == STATUE_TRAP) {
@@ -1281,6 +1283,12 @@
 	for (x = 1; x < COLNO; x++)
 	    for (y = 0; y < ROWNO; y++) {
+		if (IS_WALL(levl[x][y].typ))
 	    	levl[x][y].seenv = SVALL;
-	    	levl[x][y].waslit = TRUE;
+		else if (levl[x][y].typ == SDOOR)
+		    levl[x][y].typ = DOOR;
+		else if (levl[x][y].typ == SCORR)
+		    levl[x][y].typ = CORR;
+
+		levl[x][y].waslit = (levl[x][y].typ != CORR) ? (!iflags.dark_room) : levl[x][y].lit;
 	    	map_background(x, y, 1);
 	    	for (obj = level.objects[x][y]; obj; obj = obj->nexthere)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dig.c nethack/src/dig.c
--- nh_orig/src/dig.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dig.c	2009-11-22 07:19:36.405397990 -0500
@@ -174,7 +174,4 @@
 	    } else if(verbose) pline_The("stairs are too hard to %s.", verb);
 	    return(FALSE);
-	} else if (IS_THRONE(levl[x][y].typ) && madeby != BY_OBJECT) {
-	    if(verbose) pline_The("throne is too hard to break apart.");
-	    return(FALSE);
 	} else if (IS_ALTAR(levl[x][y].typ) && (madeby != BY_OBJECT ||
 				Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
@@ -230,5 +227,5 @@
 	    if (IS_TREE(lev->typ) && !may_dig(dpx,dpy) &&
 			dig_typ(uwep, dpx, dpy) == DIGTYP_TREE) {
-		pline("This tree seems to be petrified.");
+		pline("This %stree seems to be petrified.",christmas() ? "christmas " : "");
 		return(0);
 	    }
@@ -305,4 +302,5 @@
 		register struct obj *obj;
 		register boolean shopedge = *in_rooms(dpx, dpy, SHOPBASE);
+		boolean getcoal = FALSE;
 
 		if ((obj = sobj_at(STATUE, dpx, dpy)) != 0) {
@@ -337,5 +335,10 @@
 			}
 			if (IS_TREE(lev->typ)) {
+				if (christmas()) {
+			    digtxt = "You cut down the christmas tree.";
+				 getcoal = TRUE;
+				} else {
 			    digtxt = "You cut down the tree.";
+				}
 			    lev->typ = ROOM;
 			    if (!rn2(5)) (void) rnd_treefruit_at(dpx, dpy);
@@ -381,4 +384,7 @@
 		    newsym(dpx, dpy);
 		if(digtxt && !digging.quiet) pline(digtxt); /* after newsym */
+		if (getcoal) {
+			get_coal();
+		}
 		if(dmgtxt)
 		    pay_for_damage(dmgtxt, FALSE);
@@ -425,5 +431,6 @@
 		    return(0); /* statue or boulder got taken */
 		if(!did_dig_msg) {
-		    You("hit the %s with all your might.",
+		    You("hit the %s%s with all your might.",
+					 (christmas() && dig_target == 5) ? "christmas " : "",
 			d_target[dig_target]);
 		    did_dig_msg = TRUE;
@@ -558,8 +565,8 @@
 			(void) pickup(1);	/* detects pit */
 	    } else if(mtmp) {
-		if(is_flyer(mtmp->data) || is_floater(mtmp->data)) {
+		if(is_flyer(mtmp->data) || is_floater(mtmp->data) || is_flying(mtmp)) {
 		    if(canseemon(mtmp))
 			pline("%s %s over the pit.", Monnam(mtmp),
-						     (is_flyer(mtmp->data)) ?
+						     (is_flyer(mtmp->data) || is_flying(mtmp)) ?
 						     "flies" : "floats");
 		} else if(mtmp != madeby)
@@ -618,5 +625,5 @@
 		     /*[don't we need special sokoban handling here?]*/
 		    if (is_flyer(mtmp->data) || is_floater(mtmp->data) ||
-		        mtmp->data == &mons[PM_WUMPUS] ||
+		        is_flying(mtmp) || mtmp->data == &mons[PM_WUMPUS] ||
 			(mtmp->wormno && count_wsegs(mtmp) > 5) ||
 			mtmp->data->msize >= MZ_HUGE) return;
@@ -735,7 +742,5 @@
 		return TRUE;
 
-	/* the following two are here for the wand of digging */
-	} else if (IS_THRONE(lev->typ)) {
-		pline_The("throne is too hard to break apart.");
+	/* the following is here for the wand of digging */
 
 	} else if (IS_ALTAR(lev->typ)) {
@@ -770,11 +775,11 @@
 	exercise(A_WIS, FALSE);
 	if (Role_if(PM_ARCHEOLOGIST)) {
-	    adjalign(-sgn(u.ualign.type)*3);
+	    minor_sin();
 	    You_feel("like a despicable grave-robber!");
 	} else if (Role_if(PM_SAMURAI)) {
-	    adjalign(-sgn(u.ualign.type));
+	    venial_sin();
 	    You("disturb the honorable dead!");
 	} else if ((u.ualign.type == A_LAWFUL) && (u.ualign.record > -10)) {
-	    adjalign(-sgn(u.ualign.type));
+	    venial_sin();
 	    You("have violated the sanctity of this grave!");
 	}
@@ -917,5 +922,5 @@
 			    /* you ought to be able to let go; tough luck */
 			    /* (maybe `move_into_trap()' would be better) */
-			    nomul(-d(2,2));
+			    nomul(-d(2,2), "stuck in a spider web");
 			    nomovemsg = "You pull free.";
 			} else if (lev->typ == IRONBARS) {
@@ -1046,5 +1051,5 @@
 			str = "door";
 		    else if (IS_TREE(lev->typ))
-			str = "tree";
+			str = christmas() ? "christmas tree" : "tree";
 		    else if (IS_ROCK(lev->typ))
 			str = "wall";
@@ -1238,5 +1243,5 @@
 			unblock_point(zx,zy); /* vision */
 		    } else if (!Blind)
-			pline_The("tree shudders but is unharmed.");
+			pline_The("%stree shudders but is unharmed.",christmas() ? "christmas " : "");
 		    break;
 		} else if (room->typ == STONE || room->typ == SCORR) {
@@ -1441,4 +1446,7 @@
 		uqwepgone();
 		stop_occupation();
+	    } else if (obj == ulauncher) { /* not sure how this would be possible but */
+		ulwepgone();
+		stop_occupation();
 	    }
 	} else if (obj->where == OBJ_MINVENT && obj->owornmask) {
@@ -1554,4 +1562,15 @@
 #endif
 
+void
+get_coal()
+{
+	pline("What a Scrooge! There will surely be consequences...");
+	change_luck(-2);
+	if (!rn2(3)) {
+		pline("The Spirit of Dungeons Past appears before you!");
+		makemon(&mons[PM_SHADE],u.ux,u.uy,MM_ADJACENTOK);
+	}
+}
+
 #ifdef DEBUG
 int
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/display.c nethack/src/display.c
--- nh_orig/src/display.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/display.c	2010-04-11 12:36:57.336750392 -0400
@@ -135,4 +135,7 @@
 STATIC_DCL int FDECL(wall_angle, (struct rm *));
 
+/* needed for warning, now */
+extern const int monstr[];
+
 #ifdef INVISIBLE_OBJECTS
 /*
@@ -180,5 +183,5 @@
 	/* Floor spaces are dark if unlit.  Corridors are dark if unlit. */
 	if (lev->typ == ROOM && glyph == cmap_to_glyph(S_room))
-	    glyph = cmap_to_glyph(S_stone);
+	    glyph = cmap_to_glyph(S_darkroom);
 	else if (lev->typ == CORR && glyph == cmap_to_glyph(S_litcorr))
 	    glyph = cmap_to_glyph(S_corr);
@@ -307,5 +310,5 @@
 	if (!lev->waslit && lev->glyph == cmap_to_glyph(S_room) &&
 							    lev->typ == ROOM)
-	    lev->glyph = cmap_to_glyph(S_stone);
+	    lev->glyph = cmap_to_glyph(S_darkroom);
     } else
 	levl[x][y].glyph = cmap_to_glyph(S_stone);	/* default val */
@@ -458,7 +461,8 @@
 {
     int x = mon->mx, y = mon->my;
-    int wl = (int) (mon->m_lev / 4);
+    int wl = (int)((monstr[mon->mnum] - u.ulevel) / 3) + 3;
     int glyph;
 
+	 if (wl < 1) wl = 1;	/* won't show up right */
     if (mon_warning(mon)) {
         if (wl > WARNCOUNT - 1) wl = WARNCOUNT - 1;
@@ -561,13 +565,12 @@
 		    map_background(x, y, 1);
 		} else {
-		    lev->glyph = lev->waslit ? cmap_to_glyph(S_room) :
-					       cmap_to_glyph(S_stone);
+		    lev->glyph = (!lev->waslit) ? cmap_to_glyph(S_darkroom) : cmap_to_glyph(S_room);
 		    show_glyph(x,y,lev->glyph);
 		}
 	    } else if ((lev->glyph >= cmap_to_glyph(S_stone) &&
-			lev->glyph < cmap_to_glyph(S_room)) ||
+			lev->glyph < cmap_to_glyph(S_darkroom)) ||
 		       glyph_is_invisible(levl[x][y].glyph)) {
-		lev->glyph = lev->waslit ? cmap_to_glyph(S_room) :
-					   cmap_to_glyph(S_stone);
+		lev->glyph = (!cansee(x,y) && !lev->waslit) ? cmap_to_glyph(S_darkroom) :
+					   cmap_to_glyph(S_room);
 		show_glyph(x,y,lev->glyph);
 	    }
@@ -609,5 +612,5 @@
 	if (lev->typ == ROOM &&
 		    lev->glyph == cmap_to_glyph(S_room) && !lev->waslit)
-	    show_glyph(x,y, lev->glyph = cmap_to_glyph(S_stone));
+	    show_glyph(x,y, lev->glyph = cmap_to_glyph(S_darkroom));
 	else if (lev->typ == CORR &&
 		    lev->glyph == cmap_to_glyph(S_litcorr) && !lev->waslit)
@@ -637,4 +640,6 @@
     if (in_mklev) return;
 
+	 if (!isok(x,y)) return;
+
     /* only permit updating the hero when swallowed */
     if (u.uswallow) {
@@ -753,9 +758,9 @@
 	 * They are dependent on the position being out of sight.
 	 */
-	else if (!lev->waslit) {
+	else if (!lev->waslit || (iflags.dark_room && iflags.use_color)) {
 	    if (lev->glyph == cmap_to_glyph(S_litcorr) && lev->typ == CORR)
 		show_glyph(x, y, lev->glyph = cmap_to_glyph(S_corr));
 	    else if (lev->glyph == cmap_to_glyph(S_room) && lev->typ == ROOM)
-		show_glyph(x, y, lev->glyph = cmap_to_glyph(S_stone));
+		show_glyph(x, y, lev->glyph = cmap_to_glyph(S_darkroom));
 	    else
 		goto show_mem;
@@ -887,5 +892,5 @@
 	default:	/* do it */
 	    if (tglyph->style == DISP_BEAM) {
-		if (!cansee(x,y)) break;
+			if (!isok(x,y) || !cansee(x,y)) break;
 		/* save pos for later erasing */
 		tglyph->saved[tglyph->sidx].x = x;
@@ -897,5 +902,5 @@
 		    tglyph->sidx = 0;	/* display is presently up to date */
 		}
-		if (!cansee(x,y) && tglyph->style != DISP_ALWAYS) break;
+			if (isok(x,y) && !cansee(x,y) && tglyph->style != DISP_ALWAYS) break;
 		tglyph->saved[0].x = x;
 		tglyph->saved[0].y = y;
@@ -1219,4 +1224,8 @@
      */
     if (!isok(x, y)) {
+
+		/* Stop crashing the game just because you couldn't draw a character */
+
+#if 0
 	const char *text;
 	int  offset;
@@ -1256,12 +1265,17 @@
 	}
 
-	impossible("show_glyph:  bad pos %d %d with glyph %d [%s %d].",
-						x, y, glyph, text, offset);
+		 impossible("show_glyph:  bad pos %d %d with glyph %d [%s %d].", x, y, glyph, text, offset);
+
+#endif
+
 	return;
     }
 
     if (glyph >= MAX_GLYPH) {
-	impossible("show_glyph:  bad glyph %d [max %d] at (%d,%d).",
-					glyph, MAX_GLYPH, x, y);
+		/*
+		 * Same here.  There's no reason to crash out, just don't show an illegal glyph and move on
+		 *
+		 * impossible("show_glyph:  bad glyph %d [max %d] at (%d,%d).", glyph, MAX_GLYPH, x, y);
+		 */
 	return;
     }
@@ -1371,4 +1385,104 @@
 /* ========================================================================= */
 
+#ifdef DUMP_LOG
+/* D: Added to dump screen to output file */
+STATIC_PTR uchar get_glyph_char(glyph)
+int glyph;
+{
+    uchar   ch;
+    register int offset;
+
+    if (glyph >= NO_GLYPH)
+        return ' ';
+
+    /*
+     *  Map the glyph back to a character.
+     *
+     *  Warning:  For speed, this makes an assumption on the order of
+     *		  offsets.  The order is set in display.h.
+     */
+    if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) {	/* a warning flash */
+	ch = def_warnsyms[offset].sym;
+    } else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {	/* swallow */
+	/* see swallow_to_glyph() in display.c */
+	ch = (uchar) defsyms[S_sw_tl + (offset & 0x7)].sym;
+    } else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {	/* zap beam */
+	/* see zapdir_to_glyph() in display.c */
+	ch = defsyms[S_vbeam + (offset & 0x3)].sym;
+    } else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) {	/* cmap */
+	ch = defsyms[offset].sym;
+    } else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {	/* object */
+	ch = def_oc_syms[(int)objects[offset].oc_class];
+    } else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) { /* mon ridden */
+	ch = def_monsyms[(int)mons[offset].mlet];
+    } else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {	/* a corpse */
+	ch = def_oc_syms[(int)objects[CORPSE].oc_class];
+    } else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) { /* mon detect */
+	ch = def_monsyms[(int)mons[offset].mlet];
+    } else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) {  /* invisible */
+	ch = DEF_INVISIBLE;
+    } else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {	/* a pet */
+	ch = def_monsyms[(int)mons[offset].mlet];
+    } else {						    /* a monster */
+	ch = monsyms[(int)mons[glyph].mlet];
+    }
+    return ch;
+}
+
+#ifdef TTY_GRAPHICS
+extern const char * FDECL(compress_str, (const char *));
+#else
+const char*
+compress_str(str) /* copied from win/tty/wintty.c */
+const char *str;
+{
+	static char cbuf[BUFSZ];
+	/* compress in case line too long */
+	if((int)strlen(str) >= 80) {
+		register const char *bp0 = str;
+		register char *bp1 = cbuf;
+
+		do {
+			if(*bp0 != ' ' || bp0[1] != ' ')
+				*bp1++ = *bp0;
+		} while(*bp0++);
+	} else
+	    return str;
+	return cbuf;
+}
+#endif /* TTY_GRAPHICS */
+
+/* Take a screen dump */
+void dump_screen()
+{
+    register int x,y;
+    int lastc;
+    /* D: botl.c has a closer approximation to the size, but we'll go with
+     *    this */
+    char buf[300], *ptr;
+    
+    for (y = 0; y < ROWNO; y++) {
+	lastc = 0;
+	ptr = buf;
+	for (x = 1; x < COLNO; x++) {
+	    uchar c = get_glyph_char(gbuf[y][x].glyph);
+	    *ptr++ = c;
+	    if (c != ' ')
+		lastc = x;
+	}
+	buf[lastc] = '\0';
+	dump("", buf);
+    }
+    dump("", "");
+    bot1str(buf);
+    ptr = (char *) compress_str((const char *) buf);
+    dump("", ptr);
+    bot2str(buf);
+    dump("", buf);
+    dump("", "");
+    dump("", "");
+}
+#endif /* DUMP_LOG */
+
 /*
  * back_to_glyph()
@@ -1398,5 +1512,7 @@
 	    idx = level.flags.arboreal ? S_tree : S_stone;
 	    break;
-	case ROOM:		idx = S_room;	  break;
+	case ROOM:
+	    idx = (!cansee(x,y) && !ptr->waslit) ? S_darkroom : S_room;
+	    break;
 	case CORR:
 	    idx = (ptr->waslit || flags.lit_corridor) ? S_litcorr : S_corr;
@@ -1441,5 +1557,4 @@
 	case ALTAR:		idx = S_altar;    break;
 	case GRAVE:		idx = S_grave;    break;
-	case THRONE:		idx = S_throne;   break;
 	case LAVAPOOL:		idx = S_lava;	  break;
 	case ICE:		idx = S_ice;      break;
@@ -1455,9 +1570,9 @@
 	    case DB_LAVA:  idx = S_lava; break;
 	    case DB_ICE:   idx = S_ice;  break;
-	    case DB_FLOOR: idx = S_room; break;
+	    case DB_FLOOR: idx = (!cansee(x,y) && !ptr->waslit) ? S_darkroom : S_room; break;
 	    default:
 		impossible("Strange db-under: %d",
 			   ptr->drawbridgemask & DB_UNDER);
-		idx = S_room; /* something is better than nothing */
+		idx = (!cansee(x,y) && !ptr->waslit) ? S_darkroom : S_room; /* something is better than nothing */
 		break;
 	    }
@@ -1468,5 +1583,5 @@
 	default:
 	    impossible("back_to_glyph:  unknown level type [ = %d ]",ptr->typ);
-	    idx = S_room;
+	    idx = (!cansee(x,y) && !ptr->waslit) ? S_darkroom : S_room;
 	    break;
     }
@@ -1557,5 +1672,5 @@
 	"MOAT",		"WATER",	"DRAWBRIDGE_UP","LAVAPOOL",
 	"DOOR",		"CORR",		"ROOM",		"STAIRS",
-	"LADDER",	"FOUNTAIN",	"THRONE",	"SINK",
+	"LADDER",	"FOUNTAIN",			"SINK",
 	"ALTAR",	"ICE",		"DRAWBRIDGE_DOWN","AIR",
 	"CLOUD"
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/do.c nethack/src/do.c
--- nh_orig/src/do.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/do.c	2009-10-23 14:33:39.377272693 -0400
@@ -109,9 +109,7 @@
 		    You("find yourself on dry land again!");
 		} else if (lava && distu(rx,ry) <= 2) {
-		    You("are hit by molten lava%c",
-			Fire_resistance ? '.' : '!');
+		    You("are hit by molten lava%c", (how_resistant(FIRE_RES) > 50) ? '.' : '!');
 			burn_away_slime();
-		    losehp(d((Fire_resistance ? 1 : 3), 6),
-			   "molten lava", KILLED_BY);
+		    losehp(resist_reduce(d(3,6),FIRE_RES), "molten lava", KILLED_BY);
 		} else if (!fills_up && flags.verbose &&
 			   (pushing ? !Blind : cansee(rx,ry)))
@@ -474,4 +472,7 @@
 		setuswapwep((struct obj *)0);
 	}
+	if (obj == ulauncher) {
+		setulauncher((struct obj*)0);
+	}
 
 	if (u.uswallow) {
@@ -540,4 +541,5 @@
 	if (obj == uwep) setuwep((struct obj *)0);
 	if (obj == uquiver) setuqwep((struct obj *)0);
+	if (obj == ulauncher) setulauncher((struct obj *)0);
 	if (obj == uswapwep) setuswapwep((struct obj *)0);
 
@@ -979,22 +981,31 @@
 	/* If you have the amulet and are trying to get out of Gehennom, going
 	 * up a set of stairs sometimes does some very strange things!
-	 * Biased against law and towards chaos, but not nearly as strongly
-	 * as it used to be (prior to 3.2.0).
-	 * Odds:	    old				    new
-	 *	"up"    L      N      C		"up"    L      N      C
-	 *	 +1   75.0   75.0   75.0	 +1   75.0   75.0   75.0
-	 *	  0    0.0   12.5   25.0	  0    6.25   8.33  12.5
-	 *	 -1    8.33   4.17   0.0	 -1    6.25   8.33  12.5
-	 *	 -2    8.33   4.17   0.0	 -2    6.25   8.33   0.0
-	 *	 -3    8.33   4.17   0.0	 -3    6.25   0.0    0.0
+	 *
+	 * No longer biased, because it's bad enough to get zotzed without getting
+	 * absolutely bludgeoned to death by being dropped too many levels.  This
+	 * was really just annoying players to no good effect; Rodney's appearance
+	 * rate is tuned up for Lawful and Nootral players to help counter this change.
+	 *
+	 * Odds:        older                       old            Newest
+	 *	"up"    L      N      C		"up"    L      N      C		  L/N/C
+	 *	 +1   75.0   75.0   75.0	 +1   75.0   75.0   75.0      75.0
+	 *	  0    0.0   12.5   25.0	  0    6.25   8.33  12.5      12.5
+	 *	 -1    8.33   4.17   0.0	 -1    6.25   8.33  12.5      12.5
+	 *	 -2    8.33   4.17   0.0	 -2    6.25   8.33   0.0       0.0
+	 *	 -3    8.33   4.17   0.0	 -3    6.25   0.0    0.0       0.0
+	 *
+	 *	 11/19: Removed entirely as part of an experiment with new nasty()
+	 *	 functionality; clog the stairs with critters, but let the player move
+	 *	 between levels without jerking him around.
+	 *
 	 */
+#if 0
 	if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&
 				(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) {
 		if (!rn2(4)) {
-		    int odds = 3 + (int)u.ualign.type,		/* 2..4 */
-			diff = odds <= 1 ? 0 : rn2(odds);	/* paranoia */
-
+		    int diff = rn2(2);
 		    if (diff != 0) {
 			assign_rnd_level(newlevel, &u.uz, diff);
+
 			/* if inside the tower, stay inside */
 			if (was_in_W_tower &&
@@ -1015,4 +1026,5 @@
 		}
 	}
+#endif
 
 	/* Prevent the player from going past the first quest level unless
@@ -1134,15 +1146,8 @@
 		} else {
 		    if (newdungeon) {
-			if (Is_stronghold(&u.uz)) {
-			    register xchar x, y;
-
-			    do {
-				x = (COLNO - 2 - rnd(5));
-				y = rn1(ROWNO - 4, 3);
-			    } while(occupied(x, y) ||
-				    IS_WALL(levl[x][y].typ));
-			    u_on_newpos(x, y);
-			} else u_on_sstairs();
-		    } else u_on_dnstairs();
+				u_on_sstairs();
+			} else {
+				u_on_dnstairs();
+			}
 		}
 		/* Remove bug which crashes with levitation/punishment  KAA */
@@ -1284,4 +1289,8 @@
 		You_hear("groans and moans everywhere.");
 	    } else pline("It is hot here.  You smell smoke...");
+
+#ifdef RECORD_ACHIEVE
+            achieve.enter_gehennom = 1;
+#endif
 	}
 
@@ -1319,6 +1328,12 @@
 #endif
 	/* Final confrontation */
-	if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet)
+	if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet) {
+#ifdef WISH_TRACKER
+		char buf[512];
+		Sprintf(buf,"%s just entered the Plane of Earth on T:%d!",plname,moves);
+		makeannounce(buf);
+#endif
 		resurrect();
+	}
 	if (newdungeon && In_V_tower(&u.uz) && In_hell(&u.uz0))
 		pline_The("heat and smoke are gone.");
@@ -1357,4 +1372,12 @@
 	(void) in_out_region(u.ux, u.uy);
 	(void) pickup(1);
+
+	/* Don't autotarget a monster on a level you've just left */
+	polemonst = 0;
+
+#ifdef WHEREIS_FILE
+	touch_whereis();
+#endif
+
 }
 
@@ -1364,4 +1387,5 @@
 	struct monst *mtmp;
 	struct obj *otmp;
+	char buf[512];
 	coord mm;
 	int i;
@@ -1374,4 +1398,9 @@
 	create_mplayers(rn1(4, 3), TRUE);
 
+#ifdef WISH_TRACKER
+	Sprintf(buf,"%s just entered the Astral Plane on T:%d!",plname,moves);
+	makeannounce(buf);
+#endif
+
 	/* create a guardian angel next to player, if worthy */
 	if (Conflict) {
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dog.c nethack/src/dog.c
--- nh_orig/src/dog.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dog.c	2009-08-02 13:49:38.693407991 -0400
@@ -101,4 +101,7 @@
 	    if (chance > 2) chance = otmp->blessed ? 0 : !otmp->cursed ? 1 : 2;
 	    /* 0,1,2:  b=80%,10,10; nc=10%,80,10; c=10%,10,80 */
+		 if (Role_if(PM_KNIGHT) && mtmp->data->mlet == S_DRAGON) {
+		 	chance = 2;
+		 }
 	    if (chance > 0) {
 		mtmp->mtame = 0;	/* not tame after all */
@@ -141,6 +144,11 @@
 	if (pettype == PM_LITTLE_DOG)
 		petname = dogname;
-	else if (pettype == PM_PONY)
+	else if (pettype == PM_PONY) {
 		petname = horsename;
+		/* hijack creation for chaotic knights */
+		if (u.ualign.type == A_CHAOTIC && Role_if(PM_KNIGHT)) {
+			pettype = PM_NIGHTMARE;
+		}
+	}
 	else
 		petname = catname;
@@ -161,5 +169,5 @@
 #ifdef STEED
 	/* Horses already wear a saddle */
-	if (pettype == PM_PONY && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
+	if ((pettype == PM_PONY || pettype == PM_NIGHTMARE) && !!(otmp = mksobj(SADDLE, TRUE, FALSE))) {
 	    if (mpickobj(mtmp, otmp))
 		panic("merged saddle?");
@@ -636,4 +644,8 @@
 	mtmp->muy = new_lev.dlevel;
 	mtmp->mx = mtmp->my = 0;	/* this implies migration */
+	/* if we were targeting it, clear the target */
+	if (mtmp == polemonst) {
+		polemonst = 0;
+	}
 }
 
@@ -754,4 +766,9 @@
 		return((struct monst *)0);
 
+	/* Knights can never tame dragons.  Natural enemies, y'see. */
+	if (Role_if(PM_KNIGHT) && mtmp->data->mlet == S_DRAGON) {
+		return ((struct monst *)0);
+	}
+
 	/* worst case, at least it'll be peaceful. */
 	mtmp->mpeaceful = 1;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dogmove.c nethack/src/dogmove.c
--- nh_orig/src/dogmove.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dogmove.c	2009-08-02 13:49:38.683408178 -0400
@@ -513,5 +513,5 @@
 	/* Let steeds eat and maybe throw rider during Conflict */
 	if (mtmp == u.usteed) {
-	    if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
+	    if (Conflict && !resist_conflict(mtmp)) {
 		dismount_steed(DISMOUNT_THROWN);
 		return (1);
@@ -545,5 +545,5 @@
 	if (passes_bars(mtmp->data)) allowflags |= ALLOW_BARS;
 	if (throws_rocks(mtmp->data)) allowflags |= ALLOW_ROCK;
-	if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
+	if (Conflict && !resist_conflict(mtmp)) {
 	    allowflags |= ALLOW_U;
 	    if (!has_edog) {
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dokick.c nethack/src/dokick.c
--- nh_orig/src/dokick.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dokick.c	2009-10-05 13:36:36.238417575 -0400
@@ -18,5 +18,5 @@
 STATIC_DCL void FDECL(kick_monster, (XCHAR_P, XCHAR_P));
 STATIC_DCL int FDECL(kick_object, (XCHAR_P, XCHAR_P));
-STATIC_DCL char *FDECL(kickstr, (char *));
+STATIC_DCL char *FDECL(kickstr, (int,int,char *));
 STATIC_DCL void FDECL(otransit_msg, (struct obj *, BOOLEAN_P, long));
 STATIC_DCL void FDECL(drop_to, (coord *,SCHAR_P));
@@ -36,4 +36,6 @@
 	int blessed_foot_damage = 0;
 	boolean trapkilled = FALSE;
+	boolean forcepush = FALSE;
+	struct trap* ttmp;
 
 	if (uarmf && uarmf->otyp == KICKING_BOOTS)
@@ -87,13 +89,27 @@
 	if (uarmf) dmg += uarmf->spe;
 	dmg += u.udaminc;	/* add ring(s) of increase damage */
-	if (dmg > 0)
-		mon->mhp -= dmg;
-	if (mon->mhp > 0 && martial() && !bigmonst(mon->data) && !rn2(3) &&
-	    mon->mcanmove && mon != u.ustuck && !mon->mtrapped) {
+	if (dmg > 0) {
+		damage_mon(mon,dmg,AD_PHYS);
+	}
+
+	/* THIS. IS. YENDOOOOOR? */
+	mdx = mon->mx + u.dx;
+	mdy = mon->my + u.dy;
+	if (isok(mdx,mdy)) {
+		ttmp = t_at(mdx,mdy);
+		if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) { 
+			forcepush = TRUE;
+		}
+	}
+
+	if ((mon->mhp > 0 && !bigmonst(mon->data) && mon != u.ustuck && !mon->mtrapped) && 
+			((!rn2(3) && martial() && mon->mcanmove) || forcepush)) {
 		/* see if the monster has a place to move into */
 		mdx = mon->mx + u.dx;
 		mdy = mon->my + u.dy;
 		if(goodpos(mdx, mdy, mon, 0)) {
+			if (!forcepush) {
 			pline("%s reels from the blow.", Monnam(mon));
+			}
 			if (m_in_out_region(mon, mdx, mdy)) {
 			    remove_monster(mon->mx, mon->my);
@@ -122,4 +138,6 @@
 	register struct monst *mon = m_at(x, y);
 	register int i, j;
+	struct trap* ttmp;
+	int mdx,mdy;
 
 	bhitpos.x = x;
@@ -169,5 +187,5 @@
 
 	if(Levitation && !rn2(3) && verysmall(mon->data) &&
-	   !is_flyer(mon->data)) {
+	   !is_flyer(mon->data) && !is_flying(mon)) {
 		pline("Floating in the air, you miss wildly!");
 		exercise(A_DEX, FALSE);
@@ -182,4 +200,13 @@
 		if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) {
 			if(martial() && !rn2(2)) goto doit;
+			mdx = mon->mx + u.dx;
+			mdy = mon->my + u.dy;
+			/* even a zero-damage kick may push them in */
+			if (isok(mdx,mdy)) {
+				ttmp = t_at(mdx,mdy);
+				if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
+					goto doit;
+				}
+			}
 			Your("clumsy kick does no damage.");
 			(void) passive(mon, FALSE, 1, AT_KICK);
@@ -216,5 +243,5 @@
 				(can_teleport(mon->data) ? "teleports" :
 				 is_floater(mon->data) ? "floats" :
-				 is_flyer(mon->data) ? "swoops" :
+				 (is_flyer(mon->data) || is_flying(mon)) ? "swoops" :
 				 (nolimbs(mon->data) || slithy(mon->data)) ?
 					"slides" : "jumps"),
@@ -507,8 +534,12 @@
 		boolean otrp = kickobj->otrapped;
 
-		if(range < 2) pline("THUD!");
+		if(range < 2) pline("%s",kickobj->otyp == IRON_SAFE ? "CLANG!" : "THUD!");
 
 		container_impact_dmg(kickobj);
 
+		if (kickobj->otyp == IRON_SAFE) { /* can't kick these open or break 'em */
+			return 1;
+		}
+
 		if (kickobj->olocked) {
 		    if (!rn2(5) || (martial() && !rn2(2))) {
@@ -594,5 +625,6 @@
 
 STATIC_OVL char *
-kickstr(buf)
+kickstr(x,y,buf)
+int x,y;
 char *buf;
 {
@@ -601,8 +633,8 @@
 	if (kickobj) what = distant_name(kickobj,doname);
 	else if (IS_DOOR(maploc->typ)) what = "a door";
-	else if (IS_TREE(maploc->typ)) what = "a tree";
+	else if (IS_TREE(maploc->typ)) what = christmas() ? "a christmas tree" : "a tree";
 	else if (IS_STWALL(maploc->typ)) what = "a wall";
 	else if (IS_ROCK(maploc->typ)) what = "a rock";
-	else if (IS_THRONE(maploc->typ)) what = "a throne";
+	else if (sobj_at(FUR_THRONE, x,y)) what = "a throne";
 	else if (IS_FOUNTAIN(maploc->typ)) what = "a fountain";
 	else if (IS_GRAVE(maploc->typ)) what = "a headstone";
@@ -777,4 +809,5 @@
 	kickobj = (struct obj *)0;
 	if (OBJ_AT(x, y) &&
+	    (objects[level.objects[x][y]->otyp].oc_class != FURNITURE_CLASS) &&
 	    (!Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
 	     || sobj_at(BOULDER,x,y))) {
@@ -826,10 +859,12 @@
 		    } else goto ouch;
 		}
-		if(IS_THRONE(maploc->typ)) {
+		if(sobj_at(FUR_THRONE,x,y)) {
 		    register int i;
+		    struct obj *tmpobj = sobj_at(FUR_THRONE, x,y);
 		    if(Levitation) goto dumb;
-		    if((Luck < 0 || maploc->doormask) && !rn2(3)) {
-			maploc->typ = ROOM;
-			maploc->doormask = 0; /* don't leave loose ends.. */
+		    if((Luck < 0) && !rn2(3)) {
+			obj_extract_self(tmpobj);
+			dealloc_obj(tmpobj);
+			tmpobj = NULL;
 			(void) mkgold((long)rnd(200), x, y);
 			if (Blind)
@@ -841,5 +876,5 @@
 			exercise(A_DEX, TRUE);
 			return(1);
-		    } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
+		    } else if(Luck > 0 && !rn2(3) && !tmpobj->obroken) {
 			(void) mkgold((long) rn1(201, 300), x, y);
 			i = Luck + 1;
@@ -855,5 +890,5 @@
 			}
 			/* prevent endless milking */
-			maploc->looted = T_LOOTED;
+			tmpobj->obroken = 1;
 			return(1);
 		    } else if (!rn2(4)) {
@@ -890,4 +925,23 @@
 		if(IS_TREE(maploc->typ)) {
 		    struct obj *treefruit;
+			/* special-case for christmas... :) */
+			if (christmas()) {
+				coord loc;
+				/* we can cheat with enexto to find an empty spot
+				 * next to the tree to drop our present... */
+				if (!rn2(5) || !enexto(&loc,x,y,(struct permonst*)0) ||
+						(maploc->looted & TREE_LOOTED) || In_quest(&u.uz)) {
+					goto ouch;
+				}
+				treefruit = mkobj_at(RANDOM_CLASS,loc.x,loc.y,FALSE);
+				if (treefruit) {
+					pline("%s falls out!",Blind ? "Something" : "A present");
+					newsym(loc.x,loc.y);
+					maploc->looted |= TREE_LOOTED;
+					return 1;
+				} else {
+					goto ouch;
+				}
+			}
 		    /* nothing, fruit or trouble? 75:23.5:1.5% */
 		    if (rn2(3)) {
@@ -926,7 +980,6 @@
 		    	mm.x = x; mm.y = y;
 			while (cnt--) {
-			    if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE])
-				&& makemon(&mons[PM_KILLER_BEE],
-					       mm.x, mm.y, MM_ANGRY))
+					if (enexto(&mm, mm.x, mm.y, &mons[PM_KILLER_BEE]) && 
+							makemon(&mons[PM_KILLER_BEE], mm.x, mm.y, MM_ANGRY))
 				made++;
 			}
@@ -1010,5 +1063,5 @@
 		    }
 		    if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
-		    losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(buf),
+		    losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(x,y,buf),
 			KILLED_BY);
 		    if(Is_airlevel(&u.uz) || Levitation)
@@ -1339,4 +1392,5 @@
 	if (otmp == uwep) setuwep((struct obj *)0);
 	if (otmp == uquiver) setuqwep((struct obj *)0);
+	if (otmp == ulauncher) setulauncher((struct obj *)0);
 	if (otmp == uswapwep) setuswapwep((struct obj *)0);
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/do_name.c nethack/src/do_name.c
--- nh_orig/src/do_name.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/do_name.c	2010-04-29 10:53:23.922715740 -0400
@@ -225,5 +225,5 @@
 do_mname()
 {
-	char buf[BUFSZ];
+	char buf[BUFSZ] = "";
 	coord cc;
 	register int cx,cy;
@@ -271,4 +271,12 @@
 	(void) distant_monnam(mtmp, ARTICLE_THE, buf);
 	Sprintf(qbuf, "What do you want to call %s?", buf);
+
+	if (mtmp->data->mlet == S_DOG)
+	    strncpy(buf, dogname, BUFSZ);
+	else if (mtmp->data->mlet == S_FELINE)
+	    strncpy(buf, catname, BUFSZ);
+	else if (mtmp->data->mlet == S_UNICORN)
+	    strncpy(buf, horsename, BUFSZ);
+
 	getlin(qbuf,buf);
 	if(!*buf || *buf == '\033') return(0);
@@ -293,5 +301,5 @@
 register struct obj *obj;
 {
-	char buf[BUFSZ], qbuf[QBUFSZ];
+	char buf[BUFSZ] = "", qbuf[QBUFSZ];
 	const char *aname;
 	short objtyp;
@@ -312,13 +320,7 @@
 		return;
 	} else if (restrict_name(obj, buf) || exist_artifact(obj->otyp, buf)) {
-		int n = rn2((int)strlen(buf));
-		register char c1, c2;
-
-		c1 = lowc(buf[n]);
-		do c2 = 'a' + rn2('z'-'a'); while (c1 == c2);
-		buf[n] = (buf[n] == c1) ? c2 : highc(c2);  /* keep same case */
-		pline("While engraving your %s slips.", body_part(HAND));
+		pline("You realize there can only ever be one %s, and decide against it.",buf);
 		display_nhwindow(WIN_MESSAGE, FALSE);
-		You("engrave: \"%s\".",buf);
+		return;
 	}
 	obj = oname(obj, buf);
@@ -463,5 +465,7 @@
 		allowall[0] = ALL_CLASSES; allowall[1] = '\0';
 		obj = getobj(allowall, "name");
-		if(obj) do_oname(obj);
+		if (obj && obj->otyp == SKULL) {
+			pline("That already has its own name.");
+		} else if (obj) do_oname(obj);
 		break;
 	default :
@@ -491,5 +495,5 @@
 register struct obj *obj;
 {
-	char buf[BUFSZ], qbuf[QBUFSZ];
+	char buf[BUFSZ] = "", qbuf[QBUFSZ];
 	struct obj otemp;
 	register char **str1;
@@ -899,4 +903,5 @@
 	"Ancient Multi-Hued Dragon", "Evil Iggy",
 						/* Moria */
+	"Evil Otto", /* Berzerk */
 	"emu", "kestrel", "xeroc", "venus flytrap",
 						/* Rogue */
@@ -909,5 +914,5 @@
 	"Ent",					/* Lord of the Rings */
 	"tangle tree", "nickelpede", "wiggle",	/* Xanth */
-	"white rabbit", "snark",		/* Lewis Carroll */
+	"white rabbit",		/* Lewis Carroll */
 	"pushmi-pullyu",			/* Dr. Doolittle */
 	"smurf",				/* The Smurfs */
@@ -937,5 +942,57 @@
 	"questing beast",		/* King Arthur */
 	"Predator",				/* Movie */
-	"mother-in-law"				/* common pest */
+	"mother-in-law",				/* common pest */
+
+	"one-winged dewinged stab-bat",  /* KoL */
+	"praying mantis",
+	"arch-pedant",
+	"beluga whale",
+	"bluebird of happiness",
+	"bouncing eye", "floating nose",
+	"buffer overflow", "dangling pointer", "walking disk drive",
+	"cacodemon", "scrag",
+	"cardboard golem", "duct tape golem",
+	"chess pawn",
+	"chicken",
+	"chocolate pudding",
+	"coelacanth",
+	"corpulent porpoise",
+	"Crow T. Robot",
+	"diagonally moving grid bug",
+	"dropbear",
+	"Dudley",
+	"El Pollo Diablo",
+	"evil overlord",
+	"existential angst",
+	"figment of your imagination", "flash of insight",
+	"flying pig",
+	"gazebo",
+	"gonzo journalist",
+	"gray goo", "magnetic monopole",
+	"heisenbug",
+	"lag monster",
+	"loan shark",
+	"Lord British",
+	"newsgroup troll",
+	"ninja pirate zombie robot",
+	"octarine dragon",
+	"particle man",
+	"possessed waffle iron",
+	"poultrygeist",
+	"raging nerd",
+	"roomba",
+	"sea cucumber",
+	"spelling bee",
+	"Strong Bad",
+	"stuffed raccoon puppet",
+	"tapeworm",
+	"liger",
+	"velociraptor",
+	"vermicious knid",
+	"viking",
+	"voluptuous ampersand",
+	"wee green blobbie",
+	"wereplatypus",
+	"zergling"
 };
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dothrow.c nethack/src/dothrow.c
--- nh_orig/src/dothrow.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dothrow.c	2010-08-16 13:20:13.435709808 -0400
@@ -32,4 +32,42 @@
 extern boolean notonhead;	/* for long worms */
 
+int
+boom_flightpath_menu()
+{
+    winid win;
+    anything any;
+    menu_item *pick_list = NULL;
+    int n;
+
+    any.a_void = 0;
+    win = create_nhwindow(NHW_MENU);
+    start_menu(win);
+
+    any.a_int = 1;
+    add_menu(win, NO_GLYPH, &any, 'r', 0, ATR_NONE, "Curve right and return", MENU_UNSELECTED);
+
+    any.a_int = 2;
+    add_menu(win, NO_GLYPH, &any, 'l', 0, ATR_NONE, "Curve left and return", MENU_UNSELECTED);
+
+    any.a_int = 3;
+    add_menu(win, NO_GLYPH, &any, 's', 0, ATR_NONE, "Short straight flight and return", MENU_UNSELECTED);
+
+    any.a_int = 4;
+    add_menu(win, NO_GLYPH, &any, 'x', 0, ATR_NONE, "Long straight flight", MENU_UNSELECTED);
+
+    any.a_int = 0;
+    add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED);
+    any.a_int = 0;
+    add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, "To change this, change boom_flightpath in options", MENU_UNSELECTED);
+
+    end_menu(win, "How do you wish boomerangs to behave?");
+    n = select_menu(win, PICK_ONE, &pick_list);
+    destroy_nhwindow(win);
+    if (pick_list) {
+	n = (pick_list[0].item.a_int - 1);
+	free((genericptr_t) pick_list);
+    }
+    return n;
+}
 
 /* Throw the selected object, asking for direction */
@@ -78,4 +116,10 @@
 	if(!canletgo(obj,"throw"))
 		return(0);
+
+	if (obj->otyp == BOOMERANG) {
+	    if (iflags.boom_flight_path < 0)
+		iflags.boom_flight_path = boom_flightpath_menu();
+	}
+
 	if (obj->oartifact == ART_MJOLLNIR && obj != uwep) {
 	    pline("%s must be wielded before it can be thrown.",
@@ -128,4 +172,9 @@
 		if (obj->otyp == YA && uwep && uwep->otyp == YUMI) multishot++;
 		break;
+		 case PM_CAVEMAN:
+		if (uslinging()) {		/* give an extra rock to cavies */
+			multishot++;
+		}
+		break;
 	    default:
 		break;	/* No bonus */
@@ -296,4 +345,14 @@
 	}
 
+	/* If they've got something already picked, wield it;
+	 * wield_tool() will return error messages if they couldn't,
+	 * but go ahead and let them throw whatever even if it fails
+	 *
+	 * Must do this before autoquiver gets called since autoquiver
+	 * tries to be smart based on what you've got wielded */
+	if (ulauncher && ulauncher != uwep) {
+		wield_tool(ulauncher,"fire");
+	}
+
 	if(check_capacity((char *)0)) return(0);
 	if (!uquiver) {
@@ -470,5 +529,5 @@
 	    pline("Ouch!");
 	    if (IS_TREE(levl[x][y].typ))
-		s = "bumping into a tree";
+		s = christmas() ? "bumping into a christmas tree" : "bumping into a tree";
 	    else if (IS_ROCK(levl[x][y].typ))
 		s = "bumping into a wall";
@@ -478,4 +537,11 @@
 	    return FALSE;
 	}
+	if (IS_DOOR(levl[x][y].typ) && (levl[x][y].doormask & D_ISOPEN) &&
+	    (u.ux - x) && (u.uy - y)) {
+	    /* closed door handled above */
+	    pline("You hit the door edge!");
+	    losehp(rnd(2+*range), "bumping into a door", KILLED_BY);
+	    return FALSE;
+	}
 	if (levl[x][y].typ == IRONBARS) {
 	    You("crash into some iron bars.  Ouch!");
@@ -570,8 +636,10 @@
 	struct monst *mon = (struct monst *)arg;
 
-	/* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
+	/* TODO: Treat walls, doors, iron bars, etc. specially
 	 * rather than just stopping before.
+	 *
+	 * DONE: pools and lava (DSR 3/2/08)
 	 */
-	if (goodpos(x, y, mon, 0) && m_in_out_region(mon, x, y)) {
+	if (goodpos(x, y, mon, MM_UNSAFEOK) && m_in_out_region(mon, x, y)) {
 	    remove_monster(mon->mx, mon->my);
 	    newsym(mon->mx, mon->my);
@@ -580,4 +648,6 @@
 	    set_apparxy(mon);
 	    (void) mintrap(mon);
+		 /* TODO: we need to check minliquid here eventually to see
+		  * if monsters can properly die, but for now... */
 	    return TRUE;
 	}
@@ -609,5 +679,5 @@
     if(Punished && !carried(uball)) {
 	You_feel("a tug from the iron ball.");
-	nomul(0);
+	nomul(0, 0);
 	return;
     } else if (u.utrap) {
@@ -615,5 +685,5 @@
 	    u.utraptype == TT_WEB ? "web" : u.utraptype == TT_LAVA ? "lava" :
 		u.utraptype == TT_INFLOOR ? surface(u.ux,u.uy) : "trap");
-	nomul(0);
+	nomul(0, 0);
 	return;
     }
@@ -625,5 +695,5 @@
     if(!range || (!dx && !dy) || u.ustuck) return; /* paranoia */
 
-    nomul(-range);
+    nomul(-range, "moving through the air");
     if (verbose)
 	You("%s in the opposite direction.", range > 1 ? "hurtle" : "float");
@@ -926,7 +996,8 @@
 
 	} else if(obj->otyp == BOOMERANG && !Underwater) {
+
 		if(Is_airlevel(&u.uz) || Levitation)
 		    hurtle(-u.dx, -u.dy, 1, TRUE);
-		mon = boomhit(u.dx, u.dy);
+		mon = boomhit(u.dx, u.dy, !impaired ? iflags.boom_flight_path : rn2(4));
 		if(mon == &youmonst) {		/* the thing was caught */
 			exercise(A_DEX, TRUE);
@@ -942,4 +1013,10 @@
 	} else {
 		urange = (int)(ACURRSTR)/2;
+
+		/* hard limit this so crossbows will fire further
+		 * than anything except a superstrong elf wielding a
+		 * racial bow, or a samurai with his yumi */
+		if (urange > 9) { urange = 9; }
+
 		/* balls are easy to throw or at least roll */
 		/* also, this insures the maximum range of a ball is greater
@@ -958,10 +1035,35 @@
 
 		if (is_ammo(obj)) {
-		    if (ammo_and_launcher(obj, uwep))
-			range++;
-		    else if (obj->oclass != GEM_CLASS)
+			/* stuff that's fired from a proper launcher should have
+			 * a noticeably longer range than stuff that was just
+			 * flung (like daggers, darts, etc.) */
+		    if (ammo_and_launcher(obj, uwep)) {
+				 switch (uwep->otyp) {
+					 case ELVEN_BOW:
+					 case YUMI:
+						 range += urange + 2;	/* better workmanship... */
+						 break;
+					 case ORCISH_BOW:
+						 range += urange - 2;	/* orcish gear sucks */
+						 break;
+					 case BOW:
+						 range += urange;
+						 break;
+					 case CROSSBOW:
+						 range += 10;	 /* not strength dependent! */
+						 break;
+					 case SLING:
+						 range += (int)urange/2;
+						 break;
+					 /* case BLOWGUN: maaaybe? */
+					 default:
+						 break;
+				 }
+			 } else if (obj->oclass != GEM_CLASS) {
 			range /= 2;
 		}
 
+		}
+
 		if (Is_airlevel(&u.uz) || Levitation) {
 		    /* action, reaction... */
@@ -1196,6 +1298,7 @@
 	 * Distance and monster size affect chance to hit.
 	 */
-	tmp = -1 + Luck + find_mac(mon) + u.uhitinc +
+	tmp = -1 + (Luck/2) + find_mac(mon) + u.uhitinc + 
 			maybe_polyd(youmonst.data->mlevel, u.ulevel);
+
 	if (ACURR(A_DEX) < 4) tmp -= 3;
 	else if (ACURR(A_DEX) < 6) tmp -= 2;
@@ -1222,4 +1325,6 @@
 	    case LEATHER_GLOVES:
 	    case GAUNTLETS_OF_DEXTERITY:
+		 case GAUNTLETS_OF_FORTUNE:
+		 case GAUNTLETS_OF_FORCE:
 		break;
 	    default:
@@ -1406,4 +1511,15 @@
 		is_animal(u.ustuck->data) ? "entrails" : "currents");
 	} else {
+		struct monst* montmp;
+		/* Oz reference: Nomes ('gnomes') are afraid of eggs
+		 * ... this is both here and in uhitm because of the odd structure
+		 * related to 'hit' and 'not hit' with the huge pile of elseifs */
+		if (obj->otyp == EGG) {
+			for (montmp = fmon; montmp; montmp = montmp->nmon) {
+				if (is_gnome(montmp->data) && m_canseeu(montmp)) {
+					monflee(montmp,rnd(6)+4,TRUE,TRUE);
+				}
+			}
+		}
 	    tmiss(obj, mon);
 	}
@@ -1585,4 +1701,9 @@
 			/* monster breathing isn't handled... [yet?] */
 			break;
+#ifdef TOURIST
+	case EXPENSIVE_CAMERA:
+	    (void) camera_demon(obj, x,y);
+	    break;
+#endif
 		case EGG:
 			/* breaking your own eggs is bad luck */
@@ -1619,4 +1740,20 @@
 }
 
+struct monst *
+camera_demon(obj, x,y)
+struct obj *obj;
+schar x,y;
+{
+    struct monst *mtmp = NULL;
+    if (!rn2(3) && (mtmp = makemon(&mons[(rn2(2) ? PM_HOMUNCULUS : PM_IMP)],x,y, NO_MM_FLAGS)) != 0) {
+	pline("%s is released!", !canspotmon(mtmp) ?
+	      Something : Hallucination ?
+	      An(rndmonnam()) : "The picture-painting demon");
+	mtmp->mpeaceful = ((obj) ? !obj->cursed : 0);
+	set_malign(mtmp);
+    }
+    return mtmp;
+}
+
 /*
  * Check to see if obj is going to break, but don't actually break it.
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/do_wear.c nethack/src/do_wear.c
--- nh_orig/src/do_wear.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/do_wear.c	2009-11-22 07:19:36.431273410 -0500
@@ -40,5 +40,5 @@
 	WORN_SHIRT,
 #endif
-	WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L };
+	WORN_BOOTS, W_SWAPWEP, W_QUIVER, W_LAUNCHER, 0L };
 
 STATIC_DCL void FDECL(on_msg, (struct obj *));
@@ -100,4 +100,5 @@
     switch(uarmf->otyp) {
 	case LOW_BOOTS:
+	case GNOMISH_BOOTS:
 	case IRON_SHOES:
 	case HIGH_BOOTS:
@@ -111,4 +112,5 @@
 		/* Speed boots are still better than intrinsic speed, */
 		/* though not better than potion speed */
+		/* Can also safely assume we're not wearing molasses boots */
 		if (!oldprop && !(HFast & TIMEOUT)) {
 			makeknown(uarmf->otyp);
@@ -117,4 +119,11 @@
 		}
 		break;
+	case BOOTS_OF_MOLASSES:
+		if (!oldprop && !HSlow) {
+			makeknown(uarmf->otyp);
+			You_feel("yourself slow down.");
+			flags.botl = 1;
+		}
+		break;
 	case ELVEN_BOOTS:
 		if (!oldprop && !HStealth && !BStealth) {
@@ -158,4 +167,11 @@
 		}
 		break;
+	case BOOTS_OF_MOLASSES:
+		if (!oldprop && !HSlow) {
+			makeknown(otyp);
+			You_feel("yourself speed up.");
+			flags.botl = 1;
+		}
+		break;
 	case WATER_WALKING_BOOTS:
 		if (is_pool(u.ux,u.uy) && !Levitation && !Flying &&
@@ -187,4 +203,5 @@
 	case JUMPING_BOOTS:
 	case KICKING_BOOTS:
+	case GNOMISH_BOOTS:
 		break;
 	default: impossible(unknown_type, c_boots, otyp);
@@ -207,4 +224,7 @@
 		break;
 	case ORCISH_CLOAK:
+		if (Race_if(PM_ORC)) {
+		}
+		break;
 	case DWARVISH_CLOAK:
 	case CLOAK_OF_MAGIC_RESISTANCE:
@@ -255,4 +275,8 @@
 	case ELVEN_CLOAK:
 	case ORCISH_CLOAK:
+		if (Race_if(PM_ORC)) {
+			u.uac -= 2;
+		}
+		break;
 	case DWARVISH_CLOAK:
 	case CLOAK_OF_PROTECTION:
@@ -299,5 +323,7 @@
 	case ELVEN_LEATHER_HELM:
 	case DWARVISH_IRON_HELM:
+	case GNOMISH_HELM:
 	case ORCISH_HELM:
+	case HELM_OF_DISCOVERY:
 	case HELM_OF_TELEPATHY:
 		break;
@@ -305,4 +331,8 @@
 		adj_abon(uarmh, uarmh->spe);
 		break;
+	case HELM_OF_CLARITY:
+	   make_hallucinated(0, TRUE, 0);
+		see_monsters();
+		break;
 	case CORNUTHAUM:
 		/* people think marked wizards know what they're talking
@@ -316,8 +346,8 @@
 	case HELM_OF_OPPOSITE_ALIGNMENT:
 		if (u.ualign.type == A_NEUTRAL)
-		    u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL;
+		    u.ualign.type = (uarmh->o_id % 2) ? A_CHAOTIC : A_LAWFUL;
 		else u.ualign.type = -(u.ualign.type);
 		u.ublessed = 0; /* lose your god's protection */
-	     /* makeknown(uarmh->otyp);   -- moved below, after xname() */
+		u.ualign.record = -(u.ualign.record/2); /* your past actions now count against you */
 		/*FALLTHRU*/
 	case DUNCE_CAP:
@@ -358,5 +388,7 @@
 	case ELVEN_LEATHER_HELM:
 	case DWARVISH_IRON_HELM:
+	case GNOMISH_HELM:
 	case ORCISH_HELM:
+	case HELM_OF_DISCOVERY:
 	    break;
 	case DUNCE_CAP:
@@ -370,4 +402,5 @@
 	    break;
 	case HELM_OF_TELEPATHY:
+	case HELM_OF_CLARITY:
 	    /* need to update ability before calling see_monsters() */
 	    setworn((struct obj *)0, W_ARMH);
@@ -380,4 +413,8 @@
 	    u.ualign.type = u.ualignbase[A_CURRENT];
 	    u.ublessed = 0; /* lose the other god's protection */
+		 u.ualign.record = -(u.ualign.record); 
+								/* your past actions may count for you again...
+								 * we don't divide it by 2 here because we 
+								 * don't want to decrease it _too_ sharply */
 	    flags.botl = 1;
 	    break;
@@ -393,9 +430,10 @@
 Gloves_on()
 {
-    long oldprop =
-	u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
+    long oldprop = u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
 
     switch(uarmg->otyp) {
 	case LEATHER_GLOVES:
+		case GAUNTLETS_OF_FORCE:
+		case GAUNTLETS_OF_FORTUNE:
 		break;
 	case GAUNTLETS_OF_FUMBLING:
@@ -418,6 +456,5 @@
 Gloves_off()
 {
-    long oldprop =
-	u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
+    long oldprop = u.uprops[objects[uarmg->otyp].oc_oprop].extrinsic & ~WORN_GLOVES;
 
     takeoff_mask &= ~W_ARMG;
@@ -425,4 +462,6 @@
     switch(uarmg->otyp) {
 	case LEATHER_GLOVES:
+		case GAUNTLETS_OF_FORCE:
+		case GAUNTLETS_OF_FORTUNE:
 	    break;
 	case GAUNTLETS_OF_FUMBLING:
@@ -474,17 +513,13 @@
 Shield_on()
 {
-/*
     switch (uarms->otyp) {
-	case SMALL_SHIELD:
-	case ELVEN_SHIELD:
-	case URUK_HAI_SHIELD:
-	case ORCISH_SHIELD:
-	case DWARVISH_ROUNDSHIELD:
-	case LARGE_SHIELD:
-	case SHIELD_OF_REFLECTION:
+		case SHIELD_OF_LIGHT:
+			begin_burn(uarms,FALSE);
+			if(!Blind)
+				pline("%s to glow.",Tobjnam(uarms,"begin"));
+			break;
+		default:	 /* impossible() here was a bit paranoid */
 		break;
-	default: impossible(unknown_type, c_shield, uarms->otyp);
     }
-*/
     return 0;
 }
@@ -494,17 +529,16 @@
 {
     takeoff_mask &= ~W_ARMS;
-/*
+
     switch (uarms->otyp) {
-	case SMALL_SHIELD:
-	case ELVEN_SHIELD:
-	case URUK_HAI_SHIELD:
-	case ORCISH_SHIELD:
-	case DWARVISH_ROUNDSHIELD:
-	case LARGE_SHIELD:
-	case SHIELD_OF_REFLECTION:
+		case SHIELD_OF_LIGHT:
+			end_burn(uarms,FALSE);
+			if(!Blind)
+				pline("%s glowing.",Tobjnam(uarms,"stop"));
+			break;
+		break;
+	default: 
 		break;
-	default: impossible(unknown_type, c_shield, uarms->otyp);
     }
-*/
+
     setworn((struct obj *)0, W_ARMS);
     return 0;
@@ -551,4 +585,35 @@
 Armor_on()
 {
+	long oldprop = EFast & W_ARM;
+
+	/* It's a very cheap hack to bolt this stuff on here, but... needs must */
+	if (uarm) {
+		switch (uarm->otyp) {
+			case GOLD_DRAGON_SCALE_MAIL:
+			case GOLD_DRAGON_SCALES:
+				begin_burn(uarm,FALSE);
+				if(!Blind)
+					pline("%s to glow.",Tobjnam(uarm,"begin"));
+				break;
+			case BLUE_DRAGON_SCALE_MAIL:
+			case BLUE_DRAGON_SCALES:
+				if (!oldprop && !Very_fast) {
+					pline("You speed up%s.",Fast ? " a bit more" : "");
+				}
+				EFast |= W_ARM;
+				break;
+			case YELLOW_DRAGON_SCALE_MAIL:
+			case YELLOW_DRAGON_SCALES:
+				EConfusion_resistance |= W_ARM;
+				EStun_resistance |= W_ARM;
+				break;
+			case WHITE_DRAGON_SCALE_MAIL:
+			case WHITE_DRAGON_SCALES:
+				EWwalking |= W_ARM;
+				break;
+			default:
+				break;
+		}
+	}
     return 0;
 }
@@ -557,4 +622,30 @@
 Armor_off()
 {
+	if (uarm) {
+		switch (uarm->otyp) {
+			case GOLD_DRAGON_SCALE_MAIL:
+			case GOLD_DRAGON_SCALES:
+				end_burn(uarm,FALSE);
+				if(!Blind)
+					pline("%s glowing.",Tobjnam(uarm,"stop"));
+				break;
+			case BLUE_DRAGON_SCALE_MAIL:
+			case BLUE_DRAGON_SCALES:
+				EFast &= ~W_ARM;
+				if (!Very_fast) {
+					pline("You slow down.");
+				}
+			case YELLOW_DRAGON_SCALE_MAIL:
+			case YELLOW_DRAGON_SCALES:
+				EConfusion_resistance &= ~W_ARM;
+				EStun_resistance &= ~W_ARM;
+				break;
+			case WHITE_DRAGON_SCALE_MAIL:
+			case WHITE_DRAGON_SCALES:
+				EWwalking &= ~W_ARM;
+			default:
+				break;
+		}
+	}
     takeoff_mask &= ~W_ARM;
     setworn((struct obj *)0, W_ARM);
@@ -569,4 +660,29 @@
 Armor_gone()
 {
+	if (uarm) {
+		switch (uarm->otyp) {
+			case GOLD_DRAGON_SCALE_MAIL:
+			case GOLD_DRAGON_SCALES:
+				end_burn(uarm,FALSE);
+				break;
+			case BLUE_DRAGON_SCALE_MAIL:
+			case BLUE_DRAGON_SCALES:
+				EFast &= ~W_ARM;
+				if (!Very_fast) {
+					pline("You slow down.");
+				}
+				break;
+			case YELLOW_DRAGON_SCALE_MAIL:
+			case YELLOW_DRAGON_SCALES:
+				EConfusion_resistance &= ~W_ARM;
+				EStun_resistance &= ~W_ARM;
+				break;
+			case WHITE_DRAGON_SCALE_MAIL:
+			case WHITE_DRAGON_SCALES:
+				EWwalking &= ~W_ARM;
+			default:
+				break;
+		}
+	}
     takeoff_mask &= ~W_ARM;
     setnotworn(uarm);
@@ -584,4 +700,5 @@
 	case AMULET_OF_REFLECTION:
 	case AMULET_OF_MAGICAL_BREATHING:
+	case AMULET_OF_POWER:
 	case FAKE_AMULET_OF_YENDOR:
 		break;
@@ -645,4 +762,5 @@
 	case AMULET_OF_CHANGE:
 	case AMULET_OF_UNCHANGING:
+	case AMULET_OF_POWER:
 	case FAKE_AMULET_OF_YENDOR:
 		break;
@@ -688,4 +806,5 @@
     if (obj == uswapwep) setuswapwep((struct obj *) 0);
     if (obj == uquiver) setuqwep((struct obj *) 0);
+    if (obj == ulauncher) setulauncher((struct obj *) 0);
 
     /* only mask out W_RING when we don't have both
@@ -917,4 +1036,6 @@
 	if (otmp == uquiver)
 	    setuqwep((struct obj *) 0);
+	if (otmp == ulauncher)
+	    setulauncher((struct obj *) 0);
 	setworn(otmp, W_TOOL);
 	on_msg(otmp);
@@ -1185,5 +1306,5 @@
 	if(cursed(otmp)) return(0);
 	if(delay) {
-		nomul(delay);
+		nomul(delay, "disrobing");
 		if (is_helmet(otmp)) {
 			nomovemsg = "You finish taking off your helmet.";
@@ -1439,8 +1560,10 @@
 	if (otmp == uquiver)
 		setuqwep((struct obj *) 0);
+	if (otmp == ulauncher)
+		setulauncher((struct obj *) 0);
 	setworn(otmp, mask);
 	delay = -objects[otmp->otyp].oc_delay;
 	if(delay){
-		nomul(delay);
+		nomul(delay, "dressing up");
 		if(is_boots(otmp)) afternmv = Boots_on;
 		if(is_helmet(otmp)) afternmv = Helmet_on;
@@ -1489,4 +1612,6 @@
 	if(otmp == uquiver)
 		setuqwep((struct obj *) 0);
+	if(otmp == ulauncher)
+		setulauncher((struct obj *) 0);
 	if(otmp->oclass == RING_CLASS || otmp->otyp == MEAT_RING) {
 		if(nolimbs(youmonst.data)) {
@@ -1596,10 +1721,58 @@
 {
 	int uac = mons[u.umonnum].ac;
+	int racial_bonus;
 
-	if(uarm) uac -= ARM_BONUS(uarm);
-	if(uarmc) uac -= ARM_BONUS(uarmc);
-	if(uarmh) uac -= ARM_BONUS(uarmh);
-	if(uarmf) uac -= ARM_BONUS(uarmf);
-	if(uarms) uac -= ARM_BONUS(uarms);
+	/* Wearing racial armor is worth +x to the armor's AC; orcs get a slightly
+	 * larger bonus to compensate the crummy equipment, lack of equipment,
+	 * and the crummy orc itself :) 
+	 * ...gnomes get the same bonus and get some custom crappy armor added
+	 * solely for their use
+	 */
+	racial_bonus = (Race_if(PM_ORC) || Race_if(PM_GNOME)) ? 2 : 
+							(Race_if(PM_ELF) || Race_if(PM_DWARF)) ? 1 : 0;
+
+	if(uarm) {
+		uac -= ARM_BONUS(uarm);
+		if ((Race_if(PM_ORC) && (uarm->otyp == ORCISH_CHAIN_MAIL || uarm->otyp == ORCISH_RING_MAIL)) ||
+				(Race_if(PM_GNOME) && uarm->otyp == GNOMISH_SUIT) ||
+				(Race_if(PM_ELF) && uarm->otyp == ELVEN_MITHRIL_COAT) ||
+				(Race_if(PM_DWARF) && uarm->otyp == DWARVISH_MITHRIL_COAT)) {
+			uac -= racial_bonus;
+		}
+	}
+	if(uarmc) {
+		uac -= ARM_BONUS(uarmc);
+		if ((Race_if(PM_ORC) && uarmc->otyp == ORCISH_CLOAK) ||
+				(Race_if(PM_ELF) && uarmc->otyp == ELVEN_CLOAK) ||
+				(Race_if(PM_DWARF) && uarmc->otyp == DWARVISH_CLOAK)) {
+			uac -= racial_bonus;
+		}
+	}
+	if(uarmh) {
+		uac -= ARM_BONUS(uarmh);
+		if ((Race_if(PM_ORC) && uarmh->otyp == ORCISH_HELM) ||
+				(Race_if(PM_GNOME) && uarmh->otyp == GNOMISH_HELM) ||
+				(Race_if(PM_ELF) && uarmh->otyp == ELVEN_LEATHER_HELM) ||
+				(Race_if(PM_DWARF) && uarmh->otyp == DWARVISH_IRON_HELM)) {
+			uac -= racial_bonus;
+		}
+	}
+	if(uarmf) {
+		uac -= ARM_BONUS(uarmf);
+		if ((Race_if(PM_ELF) && uarmf->otyp == ELVEN_BOOTS) ||
+				(Race_if(PM_GNOME) && uarmf->otyp == GNOMISH_BOOTS) ||
+				(Race_if(PM_DWARF) && uarmf->otyp == IRON_SHOES)) {
+			uac -= racial_bonus;
+		}
+	}
+	if(uarms) {
+		uac -= ARM_BONUS(uarms);
+		if ((Race_if(PM_ORC) && (uarms->otyp == ORCISH_SHIELD ||
+											uarms->otyp == URUK_HAI_SHIELD)) ||
+				(Race_if(PM_ELF) && uarms->otyp == ELVEN_SHIELD) ||
+				(Race_if(PM_DWARF) && uarms->otyp == DWARVISH_ROUNDSHIELD)) {
+			uac -= racial_bonus;
+		}
+	}
 	if(uarmg) uac -= ARM_BONUS(uarmg);
 #ifdef TOURIST
@@ -1717,5 +1890,5 @@
 
 	if (otmph && (otmph != uarmf)) {
-	    erode_obj(otmph, acid_dmg, FALSE);
+	    if (!_erode_obj(otmph, AD_ACID))
 	    if (carried(otmph)) update_inventory();
 	}
@@ -1840,5 +2013,5 @@
 	}
 	/* basic curse check */
-	if (otmp == uquiver || (otmp == uswapwep && !u.twoweap)) {
+	if (otmp == uquiver || otmp == ulauncher || (otmp == uswapwep && !u.twoweap)) {
 	    ;	/* some items can be removed even when cursed */
 	} else {
@@ -1863,4 +2036,5 @@
 	else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP;
 	else if(otmp == uquiver) takeoff_mask |= W_QUIVER;
+	else if(otmp == ulauncher) takeoff_mask |= W_LAUNCHER;
 
 	else impossible("select_off: %s???", doname(otmp));
@@ -1887,4 +2061,7 @@
 	  setuqwep((struct obj *) 0);
 	  You("no longer have ammunition readied.");
+	} else if (taking_off == W_LAUNCHER) {
+		setulauncher((struct obj*) 0);
+		You("no longer have a default ranged weapon chosen.");
 	} else if (taking_off == WORN_ARMOR) {
 	  otmp = uarm;
@@ -1964,4 +2141,6 @@
 	} else if (taking_off == W_QUIVER) {
 	  todelay = 1;
+	} else if (taking_off == W_LAUNCHER) {
+	  todelay = 0;
 	} else if (taking_off == WORN_ARMOR) {
 	  otmp = uarm;
@@ -2031,5 +2210,5 @@
 	set_occupation(take_off, disrobing, 0);
 	return 0;
-    } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf &&
+    } else if (!uwep && !uswapwep && !uquiver && !uamul && !ublindf && !ulauncher &&
 		!uleft && !uright && !wearing_armor()) {
 	You("are not wearing anything.");
@@ -2047,5 +2226,5 @@
 	disrobing = "disrobing";
 	/* specific activity when handling weapons only */
-	if (!(takeoff_mask & ~(W_WEP|W_SWAPWEP|W_QUIVER)))
+	if (!(takeoff_mask & ~(W_WEP|W_SWAPWEP|W_QUIVER|W_LAUNCHER)))
 	    disrobing = "disarming";
 	(void) take_off();
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/drawing.c nethack/src/drawing.c
--- nh_orig/src/drawing.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/drawing.c	2010-05-01 11:04:47.118713846 -0400
@@ -44,5 +44,6 @@
 /*15*/	BALL_SYM,
 	CHAIN_SYM,
-	VENOM_SYM
+	VENOM_SYM,
+	FURNITURE_SYM
 };
 
@@ -68,5 +69,6 @@
 /*15*/	"iron ball",
 	"iron chain",
-	"splash of venom"
+	"splash of venom",
+	"piece of furniture"
 };
 
@@ -90,5 +92,6 @@
 /*15*/	"iron balls",
 	"chains",
-	"venoms"
+	"venoms",
+	"furniture"
 };
 
@@ -177,5 +180,5 @@
     "dragon",			"elemental",		"fungus or mold",
     "gnome",			"giant humanoid",	0,
-    "jabberwock",		"Keystone Kop",		"lich",
+    "looking-glass creature",		"Keystone Kop",		"lich",
     "mummy",			"naga",			"ogre",
     "pudding or ooze",		"quantum mechanic",	"rust monster or disenchanter",
@@ -205,5 +208,5 @@
  */
 const struct symdef defsyms[MAXPCHARS] = {
-/* 0*/	{' ', "dark part of a room",C(NO_COLOR)},	/* stone */
+/* 0*/	{' ', "unexplored area",C(NO_COLOR)},	/* stone */
 	{'|', "wall",		C(CLR_GRAY)},	/* vwall */
 	{'-', "wall",		C(CLR_GRAY)},	/* hwall */
@@ -225,4 +228,5 @@
 	{'#', "tree",		C(CLR_GREEN)},	/* tree */
 	{'.', "floor of a room",C(CLR_GRAY)},	/* room */
+	{'.', "dark part of a room",C(CLR_BLACK)},	/* dark room */
 /*20*/	{'#', "corridor",	C(CLR_GRAY)},	/* dark corr */
 	{'#', "lit corridor",	C(CLR_GRAY)},	/* lit corr (see mapglyph.c) */
@@ -233,5 +237,4 @@
 	{'_', "altar",		C(CLR_GRAY)},	/* altar */
 	{'|', "grave",      C(CLR_GRAY)},   /* grave */
-	{'\\', "opulent throne",C(HI_GOLD)},	/* throne */
 #ifdef SINKS
 	{'#', "sink",		C(CLR_GRAY)},	/* sink */
@@ -239,5 +242,5 @@
 	{'#', "",		C(CLR_GRAY)},	/* sink */
 #endif
-/*30*/	{'{', "fountain",	C(CLR_BLUE)},	/* fountain */
+/*30*/	{'{', "fountain",	C(CLR_BRIGHT_BLUE)},	/* fountain */
 	{'}', "water",		C(CLR_BLUE)},	/* pool */
 	{'.', "ice",		C(CLR_CYAN)},	/* ice */
@@ -272,4 +275,7 @@
 	{'^', "anti-magic field", C(HI_ZAP)},	/* trap */
 	{'^', "polymorph trap",	C(CLR_BRIGHT_GREEN)},	/* trap */
+	{'^', "spear trap",	C(CLR_BROWN)},	/* trap */
+	{'^', "falling-rocks trap", C(CLR_GRAY)},	/* trap */
+	{'^', "magic beam trap", C(CLR_YELLOW)},	/* trap */
 	{'|', "wall",		C(CLR_GRAY)},	/* vbeam */
 	{'-', "wall",		C(CLR_GRAY)},	/* hbeam */
@@ -336,4 +342,5 @@
 	241,	/* S_tree:	plus or minus symbol */
 	0xfa,	/* S_room:	meta-z, centered dot */
+	g_FILLER(S_stone),	/* S_darkroom:	meta-z, centered dot */
 /*20*/	0xb0,	/* S_corr:	meta-0, light shading */
 	0xb1,	/* S_litcorr:	meta-1, medium shading */
@@ -344,5 +351,4 @@
 	g_FILLER(S_altar),
 	g_FILLER(S_grave),
-	g_FILLER(S_throne),
 	g_FILLER(S_sink),
 /*30*/	0xf4,	/* S_fountain:	meta-t, integral top half */
@@ -379,4 +385,7 @@
 	g_FILLER(S_anti_magic_trap),
 	g_FILLER(S_polymorph_trap),
+	g_FILLER(S_spear_trap),
+	g_FILLER(S_falling_rocks_trap),
+	g_FILLER(S_magic_beam_trap),
 	0xb3,	/* S_vbeam:	meta-3, vertical rule */
 	0xc4,	/* S_hbeam:	meta-D, horizontal rule */
@@ -435,4 +444,5 @@
 	0xe7,	/* S_tree:	meta-g, plus-or-minus */
 	0xfe,	/* S_room:	meta-~, centered dot */
+	g_FILLER(S_stone),	/* S_darkroom:	meta-~, centered dot */
 /*20*/	g_FILLER(S_corr),
 	g_FILLER(S_litcorr),
@@ -443,5 +453,4 @@
 	g_FILLER(S_altar),	/* 0xc3, \E)3: meta-C, dagger */
 	g_FILLER(S_grave),
-	g_FILLER(S_throne),
 	g_FILLER(S_sink),
 /*30*/	g_FILLER(S_fountain),	/* 0xdb, \E)3: meta-[, integral top half */
@@ -478,4 +487,7 @@
 	g_FILLER(S_anti_magic_trap),
 	g_FILLER(S_polymorph_trap),
+	g_FILLER(S_spear_trap),
+	g_FILLER(S_falling_rocks_trap),
+	g_FILLER(S_magic_beam_trap),
 	0xf8,	/* S_vbeam:	meta-x, vertical rule */
 	0xf1,	/* S_hbeam:	meta-q, horizontal rule */
@@ -540,5 +552,4 @@
 	g_FILLER(S_altar),
 	0xef,	/* S_grave:	same as open door */
-	g_FILLER(S_throne),
 	g_FILLER(S_sink),
 /*30*/	g_FILLER(S_fountain),
@@ -575,4 +586,5 @@
 	g_FILLER(S_anti_magic_trap),
 	g_FILLER(S_polymorph_trap),
+	g_FILLER(S_spear_trap),
 	g_FILLER(S_vbeam),
 	g_FILLER(S_hbeam),
@@ -729,5 +741,6 @@
 /*15*/	BALL_SYM,
 	CHAIN_SYM,
-	VENOM_SYM
+	VENOM_SYM,
+	FURNITURE_SYM
 };
 
@@ -772,5 +785,6 @@
 /*15*/	BALL_SYM,
 	CHAIN_SYM,
-	VENOM_SYM
+	VENOM_SYM,
+	FURNITURE_SYM
 };
 # endif /* ASCIIGRAPH */
@@ -866,4 +880,7 @@
 	    showsyms[S_anti_magic_trap] = 0x04;
 	    showsyms[S_polymorph_trap] = 0x04;
+	    showsyms[S_spear_trap] = 0x04;
+	    showsyms[S_falling_rocks_trap] = 0x04;
+	    showsyms[S_magic_beam_trap] = 0x04;
 #endif
 	}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/dungeon.c nethack/src/dungeon.c
--- nh_orig/src/dungeon.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/dungeon.c	2009-09-07 11:24:04.638417961 -0400
@@ -633,4 +633,8 @@
 	{ "wizard2",	&wiz2_level },
 	{ "wizard3",	&wiz3_level },
+#ifdef RECORD_ACHIEVE
+        { "minend",     &mineend_level },
+        { "soko1",      &sokoend_level },
+#endif
 	{ X_START,	&qstart_level },
 	{ X_LOCATE,	&qlocate_level },
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/eat.c nethack/src/eat.c
--- nh_orig/src/eat.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/eat.c	2010-04-29 10:53:23.923715306 -0400
@@ -135,7 +135,5 @@
 	{"soup made from", 20},
 	{"pureed",	500},
-#define ROTTEN_TIN 4
-	{"rotten",	-50},
-#define HOMEMADE_TIN 5
+#define HOMEMADE_TIN 4
 	{"homemade",	 50},
 	{"stir fried",   80},
@@ -144,12 +142,52 @@
 	{"dried",        55},
 	{"szechuan",     70},
-#define FRENCH_FRIED_TIN 11
+#define FRENCH_FRIED_TIN 10
 	{"french fried", 40},
 	{"sauteed",      95},
 	{"broiled",      80},
 	{"smoked",       50},
+	/* only specials below; ROTTEN_TIN used as marker */
+#define ROTTEN_TIN 14
+	{"rotten",	-50},
+#define SPINACH_TIN 15
+	{"spinach",	  0},
 	{"", 0}
 };
-#define TTSZ	SIZE(tintxts)
+
+int
+tin_content_idx(obj)
+     struct obj *obj;
+{
+    /* for tins, spe==-1 means player made it, and spe==1 means spinach */
+    if (obj->spe ==  1) return SPINACH_TIN;
+    if (obj->spe == -1) return HOMEMADE_TIN;
+    /* don't select special stuff here */
+    return (obj->o_id % ROTTEN_TIN);
+}
+
+char *
+tin_content_text(obj)
+     struct obj *obj;
+{
+    static char buf[BUFSZ];
+    static const char *tin_label_msgs[] = {
+	"simulation meat",
+	"meat-like product",
+	"soylent green",
+	"spoo",
+	"stone soup"
+    };
+    int idx = (obj->corpsenm == NON_PM) ? (obj->o_id % PM_LONG_WORM_TAIL) : obj->corpsenm;
+    int t = tin_content_idx(obj);
+    if (Hallucination)
+	sprintf(buf, "%s", tin_label_msgs[obj->o_id % SIZE(tin_label_msgs)]);
+    else {
+	if (t == SPINACH_TIN)
+	    sprintf(buf, "%s", tintxts[t].txt);
+	else
+	    snprintf(buf, BUFSZ, "%s %s", tintxts[t].txt, mons[idx].mname);
+    }
+    return upstart(buf);
+}
 
 static NEARDATA struct {
@@ -232,5 +270,5 @@
 			return;
 	} else if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL) {
-			adjalign(-1);		/* gluttony is unchivalrous */
+			major_sin();		/* gluttony is unchivalrous */
 			You_feel("like a glutton!");
 	}
@@ -454,4 +492,14 @@
 		return TRUE;
 	}
+	
+	/* Cavemen get a bonus for cannibalism */
+	if (Role_if(PM_CAVEMAN) && your_race(&mons[pm])) {
+		if (allowmsg) {
+			You("consume the corpse in accordance with ancient ritual.");
+			u.ualign.record += 5;
+			return FALSE;
+		}
+	}
+
 	return FALSE;
 }
@@ -625,10 +673,10 @@
 	    case TELEPAT:
 #ifdef DEBUG
-		if (telepathic(ptr)) {
+		if (gives_telepathy(ptr)) {
 			debugpline("can get telepathy");
 			return(TRUE);
 		} else  return(FALSE);
 #else
-		return(telepathic(ptr));
+		return(gives_telepathy(ptr));
 #endif
 	    default:
@@ -638,4 +686,19 @@
 }
 
+int
+gives_telepathy_incr(ptr)
+struct permonst *ptr;
+{
+    if (ptr == &mons[PM_FLOATING_EYE]) return 6;
+    if (ptr == &mons[PM_MIND_FLAYER]) return 6;
+    if (ptr == &mons[PM_MASTER_MIND_FLAYER]) return 9;
+    if (ptr == &mons[PM_KOBOLD_SHAMAN]) return 3;
+    if (ptr == &mons[PM_GOBLIN_SHAMAN]) return 3;
+    if (ptr == &mons[PM_ORC_SHAMAN]) return 3;
+    if (ptr == &mons[PM_HILL_GIANT_SHAMAN]) return 3;
+    if (ptr == &mons[PM_GNOMISH_WIZARD]) return 3;
+    return 0;
+}
+
 /* givit() tries to give you an intrinsic based on the monster's level
  * and what type of intrinsic it is trying to give you.
@@ -647,22 +710,18 @@
 {
 	register int chance;
+	long percentincrease;
 
 #ifdef DEBUG
 	debugpline("Attempting to give intrinsic %d", type);
 #endif
-	/* some intrinsics are easier to get than others */
+	/* some intrinsics are easier to get than others...
+	 * the values seem high because there's a chance to get each when
+	 * you eat a critter now, so it has to be adjusted slightly */
 	switch (type) {
-		case POISON_RES:
-			if ((ptr == &mons[PM_KILLER_BEE] ||
-					ptr == &mons[PM_SCORPION]) && !rn2(4))
-				chance = 1;
-			else
-				chance = 15;
-			break;
 		case TELEPORT:
-			chance = 10;
+			chance = 30;
 			break;
 		case TELEPORT_CONTROL:
-			chance = 12;
+			chance = 36;
 			break;
 		case TELEPAT:
@@ -670,5 +729,5 @@
 			break;
 		default:
-			chance = 15;
+			chance = 1;	/* the rest use the new system, give it to them all the time */
 			break;
 	}
@@ -677,13 +736,16 @@
 		return;		/* failed die roll */
 
+	percentincrease = (ptr->cwt / 90);
+	if (percentincrease < 5) { percentincrease = 5; }
+
 	switch (type) {
+		 /* All these use the new system, which is based on corpse weight. */
 	    case FIRE_RES:
 #ifdef DEBUG
 		debugpline("Trying to give fire resistance");
 #endif
-		if(!(HFire_resistance & FROMOUTSIDE)) {
-			You(Hallucination ? "be chillin'." :
-			    "feel a momentary chill.");
-			HFire_resistance |= FROMOUTSIDE;
+		if((HFire_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
+			You(Hallucination ? "be chillin'." : "feel slightly more chill.");
+			incr_resistance(&HFire_resistance,percentincrease);
 		}
 		break;
@@ -692,7 +754,7 @@
 		debugpline("Trying to give sleep resistance");
 #endif
-		if(!(HSleep_resistance & FROMOUTSIDE)) {
-			You_feel("wide awake.");
-			HSleep_resistance |= FROMOUTSIDE;
+		if((HSleep_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
+			You_feel("a bit perkier.");
+			incr_resistance(&HSleep_resistance,percentincrease);
 		}
 		break;
@@ -701,7 +763,7 @@
 		debugpline("Trying to give cold resistance");
 #endif
-		if(!(HCold_resistance & FROMOUTSIDE)) {
-			You_feel("full of hot air.");
-			HCold_resistance |= FROMOUTSIDE;
+		if((HCold_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
+			You_feel("a little bit warmer.");
+			incr_resistance(&HCold_resistance,percentincrease);
 		}
 		break;
@@ -710,9 +772,7 @@
 		debugpline("Trying to give disintegration resistance");
 #endif
-		if(!(HDisint_resistance & FROMOUTSIDE)) {
-			You_feel(Hallucination ?
-			    "totally together, man." :
-			    "very firm.");
-			HDisint_resistance |= FROMOUTSIDE;
+		if((HDisint_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
+			You_feel(Hallucination ? "totally together, man." : "a touch more firm.");
+			incr_resistance(&HDisint_resistance,percentincrease);
 		}
 		break;
@@ -721,10 +781,10 @@
 		debugpline("Trying to give shock resistance");
 #endif
-		if(!(HShock_resistance & FROMOUTSIDE)) {
+		if((HShock_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
 			if (Hallucination)
 				You_feel("grounded in reality.");
 			else
-				Your("health currently feels amplified!");
-			HShock_resistance |= FROMOUTSIDE;
+				Your("health is slightly more amplified!");
+			incr_resistance(&HShock_resistance,percentincrease);
 		}
 		break;
@@ -733,10 +793,10 @@
 		debugpline("Trying to give poison resistance");
 #endif
-		if(!(HPoison_resistance & FROMOUTSIDE)) {
-			You_feel(Poison_resistance ?
-				 "especially healthy." : "healthy.");
-			HPoison_resistance |= FROMOUTSIDE;
+		if((HPoison_resistance & (TIMEOUT|FROMRACE|FROMEXPER)) < 100) {
+			You_feel(how_resistant(POISON_RES) == 100 ? "noticeably healthier." : "healthier.");
+			incr_resistance(&HPoison_resistance,percentincrease);
 		}
 		break;
+		/* From here forward, we'll use the old stuff.  But. */
 	    case TELEPORT:
 #ifdef DEBUG
@@ -769,7 +829,16 @@
 			    "a strange mental acuity.");
 			HTelepat |= FROMOUTSIDE;
-			/* If blind, make sure monsters show up. */
-			if (Blind) see_monsters();
+			u.u_telepathy_dist += gives_telepathy_incr(ptr);
+		} else {
+		    int incr = gives_telepathy_incr(ptr);
+		    if (incr && (u.u_telepathy_dist < 600)) {
+			You_feel(Hallucination ?
+				 "like everyone is tad closer." :
+				 "your senses expand a bit.");
+			u.u_telepathy_dist += incr;
+		    }
 		}
+		/* If blind, make sure monsters show up at the correct range. */
+		if (Blind) see_monsters();
 		break;
 	    default:
@@ -829,11 +898,9 @@
 		break;
 	    case PM_STALKER:
+			incr_itimeout(&HInvis, (long)rn1(100, 50));
 		if(!Invis) {
-			set_itimeout(&HInvis, (long)rn1(100, 50));
 			if (!Blind && !BInvis) self_invis_message();
 		} else {
-			if (!(HInvis & INTRINSIC)) You_feel("hidden!");
-			HInvis |= FROMOUTSIDE;
-			HSee_invisible |= FROMOUTSIDE;
+				incr_itimeout(&HSee_invisible, (long)rn1(100, 50));
 		}
 		newsym(u.ux, u.uy);
@@ -863,5 +930,5 @@
 		    if (u.usteed) dismount_steed(DISMOUNT_FELL);
 #endif
-		    nomul(-tmp);
+		    nomul(-tmp, "pretending to be a pile of gold");
 		    Sprintf(buf, Hallucination ?
 			"You suddenly dread being peeled and mimic %s again!" :
@@ -884,9 +951,13 @@
 		if (HFast & INTRINSIC) {
 			HFast &= ~INTRINSIC;
+			if (!Slow) {
 			You("seem slower.");
+			}
 		} else {
 			HFast |= FROMOUTSIDE;
+			if (!Slow) {
 			You("seem faster.");
 		}
+		}
 		break;
 	    case PM_LIZARD:
@@ -947,27 +1018,20 @@
 		 */
 
+		/* Above proof recorded for posterity, even though i'm about
+		 * to vigorously jostle the means of getting most of
+		 * the resistances in the first place; it's no longer random
+		 * for anything except telecontrol, teleport, and telepathy.
+		 *
+		 * Derek S. Ray, October 28, 2007
+		 */
+
 		 count = 0;	/* number of possible intrinsics */
 		 tmp = 0;	/* which one we will try to give */
 		 for (i = 1; i <= LAST_PROP; i++) {
 			if (intrinsic_possible(i, ptr)) {
-				count++;
-				/* a 1 in count chance of replacing the old
-				 * one with this one, and a count-1 in count
-				 * chance of keeping the old one.  (note
-				 * that 1 in 1 and 0 in 1 are what we want
-				 * for the first one
-				 */
-				if (!rn2(count)) {
-#ifdef DEBUG
-					debugpline("Intrinsic %d replacing %d",
-								i, tmp);
-#endif
-					tmp = i;
-				}
+				givit(i,ptr);
 			}
 		 }
 
-		 /* if any found try to give them one */
-		 if (count) givit(tmp, ptr);
 	    }
 	    break;
@@ -990,5 +1054,5 @@
     if (Role_if(PM_MONK)) {
 	You_feel("guilty.");
-	adjalign(-1);
+		venial_sin();
     }
     return;
@@ -1044,9 +1108,8 @@
 	    }
 	    r = tin.tin->cursed ? ROTTEN_TIN :	/* always rotten if cursed */
-		    (tin.tin->spe == -1) ? HOMEMADE_TIN :  /* player made it */
-			rn2(TTSZ-1);		/* else take your pick */
+		tin_content_idx(tin.tin);
 	    if (r == ROTTEN_TIN && (tin.tin->corpsenm == PM_LIZARD ||
 			tin.tin->corpsenm == PM_LICHEN))
-		r = HOMEMADE_TIN;		/* lizards don't rot */
+		r = tin_content_idx(tin.tin);		/* lizards don't rot */
 	    else if (tin.tin->spe == -1 && !tin.tin->blessed && !rn2(7))
 		r = ROTTEN_TIN;			/* some homemade tins go bad */
@@ -1225,5 +1288,5 @@
 		pline_The("world spins and %s %s.", what, where);
 		flags.soundok = 0;
-		nomul(-rnd(10));
+		nomul(-rnd(10), "unconscious from rotten food");
 		nomovemsg = "You are conscious again.";
 		afternmv = Hear_again;
@@ -1290,7 +1353,7 @@
 		tp++;
 		pline("Ecch - that must have been poisonous!");
-		if(!Poison_resistance) {
-			losestr(rnd(4));
-			losehp(rnd(15), "poisonous corpse", KILLED_BY_AN);
+		if(how_resistant(POISON_RES) < 100) {
+			losestr(resist_reduce(rnd(4),POISON_RES));
+			losehp(resist_reduce(rnd(15),POISON_RES), "poisonous corpse", KILLED_BY_AN);
 		} else	You("seem unaffected by the poison.");
 	/* now any corpse left too long will make you mildly ill */
@@ -1554,9 +1617,9 @@
 	    case RIN_FREE_ACTION:
 		/* Give sleep resistance instead */
-		if (!(HSleep_resistance & FROMOUTSIDE))
+			if (how_resistant(SLEEP_RES) < 100) {
 		    accessory_has_effect(otmp);
-		if (!Sleep_resistance)
 		    You_feel("wide awake.");
-		HSleep_resistance |= FROMOUTSIDE;
+			}
+			incr_resistance(&HSleep_resistance,100);
 		break;
 	    case AMULET_OF_CHANGE:
@@ -1587,4 +1650,5 @@
 	    case RIN_SUSTAIN_ABILITY:
 	    case AMULET_OF_LIFE_SAVING:
+		 case AMULET_OF_POWER:
 	    case AMULET_OF_REFLECTION: /* nice try */
 	    /* can't eat Amulet of Yendor or fakes,
@@ -1643,4 +1707,5 @@
 	if (otmp == uwep && otmp->quan == 1L) uwepgone();
 	if (otmp == uquiver && otmp->quan == 1L) uqwepgone();
+	if (otmp == ulauncher && otmp->quan == 1L) ulwepgone();
 	if (otmp == uswapwep && otmp->quan == 1L) uswapwepgone();
 
@@ -1694,5 +1759,5 @@
 		    u.mh += otmp->cursed ? -rnd(20) : rnd(20);
 		    if (u.mh > u.mhmax) {
-			if (!rn2(17)) u.mhmax++;
+			if (!rn2(17)) gainmaxhp(1);
 			u.mh = u.mhmax;
 		    } else if (u.mh <= 0) {
@@ -1702,5 +1767,5 @@
 		    u.uhp += otmp->cursed ? -rnd(20) : rnd(20);
 		    if (u.uhp > u.uhpmax) {
-			if(!rn2(17)) u.uhpmax++;
+				if(!rn2(17)) gainmaxhp(1);
 			u.uhp = u.uhpmax;
 		    } else if (u.uhp <= 0) {
@@ -1804,5 +1869,5 @@
 		else return 2;
 	}
-	if (cadaver && poisonous(&mons[mnum]) && !Poison_resistance) {
+	if (cadaver && poisonous(&mons[mnum]) && how_resistant(POISON_RES) < 100) {
 		/* poisonous */
 		Sprintf(buf, "%s like %s might be poisonous! %s",
@@ -1944,4 +2009,9 @@
 	    victual.usedtime = 0;
 	    victual.canchoke = (u.uhs == SATIATED);
+		 /* for characters with code of conduct, gluttony is bad */
+		if (Role_if(PM_KNIGHT) && u.ualign.type == A_LAWFUL) {
+			You("are slightly ashamed for overeating.");
+			venial_sin();
+		}
 		/* Note: gold weighs 1 pt. for each 1000 pieces (see */
 		/* pickup.c) so gold and non-gold is consistent. */
@@ -1970,7 +2040,7 @@
 	    if (otmp->oclass == WEAPON_CLASS && otmp->opoisoned) {
 		pline("Ecch - that must have been poisonous!");
-		if(!Poison_resistance) {
-		    losestr(rnd(4));
-		    losehp(rnd(15), xname(otmp), KILLED_BY_AN);
+		if (how_resistant(POISON_RES) < 100) {
+		    losestr(resist_reduce(rnd(4),POISON_RES));
+		    losehp(resist_reduce(rnd(15),POISON_RES), xname(otmp), KILLED_BY_AN);
 		} else
 		    You("seem unaffected by the poison.");
@@ -2245,5 +2315,5 @@
 reset_faint()	/* call when a faint must be prematurely terminated */
 {
-	if(is_fainted()) nomul(0);
+	if(is_fainted()) nomul(0, 0);
 }
 
@@ -2256,5 +2326,5 @@
 
 		flags.soundok = 0;
-		nomul(-10+(u.uhunger/10));
+		nomul(-10+(u.uhunger/10), "fainted from lack of food");
 		nomovemsg = "You regain consciousness.";
 		afternmv = unfaint;
@@ -2273,7 +2343,8 @@
 
 	newhs = (h > 1000) ? SATIATED :
-		(h > 150) ? NOT_HUNGRY :
+		(h > 200) ? NOT_HUNGRY :
 		(h > 50) ? HUNGRY :
-		(h > 0) ? WEAK : FAINTING;
+		(h > 0) ? WEAK : 
+		FAINTING;
 
 	/* While you're eating, you may pass from WEAK to HUNGRY to NOT_HUNGRY.
@@ -2321,5 +2392,5 @@
 				You("faint from lack of food.");
 				flags.soundok = 0;
-				nomul(-10+(u.uhunger/10));
+				nomul(-10+(u.uhunger/10), "fainted from lack of food");
 				nomovemsg = "You regain consciousness.";
 				afternmv = unfaint;
@@ -2490,5 +2561,5 @@
 {
 	make_sick(0L, (char *) 0, TRUE, SICK_VOMITABLE);
-	nomul(-2);
+	nomul(-2, "vomiting");
 }
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/end.c nethack/src/end.c
--- nh_orig/src/end.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/end.c	2010-08-16 13:26:43.564845433 -0400
@@ -11,4 +11,6 @@
 #endif
 #include "dlb.h"
+#include <sys/types.h>
+#include <sys/stat.h>
 
 	/* these probably ought to be generated by makedefs, like LAST_GEM */
@@ -35,4 +37,5 @@
 # endif
 #endif
+STATIC_DCL long FDECL(count_score,(int));
 STATIC_DCL void FDECL(disclose,(int,BOOLEAN_P));
 STATIC_DCL void FDECL(get_valuables, (struct obj *));
@@ -41,5 +44,13 @@
 STATIC_DCL void FDECL(savelife, (int));
 STATIC_DCL void FDECL(list_vanquished, (CHAR_P,BOOLEAN_P));
+#ifdef DUMP_LOG
+extern char msgs[][BUFSZ];
+extern int lastmsg;
+extern void NDECL(dump_spells);
+void FDECL(do_vanquished, (int, BOOLEAN_P, BOOLEAN_P));
+STATIC_DCL void FDECL(list_genocided, (int, BOOLEAN_P, BOOLEAN_P));
+#else
 STATIC_DCL void FDECL(list_genocided, (CHAR_P,BOOLEAN_P));
+#endif /* DUMP_LOG */
 STATIC_DCL boolean FDECL(should_query_disclose_option, (int,char *));
 
@@ -87,4 +98,75 @@
 extern const char * const killed_by_prefix[];	/* from topten.c */
 
+#ifdef DUMP_LOG
+FILE *dump_fp = (FILE *)0;  /* file pointer for dumps */
+/* functions dump_init, dump_exit and dump are from the dump patch */
+
+void
+dump_init ()
+{
+#ifdef UNIX
+	mode_t dumpmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
+#endif
+  if (dump_fn[0]) {
+    char *p = (char *) strstr(dump_fn, "%n");
+    if (p) {
+      int new_dump_fn_len = strlen(dump_fn)+strlen(plname)-2; /* %n */
+      char *new_dump_fn = (char *) alloc((unsigned)(new_dump_fn_len+1));
+      char *q = new_dump_fn;
+      strncpy(q, dump_fn, p-dump_fn);
+      q += p-dump_fn;
+      strncpy(q, plname, strlen(plname) + 1);
+      regularize(q);
+      q[strlen(plname)] = '\0';
+      q += strlen(q);
+      p += 2;	/* skip "%n" */
+      strncpy(q, p, strlen(p));
+      new_dump_fn[new_dump_fn_len] = '\0';
+
+      dump_fp = fopen(new_dump_fn, "w");
+      if (!dump_fp) {
+			pline("Can't open %s for output.", new_dump_fn);
+			pline("Dump file not created.");
+      } else {
+			fclose(dump_fp);
+			dump_fp = fopen(new_dump_fn, "w");
+#ifdef UNIX
+			chmod(new_dump_fn,dumpmode);
+#endif
+		}
+      free(new_dump_fn);
+      
+    } else {
+      dump_fp = fopen (dump_fn, "w");
+
+      if (!dump_fp) {
+			pline("Can't open %s for output.", dump_fn);
+			pline("Dump file not created.");
+      } else {
+			fclose(dump_fp);
+			dump_fp = fopen(dump_fn, "w");
+#ifdef UNIX
+			chmod(dump_fn,dumpmode);
+#endif
+		}
+    }
+  }
+}
+
+void
+dump_exit ()
+{
+  if (dump_fp)
+    fclose (dump_fp);
+}
+
+void dump (pre, str)
+     char *pre, *str;
+{
+  if (dump_fp)
+    fprintf (dump_fp, "%s%s\n", pre, str);
+}
+#endif  /* DUMP_LOG */
+
 /*ARGSUSED*/
 void
@@ -102,5 +184,5 @@
 		curs_on_u();
 		wait_synch();
-		if(multi > 0) nomul(0);
+		if(multi > 0) nomul(0, 0);
 	} else {
 		(void)done2();
@@ -120,5 +202,5 @@
 		curs_on_u();
 		wait_synch();
-		if(multi > 0) nomul(0);
+		if(multi > 0) nomul(0, 0);
 		if(multi == 0) {
 		    u.uinvulnerable = FALSE;	/* avoid ctrl-C bug -dlc */
@@ -225,6 +307,17 @@
 	}
 
-	if (multi) Strcat(buf, ", while helpless");
+	if (multi) {
+	  if (strlen(multi_txt) > 0)
+	    Sprintf(eos(buf), ", while %s", multi_txt);
+	  else
+	    Strcat(buf, ", while helpless");
+	}
 	killer = buf;
+	ukiller = mtmp;
+	if (ukiller && (likes_gold(ukiller->data) || likes_gems(ukiller->data) ||
+				likes_objs(ukiller->data) || likes_magic(ukiller->data) ||
+				is_covetous(ukiller->data))) {
+		pline("%s rummages through your possessions.",Monnam(ukiller));
+	}
 	if (mtmp->data->mlet == S_WRAITH)
 		u.ugrave_arise = PM_WRAITH;
@@ -245,5 +338,5 @@
 }
 
-#if defined(WIN32)
+#if defined(WIN32) || defined(UNIX)
 #define NOTIFY_NETHACK_BUGS
 #endif
@@ -273,6 +366,6 @@
 # if defined(NOTIFY_NETHACK_BUGS)
 	if (!wizard)
-	    raw_printf("Report the following error to \"%s\".",
-			"nethack-bugs@nethack.org");
+	    raw_printf("Report the following error to \"%s\""
+				 ", and it may be possible to rebuild.", "spork@sporkhack.com");
 	else if (program_state.something_worth_saving)
 	    raw_print("\nError save file being written.\n");
@@ -367,5 +460,11 @@
 	    if (!done_stopprint) {
 		c = ask ? yn_function(qbuf, ynqchars, defquery) : defquery;
-		if (c == 'y') {
+	    } else {
+		c = 'n';
+	    }
+		{
+#ifdef DUMP_LOG
+			boolean want_disp = (c == 'y')? TRUE: FALSE;
+#endif
 			struct obj *obj;
 
@@ -374,9 +473,15 @@
 			    obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
 			}
+#ifdef DUMP_LOG
+			(void) dump_inventory((char *)0, TRUE, want_disp);
+			do_containerconts(invent, TRUE, TRUE, TRUE, want_disp);
+#else
+			if (c == 'y') {
 			(void) display_inventory((char *)0, TRUE);
 			container_contents(invent, TRUE, TRUE);
 		}
-		if (c == 'q')  done_stopprint++;
+#endif /* DUMP_LOG */
 	    }
+		if (c == 'q')  done_stopprint++;
 	}
 
@@ -389,12 +494,26 @@
 	    if (c == 'q') done_stopprint++;
 	}
+#ifdef DUMP_LOG
+	if (dump_fp) {
+	  dump_enlightenment((int) (how >= PANICKED ? 1 : 2));
+	  dump_spells();
+	}
+#endif
 
 	ask = should_query_disclose_option('v', &defquery);
+#ifdef DUMP_LOG
+	do_vanquished(defquery, ask, TRUE);
+#else
 	if (!done_stopprint)
 	    list_vanquished(defquery, ask);
+#endif
 
 	ask = should_query_disclose_option('g', &defquery);
 	if (!done_stopprint)
+#ifdef DUMP_LOG
+	    list_genocided(defquery, ask,TRUE);
+#else
 	    list_genocided(defquery, ask);
+#endif
 
 	ask = should_query_disclose_option('c', &defquery);
@@ -406,4 +525,10 @@
 	    if (c == 'q') done_stopprint++;
 	}
+#ifdef DUMP_LOG
+	if (dump_fp) {
+	    dump_conduct(how >= PANICKED ? 1 : 2);
+	    dump_weapon_skill();
+	}
+#endif
 }
 
@@ -524,4 +649,9 @@
 				OBJ_NAME(objects[otmp->otyp]),
 			value, currency(value), points);
+#ifdef DUMP_LOG
+		if (dump_fp)
+		  dump("", pbuf);
+		if (endwin != WIN_ERR)
+#endif
 		putstr(endwin, 0, pbuf);
 	    }
@@ -543,4 +673,5 @@
 	struct obj *corpse = (struct obj *)0;
 	long umoney;
+	long uscore;
 
 	if (how == TRICKED) {
@@ -574,6 +705,16 @@
 		pline("But wait...");
 		makeknown(AMULET_OF_LIFE_SAVING);
-		Your("medallion %s!",
-		      !Blind ? "begins to glow" : "feels warm");
+		Your("medallion %s!", !Blind ? "begins to glow" : "feels warm");
+		/* Keep it blessed! */
+		if (uamul->cursed && !rn2(2)) {
+			pline("The chain on your medallion breaks, and you hear a faint giggling!");
+			Your("medallion suddenly falls off!");
+			pline("It doesn't look like you're going to make it after all...");
+			killer_format = KILLED_BY;
+			Strcpy(kilbuf, "a cursed amulet of life saving");
+			killer = kilbuf;
+			Lifesaved = 0L;
+			uamul = 0;
+		} else {
 		if (how == CHOKING) You("vomit ...");
 		You_feel("much better!");
@@ -587,9 +728,15 @@
 			pline("Unfortunately you are still genocided...");
 		else {
+#ifdef WISH_TRACKER
+				Sprintf(pbuf,"%s lifesaved instead of being killed by a %s on T:%d",plname,killer,moves);
+				makeannounce(pbuf);
+#endif
 			killer = 0;
 			killer_format = 0;
+				ukiller = (struct monst*)0;
 			return;
 		}
 	}
+	}
 	if ((
 #ifdef WIZARD
@@ -604,4 +751,5 @@
 		killer = 0;
 		killer_format = 0;
+		ukiller = (struct monst*)0;
 		return;
 	}
@@ -612,7 +760,24 @@
 
 die:
+	kilbuf[BUFSZ-1] = 0;	 /* cheap hack bugfix */
 	program_state.gameover = 1;
 	/* in case of a subsequent panic(), there's no point trying to save */
 	program_state.something_worth_saving = 0;
+#ifdef DUMP_LOG
+	/* D: Grab screen dump right here */
+	if (dump_fn[0]) {
+	  dump_init();
+	  Sprintf(pbuf, "%s, %s %s %s %s", plname,
+		  aligns[1 - u.ualign.type].adj,
+		  genders[flags.female].adj,
+		  urace.adj,
+		  (flags.female && urole.name.f)?
+		   urole.name.f : urole.name.m);
+	  dump("", pbuf);
+	  /* D: Add a line for clearance from the screen dump */
+	  dump("", "");
+	  dump_screen();
+	}
+#endif /* DUMP_LOG */
 	/* render vision subsystem inoperative */
 	iflags.vision_inited = 0;
@@ -621,4 +786,10 @@
 	inven_inuse(TRUE);
 
+#ifdef RECORD_REALTIME
+        /* Update the realtime counter to reflect the playtime of the current
+         * game. */
+        realtime_data.realtime = get_realtime();
+#endif /* RECORD_REALTIME */
+
 	/* Sometimes you die on the first move.  Life's not fair.
 	 * On those rare occasions you get hosed immediately, go out
@@ -693,6 +864,28 @@
 	if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE);
 
-	if (strcmp(flags.end_disclose, "none") && how != PANICKED)
+	/* Must pre-calculate score here for correct logfile writing */
+
+#ifdef LOGFILE
+	uscore = count_score(how);
+	write_log_entry(how,uscore);
+#endif
+
+	if (strcmp(flags.end_disclose, "none") && how != PANICKED) {
 		disclose(how, taken);
+#if defined(DUMP_LOG) && defined(DUMPMSGS)
+		if (lastmsg >= 0) {
+		  dump ("", "Latest messages");
+		  for (i = lastmsg + 1; i < DUMPMSGS; i++) {
+		    if (msgs[i] && strcmp(msgs[i], "") )
+		      dump ("  ", msgs[i]);
+		  } 
+		  for (i = 0; i <= lastmsg; i++) {
+		    if (msgs[i] && strcmp(msgs[i], "") )
+		      dump ("  ", msgs[i]);
+		  } 
+		  dump ("","");
+		}
+#endif
+	}
 	/* finish_paybill should be called after disclosure but before bones */
 	if (bones_ok && taken) finish_paybill();
@@ -771,5 +964,4 @@
 	}
 
-	if (!done_stopprint) {
 	    Sprintf(pbuf, "%s %s the %s...", Goodbye(), plname,
 		   how != ASCENDED ?
@@ -777,7 +969,11 @@
 		         urole.name.f : urole.name.m) :
 		      (const char *) (flags.female ? "Demigoddess" : "Demigod"));
+	if (!done_stopprint) {
 	    putstr(endwin, 0, pbuf);
 	    putstr(endwin, 0, "");
 	}
+#ifdef DUMP_LOG
+	if (dump_fp) dump("", pbuf);
+#endif
 
 	if (how == ESCAPED || how == ASCENDED) {
@@ -806,8 +1002,7 @@
 	    viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
 	    mtmp = mydogs;
-	    if (!done_stopprint) Strcpy(pbuf, "You");
+	    Strcpy(pbuf, "You");
 	    if (mtmp) {
 		while (mtmp) {
-		    if (!done_stopprint)
 			Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
 		    if (mtmp->mtame)
@@ -816,13 +1011,19 @@
 		}
 		if (!done_stopprint) putstr(endwin, 0, pbuf);
+#ifdef DUMP_LOG
+		if (dump_fp) dump("", pbuf);
+#endif
 		pbuf[0] = '\0';
 	    } else {
 		if (!done_stopprint) Strcat(pbuf, " ");
 	    }
-	    if (!done_stopprint) {
 		Sprintf(eos(pbuf), "%s with %ld point%s,",
 			how==ASCENDED ? "went to your reward" :
 					"escaped from the dungeon",
 			u.urexp, plur(u.urexp));
+#ifdef DUMP_LOG
+	    if (dump_fp) dump("", pbuf);
+#endif
+	    if (!done_stopprint) {
 		putstr(endwin, 0, pbuf);
 	    }
@@ -830,5 +1031,8 @@
 	    if (!done_stopprint)
 		artifact_score(invent, FALSE, endwin);	/* list artifacts */
-
+#ifdef DUMP_LOG
+	    else
+		artifact_score(invent, FALSE, WIN_ERR);
+#endif
 	    /* list valuables here */
 	    for (val = valuables; val->list; val++) {
@@ -856,8 +1060,11 @@
 		    }
 		    putstr(endwin, 0, pbuf);
+#ifdef DUMP_LOG
+		    if (dump_fp) dump("", pbuf);
+#endif
 		}
 	    }
 
-	} else if (!done_stopprint) {
+	} else {
 	    /* did not escape or ascend */
 	    if (u.uz.dnum == 0 && u.uz.dlevel <= 0) {
@@ -879,19 +1086,30 @@
 	    Sprintf(eos(pbuf), " with %ld point%s,",
 		    u.urexp, plur(u.urexp));
-	    putstr(endwin, 0, pbuf);
+	    if (!done_stopprint) putstr(endwin, 0, pbuf);
+#ifdef DUMP_LOG
+	    if (dump_fp) dump("", pbuf);
+#endif
 	}
 
-	if (!done_stopprint) {
 	    Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.",
 		    umoney, plur(umoney), moves, plur(moves));
-	    putstr(endwin, 0, pbuf);
+	if (!done_stopprint)  putstr(endwin, 0, pbuf);
+#ifdef DUMP_LOG
+	if (dump_fp) {
+	  dump("", pbuf);
+	  Sprintf(pbuf, "Killer: %s", killer);
+	  dump("", pbuf);
 	}
-	if (!done_stopprint) {
+#endif
 	    Sprintf(pbuf,
 	     "You were level %d with a maximum of %d hit point%s when you %s.",
 		    u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]);
+	if (!done_stopprint) {
 	    putstr(endwin, 0, pbuf);
 	    putstr(endwin, 0, "");
 	}
+#ifdef DUMP_LOG
+	    if (dump_fp) dump("", pbuf);
+#endif
 	if (!done_stopprint)
 	    display_nhwindow(endwin, TRUE);
@@ -910,4 +1128,7 @@
 	    topten(how);
 	}
+#ifdef DUMP_LOG
+	if (dump_fp) dump_exit();
+#endif
 
 	if(done_stopprint) { raw_print(""); raw_print(""); }
@@ -920,6 +1141,21 @@
 struct obj *list;
 boolean identified, all_containers;
+#ifdef DUMP_LOG
+{
+	do_containerconts(list, identified, all_containers, FALSE, TRUE);
+}
+
+void do_containerconts(list, identified, all_containers, want_dump, want_disp)
+struct obj *list;
+boolean identified, all_containers, want_dump, want_disp;
+#endif
+/* The original container_contents function */
 {
 	register struct obj *box, *obj;
+#ifdef SORTLOOT
+        struct obj **oarray;
+        int i,j,n;
+        char *invlet;
+#endif /* SORTLOOT */
 	char buf[BUFSZ];
 
@@ -930,8 +1166,57 @@
 		} else if (box->cobj) {
 		    winid tmpwin = create_nhwindow(NHW_MENU);
+#ifdef SORTLOOT
+		    /* count the number of items */
+		    for (n = 0, obj = box->cobj; obj; obj = obj->nobj) n++;
+		    /* Make a temporary array to store the objects sorted */
+		    oarray = (struct obj **) alloc(n*sizeof(struct obj*));
+
+		    /* Add objects to the array */
+		    i = 0;
+		    invlet = flags.inv_order;
+		nextclass:
+		    for (obj = box->cobj; obj; obj = obj->nobj) {
+                      if (!flags.sortpack || obj->oclass == *invlet) {
+			if (iflags.sortloot == 'f'
+			    || iflags.sortloot == 'l') {
+			  /* Insert object at correct index */
+			  for (j = i; j; j--) {
+			    if (strcmpi(cxname2(obj), cxname2(oarray[j-1]))>0
+			    || (flags.sortpack &&
+				oarray[j-1]->oclass != obj->oclass))
+			      break;
+			    oarray[j] = oarray[j-1];
+			  }
+			  oarray[j] = obj;
+			  i++;
+			} else {
+			  /* Just add it to the array */
+			  oarray[i++] = obj;
+			}
+		      }
+		    } /* for loop */
+		    if (flags.sortpack) {
+		      if (*++invlet) goto nextclass;
+		    }
+#endif /* SORTLOOT */
+#ifdef DUMP_LOG
+		    if (want_disp)
+#endif
 		    Sprintf(buf, "Contents of %s:", the(xname(box)));
+#ifdef DUMP_LOG
+		    if (want_disp) {
+#endif
 		    putstr(tmpwin, 0, buf);
 		    putstr(tmpwin, 0, "");
+#ifdef DUMP_LOG
+		    }
+		    if (dump_fp) dump("", buf);
+#endif
+#ifdef SORTLOOT
+		    for (i = 0; i < n; i++) {
+			obj = oarray[i];
+#else
 		    for (obj = box->cobj; obj; obj = obj->nobj) {
+#endif
 			if (identified) {
 			    makeknown(obj->otyp);
@@ -939,13 +1224,50 @@
 			    obj->dknown = obj->rknown = 1;
 			}
+#ifdef DUMP_LOG
+ 			if (want_dump)  dump("  ", doname(obj));
+ 			if (want_disp)
+#endif
 			putstr(tmpwin, 0, doname(obj));
 		    }
+#ifdef DUMP_LOG
+		    if (want_dump)  dump("","");
+		    if (want_disp) {
+#endif
 		    display_nhwindow(tmpwin, TRUE);
 		    destroy_nhwindow(tmpwin);
-		    if (all_containers)
+#ifdef DUMP_LOG
+		    }
+		    if (all_containers) {
+			do_containerconts(box->cobj, identified, TRUE,
+					  want_dump, want_disp);
+#else
+		    if (all_containers) {
 			container_contents(box->cobj, identified, TRUE);
+#endif
+			 }
+		} else {
+			if (box->otyp == BAG_OF_POO) {
+				Sprintf(buf," is rather full of %s poo.",rndmonnam());
+			}
+#ifdef DUMP_LOG
+		    if (want_disp) {
+#endif
+				 if (box->otyp == BAG_OF_POO) {
+					 pline("%s%s",The(xname(box)),buf);
 		} else {
 		    pline("%s empty.", Tobjnam(box, "are"));
+				 }
 		    display_nhwindow(WIN_MESSAGE, FALSE);
+#ifdef DUMP_LOG
+		    }
+		    if (want_dump) {
+				 if (box->otyp == BAG_OF_POO) {
+					 dump(The(xname(box)),buf);
+				 } else {
+					dump(The(xname(box)), " is empty.");
+				 }
+		      dump("", "");
+		    }
+#endif
 		}
 	    }
@@ -978,4 +1300,15 @@
 char defquery;
 boolean ask;
+#ifdef DUMP_LOG
+{
+  do_vanquished(defquery, ask, FALSE);
+}
+
+void
+do_vanquished(defquery, ask, want_dump)
+int defquery;
+boolean ask;
+boolean want_dump;
+#endif
 {
     register int i, lev;
@@ -997,5 +1330,10 @@
      */
     if (ntypes != 0) {
-	c = ask ? yn_function("Do you want an account of creatures vanquished?",
+#ifdef DUMP_LOG
+	c = done_stopprint ? 'n': ask ?
+#else
+	c = ask ?
+#endif
+	  yn_function("Do you want an account of creatures vanquished?",
 			      ynqchars, defquery) : defquery;
 	if (c == 'q') done_stopprint++;
@@ -1004,4 +1342,8 @@
 	    putstr(klwin, 0, "Vanquished creatures:");
 	    putstr(klwin, 0, "");
+#ifdef DUMP_LOG
+	} /* the original end of block removed by the patch */
+	    if (want_dump)  dump("", "Vanquished creatures");
+#endif
 
 	    /* countdown by monster "toughness" */
@@ -1031,18 +1373,33 @@
 				    nkilled, makeplural(mons[i].mname));
 		    }
-		    putstr(klwin, 0, buf);
+		    if (c == 'y') putstr(klwin, 0, buf);
+#ifdef DUMP_LOG
+		    if (want_dump)  dump("  ", buf);
+#endif
+		}
+		 Strcpy(buf,"and a partridge in a pear tree");
+	     if (christmas()) {
+	         if (c == 'y') putstr(klwin, 0, buf);
+#ifdef DUMP_LOG
+				if (want_dump) dump("  ",buf);
+#endif
 		}
-	    /*
-	     * if (Hallucination)
-	     *     putstr(klwin, 0, "and a partridge in a pear tree");
-	     */
 	    if (ntypes > 1) {
-		putstr(klwin, 0, "");
+		if (c == 'y') putstr(klwin, 0, "");
 		Sprintf(buf, "%ld creatures vanquished.", total_killed);
-		putstr(klwin, 0, buf);
+		if (c == 'y') putstr(klwin, 0, buf);
+#ifdef DUMP_LOG
+		if (want_dump)  dump("  ", buf);
+#endif
 	    }
+	    if (c == 'y') {
 	    display_nhwindow(klwin, TRUE);
 	    destroy_nhwindow(klwin);
 	}
+#ifdef DUMP_LOG
+	    if (want_dump)  dump("", "");
+#else
+	} /* the original end of if (c == 'y') */
+#endif
     }
 }
@@ -1060,8 +1417,16 @@
 }
 
+#ifdef DUMP_LOG
+STATIC_OVL void
+list_genocided(defquery, ask, want_dump)
+int defquery;
+boolean ask;
+boolean want_dump;
+#else
 STATIC_OVL void
 list_genocided(defquery, ask)
 char defquery;
 boolean ask;
+#endif
 {
     register int i;
@@ -1080,6 +1445,10 @@
 	if (c == 'y') {
 	    klwin = create_nhwindow(NHW_MENU);
-	    putstr(klwin, 0, "Genocided species:");
+	    Sprintf(buf, "Genocided species:");
+	    putstr(klwin, 0, buf);
 	    putstr(klwin, 0, "");
+#ifdef DUMP_LOG
+	    if (want_dump)  dump("", buf);
+#endif
 
 	    for (i = LOW_PM; i < NUMMONS; i++)
@@ -1092,4 +1461,7 @@
 			Strcpy(buf, makeplural(mons[i].mname));
 		    putstr(klwin, 0, buf);
+#ifdef DUMP_LOG
+		    if (want_dump)  dump("  ", buf);
+#endif
 		}
 
@@ -1097,4 +1469,7 @@
 	    Sprintf(buf, "%d species genocided.", ngenocided);
 	    putstr(klwin, 0, buf);
+#ifdef DUMP_LOG
+	    if (want_dump)  dump("  ", buf);
+#endif
 
 	    display_nhwindow(klwin, TRUE);
@@ -1104,3 +1479,86 @@
 }
 
+
+/* All of this is bolted together in an effort to get an accurate
+ * score now that the logfile's been moved so far up.  Don't
+ * suggest using it for anything else. */
+
+STATIC_OVL 
+long count_score(how)
+int how;
+{
+	long tmp, newscore, umoney, old_exp;
+	int deepest = deepest_lev_reached(FALSE);
+
+	newscore = u.urexp;
+
+#ifndef GOLDOBJ
+	umoney = u.ugold;
+	tmp = u.ugold0;
+#else
+	umoney = money_cnt(invent);
+	tmp = u.umoney0;
+#endif
+	umoney += hidden_gold();
+	tmp = umoney - tmp;
+
+	if (tmp < 0L) tmp = 0L;
+
+	if (how < PANICKED) {
+		tmp -= tmp / 10L;
+	}
+
+	newscore += tmp;
+	newscore += 50L * (long)(deepest - 1);
+
+	if (deepest > 20) {
+		newscore += 1000L * (long)((deepest > 30) ? 10 : deepest - 20);
+	}
+
+	if (how == ASCENDED) {
+		newscore *= 2L;
+	}
+
+	if (how == ESCAPED || how == ASCENDED) {
+		register struct monst *mtmp;
+		register struct obj *otmp;
+		register struct val_list *val;
+		register int i;
+
+		for (val = valuables; val->list; val++) {
+			for (i = 0; i < val->size; i++) {
+				val->list[i].count = 0L;
+			}
+		}
+		get_valuables(invent);
+
+		/* add points for collected valuables */
+		for (val = valuables; val->list; val++)
+				for (i = 0; i < val->size; i++)
+					if (val->list[i].count != 0L)
+						newscore += val->list[i].count * (long)objects[val->list[i].typ].oc_cost;
+
+		/* count the points for artifacts, with a juggling act since
+		 * it's inherently somewhat destructive */
+		old_exp = u.urexp;
+		u.urexp = newscore;
+		artifact_score(invent, TRUE, WIN_ERR);
+		newscore = u.urexp;
+		u.urexp = old_exp;
+
+		viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
+		mtmp = mydogs;
+		if (mtmp) {
+			while (mtmp) {
+				if (mtmp->mtame) {
+					newscore += mtmp->mhp;
+				}
+				mtmp = mtmp->nmon;
+			}
+		}
+	}
+
+	return newscore;
+}
+
 /*end.c*/
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/engrave.c nethack/src/engrave.c
--- nh_orig/src/engrave.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/engrave.c	2010-04-29 10:53:23.924715044 -0400
@@ -5,8 +5,7 @@
 #include "hack.h"
 #include "lev.h"
+#include "decl.h"
 #include <ctype.h>
 
-STATIC_VAR NEARDATA struct engr *head_engr;
-
 #ifdef OVLB
 /* random engravings */
@@ -34,4 +33,24 @@
 #endif
 	"As if!", /* Clueless */
+	"Arooo!  Werewolves of Yendor!", /* gang tag */
+	"Dig for Victory here", /* pun, duh */
+	"Don't go this way",
+	"Gaius Julius Primigenius was here.  Why are you late?", /* pompeii */
+	"Go left --->", "<--- Go right",
+	"Haermund Hardaxe carved these runes", /* viking graffiti */
+	"Here be dragons",
+	"Need a light?  Come visit the Minetown branch of Izchak's Lighting Store!",
+	"Save now, and do your homework!",
+	"Snakes on the Astral Plane - Soon in a dungeon near you",
+	"There was a hole here.  It's gone now.",
+	"The Vibrating Square",
+	"This is a pit!",
+	"This is not the dungeon you are looking for.",
+	"This square deliberately left blank.",
+	"Warning, Exploding runes!",
+	"Watch out, there's a gnome with a wand of death behind that door!",
+	"X marks the spot",
+	"X <--- You are here.",
+	"You are the one millionth visitor to this place!  Please wait 200 turns for your wand of wishing.",
 };
 
@@ -344,5 +363,5 @@
 		You("%s: \"%s\".",
 		      (Blind) ? "feel the words" : "read",  et);
-		if(flags.run > 1) nomul(0);
+		if(flags.run > 1) nomul(0, 0);
 	    }
 	}
@@ -447,5 +466,6 @@
 	xchar type = DUST;	/* Type of engraving made */
 	char buf[BUFSZ];	/* Buffer for final/poly engraving text */
-	char ebuf[BUFSZ];	/* Buffer for initial engraving text */
+	static char oebuf[BUFSZ] = "";
+	char ebuf[BUFSZ] = "";	/* Buffer for initial engraving text */
 	char qbuf[QBUFSZ];	/* Buffer for query text */
 	char post_engr_text[BUFSZ]; /* Text displayed after engraving prompt */
@@ -464,5 +484,4 @@
 
 	buf[0] = (char)0;
-	ebuf[0] = (char)0;
 	post_engr_text[0] = (char)0;
 	maxelen = BUFSZ - 1;
@@ -698,4 +717,7 @@
 			}
 			break;
+		    case WAN_WIND:
+			Strcpy(post_engr_text, "The bugs on the floor are blown away!");
+			break;
 
 		    /* type = ENGRAVE wands */
@@ -971,5 +993,8 @@
 	/* Prompt for engraving! */
 	Sprintf(qbuf,"What do you want to %s the %s here?", everb, eloc);
-	getlin(qbuf, ebuf);
+	getlin(qbuf, oebuf);
+	(void) strncpy(ebuf, oebuf, BUFSZ);
+	stripctrl(oebuf);
+	trim(oebuf);
 
 	/* Count the actual # of chars engraved not including spaces */
@@ -1230,5 +1255,367 @@
 	"Soon ripe. Soon rotten. Soon gone. But not forgotten.",
 	"Here lies the body of Jonathan Blake. Stepped on the gas instead of the brake.",
-	"Go away!"
+	"Go away!",
+	"Alas fair Death, 'twas missed in life - some peace and quiet from my wife",
+	"Applaud, my friends, the comedy is finished.",
+	"At last... a nice long sleep.",
+	"Audi Partem Alteram",
+	"Basil, assaulted by bears",
+	"Burninated",
+	"Confusion will be my epitaph",
+	"Do not open until Christmas",
+	"Don't be daft, they couldn't hit an elephant at this dist-",
+	"Don't forget to stop and smell the roses",
+	"Don't let this happen to you!",
+	"Dulce et decorum est pro patria mori",
+	"Et in Arcadia ego",
+	"Fatty and skinny went to bed.  Fatty rolled over and skinny was dead.  Skinny Smith 1983-2000.",
+	"Finally I am becoming stupider no more",
+	"Follow me to hell",
+	"...for famous men have the whole earth as their memorial",
+	"Game over, man.  Game over.",
+	"Go away!  I'm trying to take a nap in here!  Bloody adventurers...",
+	"Gone fishin'",
+	"Good night, sweet prince: And flights of angels sing thee to thy rest!",
+	"Go Team Ant!",
+	"He farmed his way here",
+	"Here lies a programmer.  Killed by a fatal error.",
+	"Here lies Bob - decided to try an acid blob",
+	"Here lies Dudley, killed by another %&#@#& newt.",
+	"Here lies Gregg, choked on an egg",
+	"Here lies Lies. It's True",
+	"Here lies The Lady's maid, died of a Vorpal Blade",
+	"Here lies the left foot of Jack, killed by a land mine.  Let us know if you find any more of him",
+	"He waited too long",
+	"I'd rather be sailing",
+	"If a man's deeds do not outlive him, of what value is a mark in stone?",
+	"I'm gonna make it!",
+	"I took both pills!",
+	"I will survive!",
+	"Killed by a black dragon -- This grave is empty",
+	"Let me out of here!",
+	"Lookin' good, Medusa.",
+	"Mrs. Smith, choked on an apple.  She left behind grieving husband, daughter, and granddaughter.",
+	"Nobody believed her when she said her feet were killing her",
+	"No!  I don't want to see my damn conduct!",
+	"One corpse, sans head",
+	"On the whole, I'd rather be in Minetown",
+	"On vacation",
+	"Oops.",
+	"Out to Lunch",
+	"SOLD",
+	"Someone set us up the bomb!",
+	"Take my stuff, I don't need it anymore",
+	"Taking a year dead for tax reasons",
+	"The reports of my demise are completely accurate",
+	"(This space for sale)",
+	"This was actually just a pit, but since there was a corpse, we filled it",
+	"This way to the crypt",
+	"Tu quoque, Brute?",
+	"VACANCY",
+	"Welcome!",
+	"Wish you were here!",
+	"Yea, it got me too",
+	"You should see the other guy",
+	"...and they made me engrave my own headstone too!",
+	"...but the blood has stopped pumping and I am left to decay...",
+	"<Expletive Deleted>",
+	"A masochist is never satisfied.",
+	"Ach, 'twas a wee monster in the loch",
+	"Adapt.  Enjoy.  Survive.",
+	"Adventure, hah!  Excitement, hah!",
+	"After all, what are friends for...",
+	"After this, nothing will shock me",
+	"After three days, fish and guests stink",
+	"Age and treachery will always overcome youth and skill",
+	"Ageing is not so bad.  The real killer is when you stop.",
+	"Ain't I a stinker?",
+	"Algernon",
+	"All else failed...",
+	"All hail RNG",
+	"All right, we'll call it a draw!",
+	"All's well that end well",
+	"Alone at last!",
+	"Always attack a floating eye from behind!",
+	"Am I having fun yet?",
+	"And I can still crawl, I'm not dead yet!",
+	"And all I wanted was a free lunch",
+	"And all of the signs were right there on your face",
+	"And don't give me that innocent look either!",
+	"And everyone died.  Boo hoo hoo.",
+	"And here I go again...",
+	"And nobody cares until somebody famous dies...",
+	"And so it ends?",
+	"And so... it begins.",
+	"And sometimes the bear eats you.",
+	"And then 'e nailed me 'ead to the floor!",
+	"And they said it couldn't be done!",
+	"And what do I look like?  The living?",
+	"And yes, it was ALL his fault!",
+	"And you said it was pretty here...",
+	"Another lost soul",
+	"Any day above ground is a good day!",
+	"Any more of this and I'll die of a stroke before I'm 30.",
+	"Anybody seen my head?",
+	"Anyone for deathmatch?",
+	"Anything for a change.",
+	"Anything that kills you makes you ... well, dead",
+	"Anything worth doing is worth overdoing.",
+	"Are unicorns supposedly peaceful if you're a virgin?  Hah!",
+	"Are we all being disintegrated, or is it just me?",
+	"At least I'm good at something",
+	"Attempted suicide",
+	"Auribus teneo lupum",
+	"Be prepared",
+	"Beauty survives",
+	"Been Here. Now Gone. Had a Good Time.",
+	"Been through Hell, eh?  What did you bring me?",
+	"Beg your pardon, didn't recognize you, I've changed a lot.",
+	"Being dead builds character",
+	"Beloved daughter, a treasure, buried here.",
+	"Best friends come and go...  Mine just die.",
+	"Better be dead than a fat slave",
+	"Better luck next time",
+	"Beware of Discordians bearing answers",
+	"Beware the ...",
+	"Bloody Hell...",
+	"Bloody barbarians!",
+	"Blown upward out of sight: He sought the leak by candlelight",
+	"Brains... Brains... Fresh human brains...",
+	"Buried the cat.  Took an hour.  Damn thing kept fighting.",
+	"But I disarmed the trap!",
+	"CONNECT 1964 - NO CARRIER 1994",
+	"Call me if you need my phone number!",
+	"Can YOU fly?",
+	"Can you believe that thing is STILL moving?",
+	"Can you come up with some better ending for this?",
+	"Can you feel anything when I do this?",
+	"Can you give me mouth to mouth, you just took my breath away.",
+	"Can't I just have a LITTLE peril?",
+	"Can't eat, can't sleep, had to bury the husband here.",
+	"Can't you hit me?!",
+	"Chaos, panic and disorder.  My work here is done.",
+	"Check enclosed.",
+	"Check this out!  It's my brain!",
+	"Chivalry is only reasonably dead",
+	"Coffin for sale.  Lifetime guarantee.",
+	"Come Monday, I'll be all right.",
+	"Come and see the violence inherent in the system",
+	"Come back here!  I'll bite your bloody knees off!",
+	"Commodore Business Machines, Inc.   Died for our sins.",
+	"Complain to one who can help you",
+	"Confess my sins to god?  Which one?",
+	"Confusion will be my epitaph",
+	"Cooties?  Ain't no cooties on me!",
+	"Could somebody get this noose off me?",
+	"Could you check again?  My name MUST be there.",
+	"Could you please take a breath mint?",
+	"Couldn't I be sedated for this?",
+	"Courage is looking at your setbacks with serenity",
+	"Cover me, I'm going in!",
+	"Crash course in brain surgery",
+	"Cross my fingers for me.",
+	"Curse god and die",
+	"Cut to fit",
+	"De'Ath",
+	"Dead Again?  Pardon me for not getting it right the first time!",
+	"Dead and loving every moment!",
+	"Dear wife of mine. Died of a broken heart, after I took it out of her.",
+	"Don't tread on me!",
+	"Dragon? What dragon?",
+	"Drawn and quartered",
+	"Either I'm dead or my watch has stopped.",
+	"Eliza -- Was I really alive, or did I just think I was?",
+	"Elvis",
+	"Enter not into the path of the wicked",
+	"Eris?  I don't need Eris",
+	"Eternal Damnation, Come and stay a long while!",
+	"Even The Dead pay taxes (and they aren't Grateful).",
+	"Even a tomb stone will say good things when you're down!",
+	"Ever notice that live is evil backwards?",
+	"Every day is starting to look like Monday",
+	"Every day, in every way, I am getting better and better.",
+	"Every survival kit should include a sense of humor",
+	"Evil I did dwell;  lewd did I live",
+	"Ex post fucto",
+	"Excellent day to have a rotten day.",
+	"Excuse me for not standing up.",
+	"Experience isn't everything. First, You've got to survive",
+	"First shalt thou pull out the Holy Pin",
+	"For a Breath, I Tarry...",
+	"For recreational use only.",
+	"For sale: One soul, slightly used. Asking for 3 wishes.",
+	"For some moments in life, there are no words.",
+	"Forget Disney World, I'm going to Hell!",
+	"Forget about the dog, Beware of my wife.",
+	"Funeral - Real fun.",
+	"Gawd, it's depressing in here, isn't it?",
+	"Genuine Exploding Gravestone.  (c)Acme Gravestones Inc.",
+	"Get back here!  I'm not finished yet...",
+	"Go ahead, I dare you to!",
+	"Go ahead, it's either you or him.",
+	"Goldilocks -- This casket is just right",
+	"Gone But Not Forgotten",
+	"Gone Underground For Good",
+	"Gone away owin' more than he could pay.",
+	"Gone, but not forgiven",
+	"Got a life. Didn't know what to do with it.",
+	"Grave?  But I was cremated!",
+	"Greetings from Hell - Wish you were here.",
+	"HELP! It's dark in here... Oh, my eyes are closed - sorry",
+	"Ha! I NEVER pay income tax!",
+	"Have you come to raise the dead?",
+	"Having a good time can be deadly.",
+	"Having a great time. Where am I exactly??",
+	"He died of the flux.",
+	"He died today... May we rest in peace!",
+	"He got the upside, I got the downside.",
+	"He lost his face when he was beheaded.",
+	"He missed me first.",
+	"He's not dead, he just smells that way.",
+	"Help! I've fallen and I can't get up!",
+	"Help, I can't wake up!",
+	"Here lies Pinocchio",
+	"Here lies the body of John Round. Lost at sea and never found.",
+	"Here there be dragons",
+	"Hey, I didn't write this stuff!",
+	"Hold my calls",
+	"Home Sweet Hell",
+	"Humpty Dumpty, a Bad Egg.  He was pushed off the wall.",
+	"I KNEW this would happen if I lived long enough.",
+	"I TOLD you I was sick!",
+	"I ain't broke but I am badly bent.",
+	"I ain't old. I'm chronologically advantaged.",
+	"I am NOT a vampire. I just like to bite..nibble, really!",
+	"I am here. Wish you were fine.",
+	"I am not dead yet, but watch for further reports.",
+	"I believe them bones are me.",
+	"I broke his brain.",
+	"I can feel it.  My mind.  It's going.  I can feel it.",
+	"I can't go to Hell. They're afraid I'm gonna take over!",
+	"I can't go to hell, they don't want me.",
+	"I didn't believe in reincarnation the last time, either.",
+	"I didn't mean it when I said 'Bite me'",
+	"I died laughing",
+	"I disbelieved in reincarnation in my last life, too.",
+	"I hacked myself to death",
+	"I have all the time in the world",
+	"I knew I'd find a use for this gravestone!",
+	"I know my mind. And it's around here someplace.",
+	"I lied!  I'll never be alright!",
+	"I like it better in the dark.",
+	"I like to be here when I can.",
+	"I may rise but I refuse to shine.",
+	"I never get any either.",
+	"I said hit HIM with the fireball, not me!",
+	"I told you I would never say goodbye.",
+	"I used to be amusing. Now I'm just disgusting.",
+	"I used up all my sick days, so now I'm calling in dead.",
+	"I was killed by <illegible scrawl>",
+	"I was somebody. Who, is no business of yours.",
+	"I will not go quietly.",
+	"I'd give you a piece of my mind... but I can't find it.",
+	"I'd rather be breathing",
+	"I'll be back!",
+	"I'll be mellow when I'm dead. For now, let's PARTY!",
+	"I'm doing this only for tax purposes.",
+	"I'm not afraid of Death!  What's he gonna do? Kill me?",
+	"I'm not getting enough money, so I'm not going to engrave anything useful here.",
+	"I'm not saying anything.",
+	"I'm weeth stupeed --->",
+	"If you thought you had problems...",
+	"Ignorance kills daily.",
+	"Ignore me... I'm just here for my looks!",
+	"Ilene Toofar -- Fell off a cliff",
+	"Is that all?",
+	"Is there life before Death?",
+	"Is this a joke, or a grave matter?",
+	"It happens sometimes. People just explode.",
+	"It must be Thursday. I never could get the hang of Thursdays.",
+	"It wasn't a fair fight",
+	"It wasn't so easy.",
+	"It's Loot, Pillage and THEN Burn...",
+	"Just doing my job here",
+	"Killed by diarrhea of mouth and constipation of brain.",
+	"Let her RIP",
+	"Let it be; I am dead.",
+	"Let's play Hide the Corpse",
+	"Life is NOT a dream",
+	"Madge Ination -- It wasn't all in my head",
+	"Meet me in Heaven",
+	"Move on, there's nothing to see here.",
+	"Mr. Flintstone -- Yabba-dabba-done",
+	"My heart is not in this",
+	"No one ever died from it",
+	"No, you want room 12A, next door.",
+	"Nope.  No trap on that chest.  I swear.",
+	"Not again!",
+	"Not every soil can bear all things",
+	"Now I have a life",
+	"Now I lay thee down to sleep... wanna join me?",
+	"OK, here is a question: Where ARE your tanlines?",
+	"Obesa Cantavit",
+	"Oh! An untimely death.",
+	"Oh, by the way, how was my funeral?",
+	"Oh, honey..I missed you! She said, and fired again.",
+	"Ok, so the light does go off. Now let me out of here.",
+	"One stone brain",
+	"Ooh! Somebody STOP me!",
+	"Oops!",
+	"Out for the night.  Leave a message.",
+	"Ow!  Do that again!",
+	"Pardon my dust.",
+	"Part of me still works.",
+	"Please, not in front of those orcs!",
+	"Prepare to meet me in Heaven",
+	"R2D2 -- Rest, Tin Piece",
+	"Relax.  Nothing ever happens on the first level.",
+	"Res omnia mea culpa est",
+	"Rest In Pieces",
+	"Rest, rest, perturbed spirit.",
+	"Rip Torn",
+	"She always said her feet were killing her but nobody believed her.",
+	"She died of a chest cold.",
+	"So let it be written, so let it be done!",
+	"So then I says, How do I know you're the real angel of death?",
+	"Some patients insist on dying.",
+	"Some people have it dead easy, don't they?",
+	"Some things are better left buried.",
+	"Sure, trust me, I'm a lawyer...",
+	"Thank God I wore my corset, because I think my sides have split.",
+	"That is all",
+	"The Gods DO have a sense of humor: I'm living proof!",
+	"The frog's dead. He Kermitted suicide.",
+	"This dungeon is a pushover",
+	"This elevator doesn't go to Heaven",
+	"This gravestone is shareware. To register, please send me 10 zorkmids",
+	"This gravestone provided by The Yendorian Grave Services Inc.",
+	"This is not an important part of my life.",
+	"This one's on me.",
+	"This side up",
+	"Tim Burr -- Smashed by a tree",
+	"Tone it down a bit, I'm trying to get some rest here.",
+	"Virtually Alive",
+	"We Will Meet Again.",
+	"Weep not, he is at rest",
+	"Welcome to Dante's.  What level please?",
+	"Well, at least they listened to my sermon...",
+	"Went to be an angel.",
+	"What are you doing over there?",
+	"What are you smiling at?",
+	"What can you say, Death's got appeal...!",
+	"What health care?",
+	"What pit?",
+	"When the gods want to punish you, they answer your prayers.",
+	"Where e'er you be let your wind go free. Keeping it in was the death of me!",
+	"Where's my refund?",
+	"Will let you know for sure in a day or two...",
+	"Wizards are wimps",
+	"Worms at work, do not disturb!",
+	"Would you mind moving a bit?  I'm short of breath down here.",
+	"Would you quit being evil over my shoulder?",
+	"Ya really had me going baby, but now I'm gone.",
+	"Yes Dear, just a few more minutes...",
+	"You said it wasn't poisonous!",
+	"You set my heart aflame. You gave me heartburn."
 };
 
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/exper.c nethack/src/exper.c
--- nh_orig/src/exper.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/exper.c	2009-08-02 13:49:38.662408417 -0400
@@ -141,5 +141,5 @@
 	}
 	num = newhp();
-	u.uhpmax -= num;
+	gainmaxhp(-num);
 	if (u.uhpmax < 1) u.uhpmax = 1;
 	u.uhp -= num;
@@ -186,4 +186,7 @@
 	if (!incr) You_feel("more experienced.");
 	num = newhp();
+	/* we let this go rather than pushing it through gainmaxhp() because
+	 * the player's HP growth from levels is already restricted at XL30
+	 * and we don't want to screw them on level gain */
 	u.uhpmax += num;
 	u.uhp += num;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/explode.c nethack/src/explode.c
--- nh_orig/src/explode.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/explode.c	2009-11-22 07:19:36.480398230 -0500
@@ -42,4 +42,10 @@
 	boolean shopdamage = FALSE;
 	boolean generic = FALSE;
+	boolean skipitems = FALSE;
+
+#if 0
+	// No good justification for this.  Why should
+	// these roles take _such_ less damage from explosions?
+	// If they're going to huck fireballs around, _be careful_.
 
 	if (olet == WAND_CLASS)		/* retributive strike */
@@ -54,4 +60,5 @@
 			default:  break;
 		}
+#endif
 
 	if (olet == MON_EXPLODE) {
@@ -105,19 +112,19 @@
 				break;
 			case AD_FIRE:
-				explmask[i][j] = !!Fire_resistance;
+				explmask[i][j] = (how_resistant(FIRE_RES) > 50);
 				break;
 			case AD_COLD:
-				explmask[i][j] = !!Cold_resistance;
+				explmask[i][j] = (how_resistant(COLD_RES) > 50);
 				break;
 			case AD_DISN:
 				explmask[i][j] = (olet == WAND_CLASS) ?
 						!!(nonliving(youmonst.data) || is_demon(youmonst.data)) :
-						!!Disint_resistance;
+						(how_resistant(DISINT_RES) > 50);
 				break;
 			case AD_ELEC:
-				explmask[i][j] = !!Shock_resistance;
+				explmask[i][j] = (how_resistant(SHOCK_RES) > 50);
 				break;
 			case AD_DRST:
-				explmask[i][j] = !!Poison_resistance;
+				explmask[i][j] = (how_resistant(POISON_RES) > 50);
 				break;
 			case AD_ACID:
@@ -226,5 +233,5 @@
 	}
 
-    if (dam)
+    if (dam) {
 	for (i=0; i<3; i++) for (j=0; j<3; j++) {
 		if (explmask[i][j] == 2) continue;
@@ -233,6 +240,5 @@
 		idamres = idamnonres = 0;
 		if (type >= 0)
-		    (void)zap_over_floor((xchar)(i+x-1), (xchar)(j+y-1),
-		    		type, &shopdamage);
+				(void)zap_over_floor((xchar)(i+x-1), (xchar)(j+y-1), type, &shopdamage, MON_CASTBALL);
 
 		mtmp = m_at(i+x-1, j+y-1);
@@ -278,5 +284,5 @@
 		if (explmask[i][j] == 1) {
 			golemeffects(mtmp, (int) adtyp, dam + idamres);
-			mtmp->mhp -= idamnonres;
+				damage_mon(mtmp,idamnonres,adtyp);
 		} else {
 		/* call resist with 0 and do damage manually so 1) we can
@@ -297,12 +303,17 @@
 			else if (resists_fire(mtmp) && adtyp == AD_COLD)
 				mdam *= 2;
-			mtmp->mhp -= mdam;
-			mtmp->mhp -= (idamres + idamnonres);
+				damage_mon(mtmp,mdam,adtyp);
+				damage_mon(mtmp,idamres + idamnonres,adtyp);
 		}
 		if (mtmp->mhp <= 0) {
-			/* KMH -- Don't blame the player for pets killing gas spores */
-			if (!flags.mon_moving) killed(mtmp);
-			else monkilled(mtmp, "", (int)adtyp);
-		} else if (!flags.mon_moving) setmangry(mtmp);
+				/* KMH -- Don't blame the player for pets killing gas spores
+				 * DSR -- And don't blame the player for monsters fireballing things */
+				if (!flags.mon_moving && olet != MON_CASTBALL) {
+					killed(mtmp);
+				} else {
+					monkilled(mtmp, "", (int)adtyp);
+				}
+			} else if (!flags.mon_moving && olet != MON_CASTBALL) setmangry(mtmp);
+		}
 	}
 
@@ -314,4 +325,8 @@
 		/* do property damage first, in case we end up leaving bones */
 		if (adtyp == AD_FIRE) burn_away_slime();
+		/* small explosions won't burn your items up anymore
+		 * ...this needs to be here so gnomish wizards aren't
+		 * frosting or toasting all your stuff on xl2 */
+		skipitems = (damu <= 16);
 		if (Invulnerable) {
 		    damu = 0;
@@ -319,5 +334,6 @@
 		} else if (Half_physical_damage && adtyp == AD_PHYS)
 		    damu = (damu+1) / 2;
-		if (adtyp == AD_FIRE) (void) burnarmor(&youmonst);
+		if (adtyp == AD_FIRE && !skipitems) (void) burnarmor(&youmonst);
+		if (!skipitems) {
 		destroy_item(SCROLL_CLASS, (int) adtyp);
 		destroy_item(SPBOOK_CLASS, (int) adtyp);
@@ -325,4 +341,5 @@
 		destroy_item(RING_CLASS, (int) adtyp);
 		destroy_item(WAND_CLASS, (int) adtyp);
+		}
 
 		ugolemeffects((int) adtyp, damu);
@@ -335,4 +352,9 @@
 		}
 
+		/* You resisted the damage, so alert critters */
+		if (uhurt == 1) {
+			monstseesu(1 << (adtyp-1));
+		}
+
 		if (u.uhp <= 0 || (Upolyd && u.mh <= 0)) {
 		    if (Upolyd) {
@@ -344,4 +366,7 @@
 				Strcpy(killer_buf, str);
 			    killer_format = KILLED_BY_AN;
+			} else if (olet == MON_CASTBALL) {
+				killer_format = KILLED_BY_AN;
+				Strcpy(killer_buf, str);
 			} else if (type >= 0 && olet != SCROLL_CLASS) {
 			    killer_format = NO_KILLER_PREFIX;
@@ -514,5 +539,5 @@
 				    int hitvalu, hitu;
 
-				    if (multi) nomul(0);
+				    if (multi) nomul(0, 0);
 				    hitvalu = 8 + stmp->obj->spe;
 				    if (bigmonst(youmonst.data)) hitvalu++;
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/extralev.c nethack/src/extralev.c
--- nh_orig/src/extralev.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/extralev.c	2010-05-13 09:22:21.979839300 -0400
@@ -329,10 +329,10 @@
 		ghostobj = mksobj_at(RING_MAIL, x, y, FALSE, FALSE);
 		ghostobj->spe = rn2(3);
-		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
+		if (!rn2(3)) set_erodeproof(ghostobj);
 		if (rn2(4)) curse(ghostobj);
 	} else {
 		ghostobj = mksobj_at(PLATE_MAIL, x, y, FALSE, FALSE);
 		ghostobj->spe = rnd(5) - 2;
-		if (!rn2(3)) ghostobj->oerodeproof = TRUE;
+		if (!rn2(3)) set_erodeproof(ghostobj);
 		if (rn2(4)) curse(ghostobj);
 	}
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/files.c nethack/src/files.c
--- nh_orig/src/files.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/files.c	2009-08-02 13:49:38.667410509 -0400
@@ -12,5 +12,5 @@
 #include <ctype.h>
 
-#if !defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)
+#if (!defined(MAC) && !defined(O_WRONLY) && !defined(AZTEC_C)) || defined(USE_FCNTL)
 #include <fcntl.h>
 #endif
@@ -535,4 +535,7 @@
 	for (x = (n_dgns ? maxledgerno() : 0); x >= 0; x--)
 		delete_levelfile(x);	/* not all levels need be present */
+#  ifdef WHEREIS_FILE
+	delete_whereis();
+#  endif
 #endif
 }
@@ -599,4 +602,110 @@
 #endif
 	
+#ifdef WISH_TRACKER
+const char* wish_tracker_file =
+# ifdef UNIX
+		"wishtracker";
+# else
+#  if defined(MAC) || defined(__BEOS__)
+		"Wish Tracker";
+#  else
+		"wishes.txt";
+#  endif
+# endif
+
+void
+trackwish(wishstring)
+char* wishstring;
+{
+	char bigbuf[512];
+	FILE* fp;
+
+	fp = fopen_datafile(wish_tracker_file,"a+",LEVELPREFIX);
+	if (fp) {
+		Sprintf(bigbuf,"%s wished for %s (%d%s wish, T:%d)\n",
+				plname,wishstring,u.uconduct.wishes,
+				u.uconduct.wishes == 1 ? "st" : u.uconduct.wishes == 2 ? "nd" : 
+				u.uconduct.wishes == 3 ? "rd" : "th",moves);
+		fwrite(bigbuf,strlen(bigbuf),1,fp);
+		fclose(fp);
+	}
+}
+
+/* Handles generic announcements.  Cheats and uses the wishtracker file. */
+void makeannounce(announcement)
+char* announcement;
+{
+	FILE* fp;
+	fp = fopen_datafile(wish_tracker_file,"a+",LEVELPREFIX);
+	if (fp) {
+		fwrite(announcement,strlen(announcement),1,fp);
+		if (announcement[strlen(announcement)-1] != '\n') { fwrite("\n",1,1,fp); }
+		fclose(fp);
+	}
+
+}
+#endif
+
+#ifdef WHEREIS_FILE
+void
+touch_whereis()
+{
+	/* Write out our current level and branch to name.whereis
+	 *
+	 *	Could eventually bolt on all kinds of info, but this way
+	 *	at least something which wants to can scan for the games.
+	 *
+	 * For now this only works on Win32 and UNIX.  I'm too lazy
+	 * to sort out all the proper other-OS stuff.
+	 */
+
+	FILE* fp;
+	char whereis_file[255];
+	char whereis_work[255];
+
+#ifdef WIN32
+	Sprintf(whereis_file,"%s-%s.whereis",get_username(0),plname);
+#else
+	Sprintf(whereis_file,"%d-%s.whereis",(int)getuid(),plname);
+#endif
+	Sprintf(whereis_work,"%d,%d,%d,%d,%d,0,0,%s,%s,%s,%d,%d\n",
+			depth(&u.uz), u.uz.dnum, u.uhp, u.uhpmax, moves,
+			urole.name.m,urace.adj,u.mfemale ? "F" : "M",u.ualign.type + 2,
+			u.uhave.amulet ? 1 : 0);
+	fp = fopen_datafile(whereis_file,"w",LEVELPREFIX);
+	if (fp) {
+		fwrite(whereis_work,strlen(whereis_work),1,fp);
+		fclose(fp);
+	}
+
+}
+
+
+/* Changed over to write out where the player last was when they
+ * left the game; including possibly 'dead' :) */
+void
+delete_whereis()
+{
+	FILE* fp;
+	char whereis_file[255];
+	char whereis_work[255];
+#if defined (WIN32)
+	Sprintf(whereis_file,"%s-%s.whereis",get_username(0),plname);
+#else
+	Sprintf(whereis_file,"%d-%s.whereis",(int)getuid(),plname);
+#endif
+	Sprintf(whereis_work,"%d,%d,%d,%d,%d,%d,1,%s,%s,%s,%d,%d\n",
+			depth(&u.uz), u.uz.dnum, u.uhp, u.uhpmax, moves, 
+			u.uevent.ascended ? 2 : killer ? 1 : 0,
+			urole.name.m,urace.adj,u.mfemale ? "F" : "M",u.ualign.type + 2,
+			u.uhave.amulet ? 1 : 0);
+	fp = fopen_datafile(whereis_file,"w",LEVELPREFIX);
+	if (fp) {
+		fwrite(whereis_work,strlen(whereis_work),1,fp);
+		fclose(fp);
+	}
+}
+#endif /* WHEREIS_FILE */
+
 /* ----------  END LEVEL FILE HANDLING ----------- */
 
@@ -1244,7 +1353,10 @@
 static int nesting = 0;
 
-#ifdef NO_FILE_LINKS	/* implies UNIX */
+#if defined(NO_FILE_LINKS) || defined(USE_FCNTL) 	/* implies UNIX */
 static int lockfd;	/* for lock_file() to pass to unlock_file() */
 #endif
+#ifdef USE_FCNTL
+struct flock sflock; /* for unlocking, same as above */
+#endif
 
 #define HUP	if (!program_state.done_hup)
@@ -1284,5 +1396,4 @@
 }
 
-
 /* lock a file */
 boolean
@@ -1304,11 +1415,28 @@
 	}
 
+#ifndef USE_FCNTL
 	lockname = make_lockname(filename, locknambuf);
-	filename = fqname(filename, whichprefix, 0);
 #ifndef NO_FILE_LINKS	/* LOCKDIR should be subsumed by LOCKPREFIX */
 	lockname = fqname(lockname, LOCKPREFIX, 2);
 #endif
+#endif
+	filename = fqname(filename, whichprefix, 0);
+
+#ifdef USE_FCNTL
+	lockfd = open(filename,O_RDWR);
+	if (lockfd == -1) {
+		HUP raw_printf("Cannot open file %s. This is a program bug.",
+			filename);
+	}
+	sflock.l_type = F_WRLCK;
+	sflock.l_whence = SEEK_SET;
+	sflock.l_start = 0;
+	sflock.l_len = 0;
+#endif
 
 #if defined(UNIX) || defined(VMS)
+# ifdef USE_FCNTL
+	while (fcntl(lockfd,F_SETLK,&sflock) == -1) {
+# else 
 # ifdef NO_FILE_LINKS
 	while ((lockfd = open(lockname, O_RDWR|O_CREAT|O_EXCL, 0666)) == -1) {
@@ -1316,4 +1444,20 @@
 	while (link(filename, lockname) == -1) {
 # endif
+# endif 
+
+#ifdef USE_FCNTL
+		if (retryct--) {
+			HUP raw_printf(
+				"Waiting for release of fcntl lock on %s. (%d retries left).",
+				filename, retryct);
+			sleep(1);
+		} else {
+		    HUP (void) raw_print("I give up.  Sorry.");
+		    HUP raw_printf("Some other process has an unnatural grip on %s.",
+					filename);
+		    nesting--;
+		    return FALSE;
+		}
+#else
 	    register int errnosv = errno;
 
@@ -1361,9 +1505,9 @@
 		return FALSE;
 	    }
-
+#endif /* USE_FCNTL */
 	}
 #endif  /* UNIX || VMS */
 
-#if defined(AMIGA) || defined(WIN32) || defined(MSDOS)
+#if (defined(AMIGA) || defined(WIN32) || defined(MSDOS)) && !defined(USE_FCNTL)
 # ifdef AMIGA
 #define OPENFAILURE(fd) (!fd)
@@ -1419,4 +1563,11 @@
 
 	if (nesting == 1) {
+#ifdef USE_FCNTL
+		sflock.l_type = F_UNLCK;
+		if (fcntl(lockfd,F_SETLK,&sflock) == -1) {
+			HUP raw_printf("Can't remove fcntl lock on %s.", filename);
+			(void) close(lockfd);
+		}
+# else
 		lockname = make_lockname(filename, locknambuf);
 #ifndef NO_FILE_LINKS	/* LOCKDIR should be subsumed by LOCKPREFIX */
@@ -1438,4 +1589,5 @@
 		lockptr = 0;
 #endif /* AMIGA || WIN32 || MSDOS */
+#endif /* USE_FCNTL */
 	}
 
@@ -1450,4 +1602,19 @@
 const char *configfile =
 #ifdef UNIX
+			".sporkrc";
+#else
+# if defined(MAC) || defined(__BEOS__)
+			"SporkHack Defaults";
+# else
+#  if defined(MSDOS) || defined(WIN32)
+			"defaults.sh";
+#  else
+			"SporkHack.cnf";
+#  endif
+# endif
+#endif
+
+const char *oldconfigfile =
+#ifdef UNIX
 			".nethackrc";
 #else
@@ -1464,4 +1631,5 @@
 
 
+
 #ifdef MSDOS
 /* conflict with speed-dial under windows
@@ -1479,4 +1647,5 @@
 #endif
 
+
 STATIC_OVL FILE *
 fopen_config_file(filename)
@@ -1521,6 +1690,8 @@
 
 #if defined(MICRO) || defined(MAC) || defined(__BEOS__) || defined(WIN32)
-	if ((fp = fopenp(fqname(configfile, CONFIGPREFIX, 0), "r"))
-								!= (FILE *)0)
+	if ((fp = fopenp(fqname(configfile, CONFIGPREFIX, 0), "r")) != (FILE *)0)
+		return(fp);
+	/* try .nethackrc? */
+	else if ((fp = fopenp(fqname(oldconfigfile, CONFIGPREFIX, 0), "r")) != (FILE *)0)
 		return(fp);
 # ifdef MSDOS
@@ -1557,4 +1728,13 @@
 	if ((fp = fopenp(tmp_config, "r")) != (FILE *)0)
 		return(fp);
+	else {
+		/* try .nethackrc? */
+		if (!envp)
+			Strcpy(tmp_config, oldconfigfile);
+		else
+			Sprintf(tmp_config, "%s/%s", envp, oldconfigfile);
+		if ((fp = fopenp(tmp_config, "r")) != (FILE *)0)
+			return(fp);
+	}
 # if defined(__APPLE__)
 	/* try an alternative */
@@ -1795,8 +1975,16 @@
 	    (void) get_uchars(fp, buf, bufp, &iflags.bouldersym, TRUE,
 			      1, "BOULDER");
+	} else if (match_varname(buf, "MENUCOLOR", 9)) {
+#ifdef MENU_COLOR
+	    (void) add_menu_coloring(bufp);
+#endif
 	} else if (match_varname(buf, "GRAPHICS", 4)) {
 	    len = get_uchars(fp, buf, bufp, translate, FALSE,
 			     MAXPCHARS, "GRAPHICS");
 	    assign_graphics(translate, len, MAXPCHARS, 0);
+#if defined(STATUS_COLORS) && defined(TEXTCOLOR)
+	} else if (match_varname(buf, "STATUSCOLOR", 11)) {
+	    (void) parse_status_color_options(bufp);
+#endif
 	} else if (match_varname(buf, "DUNGEON", 4)) {
 	    len = get_uchars(fp, buf, bufp, translate, FALSE,
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/fountain.c nethack/src/fountain.c
--- nh_orig/src/fountain.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/fountain.c	2010-05-13 09:22:21.972714813 -0400
@@ -255,5 +255,5 @@
 
 			pline_The("water is contaminated!");
-			if (Poison_resistance) {
+			if (how_resistant(POISON_RES) == 100) {
 			   pline(
 			      "Perhaps it is runoff from the nearby %s farm.",
@@ -263,6 +263,6 @@
 			   break;
 			}
-			losestr(rn1(4,3));
-			losehp(rnd(10),"contaminated water", KILLED_BY);
+			losestr(resist_reduce(rn1(4,3),POISON_RES));
+			losehp(resist_reduce(rnd(10),POISON_RES),"contaminated water", KILLED_BY);
 			exercise(A_CON, FALSE);
 			break;
@@ -301,5 +301,5 @@
 			   pline("But it disappears.");
 			}
-			HSee_invisible |= FROMOUTSIDE;
+			incr_itimeout(&HSee_invisible, (long)rn1(100, 50));
 			newsym(u.ux,u.uy);
 			exercise(A_WIS, TRUE);
@@ -330,5 +330,5 @@
 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
 			    if(!DEADMONSTER(mtmp))
-				monflee(mtmp, 0, FALSE, FALSE);
+				monflee(mtmp, 0, FALSE, canseemon(mtmp) ? TRUE : FALSE);
 			}
 			break;
@@ -364,5 +364,5 @@
 	    && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) {
 
-		if (u.ualign.type != A_LAWFUL) {
+		if (u.ualign.type != A_LAWFUL || !Role_if(PM_KNIGHT)) {
 			/* Ha!  Trying to cheat her. */
 			pline("A freezing mist rises from the water and envelopes the sword.");
@@ -380,6 +380,5 @@
 			discover_artifact(ART_EXCALIBUR);
 			bless(obj);
-			obj->oeroded = obj->oeroded2 = 0;
-			obj->oerodeproof = TRUE;
+			set_erodeproof(obj);
 			exercise(A_WIS, TRUE);
 		}
@@ -523,7 +522,9 @@
 			break;
 		case 2: You("take a sip of scalding hot water.");
-			if (Fire_resistance)
+			if (how_resistant(FIRE_RES) == 100) {
 				pline("It seems quite tasty.");
-			else losehp(rnd(6), "sipping boiling water", KILLED_BY);
+				monstseesu(M_SEEN_FIRE);
+			}
+			else losehp(resist_reduce(rnd(6),FIRE_RES), "sipping boiling water", KILLED_BY);
 			break;
 		case 3: if (mvitals[PM_SEWER_RAT].mvflags & G_GONE)
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/hack.c nethack/src/hack.c
--- nh_orig/src/hack.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/hack.c	2009-11-22 07:40:06.206272750 -0500
@@ -73,5 +73,5 @@
 	rx = u.ux + 2 * u.dx;	/* boulder destination position */
 	ry = u.uy + 2 * u.dy;
-	nomul(0);
+	nomul(0, 0);
 	if (Levitation || Is_airlevel(&u.uz)) {
 	    if (Blind) feel_location(sx, sy);
@@ -317,4 +317,5 @@
     struct obj *boulder = sobj_at(BOULDER,x,y);
     const char *digtxt = (char *)0, *dmgtxt = (char *)0;
+	 boolean getcoal = FALSE;
 
     if (digging.down)		/* not continuing previous dig (w/ pick-axe) */
@@ -323,6 +324,7 @@
     if (!boulder && IS_ROCK(lev->typ) && !may_dig(x,y)) {
 	You("hurt your teeth on the %s.",
-	    IS_TREE(lev->typ) ? "tree" : "hard stone");
-	nomul(0);
+			/* ternary abuse! */
+	    IS_TREE(lev->typ) ? christmas() ? "christmas tree" : "tree" : "hard stone");
+	nomul(0, 0);
 	return 1;
     } else if (digging.pos.x != x || digging.pos.y != y ||
@@ -340,5 +342,6 @@
 	    (boulder || IS_TREE(lev->typ)) ? "on a" : "a hole in the",
 	    boulder ? "boulder" :
-	    IS_TREE(lev->typ) ? "tree" : IS_ROCK(lev->typ) ? "rock" : "door");
+	    IS_TREE(lev->typ) ? christmas() ? "christmas tree" : "tree" : 
+			IS_ROCK(lev->typ) ? "rock" : "door");
 	watch_dig((struct monst *)0, x, y, FALSE);
 	return 1;
@@ -348,5 +351,5 @@
 		digging.chew ? "continue" : "begin",
 		boulder ? "boulder" :
-		IS_TREE(lev->typ) ? "tree" :
+		IS_TREE(lev->typ) ? christmas() ? "christmas tree" : "tree" :
 		IS_ROCK(lev->typ) ? "rock" : "door");
 	digging.chew = TRUE;
@@ -392,5 +395,10 @@
 	}
     } else if (IS_TREE(lev->typ)) {
+		 if (christmas()) {
+			digtxt = "chew through the christmas tree.";
+			getcoal = TRUE;
+		 } else {
 	digtxt = "chew through the tree.";
+		 }
 	lev->typ = ROOM;
     } else if (lev->typ == SDOOR) {
@@ -425,4 +433,5 @@
     newsym(x, y);
     if (digtxt) You(digtxt);	/* after newsym */
+	 if (getcoal) get_coal();
     if (dmgtxt) pay_for_damage(dmgtxt, FALSE);
     (void) memset((genericptr_t)&digging, 0, sizeof digging);
@@ -720,5 +729,5 @@
 	    u.dx = u.tx-u.ux;
 	    u.dy = u.ty-u.uy;
-	    nomul(0);
+	    nomul(0, 0);
 	    iflags.travelcc.x = iflags.travelcc.y = -1;
 	    return TRUE;
@@ -786,5 +795,5 @@
 				u.dy = y-uy;
 				if (x == u.tx && y == u.ty) {
-				    nomul(0);
+				    nomul(0, 0);
 				    /* reset run so domove run checks work */
 				    flags.run = 8;
@@ -856,5 +865,5 @@
     u.dx = 0;
     u.dy = 0;
-    nomul(0);
+    nomul(0, 0);
     return FALSE;
 }
@@ -892,5 +901,5 @@
 	    } else
 		You("collapse under your load.");
-	    nomul(0);
+	    nomul(0, 0);
 	    return;
 	}
@@ -926,7 +935,9 @@
 			    || resists_cold(&youmonst) || Flying
 			    || is_floater(youmonst.data) || is_clinger(youmonst.data)
-			    || is_whirly(youmonst.data))
+			    || is_whirly(youmonst.data) ||
+				 (uarm && (uarm->otyp == WHITE_DRAGON_SCALE_MAIL || 
+							  uarm->otyp == WHITE_DRAGON_SCALES)))
 			on_ice = FALSE;
-		    else if (!rn2(Cold_resistance ? 3 : 2)) {
+		    else if (!rn2((how_resistant(COLD_RES) > 50) ? 3 : 2)) {	
 			HFumbling |= FROMOUTSIDE;
 			HFumbling &= ~TIMEOUT;
@@ -944,5 +955,5 @@
 			do {
 				if(tries++ > 50) {
-					nomul(0);
+					nomul(0, 0);
 					return;
 				}
@@ -956,5 +967,5 @@
 			water_friction();
 			if (!u.dx && !u.dy) {
-				nomul(0);
+				nomul(0, 0);
 				return;
 			}
@@ -963,5 +974,5 @@
 		}
 		if(!isok(x, y)) {
-			nomul(0);
+			nomul(0, 0);
 			return;
 		}
@@ -971,9 +982,9 @@
 		     (is_pool(x, y) || is_lava(x, y)) && levl[x][y].seenv)) {
 			if(flags.run >= 2) {
-				nomul(0);
+				nomul(0, 0);
 				flags.move = 0;
 				return;
 			} else
-				nomul(0);
+				nomul(0, 0);
 		}
 
@@ -1016,5 +1027,5 @@
 				goto pull_free;
 			    You("cannot escape from %s!", mon_nam(u.ustuck));
-			    nomul(0);
+			    nomul(0, 0);
 			    return;
 			}
@@ -1032,5 +1043,5 @@
 			       Protection_from_shape_changers)) ||
 			     sensemon(mtmp))) {
-				nomul(0);
+				nomul(0, 0);
 				flags.move = 0;
 				return;
@@ -1047,5 +1058,5 @@
 	/* attack monster */
 	if(mtmp) {
-	    nomul(0);
+	    nomul(0, 0);
 	    /* only attack if we know it's there */
 	    /* or if we used the 'F' command to fight blindly */
@@ -1109,5 +1120,5 @@
 		unmap_object(x, y); /* known empty -- remove 'I' if present */
 		newsym(x, y);
-		nomul(0);
+		nomul(0, 0);
 		if (expl) {
 		    u.mh = -1;		/* dead in the current form */
@@ -1124,5 +1135,5 @@
 	if (u.usteed && !u.usteed->mcanmove && (u.dx || u.dy)) {
 		pline("%s won't move!", upstart(y_monnam(u.usteed)));
-		nomul(0);
+		nomul(0, 0);
 		return;
 	} else
@@ -1132,5 +1143,5 @@
 		    Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?
 		    "in place" : "to the ground");
-		nomul(0);
+		nomul(0, 0);
 		return;
 	}
@@ -1255,5 +1266,5 @@
 	if (!test_move(u.ux, u.uy, x-u.ux, y-u.uy, DO_MOVE)) {
 	    flags.move = 0;
-	    nomul(0);
+	    nomul(0, 0);
 	    return;
 	}
@@ -1342,5 +1353,5 @@
 		    /* there's already been a trap message, reinforce it */
 		    abuse_dog(mtmp);
-		    adjalign(-3);
+			 minor_sin();
 		    break;
 		case 2:
@@ -1351,5 +1362,5 @@
 			You_feel("guilty about losing your pet like this.");
 			u.ugangr++;
-			adjalign(-15);
+				major_sin();
 		    }
 
@@ -1371,5 +1382,5 @@
 		if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) ||
 			IS_FURNITURE(tmpr->typ))
-		    nomul(0);
+		    nomul(0, 0);
 	}
 
@@ -1404,4 +1415,15 @@
 	    move_bc(0,bc_control,ballx,bally,chainx,chainy);
 
+	/* Special effects of WDSM; don't spam the player unless he's stepped onto
+	 * water from something that wasn't water/ice already */
+	if (is_pool(u.ux,u.uy) && !Levitation && !Flying && uarm && 
+			(uarm->otyp == WHITE_DRAGON_SCALE_MAIL || uarm->otyp == WHITE_DRAGON_SCALES)) {
+		levl[u.ux][u.uy].typ = ICE;
+      if (!is_pool(u.ux0,u.uy0) && !is_ice(u.ux0,u.uy0)) {
+			pline("The pool crackles and freezes under your feet.");
+		}
+		bury_objs(u.ux,u.uy);
+	}
+
 	spoteffects(TRUE);
 
@@ -1409,5 +1431,5 @@
 	/* must come after we finished picking up, in spoteffects() */
 	if (cause_delay) {
-	    nomul(-2);
+	    nomul(-2, "dragging an iron ball");
 	    nomovemsg = "";
 	}
@@ -1437,5 +1459,5 @@
 	    struct obj *otmp = carrying(CANDELABRUM_OF_INVOCATION);
 
-	    nomul(0);		/* stop running or travelling */
+	    nomul(0, 0);		/* stop running or travelling */
 #ifdef STEED
 	    if (u.usteed) Sprintf(buf, "beneath %s", y_monnam(u.usteed));
@@ -1496,5 +1518,5 @@
 #ifdef STEED
 		if (u.usteed && !is_flyer(u.usteed->data) &&
-			!is_floater(u.usteed->data) &&
+			!is_floater(u.usteed->data) && !is_flying(u.usteed) &&
 			!is_clinger(u.usteed->data)) {
 		    dismount_steed(Underwater ?
@@ -1925,5 +1947,5 @@
     /* they polymorphed while in the middle of a long move. */
     if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) {
-	nomul(0);
+	nomul(0, 0);
 	return;
     }
@@ -2002,5 +2024,5 @@
 	}
 stop:
-	nomul(0);
+	nomul(0, 0);
 	return;
     } /* end for loops */
@@ -2065,6 +2087,7 @@
 
 void
-nomul(nval)
+nomul(nval, txt)
 	register int nval;
+const char *txt;
 {
 	if(multi < nval) return;	/* This is a bug fix by ab@unido */
@@ -2072,4 +2095,8 @@
 	u.usleep = 0;
 	multi = nval;
+	if (txt && txt[0])
+	  (void) strncpy(multi_txt, txt, BUFSZ);
+	else
+	  (void) memset(multi_txt, 0, BUFSZ);
 	flags.travel = iflags.travel1 = flags.mv = flags.run = 0;
 }
@@ -2081,4 +2108,5 @@
 {
 	multi = 0;	/* caller will usually have done this already */
+	(void) memset(multi_txt, 0, BUFSZ);
 	if (msg_override) nomovemsg = msg_override;
 	else if (!nomovemsg) nomovemsg = You_can_move_again;
@@ -2156,4 +2184,82 @@
 
 int
+gainmaxhp(desired)
+int desired;
+{
+	int softcap,hardcap,i;
+	float scaled,overpct;
+	boolean pastcap;
+	int conbonus;
+
+	/* handle everything cleanly; the current-hp checks are in case we get called
+	 * to actually lose max HP, which might be desirable in some places */
+	if (Upolyd) {
+		/* Don't need to worry about capping anything with regard to this,
+		 * since it'll generally be temporary anyway.  Someone who slaps on
+		 * the amulet of unchanging and then busts out the HP abuse, well,
+		 * very clever, congratulations ;) */
+		u.mhmax += desired;
+		if (u.mh > u.mhmax) { u.mh = u.mhmax; }
+		return u.mhmax;
+	} else if (desired < 0) {
+		/* no need to do silly stuff if we're losing maxhp */
+		u.uhpmax += desired;
+		if (u.uhp > u.uhpmax) { u.uhp = u.uhpmax; }
+		return u.uhpmax;
+	}
+
+	/* Magical methods of increasing HP should certainly allow one to step
+	 * outside of the normal range gained by levels... but perhaps not 
+	 * _ridiculously_ so, to the point of 500+ HP or better on any character.
+	 *
+	 * So implement some slide based on your role/race; you can boost it
+	 * beyond a certain point that's appropriate for your level, but the
+	 * effectiveness of those gains will slowly decrease until you hit
+	 * an effective hard cap at 150% of possible natural maxHP at L30.  */
+	
+	/* first determine the maximum natural amounts this character could have */
+	conbonus = ACURR(A_CON) - 15;
+	if (conbonus < 0) conbonus = 0; 
+	if (conbonus > 4) conbonus = 4;
+	hardcap = softcap = urole.hpadv.infix + urole.hpadv.inrnd + 
+								urace.hpadv.infix + urace.hpadv.inrnd;
+
+	for (i=1;i<=30;i++) {
+		if (i <= u.ulevel) {
+			softcap += (i < urole.xlev) ? 
+				(urole.hpadv.lofix + urole.hpadv.lornd + urace.hpadv.lofix + urace.hpadv.lornd) :
+				(urole.hpadv.hifix + urole.hpadv.hirnd + urace.hpadv.hifix + urace.hpadv.hirnd);
+			softcap += conbonus;
+		}
+		hardcap += (i < urole.xlev) ?
+			(urole.hpadv.lofix + urole.hpadv.lornd + urace.hpadv.lofix + urace.hpadv.lornd) :
+			(urole.hpadv.hifix + urole.hpadv.hirnd + urace.hpadv.hifix + urace.hpadv.hirnd);
+		hardcap += conbonus;
+	}
+
+	/* paranoia */
+	if (softcap <= 0) { impossible("HP cap suspiciously low?"); return u.uhpmax; }
+
+	/* Reduce gains related to how far you are over the top.
+	 * If you're still below the maximum hard cap, you can be up to 200%
+	 * better than you should be at your level; otherwise, don't go more
+	 * than 150% past where you should be. */
+	pastcap = u.uhpmax >= hardcap;
+	overpct = (float)u.uhpmax / (float)softcap - 1;
+	if (overpct >= 0 && overpct < (pastcap ? 0.5 : 1.0)) { 
+		scaled = (float)desired * (1 - overpct * (pastcap ? 2 : 1));	
+		u.uhpmax += (int)scaled;
+		if (scaled - (int)scaled >= .5) { u.uhpmax++; } /* round up */
+	} else if (overpct < 0) {
+		/* if you haven't even hit the soft cap, you get the full bonus */
+		u.uhpmax += desired; 
+	} 
+
+	if (u.uhp > u.uhpmax) { u.uhp = u.uhpmax; }
+	return u.uhpmax;
+
+}
+
+int
 weight_cap()
 {
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/hacklib.c nethack/src/hacklib.c
--- nh_orig/src/hacklib.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/hacklib.c	2010-04-29 10:53:23.927730767 -0400
@@ -6,4 +6,7 @@
 /* We could include only config.h, except for the overlay definitions... */
 #include "hack.h"
+#ifdef UNIX
+#include <sys/times.h>
+#endif
 /*=
     Assorted 'small' utility routines.	They're virtually independent of
@@ -18,4 +21,6 @@
 	char *		upstart		(char *)
 	char *		mungspaces	(char *)
+	char *		stripctrl	(char *)
+	char *		trim		(char *)
 	char *		eos		(char *)
 	char *		strkitten	(char *,char)
@@ -121,4 +126,33 @@
 }
 
+char *
+stripctrl(bp) /* replace non-alphanum characters with spaces */
+     char *bp;
+{
+    register char *p;
+    for (p = bp; *p != '\0'; p++)
+	if (iscntrl(*p)) *p = ' ';
+    return bp;
+}
+
+/* trim leading and trailing spaces, in place */
+char *
+trim(bp)
+     char *bp;
+{
+    register char c, *p, *p2;
+    boolean was_space = TRUE;
+
+    for (p = p2 = bp; (c = *p) != '\0'; p++) {
+	if (!isspace(c)) {
+	    *p2++ = c;
+	    was_space = FALSE;
+	} else if (!was_space) *p2++ = c;
+    }
+    p = eos(bp);
+    while (--p >= bp && isspace(*p)) *p = '\0';
+    return bp;
+}
+
 #endif /* OVLB */
 
@@ -461,9 +495,22 @@
 setrandom()
 {
+	/* This isn't terribly portable at the moment, but it will compile
+	 * on both foonix and MinGW; it isn't the best situation, since someone
+	 * on Win32 should be able to predict process IDs with little effort, but
+	 * it's more of a "problem" on public servers anywa -- which are foonix. */
+	unsigned long seed;
+#ifdef UNIX
+	struct tms buf;
+	seed = (unsigned long)times(&buf) * getpid();
+#else
+	seed = (unsigned long)time((time_t*)0) * getpid();
+#endif
+
+
 	/* the types are different enough here that sweeping the different
 	 * routine names into one via #defines is even more confusing
 	 */
 #ifdef RANDOM	/* srandom() from sys/share/random.c */
-	srandom((unsigned int) time((time_t *)0));
+	srandom(seed);
 #else
 # if defined(__APPLE__) || defined(BSD) || defined(LINUX) || defined(ULTRIX) || defined(CYGWIN32) /* system srandom() */
@@ -472,13 +519,13 @@
 	(void)
 #   endif
-		srandom((int) time((long *)0));
+		srandom(seed);
 #  else
-		srandom((int) time((time_t *)0));
+		srandom(seed);
 #  endif
 # else
 #  ifdef UNIX	/* system srand48() */
-	srand48((long) time((time_t *)0));
+	srand48(seed);
 #  else		/* poor quality system routine */
-	srand((int) time((time_t *)0));
+	srand(seed);
 #  endif
 # endif
@@ -598,4 +645,12 @@
 }
 
+boolean
+christmas()
+{
+	struct tm* lt = getlt();
+	return (boolean)(lt->tm_mon == 11 && (lt->tm_mday > 15 && lt->tm_mday < 26));
+	/* 'twas the week(ish) before christmas, and all through the dungeon... */
+}
+
 int
 night()
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/invent.c nethack/src/invent.c
--- nh_orig/src/invent.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/invent.c	2010-08-29 07:52:40.525707081 -0400
@@ -20,5 +20,10 @@
 STATIC_PTR int FDECL(ckunpaid,(struct obj *));
 STATIC_PTR int FDECL(ckvalidcat,(struct obj *));
+#ifdef DUMP_LOG
+static char FDECL(display_pickinv,
+		 (const char *,BOOLEAN_P, long *, BOOLEAN_P, BOOLEAN_P));
+#else
 static char FDECL(display_pickinv, (const char *,BOOLEAN_P, long *));
+#endif /* DUMP_LOG */
 #ifdef OVLB
 STATIC_DCL boolean FDECL(this_type_only, (struct obj *));
@@ -245,4 +250,5 @@
 struct obj *obj;
 {
+	char buf[512];
 	if (obj->oclass == COIN_CLASS) {
 #ifndef GOLDOBJ
@@ -254,13 +260,33 @@
 		if (u.uhave.amulet) impossible("already have amulet?");
 		u.uhave.amulet = 1;
+#ifdef RECORD_ACHIEVE
+		achieve.get_amulet = 1;
+#endif
+#ifdef WISH_TRACKER
+		if (Is_sanctum(&u.uz)) {
+			Sprintf(buf,
+				"%s picked up the Amulet of Yendor in Moloch's Sanctum on T:%d", 
+				plname,moves);
+			makeannounce(buf);
+		}
+#endif
 	} else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
 		if (u.uhave.menorah) impossible("already have candelabrum?");
 		u.uhave.menorah = 1;
+#ifdef RECORD_ACHIEVE
+                achieve.get_candelabrum = 1;
+#endif
 	} else if (obj->otyp == BELL_OF_OPENING) {
 		if (u.uhave.bell) impossible("already have silver bell?");
 		u.uhave.bell = 1;
+#ifdef RECORD_ACHIEVE
+                achieve.get_bell = 1;
+#endif
 	} else if (obj->otyp == SPE_BOOK_OF_THE_DEAD) {
 		if (u.uhave.book) impossible("already have the book?");
 		u.uhave.book = 1;
+#ifdef RECORD_ACHIEVE
+                achieve.get_book = 1;
+#endif
 	} else if (obj->oartifact) {
 		if (is_quest_artifact(obj)) {
@@ -272,4 +298,17 @@
 		set_artifact_intrinsic(obj, 1, W_ART);
 	}
+
+#ifdef RECORD_ACHIEVE
+        if(obj->otyp == LUCKSTONE && obj->record_achieve_special) {
+                achieve.get_luckstone = 1;
+                obj->record_achieve_special = 0;
+        } else if((obj->otyp == AMULET_OF_REFLECTION ||
+                   obj->otyp == BAG_OF_HOLDING) &&
+                  obj->record_achieve_special) {
+                achieve.finish_sokoban = 1;
+                obj->record_achieve_special = 0;
+        }
+#endif /* RECORD_ACHIEVE */
+
 }
 
@@ -917,7 +956,14 @@
 		if ((!strcmp(word, "read") &&
 		    (otmp->otyp == FORTUNE_COOKIE
+		     || otmp->otyp == TIN
+		     || otmp->otyp == CAN_OF_GREASE
+		     || otmp->otyp == CANDY_BAR
+		     || otmp->otyp == ALCHEMY_SMOCK
 #ifdef TOURIST
 			|| otmp->otyp == T_SHIRT
+		     || otmp->otyp == CREDIT_CARD
 #endif
+		     || (OBJ_DESCR(objects[otmp->otyp]) &&
+			 !strncmp(OBJ_DESCR(objects[otmp->otyp]), "runed", 5))
 		    )))
 			allowall = TRUE;
@@ -1018,5 +1064,9 @@
 			allowed_choices = altlets;
 		    ilet = display_pickinv(allowed_choices, TRUE,
-					   allowcnt ? &ctmp : (long *)0);
+					   allowcnt ? &ctmp : (long *)0
+#ifdef DUMP_LOG
+					   , FALSE, TRUE
+#endif
+					   );
 		    if(!ilet) continue;
 		    if (allowcnt && ctmp >= 0) {
@@ -1164,5 +1214,5 @@
 			W_SADDLE |
 #endif
-			W_WEP | W_SWAPWEP | W_QUIVER))));
+			W_WEP | W_SWAPWEP | W_QUIVER | W_LAUNCHER))));
 }
 
@@ -1190,6 +1240,6 @@
 #endif
 	char sym, *ip, olets[MAXOCLASSES+5], ilets[MAXOCLASSES+5];
-	char extra_removeables[3+1];	/* uwep,uswapwep,uquiver */
-	char buf[BUFSZ], qbuf[QBUFSZ];
+	char extra_removeables[4+1];	/* uwep,uswapwep,uquiver,ulauncher */
+	char buf[BUFSZ] = "", qbuf[QBUFSZ];
 
 	if (resultflags) *resultflags = 0;
@@ -1259,4 +1309,5 @@
 	    if (uswapwep) (void)strkitten(extra_removeables, uswapwep->oclass);
 	    if (uquiver) (void)strkitten(extra_removeables, uquiver->oclass);
+	    if (ulauncher) (void)strkitten(extra_removeables, ulauncher->oclass);
 	}
 
@@ -1276,5 +1327,5 @@
 		    return 0;
 		} else if (oc_of_sym == WEAPON_CLASS &&
-			!uwep && !uswapwep && !uquiver) {
+			!uwep && !uswapwep && !uquiver && !ulauncher) {
 		    You("are not wielding anything.");
 		    return 0;
@@ -1690,4 +1741,13 @@
  * any count returned from the menu selection is placed here.
  */
+#ifdef DUMP_LOG
+static char
+display_pickinv(lets, want_reply, out_cnt, want_dump, want_disp)
+register const char *lets;
+boolean want_reply;
+long* out_cnt;
+boolean want_dump;
+boolean want_disp;
+#else
 static char
 display_pickinv(lets, want_reply, out_cnt)
@@ -1695,6 +1755,11 @@
 boolean want_reply;
 long* out_cnt;
+#endif
 {
 	struct obj *otmp;
+#ifdef SORTLOOT
+	struct obj **oarray;
+	int i, j;
+#endif
 	char ilet, ret;
 	char *invlet = flags.inv_order;
@@ -1705,4 +1770,7 @@
 	menu_item *selected;
 
+#ifdef DUMP_LOG
+	if (want_disp) {
+#endif
 	/* overriden by global flag */
 	if (flags.perm_invent) {
@@ -1714,4 +1782,9 @@
 	    win = WIN_INVEN;
 
+#ifdef DUMP_LOG
+	}
+	if (want_dump)   dump("", "Your inventory");
+#endif
+
 	/*
 	Exit early if no inventory -- but keep going if we are doing
@@ -1726,4 +1799,7 @@
 	*/
 	if (!invent && !(flags.perm_invent && !lets && !want_reply)) {
+#ifdef DUMP_LOG
+	  if (want_disp) {
+#endif
 #ifndef GOLDOBJ
 	    pline("Not carrying anything%s.", u.ugold ? " except gold" : "");
@@ -1731,4 +1807,14 @@
 	    pline("Not carrying anything.");
 #endif
+#ifdef DUMP_LOG
+	  }
+	  if (want_dump) {
+#ifdef GOLDOBJ
+	    dump("  ", "Not carrying anything");
+#else
+	    dump("  Not carrying anything", u.ugold ? " except gold." : ".");
+#endif
+	  }
+#endif
 	    return 0;
 	}
@@ -1744,8 +1830,20 @@
 	    for (otmp = invent; otmp; otmp = otmp->nobj) {
 		if (otmp->invlet == lets[0]) {
+#ifdef DUMP_LOG
+		  if (want_disp) {
+#endif
 		    ret = message_menu(lets[0],
 			  want_reply ? PICK_ONE : PICK_NONE,
 			  xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L));
 		    if (out_cnt) *out_cnt = -1L;	/* select all */
+#ifdef DUMP_LOG
+		  }
+		  if (want_dump) {
+		    char letbuf[7];
+		    sprintf(letbuf, "  %c - ", lets[0]);
+		    dump(letbuf,
+			 xprname(otmp, (char *)0, lets[0], TRUE, 0L, 0L));
+		  }
+#endif
 		    break;
 		}
@@ -1754,8 +1852,74 @@
 	}
 
+#ifdef SORTLOOT
+	/* count the number of items */
+	for (n = 0, otmp = invent; otmp; otmp = otmp->nobj)
+	  if(!lets || !*lets || index(lets, otmp->invlet)) n++;
+
+	/* Make a temporary array to store the objects sorted */
+	oarray = (struct obj **)alloc(n*sizeof(struct obj*));
+
+	/* Add objects to the array */
+	i = 0;
+	for(otmp = invent; otmp; otmp = otmp->nobj)
+	  if(!lets || !*lets || index(lets, otmp->invlet)) {
+	    if (iflags.sortloot == 'f') {
+	      /* Insert object at correct index */
+	      for (j = i; j; j--) {
+		if (strcmpi(cxname2(otmp), cxname2(oarray[j-1]))>0) break;
+		oarray[j] = oarray[j-1];
+	      }
+	      oarray[j] = otmp;
+	      i++;
+	    } else {
+	      /* Just add it to the array */
+	      oarray[i++] = otmp;
+	    }
+	  }
+#endif /* SORTLOOT */
+
+#ifdef DUMP_LOG
+	if (want_disp)
+#endif
+
 	start_menu(win);
 nextclass:
 	classcount = 0;
 	any.a_void = 0;		/* set all bits to zero */
+#ifdef SORTLOOT
+	for(i = 0; i < n; i++) {
+	  otmp = oarray[i];
+	  ilet = otmp->invlet;
+	  if (!flags.sortpack || otmp->oclass == *invlet) {
+	    if (flags.sortpack && !classcount) {
+	      any.a_void = 0;             /* zero */
+#ifdef DUMP_LOG
+			if (want_disp)
+#endif
+	      add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
+		       let_to_name(*invlet, FALSE, FALSE), MENU_UNSELECTED);
+#ifdef DUMP_LOG
+	      if (want_dump)
+		  dump("  ", let_to_name(*invlet, FALSE, FALSE));
+#endif
+	      classcount++;
+	    }
+	    any.a_char = ilet;
+#ifdef DUMP_LOG
+			if (want_disp)
+#endif
+	    add_menu(win, obj_to_glyph(otmp),
+		     &any, ilet, 0, ATR_NONE, doname(otmp),
+		     MENU_UNSELECTED);
+#ifdef DUMP_LOG
+	    if (want_dump) {
+	      char letbuf[7];
+	      sprintf(letbuf, "  %c - ", ilet);
+	      dump(letbuf, doname(otmp));
+	    }
+#endif
+	  }
+	}
+#else /* SORTLOOT */
 	for(otmp = invent; otmp; otmp = otmp->nobj) {
 		ilet = otmp->invlet;
@@ -1764,9 +1928,22 @@
 			    if (flags.sortpack && !classcount) {
 				any.a_void = 0;		/* zero */
+#ifdef DUMP_LOG
+				if (want_dump)
+				    dump("  ", let_to_name(*invlet, FALSE, FALSE));
+				if (want_disp)
+#endif
 				add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
-				    let_to_name(*invlet, FALSE), MENU_UNSELECTED);
+					 let_to_name(*invlet, FALSE, FALSE), MENU_UNSELECTED);
 				classcount++;
 			    }
 			    any.a_char = ilet;
+#ifdef DUMP_LOG
+			    if (want_dump) {
+			      char letbuf[7];
+			      sprintf(letbuf, "  %c - ", ilet);
+			      dump(letbuf, doname(otmp));
+			    }
+			    if (want_disp)
+#endif
 			    add_menu(win, obj_to_glyph(otmp),
 					&any, ilet, 0, ATR_NONE, doname(otmp),
@@ -1775,4 +1952,5 @@
 		}
 	}
+#endif /* SORTLOOT */
 	if (flags.sortpack) {
 		if (*++invlet) goto nextclass;
@@ -1784,4 +1962,10 @@
 #endif
 	}
+#ifdef SORTLOOT
+	free(oarray);
+#endif
+#ifdef DUMP_LOG
+	if (want_disp) {
+#endif
 	end_menu(win, (char *) 0);
 
@@ -1793,4 +1977,8 @@
 	} else
 	    ret = !n ? '\0' : '\033';	/* cancelled */
+#ifdef DUMP_LOG
+	} /* want_disp */
+	if (want_dump)  dump("", "");
+#endif
 
 	return ret;
@@ -1809,7 +1997,22 @@
 boolean want_reply;
 {
-	return display_pickinv(lets, want_reply, (long *)0);
+	return display_pickinv(lets, want_reply, (long *)0
+#ifdef DUMP_LOG
+			       , FALSE , TRUE
+#endif
+	);
 }
 
+#ifdef DUMP_LOG
+/* See display_inventory. This is the same thing WITH dumpfile creation */
+char
+dump_inventory(lets, want_reply, want_disp)
+register const char *lets;
+boolean want_reply, want_disp;
+{
+  return display_pickinv(lets, want_reply, (long *)0, TRUE, want_disp);
+}
+#endif
+
 /*
  * Returns the number of unpaid items within the given list.  This includes
@@ -1910,5 +2113,5 @@
 		if (!flags.sortpack || otmp->oclass == *invlet) {
 		    if (flags.sortpack && !classcount) {
-			putstr(win, 0, let_to_name(*invlet, TRUE));
+			putstr(win, 0, let_to_name(*invlet, TRUE, FALSE));
 			classcount++;
 		    }
@@ -1930,5 +2133,5 @@
 	/* something unpaid is contained */
 	if (flags.sortpack)
-	    putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE));
+	    putstr(win, 0, let_to_name(CONTAINED_SYM, TRUE, FALSE));
 	/*
 	 * Search through the container objects in the inventory for
@@ -2106,6 +2309,4 @@
 	} else if (IS_FOUNTAIN(ltyp))
 	    cmap = S_fountain;				/* "fountain" */
-	else if (IS_THRONE(ltyp))
-	    cmap = S_throne;				/* "opulent throne" */
 	else if (is_lava(x,y))
 	    cmap = S_lava;				/* "molten lava" */
@@ -2236,5 +2437,5 @@
 	    if (otmp->oinvis && !See_invisible) verb = "feel";
 #endif
-	    You("%s here %s.", verb, doname(otmp));
+	    You("%s here %s.", verb, doname_with_price(otmp));
 	    if (otmp->otyp == CORPSE) feel_cockatrice(otmp, FALSE);
 	} else {
@@ -2256,5 +2457,5 @@
 			break;
 		}
-		putstr(tmpwin, 0, doname(otmp));
+		putstr(tmpwin, 0, doname_with_price(otmp));
 	    }
 	    display_nhwindow(tmpwin, TRUE);
@@ -2590,8 +2791,10 @@
 
 char *
-let_to_name(let,unpaid)
+let_to_name(let,unpaid,showsym)
 char let;
 boolean unpaid;
+boolean showsym;
 {
+	static const char *ocsymformat = "%s('%c')";
 	const char *class_name;
 	const char *pos;
@@ -2606,5 +2809,6 @@
 	    class_name = names[0];
 
-	len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "");
+	len = strlen(class_name) + (unpaid ? sizeof "unpaid_" : sizeof "") +
+	    ((oclass && showsym) ? strlen(ocsymformat) : 0);
 	if (len > invbufsiz) {
 	    if (invbuf) free((genericptr_t)invbuf);
@@ -2616,4 +2820,7 @@
 	else
 	    Strcpy(invbuf, class_name);
+	if (oclass && showsym)
+	    Sprintf(eos(invbuf), ocsymformat,
+		    iflags.menu_tab_sep ? "\t" : "  ", def_oc_syms[let]);
 	return invbuf;
 }
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/light.c nethack/src/light.c
--- nh_orig/src/light.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/light.c	2009-10-22 09:38:12.054453154 -0400
@@ -309,8 +309,8 @@
 	    if (ls->type == LS_OBJECT || ls->type == LS_MONSTER) {
 		if (ghostly) {
-		    if (!lookup_id_mapping((unsigned)ls->id, &nid))
+		    if (!lookup_id_mapping((size_t)ls->id, &nid))
 			impossible("relink_light_sources: no id mapping");
 		} else
-		    nid = (unsigned) ls->id;
+		    nid = (size_t) ls->id;
 		if (ls->type == LS_OBJECT) {
 		    which = 'o';
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/lock.c nethack/src/lock.c
--- nh_orig/src/lock.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/lock.c	2009-11-25 10:31:20.831272890 -0500
@@ -51,5 +51,6 @@
 		/* [1] */	"unlocking the chest",
 		/* [2] */	"unlocking the box",
-		/* [3] */	"picking the lock"
+		/* [3] */   "cracking the safe",
+		/* [4] */	"picking the lock"
 	};
 
@@ -58,16 +59,18 @@
 		return actions[0]+2;	/* "locking the door" */
 	else if (xlock.box && !xlock.box->olocked)
-		return xlock.box->otyp == CHEST ? actions[1]+2 : actions[2]+2;
+		return xlock.box->otyp == CHEST ? actions[1]+2 : xlock.box->otyp == IRON_SAFE ?
+			actions[3]+2 : actions[2]+2;
 	/* otherwise we're trying to unlock it */
 	else if (xlock.picktyp == LOCK_PICK)
-		return actions[3];	/* "picking the lock" */
+		return actions[4];	/* "picking the lock" */
 #ifdef TOURIST
 	else if (xlock.picktyp == CREDIT_CARD)
-		return actions[3];	/* same as lock_pick */
+		return actions[4];	/* same as lock_pick */
 #endif
 	else if (xlock.door)
 		return actions[0];	/* "unlocking the door" */
 	else
-		return xlock.box->otyp == CHEST ? actions[1] : actions[2];
+		return xlock.box->otyp == CHEST ? actions[1] : xlock.box->otyp == IRON_SAFE ?
+			actions[3] : actions[2];
 }
 
@@ -78,5 +81,7 @@
 
 	if (xlock.box) {
-	    if((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
+	    if(((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) &&
+				 (xlock.box->otyp != IRON_SAFE || abs(xlock.box->oy - u.uy) > 1 ||
+				  abs(xlock.box->ox - u.ux) > 1)) {
 		return((xlock.usedtime = 0));		/* you or it moved */
 	    }
@@ -224,7 +229,9 @@
 
 int
-pick_lock(pick) /* pick a lock with a given object */
+pick_lock(pick,rx,ry) /* pick a lock with a given object */
 	register struct	obj	*pick;
+int rx,ry;
 {
+	/* rx and ry are passed only from the use-stethoscope stuff */
 	int picktyp, c, ch;
 	coord cc;
@@ -244,4 +251,6 @@
 		if (picktyp == CREDIT_CARD) what = "card";
 #endif
+		if (picktyp == STETHOSCOPE) what = "stethoscope";
+
 		pline(no_longer, "hold the", what);
 		reset_pick();
@@ -264,5 +273,5 @@
 	}
 
-	if((picktyp != LOCK_PICK &&
+	if((picktyp != LOCK_PICK && picktyp != STETHOSCOPE &&
 #ifdef TOURIST
 	    picktyp != CREDIT_CARD &&
@@ -274,6 +283,14 @@
 	ch = 0;		/* lint suppression */
 
+	/* If this is a stethoscope, we know where we came from */
+	if (picktyp == STETHOSCOPE) {
+		cc.x = rx; cc.y = ry;
+	} else {
 	if(!get_adjacent_loc((char *)0, "Invalid location!", u.ux, u.uy, &cc)) return 0;
-	if (cc.x == u.ux && cc.y == u.uy) {	/* pick lock on a container */
+	}
+
+	/* Very clumsy special case for this, but forcing the player to
+	 * a)pply > just to open a safe, when a)pply . works in all other cases? */
+	if (cc.x == u.ux && cc.y == u.uy || picktyp == STETHOSCOPE) {	/* pick lock on a container */
 	    const char *verb;
 	    boolean it;
@@ -304,4 +321,5 @@
 		    it = 0;
 		    if (otmp->obroken) verb = "fix";
+			 else if (otmp->otyp == IRON_SAFE) verb = "crack", it = 1;
 		    else if (!otmp->olocked) verb = "lock", it = 1;
 		    else if (picktyp != LOCK_PICK) verb = "unlock", it = 1;
@@ -316,4 +334,12 @@
 		    if(c == 'n') continue;
 
+			 if (otmp->otyp == IRON_SAFE && picktyp != STETHOSCOPE) {
+				 You("aren't sure how to go about opening the safe that way.");
+				 return 0;
+			 }
+			 if (!otmp->olocked && otmp->otyp == IRON_SAFE) {
+				 You_cant("change the combination.");
+				 return 0;
+			 }
 		    if (otmp->obroken) {
 			You_cant("fix its broken lock with %s.", doname(pick));
@@ -339,4 +365,7 @@
 			    ch = 75 + ACURR(A_DEX);
 			    break;
+			case STETHOSCOPE:
+				 ch = 5 + 2*ACURR(A_DEX)*Role_if(PM_ROGUE);
+				 break;
 			default:	ch = 0;
 		    }
@@ -350,5 +379,5 @@
 	    if (c != 'y') {
 		if (!count)
-		    There("doesn't seem to be any sort of lock here.");
+		    There("doesn't seem to be any sort of pickable lock here.");
 		return(0);		/* decided against all boxes */
 	    }
@@ -467,4 +496,8 @@
 	for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
 	    if(Is_box(otmp)) {
+			 if (otmp->otyp == IRON_SAFE) {
+				 You("would need dynamite to force %s.", the(xname(otmp)));
+				 continue;
+			 }
 		if (otmp->obroken || !otmp->olocked) {
 		    There("is %s here, but its lock is already %s.",
@@ -486,5 +519,6 @@
 		    You("start bashing it with your %s.", xname(uwep));
 		xlock.box = otmp;
-		xlock.chance = objects[uwep->otyp].oc_wldam * 2;
+		xlock.chance = objects[uwep->otyp].oc_wldam * 2 +
+			(picktyp ? ((ACURR(A_DEX) > 14) ? ACURR(A_DEX) - 14 : 0) : dbon());
 		xlock.picktyp = picktyp;
 		xlock.usedtime = 0;
@@ -724,5 +758,4 @@
 	    break;
 	case WAN_POLYMORPH:
-	case SPE_POLYMORPH:
 	    /* maybe start unlocking chest, get interrupted, then zap it;
 	       we must avoid any attempt to resume unlocking it */
@@ -830,4 +863,5 @@
 	case WAN_STRIKING:
 	case SPE_FORCE_BOLT:
+	case WAN_WIND:
 	    if (door->doormask & (D_LOCKED | D_CLOSED)) {
 		if (door->doormask & D_TRAPPED) {
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/mail.c nethack/src/mail.c
--- nh_orig/src/mail.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/mail.c	2010-08-16 13:20:13.485755039 -0400
@@ -5,4 +5,8 @@
 #include "hack.h"
 
+#if !defined(MAIL) && defined(SERVER_ADMIN_MSG)
+#include <sys/stat.h>
+#endif
+
 #ifdef MAIL
 #include "mail.h"
@@ -554,5 +558,5 @@
 #  ifdef SHELL	/* can't access mail reader without spawning subprocess */
     const char *txt, *cmd;
-    char *p, buf[BUFSZ], qbuf[BUFSZ];
+    char *p, buf[BUFSZ] = "", qbuf[BUFSZ];
     int len;
 
@@ -623,3 +627,48 @@
 #endif /* MAIL */
 
+void
+ck_server_admin_msg()
+{
+#ifdef SERVER_ADMIN_MSG
+  static struct stat ost,nst;
+  static long lastchk = 0;
+
+  if (moves < lastchk + 10) return;
+  lastchk = moves;
+
+  if (!stat(SERVER_ADMIN_MSG, &nst)) {
+
+    if (nst.st_mtime > ost.st_mtime) {
+      char curline[250];
+      boolean shown_name = FALSE;
+      FILE* mb = fopen(SERVER_ADMIN_MSG, "r");
+      boolean snd = flags.soundok;
+
+      if (!mb) return;
+
+      while (fgets(curline, 250, mb) != NULL) {
+        char *msg = strchr(curline, ':');
+        if (!msg) {
+          fclose(mb);
+	  flags.soundok = snd;
+          return;
+        }
+        *msg = '\0';
+        msg++;
+        msg[strlen(msg) - 1] = '\0'; /* kill newline */
+	flags.soundok = TRUE;
+        if (!shown_name) {
+          pline("The voice of %s booms through the caverns:", curline);
+          shown_name = TRUE;
+        }
+        verbalize(msg);
+      }
+      ost.st_mtime = nst.st_mtime;
+      fclose(mb);
+      flags.soundok = snd;
+    }
+  }
+#endif /* SERVER_ADMIN_MSG */
+}
+
 /*mail.c*/
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/makemon.c nethack/src/makemon.c
--- nh_orig/src/makemon.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/makemon.c	2010-05-13 09:22:21.966714579 -0400
@@ -71,4 +71,6 @@
 	if (!pm_resistance(ptr,MR_FIRE)) return TRUE;
     } else if (Is_airlevel(&u.uz)) {
+	/* fortunately elementals can't cast 'fly' so we don't have
+	 * to check for is_flying here; we don't have a monst pointer */
 	if(!(is_flyer(ptr) && ptr->mlet != S_TRAPPER) && !is_floater(ptr)
 	   && !amorphous(ptr) && !noncorporeal(ptr) && !is_whirly(ptr))
@@ -168,4 +170,5 @@
 	register int mm = monsndx(ptr);
 	struct obj *otmp;
+	int randwand;
 
 #ifdef REINCARNATION
@@ -201,4 +204,44 @@
 			case PM_SERGEANT:
 			  w1 = rn2(2) ? FLAIL : MACE;
+			  /* The sergeants in the towers get bows and wands so
+				* they can shoot at you while you're piddling with the
+				* drawbridge.  This should suck a lot if you're low level. */
+			  if (Is_stronghold(&u.uz)) {
+				  w2 = BOW;
+				  m_initthrow(mtmp,ARROW,30);
+
+				  /* wands of death should be very rare: 1 in 400 or so
+					* since we're making 8 wands per castle at this point,
+					* we need to be sure it's _super_ rare that one shows up */
+				  do {
+					  randwand = rn2(7);
+				  } while (randwand > 5 && rn2(50));
+
+				  switch (randwand) {
+					  case 1:
+						  randwand = WAN_MAGIC_MISSILE;
+						  break;
+					  case 2:
+						  randwand = WAN_SLEEP;
+						  break;
+					  case 3:
+						  randwand = WAN_FIRE;
+						  break;
+					  case 4:
+						  randwand = WAN_COLD;
+						  break;
+					  case 5:
+						  randwand = WAN_LIGHTNING;
+						  break;
+					  case 6:
+						  randwand = WAN_DEATH;
+						  break;
+					  case 0:
+					  default:
+						  randwand = WAN_STRIKING;
+						  break;
+				  }
+				  (void)mongets(mtmp, randwand);
+			  }
 			  break;
 			case PM_LIEUTENANT:
@@ -208,4 +251,5 @@
 			case PM_WATCH_CAPTAIN:
 			  w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
+			  (void)mongets(mtmp, SKELETON_KEY);
 			  break;
 			default:
@@ -218,7 +262,8 @@
 		    if (w2) (void)mongets(mtmp, w2);
 		} else if (is_elf(ptr)) {
-		    if (rn2(2))
-			(void) mongets(mtmp,
-				   rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
+			/* only higher-ranking elves get the good armor */
+		    if (rn2(2)) (void)mongets(mtmp,
+					(rn2(2) && (mm == PM_GREY_ELF || mm == PM_ELF_LORD || mm == PM_ELVENKING)) ? 
+					ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
 		    if (rn2(2)) (void)mongets(mtmp, ELVEN_LEATHER_HELM);
 		    else if (!rn2(4)) (void)mongets(mtmp, ELVEN_BOOTS);
@@ -262,13 +307,20 @@
 		    int spe2;
 
-		    /* create minion stuff; can't use mongets */
+		    /* create minion stuff; can't use mongets.
+			  * some angelic minions will get demonbane or sunsword;
+			  * decide that ahead of time so we know what to make */
+		    if (!rn2(20) || is_lord(ptr)) {
+				spe2 = rn2(2);
+				if (spe2) {
+					otmp = mksobj(SILVER_MACE, FALSE, FALSE);	/* TODO: unhardcode this crap */
+				} else {
+					otmp = mksobj(SILVER_LONG_SWORD, FALSE, FALSE);
+				}
+				otmp = oname(otmp, artiname(spe2 ? ART_DEMONBANE : ART_SUNSWORD));
+			 } else {
 		    otmp = mksobj(LONG_SWORD, FALSE, FALSE);
-
-		    /* maybe make it special */
-		    if (!rn2(20) || is_lord(ptr))
-			otmp = oname(otmp, artiname(
-				rn2(2) ? ART_DEMONBANE : ART_SUNSWORD));
+			 }
 		    bless(otmp);
-		    otmp->oerodeproof = TRUE;
+		    set_erodeproof(otmp);
 		    spe2 = rn2(4);
 		    otmp->spe = max(otmp->spe, spe2);
@@ -279,5 +331,5 @@
 				  FALSE, FALSE);
 		    otmp->cursed = FALSE;
-		    otmp->oerodeproof = TRUE;
+		    set_erodeproof(otmp);
 		    otmp->spe = 0;
 		    (void) mpickobj(mtmp, otmp);
@@ -287,4 +339,11 @@
 	    case S_HUMANOID:
 		if (mm == PM_HOBBIT) {
+			if (!rn2(20)) {
+				(void)mongets(mtmp, ELVEN_MITHRIL_COAT);
+				(void)mongets(mtmp, ELVEN_DAGGER);
+				otmp = mksobj(RIN_INVISIBILITY,FALSE,FALSE);
+				otmp->cursed = TRUE;
+				(void) mpickobj(mtmp,otmp);
+			} else {
 		    switch (rn2(3)) {
 			case 0:
@@ -298,5 +357,5 @@
 			    break;
 		      }
-		    if (!rn2(10)) (void)mongets(mtmp, ELVEN_MITHRIL_COAT);
+			}
 		    if (!rn2(10)) (void)mongets(mtmp, DWARVISH_CLOAK);
 		} else if (is_dwarf(ptr)) {
@@ -312,5 +371,6 @@
 			}
 			(void)mongets(mtmp, DWARVISH_IRON_HELM);
-			if (!rn2(3))
+			/* only higher ranking dwarves get the good stuff */
+			if (!rn2(3) && mm != PM_DWARF)
 			    (void)mongets(mtmp, DWARVISH_MITHRIL_COAT);
 		    } else {
@@ -372,13 +432,12 @@
 
 	    case S_CENTAUR:
-		if (rn2(2)) {
-		    if(ptr == &mons[PM_FOREST_CENTAUR]) {
+			/* the skittish centaurs all need to have missile weapons at least */
+			if(ptr == &mons[PM_FOREST_CENTAUR] || ptr == &mons[PM_PLAINS_CENTAUR]) {
 			(void)mongets(mtmp, BOW);
-			m_initthrow(mtmp, ARROW, 12);
-		    } else {
+				m_initthrow(mtmp, ARROW, 24);
+			} else if (rn2(2)) {
 			(void)mongets(mtmp, CROSSBOW);
 			m_initthrow(mtmp, CROSSBOW_BOLT, 12);
 		    }
-		}
 		break;
 	    case S_WRAITH:
@@ -396,4 +455,30 @@
 					     TRIDENT : STILETTO));
 		break;
+		 case S_GNOME:
+			if (rn2(5)) { (void)mongets(mtmp, GNOMISH_HELM); }
+			if (!rn2(3)) { (void)mongets(mtmp, GNOMISH_BOOTS); }
+			if (!rn2(5)) { (void)mongets(mtmp, GNOMISH_SUIT); }
+			/* some of this ported up from below, so gnomes are
+			 * more than a speedbump again */
+			switch (rn2(4)) {
+				case 3:
+					(void) mongets(mtmp, CROSSBOW);
+					m_initthrow(mtmp, CROSSBOW_BOLT, 12);
+					break;
+				case 2:
+					(void) mongets(mtmp, BOW);
+					m_initthrow(mtmp, ARROW, 12);
+					break;
+				case 1:
+					m_initthrow(mtmp, DAGGER, 3);
+					break;
+				case 0:
+				default:
+					(void) mongets(mtmp, AKLYS);
+					if ((int) mtmp->m_lev > rn2(75)) {
+						(void) mongets(mtmp, rnd_offensive_item(mtmp));
+					}
+			}
+		break;
 	    case S_DEMON:
 		switch (mm) {
@@ -402,7 +487,4 @@
 			(void)mongets(mtmp, BROADSWORD);
 			break;
-		    case PM_ORCUS:
-			(void)mongets(mtmp, WAN_DEATH); /* the Wand of Orcus */
-			break;
 		    case PM_HORNED_DEVIL:
 			(void)mongets(mtmp, rn2(4) ? TRIDENT : BULLWHIP);
@@ -614,5 +696,5 @@
 				      TRUE, rn2(13) ? FALSE : TRUE);
 			if (otmp->spe < 2) otmp->spe = rnd(3);
-			if (!rn2(4)) otmp->oerodeproof = 1;
+			if (!rn2(4)) set_erodeproof(otmp);
 			(void) mpickobj(mtmp, otmp);
 		}
@@ -625,4 +707,5 @@
 			otmp = mksobj(LARGE_BOX, FALSE, FALSE);
 			otmp->spe = 1; /* flag for special box */
+			otmp->capacity = 3000; /* it should still be standard capacity */
 			otmp->owt = weight(otmp);
 			(void) mpickobj(mtmp, otmp);
@@ -641,7 +724,4 @@
 		if (ptr == &mons[PM_ICE_DEVIL] && !rn2(4)) {
 			(void)mongets(mtmp, SPEAR);
-		} else if (ptr == &mons[PM_ASMODEUS]) {
-			(void)mongets(mtmp, WAN_COLD);
-			(void)mongets(mtmp, WAN_FIRE);
 		}
 		break;
@@ -709,11 +789,22 @@
 	m2->mgold = 0L;
 #endif
-	/* Max HP the same, but current HP halved for both.  The caller
-	 * might want to override this by halving the max HP also.
-	 * When current HP is odd, the original keeps the extra point.
+	/* Max HP remaining the same allows infinite pudding farming
+	 * so let's go ahead and chop both in half as well, so eventually
+	 * there'll be a finite end to things...
 	 */
-	m2->mhpmax = mon->mhpmax;
+	m2->mhpmax = mon->mhpmax / 2;
 	m2->mhp = mon->mhp / 2;
+	/* Big Daddy is a bit meaner; the originals don't suffer from the split */
+	if (mon->data != &mons[PM_JUIBLEX]) {
+		mon->mhpmax -= m2->mhpmax;
 	mon->mhp -= m2->mhp;
+	}
+
+	/* don't accidentally set any of these to zero
+	 * since our caller will be expecting a live critter */
+	if (m2->mhpmax < 1) m2->mhpmax = 1;
+	if (mon->mhpmax < 1) mon->mhpmax = 1;
+	if (m2->mhp < 1) m2->mhp = 1;
+	if (mon->mhp < 1) mon->mhp = 1;
 
 	/* since shopkeepers and guards will only be cloned if they've been
@@ -828,5 +919,6 @@
 {
 	register struct monst *mtmp;
-	int mndx, mcham, ct, mitem, xlth;
+	struct obj* otmp;
+	int mndx, mcham, ct, mitem, xlth, mhitdie;
 	boolean anymon = (!ptr);
 	boolean byyou = (x == u.ux && y == u.uy);
@@ -919,6 +1011,8 @@
 	    mtmp->mhpmax = mtmp->mhp = golemhp(mndx);
 	} else if (is_rider(ptr)) {
-	    /* We want low HP, but a high mlevel so they can attack well */
-	    mtmp->mhpmax = mtmp->mhp = d(10,8);
+	    /* We want low HP, but a high mlevel so they can attack well
+		  *
+		  * DSR 10/31/09: What, are you nuts?  They're way too crunchy. */
+	    mtmp->mhpmax = mtmp->mhp = 100 + d(8,8);
 	} else if (ptr->mlevel > 49) {
 	    /* "special" fixed hp monster
@@ -928,12 +1022,30 @@
 	    mtmp->mhpmax = mtmp->mhp = 2*(ptr->mlevel - 6);
 	    mtmp->m_lev = mtmp->mhp / 4;	/* approximation */
-	} else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
-	    /* adult dragons */
-	    mtmp->mhpmax = mtmp->mhp = (int) (In_endgame(&u.uz) ?
-		(8 * mtmp->m_lev) : (4 * mtmp->m_lev + d((int)mtmp->m_lev, 4)));
+	} else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON && In_endgame(&u.uz)) {
+	    /* dragons in the endgame are always at least average HP
+		  * note modified hit die here as well; they're MZ_GIGANTIC */
+	    mtmp->mhpmax = mtmp->mhp = 7 * mtmp->m_lev + d((int)mtmp->m_lev, 8);
 	} else if (!mtmp->m_lev) {
-	    mtmp->mhpmax = mtmp->mhp = rnd(4);
+	    mtmp->mhpmax = mtmp->mhp = rnd(4);	 /* level 0 monsters are pathetic */
+	} else if (ptr->msound == MS_LEADER) {
+		/* Quest Leaders need to be fairly burly */
+		mtmp->mhpmax = mtmp->mhp = 135 + rnd(30);
 	} else {
-	    mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, 8);
+		/* plain old ordinary monsters; modify hit die based on size;
+		 * big-ass critters like mastodons should have big-ass HP, and
+		 * small things like bees and locusts should get less 
+		 */
+		switch (mtmp->data->msize) {
+			case MZ_TINY: mhitdie = 4; break;
+			case MZ_SMALL: mhitdie = 6; break;
+			case MZ_LARGE: mhitdie = 10; break;
+			case MZ_HUGE: mhitdie = 12; break;
+			case MZ_GIGANTIC: mhitdie = 15; break;
+			case MZ_MEDIUM: 
+			default:	
+				mhitdie = 8;
+				break;
+		}
+	    mtmp->mhpmax = mtmp->mhp = d((int)mtmp->m_lev, mhitdie);
 	    if (is_home_elemental(ptr))
 		mtmp->mhpmax = (mtmp->mhp *= 3);
@@ -951,4 +1063,7 @@
 	place_monster(mtmp, x, y);
 	mtmp->mcansee = mtmp->mcanmove = TRUE;
+	mtmp->mflying = is_flyer(mtmp->data);	  /* fliers start out flying */
+	mtmp->seen_resistance = M_SEEN_NOTHING;
+	mtmp->mberserk = is_berserker(mtmp->data); /* berserkers start out crazed */
 	mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr);
 
@@ -980,4 +1095,5 @@
 			break;
 		case S_JABBERWOCK:
+			break;
 		case S_NYMPH:
 			if (rn2(5) && !u.uhave.amulet) mtmp->msleeping = 1;
@@ -995,4 +1111,29 @@
 			    mon_adjust_speed(mtmp, 2, (struct obj *)0);
 			break;
+		case S_DRAGON:
+			/* Dragons are always generated awake and pissed for Knights. */
+			if (Role_if(PM_KNIGHT)) {
+				mtmp->mpeaceful = mtmp->mtame = FALSE;
+				mtmp->msleeping = 0;
+			}
+			/* Warren Robinett didn't leave this easter egg, but... */
+			if (!rn2(13)) {
+				switch (mtmp->mnum) {
+					case PM_YELLOW_DRAGON:
+						mtmp = christen_monst(mtmp,"Yorgle"); 
+						break;
+					case PM_GREEN_DRAGON:
+						mtmp = christen_monst(mtmp,"Grundle");
+						if (rn2(2)) (void)mongets(mtmp, SKELETON_KEY); /* black key */
+						break;
+					case PM_RED_DRAGON:
+						mtmp = christen_monst(mtmp,"Rhindle");
+						if (rn2(2)) (void)mongets(mtmp, SKELETON_KEY); /* white key */
+						break;
+					default:
+						break;
+				}
+			}
+			break;
 	}
 	if ((ct = emits_light(mtmp->data)) > 0)
@@ -1022,12 +1163,4 @@
 		if (!(mmflags & MM_NONAME))
 			mtmp = christen_monst(mtmp, rndghostname());
-	} else if (mndx == PM_VLAD_THE_IMPALER) {
-		mitem = CANDELABRUM_OF_INVOCATION;
-	} else if (mndx == PM_CROESUS) {
-		mitem = TWO_HANDED_SWORD;
-	} else if (ptr->msound == MS_NEMESIS) {
-		mitem = BELL_OF_OPENING;
-	} else if (mndx == PM_PESTILENCE) {
-		mitem = POT_SICKNESS;
 	}
 	if (mitem && allow_minvent) (void) mongets(mtmp, mitem);
@@ -1189,4 +1322,30 @@
 }
 
+
+struct permonst *
+get_override_mon(override)
+struct mon_gen_override *override;
+{
+    int chance, try = 100;
+    struct mon_gen_tuple *mt;
+    int ok;
+    if (!override) return NULL;
+
+    chance = rnd(override->total_mon_freq);
+    do {
+	mt = override->gen_chances;
+	while (mt && ((chance -= mt->freq) > 0)) mt = mt->next;
+	if (mt && (chance <= 0)) {
+	    if (mt->is_sym) {
+		return (mkclass(mt->monid, 0));
+	    } else {
+		if (!(mvitals[mt->monid].mvflags & G_GENOD))
+		    return (&mons[mt->monid]);
+	    }
+	}
+    } while (--try > 0);
+    return NULL;
+}
+
 static NEARDATA struct {
 	int choice_count;
@@ -1201,5 +1360,7 @@
 	register int mndx, ct;
 
-	if (u.uz.dnum == quest_dnum && rn2(7) && (ptr = qt_montype()) != 0)
+	if (level.mon_gen &&
+	    (rn2(100) < level.mon_gen->override_chance) &&
+	    ((ptr = get_override_mon(level.mon_gen)) != 0))
 	    return ptr;
 
@@ -1492,4 +1653,8 @@
 	if (!otyp) return 0;
 	otmp = mksobj(otyp, TRUE, FALSE);
+	/* special case for Vlad's new sword */
+	if (mtmp->mnum == PM_VLAD_THE_IMPALER && otyp == TWO_HANDED_SWORD) {
+		otmp = mk_artifact(otmp,(aligntyp)A_NONE);
+	}
 	if (otmp) {
 	    if (mtmp->data->mlet == S_DEMON) {
@@ -1500,5 +1665,5 @@
 		otmp->cursed = FALSE;
 		if(otmp->spe < 0) otmp->spe = 0;
-		otmp->oerodeproof = TRUE;
+		set_erodeproof(otmp);
 	    } else if(is_mplayer(mtmp->data) && is_sword(otmp)) {
 		otmp->spe = (3 + rn2(4));
@@ -1510,6 +1675,4 @@
 		otmp->lamplit = FALSE;
 		otmp->blessed = otmp->cursed = FALSE;
-	    } else if (otmp->otyp == BELL_OF_OPENING) {
-		otmp->blessed = otmp->cursed = FALSE;
 	    } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
 		otmp->blessed = FALSE;
@@ -1544,10 +1707,10 @@
 		case PM_LEATHER_GOLEM: return 40;
 		case PM_GOLD_GOLEM: return 40;
-		case PM_WOOD_GOLEM: return 50;
+		case PM_WOOD_GOLEM: return 60;
 		case PM_FLESH_GOLEM: return 40;
-		case PM_CLAY_GOLEM: return 50;
-		case PM_STONE_GOLEM: return 60;
-		case PM_GLASS_GOLEM: return 60;
-		case PM_IRON_GOLEM: return 80;
+		case PM_CLAY_GOLEM: return 60;
+		case PM_STONE_GOLEM: return 150;		/* it's a rock */
+		case PM_GLASS_GOLEM: return 80;
+		case PM_IRON_GOLEM: return 150;		/* it's solid iron */
 		default: return 0;
 	}
@@ -1642,5 +1805,5 @@
 			mtmp->malign = 0;
 		else
-			mtmp->malign = max(5,absmal);
+			mtmp->malign = max(3,absmal);
 	} else if (coaligned) {
 		int absmal = abs(mal);
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/mapglyph.c nethack/src/mapglyph.c
--- nh_orig/src/mapglyph.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/mapglyph.c	2010-04-11 12:36:57.402750082 -0400
@@ -113,9 +113,9 @@
 	    if (offset >= S_vwall && offset <= S_hcdoor)
 		color = CLR_BROWN;
-	    else if (offset >= S_arrow_trap && offset <= S_polymorph_trap)
+	    else if (offset >= S_arrow_trap && offset <= S_magic_beam_trap)
 		color = CLR_MAGENTA;
 	    else if (offset == S_corr || offset == S_litcorr)
 		color = CLR_GRAY;
-	    else if (offset >= S_room && offset <= S_water)
+	    else if (offset >= S_room && offset <= S_water && offset != S_darkroom)
 		color = CLR_GREEN;
 	    else
@@ -133,5 +133,7 @@
 	    cmap_color(offset);
     } else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {	/* object */
-	if (offset == BOULDER && iflags.bouldersym) ch = iflags.bouldersym;
+	if (objects[offset].oc_class == FURNITURE_CLASS) {
+	    ch = objects[offset].oc_oc1;
+	} else if (offset == BOULDER && iflags.bouldersym) ch = iflags.bouldersym;
 	else ch = oc_syms[(int)objects[offset].oc_class];
 #ifdef ROGUE_COLOR
diff -X /home/derek/bin/nhdiff_exceptions -iNdEwr -U2 nh_orig/src/mcastu.c nethack/src/mcastu.c
--- nh_orig/src/mcastu.c	2003-12-07 18:39:13.000000000 -0500
+++ nethack/src/mcastu.c	2009-11-22 07:40:25.916272781 -0500
@@ -4,4 +4,6 @@
 
 #include "hack.h"
+#include "edog.h"
+#include "epri.h"
 
 /* monster mage spells */
@@ -18,4 +20,8 @@
 #define MGC_CLONE_WIZ	10
 #define MGC_DEATH_TOUCH	11
+#define MGC_FLY			12
+#define MGC_ENRAGE		13
+#define MGC_FIRE_BOLT   14
+#define MGC_ICE_BOLT    15
 
 /* monster cleric spells */
@@ -30,12 +36,16 @@
 #define CLC_FIRE_PILLAR	 8
 #define CLC_GEYSER	 9
+#define CLC_FLY			10
+#define CLC_VULN_YOU		11
+#define CLC_SUMMON_ELM  12
 
 STATIC_DCL void FDECL(cursetxt,(struct monst *,BOOLEAN_P));
-STATIC_DCL int FDECL(choose_magic_spell, (int));
-STATIC_DCL int FDECL(choose_clerical_spell, (int));
+STATIC_DCL int FDECL(choose_magic_spell, (struct monst *, int));
+STATIC_DCL int FDECL(choose_clerical_spell, (struct monst *, int));
 STATIC_DCL void FDECL(cast_wizard_spell,(struct monst *, int,int));
 STATIC_DCL void FDECL(cast_cleric_spell,(struct monst *, int,int));
 STATIC_DCL boolean FDECL(is_undirected_spell,(unsigned int,int));
 STATIC_DCL boolean FDECL(spell_would_be_useless,(struct monst *,unsigned int,int));
+STATIC_DCL void FDECL(cast_fly,(struct monst *));
 
 #ifdef OVL0
@@ -78,26 +88,39 @@
    inappropriate choices will be screened out by spell_would_be_useless() */
 STATIC_OVL int
-choose_magic_spell(spellval)
+choose_magic_spell(mtmp,spellval)
+struct monst* mtmp;
 int spellval;
 {
+	struct trap* tr;
+	int i;
+
+	/* If we're stuck in a pit, we know a way out */
+	tr = t_at(mtmp->mx,mtmp->my);
+	if (mtmp->mtrapped && tr && (tr->ttyp == PIT || tr->ttyp == SPIKED_PIT) 
+			&& mtmp->m_lev > 5) { spellval = 5; }
+
+	/* If we're hurt, seriously consider giving fixing ourselves priority */
+	if ((mtmp->mhp * 4) <= mtmp->mhpmax) { spellval = 1; }
+
     switch (spellval) {
     case 22:
     case 21:
-    case 20:
 	return MGC_DEATH_TOUCH;
+		case 20:
     case 19:
-    case 18:
 	return MGC_CLONE_WIZ;
+		case 18:
     case 17:
+			return MGC_ENRAGE;
     case 16:
     case 15:
 	return MGC_SUMMON_MONS;
     case 14:
-    case 13:
 	return 