Showing posts with label nethack. Show all posts
Showing posts with label nethack. Show all posts

Screenshots: NetHack Fourk 4.3.0.4

These screenshots are for NetHack Fourk version 4.3.0.4, which is being released today.

A Little Something I've Been Working On...

I recently made an announcement. Here are some screenshots...

The source repo is on github. You should totally play this game.

ENABLE_EXTENDED_FLAGS undeclared

Ok, so I acquire an older-model computer (Pentium4, 2GB of RAM), and of course it comes with Windows XP installed. What's one of the first things I try to do with it?

What would a normal person try to do with it? Maybe watch some YouTube videos, or check Yahoo Mail, something like that? Facebook?

I tried to do this:

I my defense, I already have a computer, which in the first place is several years newer (multi-core, 8GB of RAM about to be increased to 16 next time I'm willing to reboot it) and, additionally, runs a much better operating system. So if I wanted to do just regular stuff on the computer, I could do it on my main system. I got this other, older system, and my thinking is, while it still has the default Windows install on it, is there anything I want to try doing in Windows? And in that context, this is the answer I came up with: Didn't somebody on IRC say that building NetHack4 on Windows is broken right now? Maybe I should try that.

NAO game 115, Turn 100856

Another NetHack screenshot, this time in color:

You are blinded by the flash! ----------------------------------------------------------------------------- | 0| 0 * * ) |* | *| | | - - ----- | ----- ------------------------------| | -- --- | ----- | | | |*| | | | | | --------------| | | % < | | | | | --- --- --- | | | -- | CaB | | --- ----------*| | | | | | | |^ | --@--------|--| | | | | | | | | ----- --- --- | |-- | @ c i@S | |-- | | | | ----- |---| | | |) | | | | : & :@E@H| | | | | | | | | | ------- | --| --- | -- c$qxc&@Q$| -|-| --- | ----|%----| | | | | | |*| |0Y | t |$HDcdf@@@| | | | | | | | | | | --------- | | -----%| |HH c d $| | | | ----- - - | --- --| | | | | | | | | | | C u d$||--%-- | | | ** | | | | | | | | - |-- | | | | | --- | Quacf O| |[ [| | ----- | | ------- | | | | |[ | | | | | | )| -----| | | | | | | | | | | --- --| | |%| | | | | H |> - | ^ | | --- | | |)----- | | --- | | | | | | | | -------- ---- | | | | | * |*| | --- | | - --- | --------------------------------- ----- - | | ------- | | | > % H | ----------------------------------------------------------------------------- Jonadab the Heroine St:18/** Dx:22 Co:18 In:22 Wi:22 Ch:18 Lawful S:1675355 Dlvl:39 $:0 HP:236(241) Pw:71(71) AC:-40 Xp:22/25786222 T:100856 Blind

At this point in the game I am on my way to wake the Wizard. This room full of hostile monsters is just one of the things that's supposed to slow you down on the way, but it's a pretty weak defense against any character who has made it this far.

Yes, you see five pets. There's even a sixth: my original pet, Griff, found a polytrap somewhere when I wasn't paying attention and became a quivering blob, and I chose to leave him that way, because it keeps him from attacking things and getting killed. Quivering blobs, of course, do not show up on telepathy, which is why you don't see him. If all goes well, this will be the first time I ascend with my original starting pet. The other pets were domestics (cats, mostly) that I picked up in Gehennom using tripe and transformed into various more powerful things using polytraps on purpose. I originally collected them mainly so I could get the robe from the Valley priest, and then I kept them around for now just because I can. There used to be a Jabberwock, but something happened to it (possibly a purple worm; I've seen several).

Convict Role patch 0.7 ported to NH4

As anyone who follows rgrn knows, Karl Garrison has created a patch for NetHack 3.4.3, which adds a Convict role. Meanwhile, some other people have been working on a fork, called "NetHack4" (which can be easily downloaded here).

I have now ported the Convict role patch to work with NetHack4. For lack of a better place to put it, here it is:

diff -Nurd nitrohack-ais523//libnethack/dat/CMakeLists.txt nitrohack-ais523-convict//libnethack/dat/CMakeLists.txt
--- nitrohack-ais523//libnethack/dat/CMakeLists.txt 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/dat/CMakeLists.txt 2012-04-27 11:44:41.000000000 -0400
@@ -6,6 +6,7 @@
     ${LNH_DAT}/bigroom.des
     ${LNH_DAT}/castle.des
     ${LNH_DAT}/Caveman.des
+    ${LNH_DAT}/Convict.des
     ${LNH_DAT}/endgame.des
     ${LNH_DAT}/gehennom.des
     ${LNH_DAT}/Healer.des
@@ -35,29 +36,30 @@
     Bar-loca.lev Bar-strt.lev bigrm-1.lev  bigrm-2.lev
     bigrm-3.lev  bigrm-4.lev  bigrm-5.lev  castle.lev
     Cav-fila.lev Cav-filb.lev Cav-goal.lev Cav-loca.lev
-    Cav-strt.lev earth.lev    fakewiz1.lev fakewiz2.lev
-    fire.lev     Hea-fila.lev Hea-filb.lev Hea-goal.lev
-    Hea-loca.lev Hea-strt.lev juiblex.lev  Kni-fila.lev
-    Kni-filb.lev Kni-goal.lev Kni-loca.lev Kni-strt.lev
-    knox.lev     medusa-1.lev medusa-2.lev minefill.lev
-    minend-1.lev minend-2.lev minend-3.lev minetn-1.lev
-    minetn-2.lev minetn-3.lev minetn-4.lev minetn-5.lev
-    minetn-6.lev minetn-7.lev Mon-fila.lev Mon-filb.lev
-    Mon-goal.lev Mon-loca.lev Mon-strt.lev oracle.lev
-    orcus.lev    Pri-fila.lev Pri-filb.lev Pri-goal.lev
-    Pri-loca.lev Pri-strt.lev Ran-fila.lev Ran-filb.lev
-    Ran-goal.lev Ran-loca.lev Ran-strt.lev Rog-fila.lev
-    Rog-filb.lev Rog-goal.lev Rog-loca.lev Rog-strt.lev
-    Sam-fila.lev Sam-filb.lev Sam-goal.lev Sam-loca.lev
-    Sam-strt.lev sanctum.lev  soko1-1.lev  soko1-2.lev
-    soko2-1.lev  soko2-2.lev  soko3-1.lev  soko3-2.lev
-    soko4-1.lev  soko4-2.lev  Tou-fila.lev Tou-filb.lev
-    Tou-goal.lev Tou-loca.lev Tou-strt.lev tower1.lev
-    tower2.lev   tower3.lev   Val-fila.lev Val-filb.lev
-    Val-goal.lev valley.lev   Val-loca.lev Val-strt.lev
-    water.lev    wizard1.lev  wizard2.lev  wizard3.lev
-    Wiz-fila.lev Wiz-filb.lev Wiz-goal.lev Wiz-loca.lev
-    Wiz-strt.lev
+    Cav-strt.lev Con-strt.lev Con-loca.lev Con-goal.lev
+    Con-fila.lev Con-filb.lev earth.lev    fakewiz1.lev
+    fakewiz2.lev fire.lev     Hea-fila.lev Hea-filb.lev
+    Hea-goal.lev Hea-loca.lev Hea-strt.lev juiblex.lev 
+    Kni-fila.lev Kni-filb.lev Kni-goal.lev Kni-loca.lev
+    Kni-strt.lev knox.lev     medusa-1.lev medusa-2.lev
+    minefill.lev minend-1.lev minend-2.lev minend-3.lev
+    minetn-1.lev minetn-2.lev minetn-3.lev minetn-4.lev
+    minetn-5.lev minetn-6.lev minetn-7.lev Mon-fila.lev
+    Mon-filb.lev Mon-goal.lev Mon-loca.lev Mon-strt.lev
+    oracle.lev   orcus.lev    Pri-fila.lev Pri-filb.lev
+    Pri-goal.lev Pri-loca.lev Pri-strt.lev Ran-fila.lev
+    Ran-filb.lev Ran-goal.lev Ran-loca.lev Ran-strt.lev
+    Rog-fila.lev Rog-filb.lev Rog-goal.lev Rog-loca.lev
+    Rog-strt.lev Sam-fila.lev Sam-filb.lev Sam-goal.lev
+    Sam-loca.lev Sam-strt.lev sanctum.lev  soko1-1.lev 
+    soko1-2.lev  soko2-1.lev  soko2-2.lev  soko3-1.lev
+    soko3-2.lev  soko4-1.lev  soko4-2.lev  Tou-fila.lev
+    Tou-filb.lev Tou-goal.lev Tou-loca.lev Tou-strt.lev
+    tower1.lev   tower2.lev   tower3.lev   Val-fila.lev
+    Val-filb.lev Val-goal.lev valley.lev   Val-loca.lev
+    Val-strt.lev water.lev    wizard1.lev  wizard2.lev 
+    wizard3.lev  Wiz-fila.lev Wiz-filb.lev Wiz-goal.lev
+    Wiz-loca.lev Wiz-strt.lev
     )
 
 set (NHDAT_SRC dungeon quest.dat rumors oracles ${COMPILED_LEVELS} history data)
diff -Nurd nitrohack-ais523//libnethack/dat/Convict.des nitrohack-ais523-convict//libnethack/dat/Convict.des
--- nitrohack-ais523//libnethack/dat/Convict.des 1969-12-31 19:00:00.000000000 -0500
+++ nitrohack-ais523-convict//libnethack/dat/Convict.des 2012-04-27 09:37:17.000000000 -0400
@@ -0,0 +1,411 @@
+#
+# The "start" level for the quest.
+#
+# Here you meet your (besieged) class leader, Robert the Lifer
+# and receive your quest assignment.
+#
+MAZE:"Con-strt",' '
+FLAGS:noteleport,hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+|--------------------------------------------------------|-----------------|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|................K|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|---.---.---.---.---.---.---.---.---.---.---.---.---.---.|.................|
+|..........................................................................|
+|..........................................................................|
+|....|.---.---.---.---.---.---.---.---.---.---.---.---.--------------..----|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|---------------------------------------------------|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|--.---.---.---.---.---.---.---.---.---.---.---.---.|-----------------|
+|..........................................................................|
+|..........................................................................|
+|..........................................................................|
+|.----.---.---.---.---.---.---.---.---.---.---.---.---.--|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|....|...|...|...|...|...|...|...|...|...|...|...|...|...|.................|
+|--------------------------------------------------------|-----------------|
+ENDMAP
+# Dungeon Description
+REGION:(00,00,75,19),lit,"ordinary"
+# Stairs
+STAIR:(64,08),down
+# Portal arrival point
+BRANCH:(71,03,71,03),(0,0,0,0)
+# Altar
+ALTAR:(70,16),chaos,shrine
+# Robert the Lifer
+MONSTER:'@',"Robert the Lifer",(74,18)
+# fellow prisoners
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+MONSTER:'@',"inmate",random
+# Corrupt guards
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+# Good `ol mimics
+MONSTER:'m',"giant mimic", (74,05), m_feature "staircase up"
+# Random traps
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+# Prison debris
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[50%]: '0', "heavy iron ball", random
+OBJECT[50%]: '0', "heavy iron ball", random
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+
+#
+# The "locate" level for the quest.
+#
+# Here you have to find the exit from the Royal Dungeons
+# to go further towards your assigned quest.
+#
+
+MAZE:"Con-loca",' '
+FLAGS:noteleport,hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+---------------                                              ---------------
+|.....F.......| #################################            |............K|
+|.....F.......+##              #                #############+.............|
+|.....F.......|                #                #            |.............|
+|.....+.......|                #                #            |.............|
+|.....F.......|                #                #            |.............|
+|.....F.......|              ###                #            |.............|
+|.....F.......|             ##                  #            |FFFFFFFFFFFFF|
+|--------------     #########                   #            |......|......|
+                    #      |S-------|           #            |......|......|
+                    #      |........|      ######            |-------------|
+    #################      |........|      #    H                           
+    #                      |........+#######    #                           
+    #                      |----S---|           #            |----------|   
+ |--+-------|                   #               #####        |..........|   
+ |..........|                   #               #   #        |..........|   
+ |..........|                   #     |------|  #   #########+..........|   
+ |..........|                   ######S......+###            |..........|   
+ |----------|                         |......|               |----------|   
+                                      |------|                              
+ENDMAP
+# Dungeon Description
+REGION:(01,01,13,07),lit,"ordinary"
+REGION:(02,15,11,17),lit,"ordinary"
+REGION:(62,01,74,09),lit,"ordinary"
+REGION:(62,14,71,17),lit,"shop"
+REGION:(28,10,35,12),lit,"barracks"
+REGION:(39,17,44,18),lit,"ordinary"
+# Stairs
+STAIR:(02,03),up
+STAIR:(39,17),down
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+DOOR:locked,(04,14)
+DOOR:locked,(06,04)
+DOOR:open,(14,02)
+DOOR:closed,(61,16)
+DOOR:closed,(45,17)
+DOOR:locked,(36,12)
+DOOR:closed,(61,02)
+# Police station kops
+MONSTER: '@',"inmate",(63,08)
+MONSTER: '@',"inmate",(70,08)
+MONSTER: 'K',"Keystone Kop",(62,01),asleep
+MONSTER: 'K',"Keystone Kop",(65,01),asleep
+MONSTER: 'K',"Keystone Kop",(66,01),asleep
+MONSTER: 'K',"Keystone Kop",(74,02),asleep
+MONSTER: 'K',"Kop Sergeant",(63,03),asleep
+MONSTER: 'K',"Kop Sergeant",(72,03),asleep
+MONSTER: 'K',"Kop Lieutenant",(71,04),asleep
+MONSTER: 'K',"Kop Lieutenant",(68,05),asleep
+MONSTER: 'K',"Kop Kaptain",(64,06),asleep
+# Iron golem in supply room
+MONSTER: ''',"iron golem",(11,17),asleep
+# Supply room junk
+OBJECT: '_', "iron chain", (2,15)
+OBJECT: '_', "iron chain", (2,15)
+OBJECT: '_', "iron chain", (3,15)
+OBJECT: '_', "iron chain", (3,15)
+OBJECT: '_', "iron chain", (4,15)
+OBJECT: '0', "heavy iron ball", (4,15)
+OBJECT: '_', "iron chain", (4,15)
+OBJECT: '_', "iron chain", (5,15)
+OBJECT: '_', "iron chain", (5,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (6,15)
+OBJECT: '_', "iron chain", (7,15)
+OBJECT: '0', "heavy iron ball", (7,15)
+OBJECT: '_', "iron chain", (8,15)
+OBJECT: '_', "iron chain", (8,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (9,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (10,15)
+OBJECT: '_', "iron chain", (11,15)
+OBJECT: '_', "iron chain", (11,15)
+OBJECT: '0', "heavy iron ball", (11,15)
+OBJECT: '_', "iron chain", (2,16)
+OBJECT: '0', "heavy iron ball", (2,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (3,16)
+OBJECT: '_', "iron chain", (4,16)
+OBJECT: '_', "iron chain", (4,16)
+OBJECT: '_', "iron chain", (5,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (6,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '0', "heavy iron ball", (7,16)
+OBJECT: '_', "iron chain", (7,16)
+OBJECT: '_', "iron chain", (8,16)
+OBJECT: '_', "iron chain", (8,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (9,16)
+OBJECT: '_', "iron chain", (10,16)
+OBJECT: '_', "iron chain", (10,16)
+OBJECT: '_', "iron chain", (11,16)
+OBJECT: '_', "iron chain", (2,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (3,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '0', "heavy iron ball", (4,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '_', "iron chain", (4,17)
+OBJECT: '0', "heavy iron ball", (4,17)
+OBJECT: '_', "iron chain", (5,17)
+OBJECT: '_', "iron chain", (6,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (7,17)
+OBJECT: '_', "iron chain", (8,17)
+OBJECT: '0', "heavy iron ball", (8,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '0', "heavy iron ball", (9,17)
+OBJECT: '_', "iron chain", (9,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '_', "iron chain", (10,17)
+OBJECT: '0', "heavy iron ball", (10,17)
+OBJECT: '_', "iron chain", (11,17)
+
+
+#
+# The "goal" level for the quest.
+#
+# Here you meet Warden Arianna, your nemesis monster.  You have to
+# defeat Warden Arianna in combat to gain the artifact you have
+# been assigned to retrieve.
+#
+
+MAZE:"Con-goal",' '
+FLAGS:hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+---------------------------------------------------------
+|...|        |............................|             |
+|...|       --............................|             |
+|...|       |.............................|             |
+|...|      --.............................|             |
+|...|      |..............................|             |
+|...|     --...................L..........|             |
+|...|     |....................L..........|             |
+|...|    --...................L.L.........|             |
+|...|    |..............L.L.L.L.L.L.L.L...|             |
+|...|-----................L..L...L..L.....|             |
+|...........................L.L.L.L.......|             |
+|...........................L.L.L.L.......|             |
+|..........................L.L...L.L......|             |
+|.........................................|-------------|
+|.........................................|.............|
+|.........................................S.............|
+|.........................................|.............|
+|.........................................|.............|
+---------------------------------------------------------
+ENDMAP
+# Dungeon Description
+REGION:(00,00,56,19),lit,"ordinary"
+# Stairs
+STAIR:(02,02),up
+# Non diggable walls
+NON_DIGGABLE:(00,00,56,19)
+# Random traps
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+TRAP:"fire",random
+# Lava demons
+MONSTER: '&',"lava demon",(30,05),hostile,awake
+MONSTER: '&',"lava demon",(23,09),hostile,awake
+MONSTER: '&',"lava demon",(39,09),hostile,awake
+MONSTER: '&',"lava demon",(36,14),hostile,awake
+MONSTER: '&',"lava demon",(26,14),hostile,awake
+# Elite guard
+MONSTER: ''',"iron golem",(04,13),hostile
+# Objects
+OBJECT:'0',"heavy iron ball",(31,10),blessed,0,"The Iron Ball of Liberation"
+OBJECT:'(',"chest",(55,18),blessed,2
+# Warden Arianna
+MONSTER:'@',"Warden Arianna",(31,10),hostile
+
+#
+#       The "fill" levels for the quest.
+#
+#       These levels are used to fill out any levels not occupied by specific
+#       levels as defined above. "filla" is the upper filler, between the
+#       start and locate levels, and "fillb" the lower between the locate
+#       and goal levels.
+#
+
+MAZE:"Con-fila",' '
+FLAGS:hardfloor
+GEOMETRY:left,top
+#123456789012345678901234567890123456789012345678901234567890123456789012345
+MAP
+----------------------------------------------------------------------------
+|....................---------.......................---------.............|
+|....................F...|...|.......................F...|...|.............|
+|....................|...|...F.......................|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|........|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...F.......|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|....F...|...|.......F...|...|.......F...|...|.......F...|...|.............|
+|....|...|...F.......|...|...........|...|...F.......|...|...F.............|
+|....|---|---|.......|---|---|.......|---|---|.......|---|---|.............|
+|........|...|.......................F...|...|.............................|
+|....|...|...F.......................|...|...F.............................|
+|--------------------------------------------------------------------------|
+ENDMAP
+# Dungeon Description
+REGION:(00,00,75,19),lit,"ordinary"
+# Stairs
+STAIR:(74,03),up
+STAIR:(03,17),down
+# Non diggable walls
+NON_DIGGABLE:(00,00,75,19)
+# "Regular" prisoners
+MONSTER:'@',"inmate",(59,02)
+MONSTER:'@',"inmate",(55,08)
+MONSTER:'@',"inmate",(43,14)
+MONSTER:'@',"inmate",(38,05)
+MONSTER:'@',"inmate",(27,02)
+MONSTER:'@',"inmate",(23,08)
+MONSTER:'@',"inmate",(11,14)
+MONSTER:'@',"inmate",(06,05)
+# Undead prisoners
+MONSTER:' ',"ghost",(42,17),"Orzo the Inmate"
+MONSTER[50%]:' ',"ghost",(40,18),"Fredgar the Inmate"
+MONSTER[50%]:' ',"ghost",(06,12),"Rastilon the Inmate"
+MONSTER:'Z',"skeleton",(28,15),awake
+# Bugs and snakes
+MONSTER:'S',"pit viper",(06,17)
+MONSTER:'x',"xan",random
+# Corrupt guards
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+MONSTER[50%]:'@',"prison guard",random
+# Random traps
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+TRAP:"web",random
+# Prison debris
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[75%]: '_', "iron chain", random
+OBJECT[50%]: '0', "heavy iron ball", random
+OBJECT[50%]: '0', "heavy iron ball", random
+
+
+MAZE:"Con-filb",' '
+FLAGS:hardfloor
+INIT_MAP: '#' , ' ', true, true, unlit, true
+MESSAGE: "This appears to be a prison level that is still under construction"
+NOMAP
+#
+STAIR: random, up
+STAIR: random, down
+# Peaceful miners
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+MONSTER:'@',"miner",random,peaceful
+# Earth creatures
+MONSTER:'X',"xorn",random
+MONSTER:'E',"earth elemental",random
+MONSTER[50%]:'X',"xorn",random
+MONSTER[50%]:'E',"earth elemental",random
+# Other nasties
+MONSTER:'t',"lurker above",random
+MONSTER:'t',"trapper",random
+MONSTER[50%]:'t',"lurker above",random
+MONSTER[50%]:'t',"trapper",random
+MONSTER[50%]:'p',"rock piercer",random
+MONSTER[50%]:'p',"rock piercer",random
+MONSTER[50%]:'p',"iron piercer",random
+MONSTER[50%]:'p',"iron piercer",random
+MONSTER[50%]:'p',"glass piercer",random
+MONSTER[50%]:'p',"glass piercer",random
+# Tools and corpses
+OBJECT[50%]: '(', "pick-axe", random
+OBJECT[75%]: '(', "brass lantern", random
+OBJECT[50%]: '(', random, random
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+OBJECT[25%]: '%', "corpse", random, "miner", 0
+# Natural cavern hazards
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "pit", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "falling rock", random
+TRAP: "web", random
+TRAP: "web", random
+
diff -Nurd nitrohack-ais523//libnethack/dat/quest.txt nitrohack-ais523-convict//libnethack/dat/quest.txt
--- nitrohack-ais523//libnethack/dat/quest.txt 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/dat/quest.txt 2012-04-27 09:41:09.000000000 -0400
@@ -809,6 +809,302 @@
 "Sacrifice the Amulet on the altar.  Thus shall %d become supreme!"
 %E
 #
+# Convict
+#
+%Cc Con 00001
+Somehow, you have been captured and teleported back to
+%H!  But wait, the portal you went through is still
+here.  You had heard your old mentor %l,
+the prison chaplain who taught you the ways of
+%d calling for your help.  Also, %H
+is not as you had left it.  There seems to be damage
+to the walls, and you hear sounds of strife all
+around you.
+%E
+%Cp Con 00002
+You have returned to %H.  Somehow, things are even
+worse now than when you were on your previous visit.  Has
+%l managed to still hold out?
+%E
+%Cp Con 00003
+The situation seems to degrade, and you wonder how long
+your fellow %gp can hold out against the corrupt
+guards and creatures of the Underdark that pervade the
+formerly tranquil %H.
+%E
+%Cp Con 00005
+"How did you manage to escape?"
+%E
+%Cp Con 00006
+"How is life on the outside?"
+%E
+%Cp Con 00007
+"Between the abusive guards, and the nasty vermin, I
+don't know how we will hold out."
+%E
+%Cp Con 00008
+"This place used to be so much nicer before %n
+became corrupt."
+%E
+%Cp Con 00009
+"You are really back?  I thought you were gone for
+good."
+%E
+%Cp Con 00010
+"Thank you for ridding us of %n.  I hope the
+new warden will be better."
+%E
+%Cp Con 00011
+"Take me with you!  I will be glad to be rid of this
+awful place."
+%E
+%Cp Con 00012
+"Don't forget to come back for us once you have
+completed your quest!"
+%E
+%Cp Con 00013
+"Thank you for coming back to help us in our hour
+of need!"
+%E
+%Cp Con 00014
+"Leave while you still can!  If you can escape,
+maybe there is hope for the rest of us."
+%E
+%Cc Con 00015
+"%p, I am very happy to see that you are
+alive and well!  We were all proud of your daring
+escape, and hoped that you were doing well.
+Things have become much worse in your absence,
+however, and we desperately need your help.  Let
+me have a look at you, and see if you are ready."
+%E
+%Cp Con 00016
+"I see that you are back, %p.  I hope that
+you are now ready to help us?  Let me see if you
+are."
+%E
+%Cp Con 00017
+"Once again, you have returned.  Let me see if you
+are finally ready to help us."
+%E
+%Cc Con 00018
+"You have betrayed us all, %p!  Begone from
+here, and don't come back!  You are not even worthy
+to share a cell with the least of us now."
+%E
+%Cc Con 00019
+"%p, I am afraid that a %r will be no
+match for %n.  If I sent you now,
+she would dispatch you all too easily.
+
+"Continue your other quest, and practice your
+skills.  Return to us once you have achieved the rank
+of %R."
+%E
+%Cc Con 00020
+"%p, I see that you are not yet a loyal servant of
+%d.  Leave this place for now, and only
+return when you have cleansed your spirit.  Only then
+will you be ready to stand up to %n and
+recover %o."
+%E
+%Cc Con 00021
+"Yes, %p, it looks like you are now ready to
+help us.  Things have become much worse since you
+left.  The dungeons are overrun by vermin, guards
+have become brutal and corrupt, and I believe that
+%n has had dealings with dark powers.
+
+"I had spent many years enchanting my iron ball
+with powers to help lead an escape from this place,
+turning it into %o.
+Unfortunately, %n stole it from me,
+likely using it for dark, twisted purposes.
+
+"We need your help to go down to the warden's level
+to defeat the corrupt %n and recover
+%o for us so that
+%H will be safe again."
+%E
+%Cp Con 00025
+"The sooner you are able to recover %o,
+the better off we will be."
+%E
+%Cp Con 00026
+"I am not sure what has happened, but even without
+%o, %n will make a formidable opponent."
+%E
+%Cp Con 00027
+"Stay true to the teachings of %d, and good
+fortune will be with you."
+%E
+%Cp Con 00028
+"I am afraid without the power of %o
+to protect us, we will soon be overwhelmed."
+%E
+%Cp Con 00029
+"%n used to be a woman of honor before turning
+to dark ways.  It is much too late for
+redemption, however."
+%E
+%Cp Con 00030
+"%n is arrogant, and will try to diminish
+your confidence.  Do not let yourself be
+discouraged!"
+%E
+%Cp Con 00031
+"You will have to be very alert, and will need
+to use all of your cunning if you hope to
+defeat %n."
+%E
+%Cp Con 00032
+"Call upon the power of %d to protect you
+when you encounter %n."
+%E
+%Cp Con 00033
+"If you remain true to your faith, you should
+be able to sense the power of %o when
+you are near."
+%E
+%Cp Con 00034
+"You should be able to defeat %n easily
+enough in a fair fight.  Unfortunately, she doesn't
+fight fair."
+%E
+%Cc Con 00035
+This must be the level that leads to the warden's
+area.  You must be getting closer to
+%o now!
+%E
+%Cp Con 00036
+Once again, you find yourself near the entrance to
+the warden's area.  Hopefully, you can acquire
+%o before it's too late!
+%E
+%Cc Con 00040
+You sense the presence of %o as soon as you
+enter this level.  If %o is here, then
+%n must not be far away.
+%E
+%Cp Con 00041
+Once again, you find yourself in the abode of
+%n, and feel the presence of
+%o.
+%E
+%Cc Con 00050
+"So, %p.  You have returned, and are here to get
+%o for %l?
+What makes you think you can get it if
+%l couldn't?  I have many
+allies that have made me even stronger."
+%E
+%Cp Con 00051
+"I see that you have returned, %p.  I
+suggest you leave and save yourself while you still
+have a chance."
+%E
+%Cp Con 00052
+"Back again, %p?  You will certainly die in
+your attempt to defeat me."
+%E
+%Cp Con 00053
+"I will get %o from you, just as I did
+%l!  You can not defeat me."
+%E
+%Cp Con 00060
+"You should never come back.  You will not escape
+here alive again!"
+%E
+%Cp Con 00061
+"Even all of your pathetic lot put together would
+not be enough to defeat me."
+%E
+%Cp Con 00062
+"You are no more than lowly prison scum.  You are
+unworthy to even challenge me."
+%E
+%Cp Con 00063
+"Even %l could not stand up to me, so
+you have no chance at all."
+%E
+%Cp Con 00064
+"Even %o would not be enough to
+make you my equal."
+%E
+%Cp Con 00065
+"Your pathetic devotion to %d will not
+save you, either."
+%E
+%Cp Con 00066
+"After I kill you, I will go after %l next,
+and any that dare to defy me again!"
+%E
+%Cp Con 00067
+"Die with dishonor, lowly %c!"
+%E
+%Cp Con 00068
+"Once a %c, always a %c."
+%E
+%Cp Con 00069
+"How about you find yourself a cosy little cell,
+and hope that I forgive your insolence?"
+%E
+%Cc Con 00070
+As you pick up %o, you feel its power
+flow through you, protecting you, and making you
+more aware of your surroundings.  You know that
+you need to get it back to %l as soon
+as possible now.
+%E
+%Cc Con 00080
+As %n approaches death, you see sudden
+clarity in her eyes.
+
+"What have I done?  Those demons have been clouding my mind.
+Please forgive me, %p, although I know that I
+probably do not deserve it.  Take 
+%o back to %l
+with my blessing."
+
+With a final coughing fit, %n spasms, and her
+eyes see no more.
+%E
+%Cc Con 00081
+"Congratulations, %p!  You have returned with
+your life, and with %o!  I had
+planned to use %o to lead an
+escape from here, but with %n defeated,
+life should go back to normal before long.
+
+"Whether I like it or not, I know my place is here.  I
+see that %o has already attuned
+itself to you.  I offer it to you in hopes that
+it will aid in your quest to recover the Amulet
+of Yendor." 
+%E
+%Cc Con 00082
+%l looks upon %o
+with fondness.
+"You are its keeper now.  Take it with you back to
+%Z, through the magic portal
+that brought you here."
+%E
+%Cc Con 00090
+"Welcome back, %p.  We have done well in your
+absence.  How far have you come with your quest to
+regain the Amulet of Yendor for %d?"
+%E
+%Cc Con 00091
+"Congratulations, %p!  You have redeemed yourself
+and proven yourself a worthy servant of %d,
+and in doing so have made all of us proud.
+
+"One final task remains for you now.  You must take
+the Amulet up to the Great Temple of %d, on
+the Astral plane.  There you must offer the Amulet
+to %d."
+%E
+#
 # Healer
 #
 %Cc Hea 00001
@@ -3504,3 +3800,25 @@
  S suffix: return s_suffix(capitalized(root));
  t suffix: return strip_the_prefix(root);
 %E
+#
+# Alternate legacy text for Convict role
+#
+%Cc - 00199
+It is written in the Book of %d:
+
+    After the Creation, the cruel god Moloch rebelled
+    against the authority of Marduk the Creator.
+    Moloch stole from Marduk the most powerful of all
+    the artifacts of the gods, the Amulet of Yendor,
+    and he hid it in the dark cavities of Gehennom, the
+    Under World, where he now lurks, and bides his time.
+
+Your %G %d seeks to possess the Amulet, and with it
+to gain deserved ascendance over the other gods.
+
+You, a newly escaped %r, have chosen to redeem
+yourself by recovering the Amulet for %d.  You are
+determined to recover the Amulet for your deity, or die
+in the attempt.  Your hour of destiny has come.  For
+the sake of us all:  Go bravely with %d!
+%E
diff -Nurd nitrohack-ais523//libnethack/include/artifact.h nitrohack-ais523-convict//libnethack/include/artifact.h
--- nitrohack-ais523//libnethack/include/artifact.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/artifact.h 2012-04-27 09:42:29.000000000 -0400
@@ -59,5 +59,6 @@
 #define CREATE_PORTAL (LAST_PROP+7)
 #define ENLIGHTENING (LAST_PROP+8)
 #define CREATE_AMMO (LAST_PROP+9)
+#define PHASING  (LAST_PROP+10)
 
 #endif /* ARTIFACT_H */
diff -Nurd nitrohack-ais523//libnethack/include/artilist.h nitrohack-ais523-convict//libnethack/include/artilist.h
--- nitrohack-ais523//libnethack/include/artilist.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/artilist.h 2012-04-27 09:45:41.000000000 -0400
@@ -42,6 +42,10 @@
 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 ),
+/* Convict role first sacrifice gift: */
+A("Luck Blade",   BROADSWORD,
+ (SPFX_RESTR|SPFX_LUCK|SPFX_INTEL),0,0,
+ PHYS(5,6), NO_DFNS, NO_CARY, 0, A_CHAOTIC, PM_CONVICT, NON_PM, 3000L ),
 /*
  * Stormbringer only has a 2 because it can drain a level,
  * providing 8 more.
@@ -167,6 +171,12 @@
  PHYS(5,0), NO_DFNS, CARY(AD_MAGM),
  CONFLICT, A_LAWFUL, PM_CAVEMAN, NON_PM, 2500L ),
 
+A("The Iron Ball of Liberation", HEAVY_IRON_BALL,
+ (SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL),
+  (SPFX_STLTH|SPFX_SEARCH|SPFX_WARN), 0,
+ NO_ATTK, NO_DFNS, CARY(AD_MAGM),
+ PHASING, A_NEUTRAL, PM_PRISONER, NON_PM, 5000L ),
+
 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,
diff -Nurd nitrohack-ais523//libnethack/include/decl.h nitrohack-ais523-convict//libnethack/include/decl.h
--- nitrohack-ais523//libnethack/include/decl.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/decl.h 2012-04-27 09:46:23.000000000 -0400
@@ -142,6 +142,7 @@
 extern char dogname[];
 extern char catname[];
 extern char horsename[];
+extern char ratname[];
 extern char preferred_pet;
 extern const char *occtxt;   /* defined when occupation != NULL */
 extern const char *nomovemsg;
