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.
+

0 comments: