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:
Post a Comment