diff -Nurd nitrohack-ais523//libnethack/include/eshk.h nitrohack-ais523-convict//libnethack/include/eshk.h
--- nitrohack-ais523//libnethack/include/eshk.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/eshk.h 2012-04-27 09:47:07.000000000 -0400
@@ -31,6 +31,7 @@
  schar shoproom;  /* index in rooms; set by inshop() */
  boolean following; /* following customer since he owes us sth */
  boolean surcharge; /* angry shk inflates prices */
+ boolean pbanned; /* player is banned from the shop (convict role) */
  char customer[PL_NSIZ]; /* most recent customer */
  char shknam[PL_NSIZ];
 };
diff -Nurd nitrohack-ais523//libnethack/include/mondata.h nitrohack-ais523-convict//libnethack/include/mondata.h
--- nitrohack-ais523//libnethack/include/mondata.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/mondata.h 2012-04-27 09:48:46.000000000 -0400
@@ -89,6 +89,11 @@
 #define is_bat(ptr)  ((ptr) == &mons[PM_BAT] || \
      (ptr) == &mons[PM_GIANT_BAT] || \
      (ptr) == &mons[PM_VAMPIRE_BAT])
+# define is_rat(ptr)  ((ptr) == &mons[PM_SEWER_RAT] || \
+     (ptr) == &mons[PM_GIANT_RAT] || \
+     (ptr) == &mons[PM_RABID_RAT] || \
+     (ptr) == &mons[PM_ENORMOUS_RAT] || \
+     (ptr) == &mons[PM_RODENT_OF_UNUSUAL_SIZE])
 #define is_bird(ptr)  ((ptr)->mlet == S_BAT && !is_bat(ptr))
 #define is_giant(ptr)  (((ptr)->mflags2 & M2_GIANT) != 0L)
 #define is_golem(ptr)  ((ptr)->mlet == S_GOLEM)
