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