@@ -195,6 +200,6 @@
      (ptr) != &mons[PM_BLACK_PUDDING]))
 
 #define befriend_with_obj(ptr, obj) ((obj)->oclass == FOOD_CLASS && \
-         is_domestic(ptr))
+         (is_domestic(ptr) || (is_rat(ptr) && Role_if(PM_CONVICT))))
 
 #endif /* MONDATA_H */
diff -Nurd nitrohack-ais523//libnethack/include/youprop.h nitrohack-ais523-convict//libnethack/include/youprop.h
--- nitrohack-ais523//libnethack/include/youprop.h 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/include/youprop.h 2012-04-27 09:49:40.000000000 -0400
@@ -268,7 +268,7 @@
 #define EPasses_walls  u.uprops[PASSES_WALLS].extrinsic
 #define Passes_walls  (HPasses_walls || EPasses_walls || \
      passes_walls(youmonst.data))
-
+#define Phasing                 u.uprops[PASSES_WALLS].intrinsic
 
 /*** Physical attributes ***/
 #define HSlow_digestion  u.uprops[SLOW_DIGESTION].intrinsic
diff -Nurd nitrohack-ais523//libnethack/src/allmain.c nitrohack-ais523-convict//libnethack/src/allmain.c
--- nitrohack-ais523//libnethack/src/allmain.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/allmain.c 2012-04-27 18:45:55.000000000 -0400
@@ -882,13 +882,26 @@
     if (MON_AT(level, u.ux, u.uy)) mnexto(m_at(level, u.ux, u.uy));
     makedog();
     doredraw();
+
+    if (Role_if(PM_CONVICT)) {
+        setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
+        setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+        uball->spe = 1;
+        placebc();
+        newsym(u.ux,u.uy);
+    }
     
     /* help the window port get it's display charset/tiles sorted out */
     notify_levelchange();
 
     if (flags.legacy) {
-     flush_screen();
-     com_pager(1);
+       flush_screen();
+       if (Role_if(PM_CONVICT)) {
+          com_pager(199); /* Convicts are "escaped" rather than
+                           * "trained", among other things. */
+       } else {
+          com_pager(1);
+       }
     }
 
     program_state.something_worth_saving++; /* useful data now exists */
diff -Nurd nitrohack-ais523//libnethack/src/artifact.c nitrohack-ais523-convict//libnethack/src/artifact.c
--- nitrohack-ais523//libnethack/src/artifact.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/artifact.c 2012-04-27 19:13:20.000000000 -0400
@@ -504,6 +504,17 @@
  if (yours) pline("%s your grasp!", Tobjnam(obj, "evade"));
  return 0;
     }
+    /* This is a kludge, but I'm not sure where else to put it */
+    if (oart == &artilist[ART_IRON_BALL_OF_LIBERATION]) {
+ if (Role_if(PM_CONVICT) && (!obj->oerodeproof)) {
+     obj->oerodeproof = TRUE;
+     obj->owt = 300; /* Magically lightened, but still heavy */
+ }
+
+ if (Punished && (obj != uball)) {
+     unpunish(); /* Remove a mundane heavy iron ball */
+ }
+    }
 
     return 1;
 }
@@ -1328,6 +1339,33 @@
      otmp->owt = weight(otmp);
      hold_another_object(otmp, "Suddenly %s out.", aobjnam(otmp, "fall"), NULL);
      break;
+ case PHASING:   /* Walk through walls and stone like a xorn */
+            if (Passes_walls) goto nothing_special;
+            if (oart == &artilist[ART_IRON_BALL_OF_LIBERATION]) {
+                if (Punished && (obj != uball)) {
+                    unpunish(); /* Remove a mundane heavy iron ball */
+                }
+                
+                if (!Punished) {
+                    setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
+                    setworn(obj, W_BALL);
+                    uball->spe = 1;
+                    if (!u.uswallow) {
+                        placebc();
+                        if (Blind) set_bc(1); /* set up ball and chain variables */
+                        newsym(u.ux,u.uy);    /* see ball&chain if can't see self */
+                    }
+                    pline("Your %s chains itself to you!", xname(obj));
+                }
+            }
+            if (!Hallucination) {    
+                pline("Your body begins to feel less solid.");
+            } else {
+                pline("You feel one with the spirit world.");
+            }
+            incr_itimeout(&Phasing, (50 + rnd(100)));
+            obj->age += Phasing; /* Time begins after phasing ends */
+            break;
    }
  }
     } else {
diff -Nurd nitrohack-ais523//libnethack/src/attrib.c nitrohack-ais523-convict//libnethack/src/attrib.c
--- nitrohack-ais523//libnethack/src/attrib.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/attrib.c 2012-04-27 10:08:56.000000000 -0400
@@ -36,6 +36,11 @@
        { 15, &(HWarning), "sensitive", "" },
        {  0, 0, 0, 0 } },
 
+ con_abil[] = { {   1, &(HSick_resistance), "", "" },
+                       {   7, &(HPoison_resistance), "healthy", "" },
+                       {  20, &(HSearching), "perceptive", "unaware" },
+                       {   0, 0, 0, 0 } },
+
  hea_abil[] = { {  1, &(HPoison_resistance), "", "" },
        { 15, &(HWarning), "sensitive", "" },
        {  0, 0, 0, 0 } },
@@ -467,6 +472,7 @@
  case PM_ARCHEOLOGIST:   abil = arc_abil; break;
  case PM_BARBARIAN:      abil = bar_abil; break;
  case PM_CAVEMAN:        abil = cav_abil; break;
+ case PM_CONVICT:        abil = con_abil; break;
  case PM_HEALER:         abil = hea_abil; break;
  case PM_KNIGHT:         abil = kni_abil; break;
  case PM_MONK:           abil = mon_abil; break;
diff -Nurd nitrohack-ais523//libnethack/src/cmd.c nitrohack-ais523-convict//libnethack/src/cmd.c
--- nitrohack-ais523//libnethack/src/cmd.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/cmd.c 2012-04-27 18:53:41.000000000 -0400
@@ -632,6 +632,9 @@
    if (u.usick_type & SICK_NONVOMITABLE)
     you_are(&menu, "sick from illness");
   }
+                if (Punished) {
+                    you_are(&menu, "punished");
+                }
  }
  if (Stoned) you_are(&menu, "turning to stone");
  if (Slimed) you_are(&menu, "turning into slime");
diff -Nurd nitrohack-ais523//libnethack/src/decl.c nitrohack-ais523-convict//libnethack/src/decl.c
--- nitrohack-ais523//libnethack/src/decl.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/decl.c 2012-04-27 10:24:44.000000000 -0400
@@ -135,6 +135,7 @@
 char dogname[PL_PSIZ];
 char catname[PL_PSIZ];
 char horsename[PL_PSIZ];
+char ratname[PL_PSIZ];
 char preferred_pet; /* '\0', 'c', 'd', 'n' (none) */
 /* monsters that went down/up together with @ */
 struct monst *mydogs;
@@ -233,6 +234,7 @@
     memset(dogname, 0, sizeof(dogname));
     memset(catname, 0, sizeof(catname));
     memset(horsename, 0, sizeof(horsename));
+    memset(ratname, 0, sizeof(ratname));
     memset(&youmonst, 0, sizeof(youmonst));
     memset(&zeroobj, 0, sizeof(zeroobj));
     memset(mvitals, 0, sizeof(mvitals));
diff -Nurd nitrohack-ais523//libnethack/src/do.c nitrohack-ais523-convict//libnethack/src/do.c
--- nitrohack-ais523//libnethack/src/do.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/do.c 2012-04-27 10:13:15.000000000 -0400
@@ -1022,7 +1022,11 @@
       pline("You fly down along the %s.",
    at_ladder ? "ladder" : "stairs");
   else if (at_stairs &&
-      (near_capacity() > UNENCUMBERED || Punished || Fumbling)) {
+      (near_capacity() > UNENCUMBERED
+                     || (Punished && ((uwep != uball)
+                                      || ((P_SKILL(P_FLAIL) < P_BASIC))
+                                      || !Role_if(PM_CONVICT)))
+       || Fumbling)) {
       pline("You fall down the %s.", at_ladder ? "ladder" : "stairs");
       if (Punished) {
    drag_down();
diff -Nurd nitrohack-ais523//libnethack/src/dog.c nitrohack-ais523-convict//libnethack/src/dog.c
--- nitrohack-ais523//libnethack/src/dog.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/dog.c 2012-04-27 10:18:02.000000000 -0400
@@ -131,6 +131,8 @@
   petname = dogname;
  else if (pettype == PM_PONY)
   petname = horsename;
+ else if (pettype == PM_SEWER_RAT)
+  petname = ratname;
  else
   petname = catname;
 
@@ -142,6 +144,9 @@
      if (Role_if(PM_BARBARIAN)) petname = "Idefix";  /* Obelix */
      if (Role_if(PM_RANGER)) petname = "Sirius";     /* Orion's dog */
  }
+ if (!*petname && pettype == PM_SEWER_RAT) {
+     if(Role_if(PM_CONVICT)) petname = "Nicodemus"; /* Rats of NIMH */
+        }
 
  mtmp = makemon(&mons[pettype], level, u.ux, u.uy, MM_EDOG);
 
@@ -708,6 +713,12 @@
       && mtmp->data->mlet == S_DOG)
   return NULL;
 
+        if (Role_if(PM_CONVICT) && (is_domestic(mtmp->data) && obj)) {
+            /* Domestic animals are wary of the Convict */
+            pline("%s still looks wary of you.", Monnam(mtmp));
+            return NULL;
+        }
+
  /* If we cannot tame it, at least it's no longer afraid. */
  mtmp->mflee = 0;
  mtmp->mfleetim = 0;
diff -Nurd nitrohack-ais523//libnethack/src/dokick.c nitrohack-ais523-convict//libnethack/src/dokick.c
--- nitrohack-ais523//libnethack/src/dokick.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/dokick.c 2012-04-27 10:18:35.000000000 -0400
@@ -309,6 +309,8 @@
       goldreqd = 500L;
    else if (mtmp->data == &mons[PM_CAPTAIN])
       goldreqd = 750L;
+   else if (mtmp->data == &mons[PM_PRISON_GUARD])
+      goldreqd = 200L;
 
    if (goldreqd) {
       if (value > goldreqd +
diff -Nurd nitrohack-ais523//libnethack/src/eat.c nitrohack-ais523-convict//libnethack/src/eat.c
--- nitrohack-ais523//libnethack/src/eat.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/eat.c 2012-04-27 10:22:08.000000000 -0400
@@ -1210,12 +1210,15 @@
      "Mmm, tripe... not bad!");
   else {
       pline("Yak - dog food!");
+      if (Role_if(PM_CONVICT))
+   pline("At least it's not prison food.");
       more_experienced(1,0);
       newexplevel();
       /* not cannibalism, but we use similar criteria
          for deciding whether to be sickened by this meal */
       if (rn2(2) && !CANNIBAL_ALLOWED())
-   make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
+                        if (!Role_if(PM_CONVICT))
+                            make_vomiting((long)rn1(victual.reqtime, 14), FALSE);
   }
   break;
      case MEATBALL:
@@ -1253,7 +1256,10 @@
 #endif
   if (otmp->otyp == EGG && stale_egg(otmp)) {
       pline("Ugh.  Rotten egg."); /* perhaps others like it */
-      make_vomiting(Vomiting+dice(10,4), TRUE);
+                    if (Role_if(PM_CONVICT) && (rn2(8) > u.ulevel)) {
+                        pline("You feel a slight stomach ache."); /* prisoners are used to bad food */
+                    } else
+                        make_vomiting(Vomiting+dice(10,4), TRUE);
   } else
  give_feedback:
       pline("This %s is %s", singular(otmp, xname),
@@ -1943,6 +1949,8 @@
 
  if ((!u.usleep || !rn2(10)) /* slow metabolic rate while asleep */
   && (carnivorous(youmonst.data) || herbivorous(youmonst.data))
+            /* Convicts can last twice as long at hungry and below */
+            && (!Role_if(PM_CONVICT) || (moves % 2) || (u.uhs < HUNGRY))
   && !Slow_digestion)
      u.uhunger--;  /* ordinary food consumption */
 
diff -Nurd nitrohack-ais523//libnethack/src/hack.c nitrohack-ais523-convict//libnethack/src/hack.c
--- nitrohack-ais523//libnethack/src/hack.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/hack.c 2012-04-27 10:25:45.000000000 -0400
@@ -590,7 +590,8 @@
  }
  if (invent && (inv_weight() + weight_cap() > 600)) {
      if (mode == DO_MOVE)
-  pline("You are carrying too much to get through.");
+                if (!Passes_walls)
+                    pline("You are carrying too much to get through.");
      return FALSE;
  }
     }
diff -Nurd nitrohack-ais523//libnethack/src/makemon.c nitrohack-ais523-convict//libnethack/src/makemon.c
--- nitrohack-ais523//libnethack/src/makemon.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/makemon.c 2012-04-27 18:56:16.000000000 -0400
@@ -179,6 +179,7 @@
    case PM_LIEUTENANT:
      w1 = rn2(2) ? BROADSWORD : LONG_SWORD;
      break;
+   case PM_PRISON_GUARD:
    case PM_CAPTAIN:
    case PM_WATCH_CAPTAIN:
      w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
@@ -229,6 +230,11 @@
    if (!rn2(2)) curse(otmp);
    mpickobj(mtmp, otmp);
       }
+  } else if (mm == PM_MINER) {
+      (void)mongets(mtmp, PICK_AXE);
+      otmp = mksobj(level, BRASS_LANTERN, TRUE, FALSE);
+                    (void) mpickobj(mtmp, otmp);
+                    begin_burn(otmp, FALSE);
   }
   break;
 
@@ -469,6 +475,7 @@
 
       switch(monsndx(ptr)) {
    case PM_GUARD: mac = -1; break;
+   case PM_PRISON_GUARD: mac = -2; break;
    case PM_SOLDIER: mac = 3; break;
    case PM_SERGEANT: mac = 0; break;
    case PM_LIEUTENANT: mac = -2; break;
@@ -513,6 +520,7 @@
    mongets(mtmp, LEATHER_CLOAK);
 
       if (ptr != &mons[PM_GUARD] &&
+   ptr != &mons[PM_PRISON_GUARD] &&
    ptr != &mons[PM_WATCHMAN] &&
    ptr != &mons[PM_WATCH_CAPTAIN]) {
    if (!rn2(3)) mongets(mtmp, K_RATION);
diff -Nurd nitrohack-ais523//libnethack/src/mondata.c nitrohack-ais523-convict//libnethack/src/mondata.c
--- nitrohack-ais523//libnethack/src/mondata.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/mondata.c 2012-04-27 10:29:44.000000000 -0400
@@ -511,6 +511,8 @@
  {PM_ORC, PM_ORC_CAPTAIN}, {PM_HILL_ORC, PM_ORC_CAPTAIN},
  {PM_MORDOR_ORC, PM_ORC_CAPTAIN}, {PM_URUK_HAI, PM_ORC_CAPTAIN},
  {PM_SEWER_RAT, PM_GIANT_RAT},
+ {PM_GIANT_RAT, PM_ENORMOUS_RAT},
+ {PM_ENORMOUS_RAT, PM_RODENT_OF_UNUSUAL_SIZE},
  {PM_CAVE_SPIDER, PM_GIANT_SPIDER},
  {PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
  {PM_ELF, PM_ELF_LORD}, {PM_WOODLAND_ELF, PM_ELF_LORD},
diff -Nurd nitrohack-ais523//libnethack/src/monmove.c nitrohack-ais523-convict//libnethack/src/monmove.c
--- nitrohack-ais523//libnethack/src/monmove.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/monmove.c 2012-04-27 10:32:57.000000000 -0400
@@ -45,6 +45,13 @@
  if (mtmp->mpeaceful && in_town(u.ux, u.uy) &&
     mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
 
+            if(Role_if(PM_CONVICT) && !Upolyd) {
+                verbalize("%s yells: Hey!  You are the one from the wanted poster!",
+                          Amonnam(mtmp));
+                angry_guards(!(flags.soundok));
+                stop_occupation();
+                return;
+            }
      if (picking_lock(&x, &y) && IS_DOOR(level->locations[x][y].typ) &&
         (level->locations[x][y].doormask & D_LOCKED)) {
 
@@ -327,7 +334,8 @@
 
  /* Demonic Blackmail! */
  if (nearby && mdat->msound == MS_BRIBE &&
-    mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
+            (monsndx(mdat) != PM_PRISON_GUARD) &&
+            mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
      if (multi < 0) return(0); /* wait for you to be able to respond */
   if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
    pline("%s whispers at thin air.",
@@ -346,6 +354,24 @@
   } else if (demon_talk(mtmp)) return 1; /* you paid it off */
  }
 
+ /* Prison guard extortion */
+        if(nearby && (monsndx(mdat) == PM_PRISON_GUARD) && !mtmp->mpeaceful
+           && !mtmp->mtame && !u.uswallow && (!mtmp->mspec_used)) {
+            long gdemand = 500 * u.ulevel;
+            long goffer = 0;
+            
+            pline("%s demands %ld %s to avoid re-arrest.", Amonnam(mtmp),
+                  gdemand, currency(gdemand));
+            if ((goffer = bribe(mtmp)) >= gdemand) {
+                verbalize("Good.  Now beat it, scum!");
+                mtmp->mpeaceful = 1;
+                set_malign(mtmp);
+            } else {
+                pline("I said %ld!", gdemand);
+                mtmp->mspec_used = 1000;
+            }
+        }
+
  /* the watch will look around and see if you are up to no good :-) */
  if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN])
   watch_on_duty(mtmp);
diff -Nurd nitrohack-ais523//libnethack/src/monst.c nitrohack-ais523-convict//libnethack/src/monst.c
--- nitrohack-ais523//libnethack/src/monst.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/monst.c 2012-04-27 10:38:38.000000000 -0400
@@ -810,6 +810,20 @@
  SIZ(40, 30, 0, MS_SQEEK, MZ_TINY), MR_POISON, 0,
  M1_NOHANDS|M1_POIS|M1_REGEN|M1_CARNIVORE,
  M2_NOPOLY|M2_WERE|M2_HOSTILE, M3_INFRAVISIBLE, CLR_BROWN|HI_ULINE),
+    MON("enormous rat", S_RODENT,
+ LVL(3, 9, 6, 0, 0), (G_GENO|G_SGROUP|1),
+ A(ATTK(AT_BITE, AD_PHYS, 1, 6),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(200, 100, 0, MS_SQEEK, MZ_SMALL), 0, 0,
+ M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
+ CLR_BROWN),
+    MON("rodent of unusual size", S_RODENT,
+ LVL(7, 8, 4, 0, 0), (G_GENO|1),
+ A(ATTK(AT_BITE, AD_PHYS, 2, 6),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(500, 200, 0, MS_SQEEK, MZ_MEDIUM), 0, 0,
+ M1_ANIMAL|M1_NOHANDS|M1_CARNIVORE, M2_HOSTILE, M3_INFRAVISIBLE,
+ CLR_BROWN),
     MON("rock mole", S_RODENT,
  LVL(3, 3, 0, 20, 0), (G_GENO|2),
  A(ATTK(AT_BITE, AD_PHYS, 1, 6),
@@ -2234,6 +2248,22 @@
  M1_HUMANOID|M1_OMNIVORE,
  M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_COLLECT,
  M3_INFRAVISIBLE, HI_DOMESTIC2),
+    MON("miner", S_HUMAN,
+ LVL(2, 6, 10, 10, 4), (G_GENO|G_NOGEN),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 8),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_HUMANOID, MZ_HUMAN), 0, 0,
+ M1_TUNNEL|M1_NEEDPICK|M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_STRONG,
+ M3_INFRAVISIBLE, CLR_GRAY),
+    MON("prison guard", S_HUMAN,
+ LVL(12, 10, 10, 15, -6), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_PHYS, 4, 4),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_BRIBE, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_MERC|M2_STALK|M2_HOSTILE|M2_STRONG|M2_COLLECT,
+ M3_INFRAVISIBLE, HI_METAL),
     MON("wererat", S_HUMAN,
  LVL(2, 12, 10, 10, -7), (1),
  A(ATTK(AT_WEAP, AD_PHYS, 2, 4),
@@ -2475,6 +2505,14 @@
  M3_INFRAVISIBLE|M3_INFRAVISION, CLR_BLUE),
  /* standard demons & devils
   */
+    MON("lava demon", S_DEMON,
+ LVL(12, 12,-8, 40, -7), (G_NOCORPSE|G_NOGEN),
+ A(ATTK(AT_WEAP, AD_PHYS, 2, 4), ATTK(AT_BITE, AD_PHYS, 1, 8),
+   ATTK(AT_BITE, AD_FIRE, 2, 6), NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_SILENT, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
+ M1_HUMANOID|M1_POIS,
+ M2_NOPOLY|M2_DEMON|M2_STALK|M2_HOSTILE|M2_NASTY|M2_COLLECT,
+ M3_INFRAVISIBLE|M3_INFRAVISION, CLR_RED),
     MON("horned devil", S_DEMON,
  LVL(6, 9, -5, 50, 11), (G_HELL|G_NOCORPSE|2),
  A(ATTK(AT_WEAP, AD_PHYS, 1, 4), ATTK(AT_CLAW, AD_PHYS, 1, 4),
@@ -2483,7 +2521,7 @@
  SIZ(WT_HUMAN, 400, 0, MS_SILENT, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
  M1_POIS|M1_THICK_HIDE,
  M2_DEMON|M2_STALK|M2_HOSTILE|M2_NASTY, M3_INFRAVISIBLE|M3_INFRAVISION,
- CLR_BROWN),
+ CLR_RED),
 #define SEDUCTION_ATTACKS \
  A(ATTK(AT_BITE, AD_SSEX, 2, 6), ATTK(AT_CLAW, AD_PHYS, 1, 3), \
    ATTK(AT_CLAW, AD_PHYS, 1, 3), NO_ATTK, NO_ATTK, NO_ATTK)
@@ -2870,6 +2908,13 @@
  M1_HUMANOID|M1_OMNIVORE,
  M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_FEMALE|M2_COLLECT, M3_INFRAVISIBLE,
  HI_DOMESTIC3),
+    MON("convict", S_HUMAN,
+ LVL(10, 12, 10, 1, 0), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_HUMANOID, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_STRONG|M2_COLLECT, M3_INFRAVISIBLE, HI_DOMESTIC),
     MON("healer", S_HUMAN,
  LVL(10, 12, 10, 1, 0), G_NOGEN,
  A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
@@ -2984,6 +3029,15 @@
  M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_PEACEFUL|M2_STRONG|M2_MALE|
    M2_COLLECT|M2_MAGIC,
  M3_CLOSE|M3_INFRAVISIBLE, HI_QUEST),
+    MON("Robert the Lifer", S_HUMAN,
+ LVL(20, 12, 0, 40, -20), (G_NOGEN|G_UNIQ),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_LEADER, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_PEACEFUL|M2_STRONG|M2_MALE|
+   M2_COLLECT|M2_MAGIC,
+ M3_CLOSE|M3_INFRAVISIBLE, HI_DOMESTIC),
     MON("Hippocrates", S_HUMAN,
  LVL(20, 12, 0, 40, 0), (G_NOGEN|G_UNIQ),
  A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
@@ -3115,6 +3169,15 @@
  M2_NOPOLY|M2_HOSTILE|M2_FEMALE|M2_STALK|M2_STRONG|M2_NASTY|
    M2_GREEDY|M2_JEWELS|M2_MAGIC,
  M3_WANTSARTI|M3_WAITFORU|M3_INFRAVISIBLE, HI_QUEST),
+    MON("Warden Arianna", S_HUMAN,
+ LVL(20, 12, 0, 40, -14), (G_NOGEN|G_UNIQ|G_NOCORPSE),
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 25), ATTK(AT_WEAP, AD_PHYS, 1, 25),
+   ATTK(AT_CLAW, AD_SAMU, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_NEMESIS, MZ_HUMAN), MR_FIRE|MR_POISON, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PNAME|M2_HOSTILE|M2_STRONG|M2_STALK|
+   M2_NASTY|M2_FEMALE|M2_COLLECT|M2_MAGIC,
+ M3_WANTSARTI|M3_WAITFORU|M3_INFRAVISIBLE, HI_LORD),
     MON("Cyclops", S_GIANT,
  LVL(18, 12, 0, 0, -15), (G_NOGEN|G_UNIQ),
  A(ATTK(AT_WEAP, AD_PHYS, 4, 8), ATTK(AT_WEAP, AD_PHYS, 4, 8),
@@ -3235,6 +3298,14 @@
  M1_HUMANOID|M1_OMNIVORE,
  M2_NOPOLY|M2_HUMAN|M2_PEACEFUL|M2_STRONG|M2_COLLECT, M3_INFRAVISIBLE,
  HI_GUARDIAN),
+    MON("inmate", S_HUMAN,
+ LVL(12, 12, 10, 0, 0), G_NOGEN,
+ A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
+   NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
+ SIZ(WT_HUMAN, 400, 0, MS_GUARDIAN, MZ_HUMAN), 0, 0,
+ M1_HUMANOID|M1_OMNIVORE,
+ M2_NOPOLY|M2_HUMAN|M2_PEACEFUL|M2_STRONG|M2_COLLECT,
+ M3_INFRAVISIBLE|M3_CLOSE, CLR_BLACK),
     MON("attendant", S_HUMAN,
  LVL(5, 12, 10, 10, 3), G_NOGEN,
  A(ATTK(AT_WEAP, AD_PHYS, 1, 6),
diff -Nurd nitrohack-ais523//libnethack/src/objects.c nitrohack-ais523-convict//libnethack/src/objects.c
--- nitrohack-ais523//libnethack/src/objects.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/objects.c 2012-04-27 10:40:09.000000000 -0400
@@ -383,6 +383,8 @@
 /* shirts */
 ARMOR("Hawaiian shirt", NULL,
  1, 0, 0, 0,  8, 0,  5,   3, 10, 0, ARM_SHIRT, CLOTH, CLR_MAGENTA),
+ARMOR("striped shirt", NULL,
+ 1, 0, 0, 0,  0, 0,  5,   2, 10, 0, ARM_SHIRT, CLOTH, CLR_GRAY),
 ARMOR("T-shirt", NULL,
  1, 0, 0, 0,  2, 0,  5,   2, 10, 0, ARM_SHIRT, CLOTH, CLR_WHITE),
 
@@ -917,7 +919,7 @@
 OBJECT(OBJ("statue", NULL), BITS(1,0,0,1,0,0,0,0,0,0,0,P_NONE,MINERAL), 0,
   ROCK_CLASS,   900, 0, 2500,  0, 20, 20, 0, 0, 2500, CLR_WHITE),
 
-OBJECT(OBJ("heavy iron ball", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
+OBJECT(OBJ("heavy iron ball", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_FLAIL,IRON), 0,
   BALL_CLASS,  1000, 0,  480, 10, 25, 25, 0, 0,  200, HI_METAL),
       /* +d4 when "very heavy" */
 OBJECT(OBJ("iron chain", NULL), BITS(1,0,0,0,0,0,0,0,0,0,WHACK,P_NONE,IRON), 0,
diff -Nurd nitrohack-ais523//libnethack/src/options.c nitrohack-ais523-convict//libnethack/src/options.c
--- nitrohack-ais523//libnethack/src/options.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/options.c 2012-04-27 10:44:05.000000000 -0400
@@ -158,6 +158,7 @@
     { "catname",       "the name of your (first) cat", OPTTYPE_STRING, {NULL}},
     { "dogname",       "the name of your (first) dog", OPTTYPE_STRING, {NULL}},
     { "horsename",     "the name of your (first) horse", OPTTYPE_STRING, {NULL}},
+    { "ratname",       "the name of your (first) rat (e.g., ratname:Squeak)", OPTTYPE_STRING, {NULL}},
     { "pettype",       "your preferred initial pet type", OPTTYPE_ENUM, {0}},
     
     {NULL, NULL, OPTTYPE_BOOL, { NULL }}
@@ -308,6 +309,7 @@
  find_option(birth_options, "catname")->s.maxlen = PL_PSIZ;
  find_option(birth_options, "dogname")->s.maxlen = PL_PSIZ;
  find_option(birth_options, "horsename")->s.maxlen = PL_PSIZ;
+ find_option(birth_options, "ratname")->s.maxlen = PL_PSIZ;
 
  /* If no config file exists, these values will not get set until they
   * have already been used during game startup.  (-1) is a much better
@@ -638,6 +640,9 @@
  else if (!strcmp("horsename", option->name)) {
   strncpy(horsename, option->value.s, PL_PSIZ);
  }
+ else if (!strcmp("ratname", option->name)) {
+  strncpy(ratname, option->value.s, PL_PSIZ);
+ }
  else if (!strcmp("pettype", option->name)) {
   preferred_pet = (char)option->value.e;
  }
diff -Nurd nitrohack-ais523//libnethack/src/read.c nitrohack-ais523-convict//libnethack/src/read.c
--- nitrohack-ais523//libnethack/src/read.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/read.c 2012-04-27 10:47:04.000000000 -0400
@@ -1605,6 +1605,7 @@
 
 void punish(struct obj *sobj)
 {
+        struct obj *otmp;
  /* KMH -- Punishment is still okay when you are riding */
  pline("You are being punished for your misbehavior!");
  if (Punished){
@@ -1618,7 +1619,13 @@
   return;
  }
  setworn(mkobj(level, CHAIN_CLASS, TRUE), W_CHAIN);
- setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+        if (((otmp = carrying(HEAVY_IRON_BALL)) != 0)
+            &&(otmp->oartifact == ART_IRON_BALL_OF_LIBERATION)) {
+            setworn(otmp, W_BALL);
+            pline("Your %s chains itself to you!", xname(otmp));
+        } else {
+            setworn(mkobj(level, BALL_CLASS, TRUE), W_BALL);
+        }
  uball->spe = 1;  /* special ball (see save) */
 
  /*
diff -Nurd nitrohack-ais523//libnethack/src/role.c nitrohack-ais523-convict//libnethack/src/role.c
--- nitrohack-ais523//libnethack/src/role.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/role.c 2012-04-27 10:48:59.000000000 -0400
@@ -108,6 +108,32 @@
  {  1, 0,  0, 1,  0, 1 },10, /* Energy */
  0, 12, 0, 1,  8, A_INT, SPE_DIG,             -4
 },
+{ {"Convict", 0}, {
+ {"Detainee",     0},
+ {"Inmate",   0},
+ {"Jail-bird",0},
+ {"Prisoner",0},
+ {"Outlaw",    0},
+ {"Crook",   0},
+ {"Desperado",     0},
+ {"Felon",    0},
+ {"Fugitive",  0} },
+ "Ilmater", "Grumbar", "_Tymora", /* Faerunian */
+ "Con", "Castle Waterdeep Dungeon", "the Warden's Level",
+ PM_CONVICT, NON_PM, PM_SEWER_RAT,
+ PM_ROBERT_THE_LIFER, PM_INMATE, PM_WARDEN_ARIANNA,
+ PM_GIANT_BEETLE, PM_SOLDIER_ANT, S_RODENT, S_SPIDER,
+ ART_IRON_BALL_OF_LIBERATION,
+ MH_HUMAN|MH_DWARF|MH_GNOME|MH_ORC | ROLE_MALE|ROLE_FEMALE |
+   ROLE_CHAOTIC,
+ /* Str Int Wis Dex Con Cha */
+ {  10,  7,  7,  7, 13,  6 },
+ {  20, 20, 10, 20, 20, 10 },
+ /* Init   Lower  Higher */
+ {  8, 0,  0, 8,  0, 0 }, /* Hit points */
+ {  1, 0,  0, 1,  0, 1 },10, /* Energy */
+ -10, 5, 0, 2, 10, A_INT, SPE_TELEPORT_AWAY,   -4
+},
 { {"Healer", 0}, {
  {"Rhizotomist",    0},
  {"Empiric",        0},
diff -Nurd nitrohack-ais523//libnethack/src/shk.c nitrohack-ais523-convict//libnethack/src/shk.c
--- nitrohack-ais523//libnethack/src/shk.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/shk.c 2012-04-27 18:58:40.000000000 -0400
@@ -485,6 +485,11 @@
      return;
  }
 
+ /* Visible striped prison shirt */
+ if ((uarmu && (uarmu->otyp == STRIPED_SHIRT)) && !uarm && !uarmc) {
+     eshkp->pbanned = TRUE;
+ }
+
  rt = level->rooms[*enterstring - ROOMOFFSET].rtype;
 
  if (ANGRY(shkp)) {
@@ -495,11 +500,12 @@
  } else if (eshkp->robbed) {
      pline("%s mutters imprecations against shoplifters.", shkname(shkp));
  } else {
-     verbalize("%s, %s!  Welcome%s to %s %s!",
-        Hello(shkp), plname,
-        eshkp->visitct++ ? " again" : "",
-        s_suffix(shkname(shkp)),
-        shtypes[rt - SHOPBASE].name);
+            if (!eshkp->pbanned || inside_shop(level, u.ux, u.uy))
+                verbalize("%s, %s!  Welcome%s to %s %s!",
+                          Hello(shkp), plname,
+                          eshkp->visitct++ ? " again" : "",
+                          s_suffix(shkname(shkp)),
+                          shtypes[rt - SHOPBASE].name);
  }
  /* can't do anything about blocking if teleported in */
  if (!inside_shop(level, u.ux, u.uy)) {
@@ -536,6 +542,9 @@
      "Will you please leave %s outside?" :
      "Leave %s outside.", y_monnam(u.usteed));
   should_block = TRUE;
+     } else if (eshkp->pbanned) {
+                verbalize("I don't sell to your kind here.");
+  should_block = TRUE;
      } else {
   should_block = (Fast && (sobj_at(PICK_AXE, level, u.ux, u.uy) ||
           sobj_at(DWARVISH_MATTOCK, level, u.ux, u.uy)));
@@ -1400,6 +1409,7 @@
   else {
       numsk++;
       taken |= inherits(mtmp, numsk, croaked);
+      ESHK(mtmp)->pbanned = FALSE; /* Un-ban for bones levels */
   }
      }
  }
@@ -2948,6 +2958,7 @@
       uondoor = (u.ux == eshkp->shd.x && u.uy == eshkp->shd.y);
       if (uondoor) {
    badinv = (carrying(PICK_AXE) || carrying(DWARVISH_MATTOCK) ||
+                                  eshkp->pbanned ||
       (Fast && (sobj_at(PICK_AXE, level, u.ux, u.uy) ||
       sobj_at(DWARVISH_MATTOCK, level, u.ux, u.uy))));
    if (satdoor && badinv)
diff -Nurd nitrohack-ais523//libnethack/src/sounds.c nitrohack-ais523-convict//libnethack/src/sounds.c
--- nitrohack-ais523//libnethack/src/sounds.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/sounds.c 2012-04-27 10:55:01.000000000 -0400
@@ -712,10 +712,31 @@
      }
      break;
  case MS_BRIBE:
-     if (mtmp->mpeaceful && !mtmp->mtame) {
-  demon_talk(mtmp);
-  break;
-     }
+            if (monsndx(ptr) == PM_PRISON_GUARD) {
+                long gdemand = 500 * u.ulevel;
+                long goffer = 0;
+                
+                if (!mtmp->mpeaceful && !mtmp->mtame) {
+                    pline("%s demands %ld %s to avoid re-arrest.",
+                          Amonnam(mtmp), gdemand, currency(gdemand));
+                    if ((goffer = bribe(mtmp)) >= gdemand) {
+                        verbl_msg = "Good.  Now beat it, scum!";
+                        mtmp->mpeaceful = 1;
+                        set_malign(mtmp);
+                        break;
+                    } else {
+                        pline("I said %ld!", gdemand);
+                        mtmp->mspec_used = 1000;
+                        break;
+                    }
+                } else {
+                    verbl_msg = "Out of my way, scum!"; /* still a jerk */
+                }
+            } else
+                if (mtmp->mpeaceful && !mtmp->mtame) {
+                    demon_talk(mtmp);
+                    break;
+                }
      /* fall through */
  case MS_CUSS:
      if (!mtmp->mpeaceful)
@@ -881,6 +902,23 @@
  return 0;
     }
 
+    if (Role_if(PM_CONVICT) && is_rat(mtmp->data) && !mtmp->mpeaceful &&
+        !mtmp->mtame) {
+        pline("You attempt to soothe the %s with chittering sounds.",
+            l_monnam(mtmp));
+        if (rnl(10) < 2) {
+            (void) tamedog(mtmp, (struct obj *) 0);
+        } else {
+            if (rnl(10) > 8) {
+                pline("%s unfortunately ignores your overtures.",
+                      Monnam(mtmp));
+                return 0;
+            }
+            mtmp->mpeaceful = 1;
+            set_malign(mtmp);
+        }
+        return 0;
+    }
     return domonnoise(mtmp);
 }
 
diff -Nurd nitrohack-ais523//libnethack/src/timeout.c nitrohack-ais523-convict//libnethack/src/timeout.c
--- nitrohack-ais523//libnethack/src/timeout.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/timeout.c 2012-04-27 19:01:19.000000000 -0400
@@ -6,6 +6,7 @@
 
 static void stoned_dialogue(void);
 static void vomiting_dialogue(void);
+static void phasing_dialogue(void);
 static void choke_dialogue(void);
 static void slime_dialogue(void);
 static void slip_or_trip(void);
@@ -40,6 +41,26 @@
  exercise(A_DEX, FALSE);
 }
 
+static void
+phasing_dialogue()
+{
+    if (Phasing == 15) {
+        if (!Hallucination) {
+            pline("Your body is beginning to feel more solid.");
+        } else {
+            pline("You feel more distant from the spirit world.");
+        }
+        stop_occupation();
+    } else if (Phasing == 1) {
+        if (!Hallucination) {
+            pline("Your body is solid again.");
+        } else {
+            pline("You feel totally separated from the spirit world.");
+        }
+        stop_occupation();
+    }
+}
+
 /* He is getting sicker and sicker prior to vomiting */
 static const char * const vomiting_texts[] = {
  "You are feeling mildly nauseated.", /* 14 */
@@ -176,6 +197,7 @@
      else if (u.uluck < baseluck && (nostone || time_luck > 0))
   u.uluck++;
  }
+        if (Phasing) phasing_dialogue();
  if (u.uinvulnerable) return; /* things past this point could kill you */
  if (Stoned) stoned_dialogue();
  if (Slimed) slime_dialogue();
diff -Nurd nitrohack-ais523//libnethack/src/uhitm.c nitrohack-ais523-convict//libnethack/src/uhitm.c
--- nitrohack-ais523//libnethack/src/uhitm.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/uhitm.c 2012-04-27 10:59:32.000000000 -0400
@@ -255,6 +255,14 @@
  if (is_orc(mtmp->data) && maybe_polyd(is_elf(youmonst.data),
    Race_if (PM_ELF)))
      tmp++;
+        /* Now that iron ball uses a weapon skill (flail), that gives
+           a -4 penalty for unskilled vs no penalty for non-weapon
+           objects.  Add 4 to compensate. */
+        if (uwep && (uwep->otyp == HEAVY_IRON_BALL)) {
+            tmp += 4;   /* Compensate for flail weapon skill -4
+                           penalty for unskilled vs no penalty for
+                           non- weapon objects. */
+        }
  if (Role_if(PM_MONK) && !Upolyd) {
      if (uarm) {
   pline("Your armor is rather cumbersome...");
@@ -551,7 +559,7 @@
  } else {
      strcpy(saved_oname, cxname(obj));
      if (obj->oclass == WEAPON_CLASS || is_weptool(obj) ||
-        obj->oclass == GEM_CLASS) {
+        obj->oclass == GEM_CLASS || obj->otyp == HEAVY_IRON_BALL) {
 
   /* is it not a melee weapon? */
   if (/* if you strike with a bow... */
diff -Nurd nitrohack-ais523//libnethack/src/u_init.c nitrohack-ais523-convict//libnethack/src/u_init.c
--- nitrohack-ais523//libnethack/src/u_init.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/u_init.c 2012-04-27 19:07:02.000000000 -0400
@@ -54,6 +54,11 @@
  { LEATHER_ARMOR, 0, ARMOR_CLASS, 1, UNDEF_BLESS },
  { 0, 0, 0, 0, 0 }
 };
+static struct trobj Convict[] = {
+ { ROCK, 0, GEM_CLASS, 1, 0 },
+ { STRIPED_SHIRT, 0, ARMOR_CLASS, 1, 0 },
+ { 0, 0, 0, 0, 0 }
+};
 static const struct trobj Healer[] = {
  { SCALPEL, 0, WEAPON_CLASS, 1, UNDEF_BLESS },
  { LEATHER_GLOVES, 1, ARMOR_CLASS, 1, UNDEF_BLESS },
@@ -292,6 +297,18 @@
     { P_NONE, 0 }
 };
 
+static const struct def_skill Skill_Con[] = {
+    { P_DAGGER, P_SKILLED },  { P_KNIFE,  P_EXPERT },
+    { P_HAMMER, P_SKILLED },  { P_PICK_AXE, P_EXPERT },
+    { P_CLUB, P_EXPERT },      { P_MACE, P_BASIC },
+    { P_DART, P_SKILLED },      { P_FLAIL, P_EXPERT },
+    { P_SHORT_SWORD, P_BASIC },  { P_SLING, P_SKILLED },
+    { P_ATTACK_SPELL, P_BASIC }, { P_ESCAPE_SPELL, P_EXPERT },
+    { P_TWO_WEAPON_COMBAT, P_SKILLED },
+    { P_BARE_HANDED_COMBAT, P_SKILLED },
+    { P_NONE, 0 }
+};
+
 static const struct def_skill Skill_H[] = {
     { P_DAGGER, P_SKILLED },  { P_KNIFE, P_EXPERT },
     { P_SHORT_SWORD, P_SKILLED }, { P_SCIMITAR, P_BASIC },
@@ -590,6 +607,18 @@
   ini_inv(trobj_list, nclist);
   skill_init(Skill_C);
   break;
+ case PM_CONVICT:
+            trobj_list = copy_trobj_list(Convict);
+            ini_inv(trobj_list, nclist);
+            knows_object(SKELETON_KEY);
+            knows_object(GRAPPLING_HOOK);
+            skill_init(Skill_Con);
+            u.uhunger = 200;  /* On the verge of hungry */
+            u.ualignbase[A_CURRENT] = u.ualignbase[A_ORIGINAL] =
+                u.ualign.type = A_CHAOTIC; /* Override racial alignment */
+            urace.hatemask |= urace.lovemask;   /* Hated by the race's allies */
+            urace.lovemask = 0; /* Convicts are pariahs of their race */
+            break;
  case PM_HEALER:
   u.umoney0 = rn1(1000, 1001);
   ini_inv(Healer, nclist);
@@ -744,7 +773,8 @@
  case PM_ORC:
      /* compensate for generally inferior equipment */
      if (!Role_if (PM_WIZARD))
-  ini_inv(Xtra_food, nclist);
+                if (!Role_if(PM_CONVICT))
+                    ini_inv(Xtra_food, nclist);
      /* Orcs can recognize all orcish objects */
      knows_object(ORCISH_SHORT_SWORD);
      knows_object(ORCISH_ARROW);
@@ -936,6 +966,9 @@
     is_graystone(obj) && obj->otyp != FLINT) {
        obj->quan = 1L;
    }
+                        if (obj->otyp == STRIPED_SHIRT ) {
+                            obj->cursed = TRUE;
+                        }
    if (trop->trspe != UNDEF_SPE)
        obj->spe = trop->trspe;
    if (trop->trbless != UNDEF_BLESS)
diff -Nurd nitrohack-ais523//libnethack/src/vault.c nitrohack-ais523-convict//libnethack/src/vault.c
--- nitrohack-ais523//libnethack/src/vault.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/vault.c 2012-04-27 11:34:59.000000000 -0400
@@ -265,6 +265,15 @@
      mongone(guard);
      return;
  }
+        if (Role_if(PM_CONVICT) && !Upolyd) {
+            setmangry(guard);
+            verbalize("I saw your pic on the wanted poster!");
+            if (!MON_WEP(guard)) {
+                guard->weapon_check = NEED_HTH_WEAPON;
+                mon_wield_item(guard);
+            }
+            return;
+        }
  if (Strangled || is_silent(youmonst.data) || multi < 0) {
      /* [we ought to record whether this this message has already
         been given in order to vary it upon repeat visits, but
diff -Nurd nitrohack-ais523//libnethack/src/weapon.c nitrohack-ais523-convict//libnethack/src/weapon.c
--- nitrohack-ais523//libnethack/src/weapon.c 2012-04-25 16:53:48.000000000 -0400
+++ nitrohack-ais523-convict//libnethack/src/weapon.c 2012-04-27 11:35:36.000000000 -0400
@@ -1127,7 +1127,9 @@
  if (!obj)
   /* Not using a weapon */
   return P_BARE_HANDED_COMBAT;
- if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS &&
+        if ((obj->otyp == HEAVY_IRON_BALL) && Role_if(PM_CONVICT))
+            return objects[obj->otyp].oc_skill;
+        if (obj->oclass != WEAPON_CLASS && obj->oclass != TOOL_CLASS &&
      obj->oclass != GEM_CLASS)
   /* Not a weapon, weapon-tool, or ammo */
   return P_NONE;
diff -Nurd nitrohack-ais523//README-convict.txt nitrohack-ais523-convict//README-convict.txt
--- nitrohack-ais523//README-convict.txt 1969-12-31 19:00:00.000000000 -0500
+++ nitrohack-ais523-convict//README-convict.txt 2012-04-27 09:51:30.000000000 -0400
@@ -0,0 +1,115 @@
+Convict role patch v0.7
+Karl Garrison <kgarrison@pobox.com>
+Originally for NetHack 3.4.3
+Ported to NetHack4 by Jonadab
+
+
+Non-spoiler Information
+~~~~~~~~~~~~~~~~~~~~~~~
+
+This patch adds a new role to NetHack: the Convict.  The Convict is an
+escaped prisoner who seeks to redeem himself by seeking the Amulet in
+the Dungeons of Doom.  They start out with a striped shirt, some rocks,
+and heavy iron ball chained to them.  A trusty sewer rat accompanies
+the Convict into the dungeon: a companion from his days of
+imprisonment.  Convicts have an affinity with rats, but many other
+animals do not trust him.
+
+Race: Human, Dwarf, Gnome, or Orc
+Alignment: Chaotic
+Deity: Tymora (Forgotten Realms)
+
+New configuration file option: ratname.  Example:
+
+OPTIONS=ratname:Squeak
+
+
+
+
+
+
+
+
+
+
+
+
+
+Spoiler Information
+~~~~~~~~~~~~~~~~~~~
+
+There may be a few surprises to this role for the unaware.  They start
+with a negative alignment ("You have transgressed").  This means that a
+Convict will not be able to pray successfully early on.  Some time and
+killing of monsters will make up for this before too long, though.
+They also start the game on the verge of hungry, which also makes the
+very early game challenging for Convicts.  On the bright side, it takes
+them longer to progress from hungry to weak, etc, due to their higher
+tolerance for irregular meals.
+
+Stats: Excellent CON, good STR, average DEX and INT, poor WIS and CHA.
+
+Intrinsics: Sick resistance at level 1 (due to exposure to unhealthy
+prison conditions, as well as bad food), poison resistance at level 7,
+search at level 20.
+
+Pet: The convict starts with a sewer rat, which quickly advances to a
+giant rat, and can eventually become an enormous rat, then a rodent of
+unusual size.  Convicts can tame rats with food, but not domestic
+amimals like dogs and cats.  The latter are instead made peaceful.
+
+Convicts can also usually make rats peaceful and occasionally tame by
+#chatting with them.
+
+Iron Ball: The Convict starts with a heavy iron ball chained to him, as
+if he had read a scroll of punishment.  Since he starts with no real
+weapons apart from his rocks, he may wish to wield it as a weapon.
+Convicts (and only Convicts) will practice the flail skill when he
+weilds an iron ball.  Advancing flail skill improves his chance to hit,
+and prevents him from automatically falling down the stairs if one is
+chained to him, so long as he is currently wielding it.
+
+Striped Shirt: Shopkeepers who can see the Convict wearing his striped
+shirt will recognize the player as an escaped prisoner, and will ban
+him from the shop.  Even if he later hides the shirt, that shopkeeper
+will remember the player.
+
+Guards: Guards (town watch and vault guards) who see a Convict will
+recognize him from wanted posters, and immediately become hostile.
+
+Hunger: Convicts start on the verge of hungry, but the effects of
+hunger kick in a bit more slowly for this role, due to their learned
+tolerance of inadequate nutrition.
+
+Weapon Skills:
+
+Basic: mace, short sword
+
+Skilled: dagger, dart, hammer, sling, two-weapon combat
+bare-handed combat
+
+Expert: club, flail, knife, pick-axe
+
+
+Spellcasting Skills:
+
+Basic: Matter
+
+Expert: Escape
+
+
+Luck Sword: This is a Chaotic broadsword which acts as a luckstone, and
+is the Convict's first sacrifice gift.
+
+The Quest: The Convict quest has the player return to Castle
+Waterdeep's dungeons in order to retrieve the Iron Ball of Liberation
+from the corrupted Warden Arianna on behalf of their quest leader,
+Robert the Lifer.
+
+The Iron Ball of Liberation: This is a (slightly lighter) heavy iron
+ball that grants magic resistance, stealth, searching and warning.
+When invoked, it allows phasing for a limited time (the ability to
+walk through walls/stone like a xorn).  The downsides are its weight
+(almost as heavy as a normal iron ball) and the fact that it chains
+itself to the player everytime its power is invoked.
+