Guest User

NetHack Infidel role patch v1.2

a guest
Jun 23rd, 2020
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 187.22 KB | None | 0 0
  1. diff --git c/Files w/Files
  2. index d81ad0c..96f9380 100644
  3. --- c/Files
  4. +++ w/Files
  5. @@ -38,7 +38,7 @@ endgame.des   engrave.txt   epitaph.txt   gehennom.des  help
  6.  hh            history       keyhelp       knox.des      license
  7.  medusa.des    mines.des     opthelp       oracle.des    oracles.txt
  8.  quest.txt     rumors.fal    rumors.tru    sokoban.des   symbols
  9. -tower.des     tribute       wizhelp       yendor.des
  10. +tower.des     tribute       wizhelp       yendor.des    Infidel.des
  11.  
  12.  doc:
  13.  (files for all versions)
  14. diff --git c/dat/Infidel.des w/dat/Infidel.des
  15. new file mode 100644
  16. index 0000000..df7502e
  17. --- /dev/null
  18. +++ w/dat/Infidel.des
  19. @@ -0,0 +1,385 @@
  20. +#  The "start" level for the quest.
  21. +#
  22. +#  Here you meet your class leader, the preacher of Moloch,
  23. +#  and receive an invitation to a duel with the Paladin.
  24. +#
  25. +MAZE: "Inf-strt", ' '
  26. +FLAGS: noteleport, hardfloor
  27. +GEOMETRY: right, center
  28. +#          1         2         3         4         5         6
  29. +#01234567890123456789012345678901234567890123456789012345678901
  30. +MAP
  31. +0                                    |.........................
  32. +1                                    |.........................
  33. +2                  -----             --........................
  34. +3   ----         ---...-----         --........................
  35. +4   |..|        --.........|         |.........................
  36. +5   |..|        |..........|        --.........................
  37. +6   -+--      ---..........----     |..........................
  38. +7    #      ---...............|     --.........................
  39. +8    #      |.................---    |.........................
  40. +9 ---S-   ---...................|    |-........................
  41. +0 |...|   |.....................+####S.........................
  42. +1 |...+###+.....................|    |.........................
  43. +2 |...|   |....................--    |.........................
  44. +3 -----   ----.................|    --.........................
  45. +4            |.................|    |..........................
  46. +5     ---- ##S...............---   --..........................
  47. +6     |..| # ---............--     |...........................
  48. +7     |..+##   |........-----      --..........................
  49. +8     |..|     ----------           |..........................
  50. +9     |..|                          |-.........................
  51. +0     ----                          |..........................
  52. +ENDMAP
  53. +NON_DIGGABLE: (00, 00, 37, 20)
  54. +
  55. +# You arrive at a sparsely wooded cliffside.
  56. +REPLACE_TERRAIN: (35, 00, 61, 20), '.', 'T', 1%
  57. +BRANCH: (38, 00, 61, 20), (00, 00, 00, 00)
  58. +$outside = selection: filter('.', fillrect(35, 00, 61, 20))
  59. +LOOP [3d4] { MONSTER: 'd', rndcoord($outside) }
  60. +[20%]: MONSTER: "black unicorn", rndcoord($outside)
  61. +TRAP: random, rndcoord($outside)
  62. +TRAP: random, rndcoord($outside)
  63. +TRAP: random, rndcoord($outside)
  64. +
  65. +# The Hidden Temple is behind a secret door.
  66. +# The altar is coaligned, but haunted,
  67. +# presumably having been forcibly converted in the past.
  68. +TRAP: "dart", (37, 10)
  69. +DOOR: locked, (31, 10)
  70. +REGION: (20, 10, 20, 10), lit, "temple", irregular
  71. +ALTAR: (20, 10), coaligned, altar
  72. +MONSTER: "preacher of Moloch", (20, 10)
  73. +MONSTER: "cultist", (20, 07)
  74. +MONSTER: "cultist", (23, 08)
  75. +MONSTER: "cultist", (24, 10)
  76. +MONSTER: "cultist", (23, 12)
  77. +MONSTER: "cultist", (20, 13)
  78. +MONSTER: "cultist", (17, 12)
  79. +MONSTER: "cultist", (16, 10)
  80. +MONSTER: "cultist", (17, 08)
  81. +
  82. +# Some "decorations".
  83. +$around_altar = selection: ellipse((20, 10), 4, 3)
  84. +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
  85. +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
  86. +OBJECT: "corpse", montype: "elf", rndcoord($around_altar)
  87. +OBJECT: "corpse", montype: "human", rndcoord($around_altar)
  88. +OBJECT: "corpse", montype: "human", rndcoord($around_altar)
  89. +$statues = { (20, 04), (24, 05), (27, 08), (28, 13),
  90. +             (25, 15), (19, 16), (14, 14), (13, 09) }
  91. +SHUFFLE: $statues
  92. +CONTAINER: "statue", montype: "horned devil", $statues[0] {}
  93. +CONTAINER: "statue", montype: "barbed devil", $statues[1] {}
  94. +CONTAINER: "statue", montype: "marilith", $statues[2] {}
  95. +CONTAINER: "statue", montype: "vrock", $statues[3] {}
  96. +CONTAINER: "statue", montype: "hezrou", $statues[4] {}
  97. +CONTAINER: "statue", montype: "bone devil", $statues[5] {}
  98. +CONTAINER: "statue", montype: "ice devil", $statues[6] {}
  99. +CONTAINER: "statue", montype: "pit fiend", $statues[7] {}
  100. +
  101. +# Entrance to the underground complex leading to the Howling Forest.
  102. +DOOR: closed, (09, 11)
  103. +DOOR: closed, (05, 11)
  104. +REGION: (02, 10, 04, 12), lit, "ordinary"
  105. +STAIR: (03, 11), down
  106. +
  107. +# Unholy water supply.
  108. +DOOR: locked, (04, 06)
  109. +REGION: (04, 04, 05, 05), lit, "ordinary"
  110. +OBJECT: ('!', "water"), cursed, quantity: 1d2, (04, 04)
  111. +OBJECT: ('!', "water"), cursed, quantity: 1d2, (05, 04)
  112. +
  113. +# A small cache of valuables.
  114. +DOOR: locked, (08, 17)
  115. +REGION: (06, 16, 07, 19), lit, "ordinary"
  116. +OBJECT: random, (06, 16)
  117. +OBJECT: random, (06, 17)
  118. +OBJECT: "axe", (06, 18)
  119. +OBJECT: random, (06, 19)
  120. +
  121. +#
  122. +#  The "locate" level for the quest.
  123. +#
  124. +#  This is the edge of the Howling Forest.
  125. +#  Somewhere in here the Paladin awaits you.
  126. +
  127. +MAZE: "Inf-loca", ' '
  128. +FLAGS: hardfloor
  129. +INIT_MAP: mines, '.', 'T', true, true, unlit, true
  130. +GEOMETRY: (49, 00)
  131. +#         1         2
  132. +#12345678901234567890123456789
  133. +MAP
  134. +xxxx.|            ----        0
  135. +xxx..--           |..|        1
  136. +x.....---         |..|        2
  137. +...}}...|         -+--        3
  138. +...}}}..--         #          4
  139. +..}}}....|         #          5
  140. +...}}....|       --S-         6
  141. +.........--      |..|         7
  142. +..........--     |..|         8
  143. +...........|     |..+####     9
  144. +...........+#####+..|   #     0
  145. +...........|     |..|   #     1
  146. +...........|     ----   #     2
  147. +..........--            #     3
  148. +.........--             #     4
  149. +.........|              #     5
  150. +........-|            --+--   6
  151. +.........|            |...|   7
  152. +x......---            |...|   8
  153. +xxx.----              -----   9
  154. +xxxx|                         0
  155. +ENDMAP
  156. +NON_DIGGABLE: (05, 00, 29, 20)
  157. +
  158. +# Upstairs to (rest of) the underground complex.
  159. +REGION: (23, 17, 25, 18), random, "ordinary"
  160. +STAIR: (24, 18), up
  161. +MONSTER: 'k', rndcoord(fillrect(23, 17, 25, 18))
  162. +DOOR: random, (24, 16)
  163. +
  164. +# The last room before the Forest!
  165. +DOOR: random, (20, 09)
  166. +REGION: (18, 07, 19, 11), random, "ordinary"
  167. +MONSTER: 'h', rndcoord(fillrect(18, 07, 19, 11))
  168. +DOOR: random, (17, 10)
  169. +DOOR: random, (11, 10)
  170. +
  171. +# An ogre guards some treasure.
  172. +DOOR: locked, (19, 03)
  173. +REGION: (19, 01, 20, 02), random, "ordinary"
  174. +MONSTER: 'O', (19, 02)
  175. +OBJECT: "chest", (19, 01)
  176. +OBJECT: "chest", (20, 01)
  177. +
  178. +# The lake.
  179. +MONSTER: "piranha", (03, 03)
  180. +MONSTER: "piranha", (04, 04)
  181. +MONSTER: "piranha", (04, 05)
  182. +
  183. +# The forest's edge.
  184. +REPLACE_TERRAIN: (00, 00, 10, 20), '.', 'T', 5%
  185. +NOMAP
  186. +STAIR: (00, 00, 39, 20), (0, 0, 0, 0), down
  187. +$forest = selection: filter('.', fillrect(00, 00, 60, 20))
  188. +MONSTER: "werewolf", rndcoord($forest)
  189. +MONSTER: "werewolf", rndcoord($forest)
  190. +MONSTER: "werewolf", rndcoord($forest)
  191. +LOOP [4d4] { MONSTER: 'd', rndcoord($forest) }
  192. +MONSTER: 'u', rndcoord($forest)
  193. +MONSTER: 'u', rndcoord($forest)
  194. +[65%]: MONSTER: "forest centaur", rndcoord($forest)
  195. +[40%]: MONSTER: "woodchuck", rndcoord($forest)
  196. +
  197. +# Some traps and a little loot.
  198. +OBJECT: random, random
  199. +OBJECT: random, random
  200. +OBJECT: random, random
  201. +OBJECT: random, random
  202. +TRAP: random, random
  203. +TRAP: random, random
  204. +TRAP: random, random
  205. +TRAP: random, random
  206. +TRAP: random, random
  207. +TRAP: random, random
  208. +
  209. +#
  210. +#  The "goal" level for the quest.
  211. +#
  212. +#  In this part of the Howling Forest the Paladin awaits you for a duel
  213. +#  amidst some ancient ruins.  Kill her to claim the Idol of Moloch!
  214. +#
  215. +#  Note: some may find the Paladin a tough opponent.  It's intentional!
  216. +#  You come here to duel her at HER behest, on HER conditions.
  217. +#  She expects to defeat you and came prepared.  To win, you need to
  218. +#  outwit her.
  219. +#
  220. +
  221. +MAZE: "Inf-goal", ' '
  222. +FLAGS: hardfloor
  223. +INIT_MAP: mines, '.', 'T', true, true, unlit, true
  224. +GEOMETRY: half-left, center
  225. +#          1         2
  226. +#0123456789012345678901234567
  227. +MAP
  228. +0xxxxxxxxxx........xxxxxxxxxx
  229. +1xxxxxxx..............xxxxxxx
  230. +2xxxx....................xxxx
  231. +3xx........--..-...........xx
  232. +4x.........|.....|..........x
  233. +5.............--.|...........
  234. +6x........--................x
  235. +7xx........|..|...--.......xx
  236. +8xxxx.........|..........xxxx
  237. +9xxxxxxx..............xxxxxxx
  238. +0xxxxxxxxxx........xxxxxxxxxx
  239. +ENDMAP
  240. +
  241. +# The Paladin and her entourage.
  242. +MONSTER: "Paladin", (13, 06)
  243. +OBJECT: "figurine", name: "The Idol of Moloch", cursed, (13, 06)
  244. +MONSTER: "templar", (13, 03), asleep
  245. +MONSTER: "templar", (15, 04), asleep
  246. +MONSTER: "templar", (17, 06), asleep
  247. +MONSTER: "aligned priest", (16, 08), law, hostile, asleep
  248. +MONSTER: "templar", (13, 09), asleep
  249. +MONSTER: "templar", (10, 08), asleep
  250. +MONSTER: "templar", (09, 05), asleep
  251. +MONSTER: "aligned priest", (11, 04), law, hostile, asleep
  252. +
  253. +# Just pretend they're tripwires.
  254. +$around = selection: filter('.', filter(ellipse((13, 05), 9, 5),
  255. +                                        complement(ellipse((13, 05), 4, 3))))
  256. +TRAP: "board", rndcoord($around)
  257. +TRAP: "board", rndcoord($around)
  258. +TRAP: "board", rndcoord($around)
  259. +TRAP: "board", rndcoord($around)
  260. +
  261. +# There's still some treasure buried in the ruins.
  262. +$ruins = selection: circle((13, 06), 4)
  263. +OBJECT: "gold piece", quantity: 10d100, buried, rndcoord($ruins)
  264. +OBJECT: "gold piece", quantity: 10d100, buried, rndcoord($ruins)
  265. +OBJECT: '*', buried, rndcoord($ruins)
  266. +OBJECT: '*', buried, rndcoord($ruins)
  267. +OBJECT: '*', buried, rndcoord($ruins)
  268. +[60%]: OBJECT: '=', buried, rndcoord($ruins)
  269. +[50%]: OBJECT: '=', buried, rndcoord($ruins)
  270. +[40%]: OBJECT: '"', buried, rndcoord($ruins)
  271. +
  272. +# The surrounding woods.
  273. +NOMAP
  274. +STAIR: (45, 0, 79, 20), (0, 0, 0, 0), up
  275. +MONSTER: "werewolf", random
  276. +MONSTER: "werewolf", random
  277. +MONSTER: "werewolf", random
  278. +MONSTER: "werewolf", random
  279. +LOOP [5d4] { MONSTER: 'd', random }
  280. +MONSTER: 'u', random
  281. +MONSTER: 'u', random
  282. +MONSTER: 'u', random
  283. +[80%]: MONSTER: "forest centaur", random
  284. +[50%]: MONSTER: "woodchuck", random
  285. +
  286. +# And a bit of random junk.
  287. +OBJECT: random, random
  288. +OBJECT: random, random
  289. +OBJECT: random, random
  290. +TRAP: random, random
  291. +TRAP: random, random
  292. +TRAP: random, random
  293. +TRAP: random, random
  294. +TRAP: random, random
  295. +TRAP: random, random
  296. +TRAP: random, random
  297. +
  298. +#
  299. +#  The "fill" levels for the quest.
  300. +#
  301. +#  These levels are used to fill out any levels not occupied by specific
  302. +#  levels as defined above. "fila" is the upper filler, between the
  303. +#  start and locate levels, and "filb" the lower between the locate
  304. +#  and goal levels.
  305. +#
  306. +#  The upper filler is the underground complex that leads to the Forest.
  307. +#  It's a standard room-and-corridor dungeon populated with hkO.
  308. +#
  309. +
  310. +LEVEL: "Inf-fila"
  311. +FLAGS: hardfloor
  312. +
  313. +ROOM: "ordinary", random, random, random, random {
  314. +  STAIR: random, up
  315. +  OBJECT: random, random
  316. +  MONSTER: 'k', random
  317. +}
  318. +
  319. +ROOM: "ordinary", random, random, random, random {
  320. +  STAIR: random, down
  321. +  OBJECT: random, random
  322. +  TRAP: random, random
  323. +  MONSTER: 'h', random
  324. +  MONSTER: 'k', random
  325. +}
  326. +
  327. +# Quest dungeons always seem so empty, so here's a fountain.
  328. +ROOM: "ordinary", random, random, random, random {
  329. +  FOUNTAIN: random
  330. +  OBJECT: random, random
  331. +  MONSTER: 'h', random
  332. +}
  333. +
  334. +# Throne monsters roughly suit the hkO theme.
  335. +ROOM: "throne" [25%], random, random, random, random {
  336. +  OBJECT: random, random
  337. +  TRAP: random, random
  338. +}
  339. +
  340. +ROOM: "ordinary", random, random, random, random {
  341. +  OBJECT: random, random
  342. +  TRAP: random, random
  343. +  MONSTER: 'k', random
  344. +  MONSTER: 'k', random
  345. +}
  346. +
  347. +ROOM: "ordinary", random, random, random, random {
  348. +  OBJECT: random, random
  349. +  OBJECT: random, random
  350. +  TRAP: random, random
  351. +  TRAP: random, random
  352. +  MONSTER: 'O', random
  353. +  MONSTER: 'h', random
  354. +}
  355. +
  356. +ROOM: "ordinary", random, random, random, random {
  357. +  OBJECT: random, random
  358. +  OBJECT: random, random
  359. +  TRAP: random, random
  360. +  TRAP: random, random
  361. +  MONSTER: 'O', random
  362. +  MONSTER: 'k', random
  363. +}
  364. +
  365. +RANDOM_CORRIDORS
  366. +
  367. +#
  368. +#  The lower fillers are some nondescript areas of the Howling Forest.
  369. +#  There's a lot of werewolves and other d and perhaps a woodchuck.
  370. +#
  371. +
  372. +MAZE: "Inf-filb", ' '
  373. +FLAGS: hardfloor
  374. +INIT_MAP: mines, '.', 'T', true, true, unlit, true
  375. +NOMAP
  376. +
  377. +STAIR: (45, 00, 79, 20), (0, 0, 0, 0), up
  378. +STAIR: (00, 00, 34, 20), (0, 0, 0, 0), down
  379. +
  380. +MONSTER: "werewolf", random
  381. +MONSTER: "werewolf", random
  382. +MONSTER: "werewolf", random
  383. +MONSTER: "werewolf", random
  384. +MONSTER: "werewolf", random
  385. +LOOP [6d4] { MONSTER: 'd', random }
  386. +MONSTER: 'u', random
  387. +MONSTER: 'u', random
  388. +MONSTER: 'u', random
  389. +MONSTER: 'u', random
  390. +MONSTER: "forest centaur", random
  391. +[60%]: MONSTER: "woodchuck", random
  392. +
  393. +OBJECT: random, random
  394. +OBJECT: random, random
  395. +OBJECT: random, random
  396. +OBJECT: random, random
  397. +TRAP: random, random
  398. +TRAP: random, random
  399. +TRAP: random, random
  400. +TRAP: random, random
  401. +TRAP: random, random
  402. +TRAP: random, random
  403. +TRAP: random, random
  404. +TRAP: random, random
  405. diff --git c/dat/data.base w/dat/data.base
  406. index 4046259..0c1b1c2 100644
  407. --- c/dat/data.base
  408. +++ w/dat/data.base
  409. @@ -71,6 +71,16 @@ agate*
  410.     solution is slowly deposited into cavities and veins in older
  411.     rock.
  412.         [ The Columbia Encyclopedia, Sixth Edition ]
  413. +agent
  414. +agent of *
  415. +   It was part of his profession to kill people.  He had never liked
  416. +   doing it and when he had to kill he did it as well as he knew how
  417. +   and forgot about it.  As a secret agent who held the rare double-O
  418. +   prefix -- the licence to kill in the Secret Service -- it was his
  419. +   duty to be as cool about death as a surgeon.  If it happened,
  420. +   it happened.  Regret was unprofessional -- worse, it was
  421. +   death-watch beetle in the soul.
  422. +       [ Goldfinger, by Ian Fleming ]
  423.  aleax
  424.     Said to be a doppelganger sent to inflict divine punishment
  425.     for alignment violations.
  426. @@ -412,6 +422,8 @@ banshee
  427.         [ Brewer's Concise Dictionary of Phrase and Fable ]
  428.  barbarian
  429.  * barbarian
  430. +champion
  431. +champion of *
  432.     They dressed alike -- in buckskin boots, leathern breeks and
  433.     deerskin shirts, with broad girdles that held axes and short
  434.     swords; and they were all gaunt and scarred and hard-eyed;
  435. @@ -2436,6 +2448,11 @@ idefix
  436.     strong views on the environment (he howls whenever he sees an
  437.     uprooted tree).
  438.         [ Wikipedia, the free encyclopedia ]
  439. +*idol of moloch
  440. +   One of the rare few artifacts able to exert Moloch's influence
  441. +   aboveground.  By drawing on Moloch's power, the faithful are able
  442. +   to summon demons, defile shrines, and replenish their magical
  443. +   energy.  The Idol also protects its holder from hostile magics.
  444.  # takes "imp or minor demon" when specifying 'i'
  445.  imp
  446.  imp or minor demon
  447. @@ -2458,6 +2475,23 @@ succubus
  448.     same demon, one who lies with a human for its own purposes,
  449.     usually to the detriment of the mortals who are unwise in
  450.     their dealings with them.
  451. +infidel
  452. +* infidel
  453. +cultist
  454. +malefic*
  455. +   We must especially observe that this heresy, witchcraft, not only
  456. +   differs from all other heresy in this, that not merely by a tacit
  457. +   compact, but by a compact which is exactly defined and expressed
  458. +   it blasphemes the Creator and endeavours to the utmost to profane Him
  459. +   and to harm His creatures, for all other simple heresies have made
  460. +   no open compact with the devil, no compact, that is, either tacit
  461. +   or exactly expressed, although their errors and misbelief are directly
  462. +   to be attributed to the Father of errors and lies.  Moreover,
  463. +   maleficium (witchcraft) differs from all other harmful and mysterious
  464. +   arts in this point, that of all superstition it is essentially
  465. +   the vilest, the most evil and the worst, wherefore it derives its name
  466. +   from doing evil, and from blaspheming the true faith.
  467. +       [ The Malleus Maleficarum, translated by Montague Summers ]
  468.  *insect
  469.  *insects
  470.     A minute invertebrate animal; one of the class _Insecta_.
  471. @@ -3851,6 +3885,17 @@ page
  472.     of gentle parentage attending a royal or princely personage.
  473.         [ Webster's Comprehensive International Dictionary
  474.           of the English Language ]
  475. +*paladin
  476. +*paladin of *
  477. +   The paladin is a noble and heroic warrior, the symbol of all
  478. +   that is right and true in the world.  As such, he has high ideals
  479. +   that he must maintain at all times.  Throughout legend and history
  480. +   there are many heroes who could be called paladins: Roland and
  481. +   the 12 Peers of Charlemagne, Sir Lancelot, Sir Gawain, and Sir Galahad
  482. +   are all examples of the class.  However, many brave and
  483. +   heroic soldiers have tried and failed to live up to the ideals of
  484. +   the paladin.  It is not an easy task!
  485. +       [ AD&D Player's Handbook, 2nd Edition ]
  486.  *pall
  487.     _Pallium._  The Roman name for a square woollen cloak worn
  488.     by men in ancient Greece, especially by philosophers and
  489. @@ -4588,6 +4633,14 @@ scroll *
  490.     I read these words, and read again, and tried
  491.     My eyes against the heavens, and read again.
  492.         [ Endymion, by John Keats ]
  493. +secespita
  494. +   The secespita is a long iron sacrificial knife, made of brass
  495. +   and copper from Cyprus, with a solid and rounded ivory handle,
  496. +   which is secured to the hilt by a ring of silver or gold.
  497. +   The flamens and their wives, the flaminicae, who were priests
  498. +   and priestesses of the Ancient Rome, the virgins and the pontiffs
  499. +   made use of it for sacrifices.
  500. +       [ Wikipedia, the free encyclopedia ]
  501.  set
  502.  seth
  503.     The ancient Egyptian god of chaos (Set), the embodiment of
  504. @@ -4837,6 +4890,12 @@ javelin
  505.     don't I?"
  506.     "Why, yes, of course," said Wilbur.
  507.         [ Charlotte's Web, by E.B. White ]
  508. +splanchomanc*
  509. +anthropomanc*
  510. +   Anthropomancy is a method of divination by the entrails of dead
  511. +   or dying men or women, often virgin female children, through
  512. +   sacrifice.  This practice was sometimes also called splanchomancy.
  513. +       [ Wikipedia, the free encyclopedia ]
  514.  *spore
  515.  *sphere
  516.     The attack by those who want to die -- this is the attack
  517. @@ -4981,6 +5040,20 @@ susano*o
  518.         [ Encyclopedia of Gods, by Michael Jordan ]
  519.  tanko
  520.     Samurai plate armor of the Yamato period (AD 300 - 710).
  521. +templar
  522. +templar of *
  523. +   Above all things, whosoever would be a knight of Christ,
  524. +   choosing such holy orders, you in your profession of faith
  525. +   must unite pure diligence and firm perseverence, which is so worthy
  526. +   and so holy, and is known to be so noble, that if it is preserved
  527. +   untainted for ever, you will deserve to keep company with the martyrs
  528. +   who gave their souls for Jesus Christ.  In this religious order
  529. +   has flourished and is revitalised the order of knighthood. [...]
  530. +   God works well with us and our saviour Jesus Christ; He has sent
  531. +   his friends from the Holy City of Jerusalem to the marches of France
  532. +   and Burgundy, who for our salvation and the spread of the true faith
  533. +   do not cease to offer their souls to God, a welcome sacrifice.
  534. +       [ Rule of the Knights Templar, translated by J. M. Upton-Ward ]
  535.  tengu
  536.     The tengu was the most troublesome creature of Japanese
  537.     legend.  Part bird and part man, with red beak for a nose
  538. diff --git c/dat/endgame.des w/dat/endgame.des
  539. index ebd9049..2e6b738 100644
  540. --- c/dat/endgame.des
  541. +++ w/dat/endgame.des
  542. @@ -479,7 +479,7 @@ MONSTER:('E',"water elemental"),random,hostile
  543.  MAZE:"astral",' '
  544.  FLAGS: noteleport,hardfloor,nommap,shortsighted,solidify
  545.  MESSAGE: "You arrive on the Astral Plane!"
  546. -MESSAGE: "Here the High Temple of %d is located."
  547. +MESSAGE: "Here the High Temples of the heaven are located."
  548.  MESSAGE: "You sense alarm, hostility, and excitement in the air!"
  549.  GEOMETRY:center,center
  550.  MAP
  551. diff --git c/dat/gehennom.des w/dat/gehennom.des
  552. index 65fab4e..fcd2be7 100644
  553. --- c/dat/gehennom.des
  554. +++ w/dat/gehennom.des
  555. @@ -75,6 +75,7 @@ NON_DIGGABLE:(00,00,75,19)
  556.  # **LOTS** of dead bodies (all human).
  557.  # note: no priest(esse)s or monks - maybe Moloch has a *special*
  558.  #       fate reserved for members of *those* classes.
  559. +#       Obviously, no Infidel corpses as well.
  560.  #
  561.  OBJECT:('%',"corpse"),random,montype:"archeologist"
  562.  OBJECT:('%',"corpse"),random,montype:"archeologist"
  563. diff --git c/dat/quest.txt w/dat/quest.txt
  564. index 269ec76..ef77f54 100644
  565. --- c/dat/quest.txt
  566. +++ w/dat/quest.txt
  567. @@ -10,7 +10,7 @@
  568.  #  QT_FIRSTTIME     1
  569.  #  QT_NEXTTIME  2
  570.  #  QT_OTHERTIME     3
  571. -#
  572. +#       QT_ALTSTART      4      /* alternate game start message (optional) */
  573.  #  QT_GUARDTALK     5  /* 5 random things guards say before quest */
  574.  #  QT_GUARDTALK2   10  /* 5 random things guards say after quest */
  575.  #
  576. @@ -41,6 +41,11 @@
  577.  #
  578.  #  QT_GOTIT    70
  579.  #
  580. +#              /* For Infidels: Moloch's dialogue */
  581. +#  QT_MOLOCH_1 71  /* offered Amulet, no Idol */
  582. +#  QT_MOLOCH_2 72  /* offered Amulet, got Idol */
  583. +#  QT_MOLOCH_3 73  /* high priest's altar hint */
  584. +#
  585.  #  QT_KILLEDNEM    80
  586.  #  QT_OFFEREDIT    81
  587.  #  QT_OFFEREDIT2   82  /* if you throw artifact to leader after #81 */
  588. @@ -1086,6 +1091,353 @@ to the Astral, and there return the Amulet to %d.  Go forth and
  589.  may our prayers be as a wind upon your back."
  590.  %E ["You have recovered the Amulet.  Travel to the Astral Plane and return it to %d."]
  591.  #
  592. +#  Infidel
  593. +#
  594. +%Cc Inf 00001
  595. +You arrive at the mouth of a cave that hosts %H.  This is
  596. +the place where %l taught you the glory of %d,
  597. +where you studied black arts with your fellow %gp,
  598. +and where you were chosen for your unholy mission.
  599. +
  600. +You did not expect to be back so soon.
  601. +Why has %l called you?
  602. +
  603. +It is nighttime, and the moonlight is scattered by clouds.  You make sure
  604. +to stay in the shadows, for even here you are likely to be ambushed
  605. +for your precious cargo.  The surface is never safe for you now.
  606. +%E [You arrive near %H.  Talk to %l to find out why %lh called you.]
  607. +%Cp Inf 00002
  608. +Once again, you near %H.
  609. +%E
  610. +%Cp Inf 00003
  611. +Again you face %H.  %dS presence feels fainter than usual.
  612. +You wonder if you'll be allowed to return here yet again.
  613. +%E
  614. +# Note: %lh is just to randomize the pronoun,
  615. +# the unlucky hero was not actually your leader
  616. +%Cc Inf 00004
  617. +It is written in the Book of %d:
  618. +
  619. +    After the Creation, the mighty %G %d rebelled
  620. +    against the tyranny of Marduk the Creator.  %d
  621. +    defeated Marduk and obtained from him the most powerful
  622. +    of all the artifacts of the gods, the Amulet of Yendor,
  623. +    and %dH hid it in %dJ dark domain of Gehennom, the
  624. +    Under World, where %dH now gathers power and prepares for
  625. +    the final confrontation.
  626. +
  627. +Many fools were sent by the gods of the heaven after the Amulet,
  628. +only to die in the underground mazes.  By pure luck, one of them
  629. +has succeeded; thankfully, %lh was ambushed on the way back
  630. +and the Amulet was recovered by %ds Cult.
  631. +
  632. +You, a newly trained %r, have been heralded
  633. +from birth as the instrument of %d.  You are destined
  634. +to return the Amulet to its rightful owner, or die in the
  635. +attempt.  Your hour of destiny has come.  For the sake
  636. +of us all:  Go bravely with %d!
  637. +%E [%dC has chosen you to return the Amulet of Yendor to %dI.]
  638. +%Cp Inf 00005
  639. +"Agents of the false gods are everywhere!  I got my purse stolen!"
  640. +%E
  641. +%Cp Inf 00006
  642. +"I was once biten by a werewolf in %i.
  643. +It's not nearly as glamorous as the books make it sound."
  644. +%E
  645. +%Cp Inf 00007
  646. +"I just noticed a pile of skulls in that corner.  %pC... are we the baddies?"
  647. +%E
  648. +# Note: this will obviously need to be rewritten
  649. +# if the Paladin's gender changes
  650. +%Cp Inf 00008
  651. +"%nC of %D acts all high and mighty, but %nh's still just a woman."
  652. +%E
  653. +%Cp Inf 00009
  654. +"We were THIS close to recovering %o by ourselves!
  655. +The church of %D just got lucky... and a better funding."
  656. +%E
  657. +%Cp Inf 00010
  658. +"Agents of the false gods are everywhere!  I got my purse stolen!"
  659. +%E
  660. +%Cp Inf 00011
  661. +"Glory to %d, %s!  Let's drink elf blood together!"
  662. +%E
  663. +%Cp Inf 00012
  664. +"I just noticed a pile of skulls in that corner.  %pC... are we the baddies?"
  665. +%E
  666. +%Cp Inf 00013
  667. +"Have you made sure to properly desecrate %ns corpse?
  668. +Appearances are important!"
  669. +%E
  670. +%Cp Inf 00014
  671. +"%oC is ours!  Take that, professional archeology!"
  672. +%E
  673. +%Cc Inf 00015
  674. +"My %S, welcome back.  You must be wondering why I have interrupted
  675. +your mission!  As it happens, another quest has arisen that
  676. +only you can undertake.  Let me see if you're up to the challenge."
  677. +%E [I have another important mission for you, if you're ready.]
  678. +%Cp Inf 00016
  679. +"Welcome again, %p.  I hope you're ready this time."
  680. +%E
  681. +%Cp Inf 00017
  682. +"Again you return, %p.  %nC won't wait forever!  Are you ready now?"
  683. +%E
  684. +%Cc Inf 00018
  685. +"I am most disappointed, %p.  The fire of %d no longer
  686. +burns in your breast!  How could you abandon your faith so easily?
  687. +You're no longer our %s.  Begone and never return!  We will
  688. +find someone else to finish your quest."
  689. +%E [You're exiled from the Cult for your lack of faith.]
  690. +%Cc Inf 00019
  691. +"Alas, %p, you're still weak.  I cannot in good faith send you
  692. +against %n of %D now; %nh'll squash you
  693. +like an insect!  You must train and attain more skill;
  694. +come back when you're a proper %R."
  695. +%E [%rA has no chance against %n.  Come back when you are %Ra.]
  696. +%Cc Inf 00020
  697. +"No, that will not do.  The fire of %d within you is too weak.
  698. +Only with the support of our faith can you hope to prevail!
  699. +Go back to %Z and perform more sacrifices to
  700. +honor %d.  When your devotion is strong again, you may return."
  701. +%E [Your faith is too weak.  Return when you're sufficently %a.]
  702. +%Cc Inf 00021
  703. +"Yes, my %S.  You are now as ready as you'll ever be.  Listen
  704. +carefully as I explain the current situation and your new quest.
  705. +
  706. +"As you must know, we have long searched for the lost %ot,
  707. +for it is vitally important both to our faith and the ultimate plan
  708. +of our %GC %d.  But the church of %D
  709. +has learned of our efforts and sponsored a team of professional
  710. +archeologists to find %O first.  Unfortunately, it seems
  711. +they were succesful.
  712. +
  713. +"A week ago, the Cult has received a message from a prominent %nt
  714. +of %D.  %nH claims that %O is in
  715. +%nj posession, and challenges you to a `honorable duel' for the artifact.
  716. +%nC was adamant in dueling you specifically, so it's
  717. +clearly a ploy to obtain the Amulet of Yendor that was entrusted to you.
  718. +
  719. +"We have no choice but to accept, as without %O %ds plan
  720. +cannot be completed.  %nC of %D
  721. +waits for you in the ancient ruins amidst %i, which
  722. +can be reached through the underground complex below our temple.
  723. +You must travel there and retrieve %o by any means.
  724. +
  725. +"%dC be your strength, %p.  Go with %dJ blessing."
  726. +%E [%nC of %D found %o and challenged you to a duel.  Kill %ni by any means.]
  727. +%Cp Inf 00025
  728. +"As long as the fire of %d burns within your chest, you will prevail."
  729. +%E
  730. +%Cp Inf 00026
  731. +"%nC of %D is a capable spellcaster as well as a powerful warrior.
  732. +Approach %ni with care and think before acting."
  733. +%E
  734. +%Cp Inf 00027
  735. +"%nC of %Ds faith is very strong, and as such %nh knows no fear."
  736. +%E
  737. +%Cp Inf 00028
  738. +"%iC is plagued by werewolves.  If you can wield silver weapons, do so."
  739. +%E
  740. +%Cp Inf 00029
  741. +"If you know how to evoke fireballs, it will be your greatest aid.
  742. +%nC may be well-armored, but that won't protect %ni from burning alive!"
  743. +%E
  744. +%Cp Inf 00030
  745. +"%oC protects %oi holder from many harmful magics.
  746. +Unfortunately, %oi current holder is %n.
  747. +If you can somehow steal %oh, it will aid you greatly."
  748. +%E
  749. +%Cp Inf 00031
  750. +"When you obtain %o, you may call for %ds aid at any time.
  751. +Even at the surface, you will be answered."
  752. +%E
  753. +%Cp Inf 00032
  754. +"Watch where you aim your wands: %n of %D has a magical reflective shield."
  755. +%E
  756. +%Cp Inf 00033
  757. +"The church of %D wouldn't risk %O if they weren't sure %n can defeat you
  758. +in a fair fight.  So don't fight fair!"
  759. +%E
  760. +%Cp Inf 00034
  761. +"%nC of %D is immune to mundane poisons, but a paralyzing venom
  762. +will work wonders on %ni."
  763. +%E
  764. +%Cc Inf 00035
  765. +The gloom and stillness of the underground caves gives way to moonlight,
  766. +hooting of owls, and an occasional blood-chilling howl.
  767. +
  768. +%iC lies ahead.  Somewhere in these woods
  769. +%n of %D awaits you.
  770. +%E [You have reached %i.  %nC is somewhere ahead.]
  771. +%Cp Inf 00036
  772. +Again, you stand at the edge of %i.
  773. +%E
  774. +%Cc Inf 00040
  775. +You've reached a clearing in the forest.  In the distance, you can %x
  776. +the ancient ruins where %n of %D
  777. +has challenged you to the duel.
  778. +
  779. +It's still nighttime.  Hopefully you can sneak up unnoticed, but what then?
  780. +%E [You have found the dueling field.  You must proceed carefully.]
  781. +%Cp Inf 00041
  782. +Once again, you approach the ancient ruins.
  783. +%E
  784. +%Cc Inf 00050
  785. +"Ah, %p.  You've answered my challenge, after all.
  786. +It seems that your vile cult has at least some recognition of honor.
  787. +
  788. +"But no matter.  Your malignant existence is an affront to
  789. +%D, and it is by my hand that it will end today.
  790. +
  791. +"And after I defeat you and take the Amulet from your undeserving grasp,
  792. +I will destroy %o once and for all, and your cult
  793. +shall soon follow!
  794. +
  795. +"Prepare yourself, villian, for your final judgement!"
  796. +%E [I shall defeat you and then destroy %o and your cult.]
  797. +%Cp Inf 00051
  798. +"Again you return, %p.  Did you think running away could help you somehow?"
  799. +%E
  800. +%Cp Inf 00052
  801. +"Surely by now you understand that you haven't got a chance.
  802. +Accept your fate and die, coward!"
  803. +%E
  804. +%Cp Inf 00053
  805. +"Wha-- how?  Get back here, thief!  We're not done yet!"
  806. +%E
  807. +%Cp Inf 00060
  808. +"%dC is a coward who can but hide underground.  Aren't you ashamed
  809. +to be %dj slave?"
  810. +%E
  811. +%Cp Inf 00061
  812. +"You're a disgrace both as a combatant and as %ra.  Why do I even bother?"
  813. +%E
  814. +%Cp Inf 00062
  815. +"I hope you like fire, because that's how you're going to spend
  816. +the rest of eternity."
  817. +%E
  818. +%Cp Inf 00063
  819. +"Ready to give up, %p?  You know your %G can't help you here."
  820. +%E
  821. +%Cp Inf 00064
  822. +"The judgement of %D is upon you now!"
  823. +%E
  824. +%Cp Inf 00065
  825. +"When I claim the Amulet of Yendor for %D,
  826. +%d will become but a footnote in a history book."
  827. +%E
  828. +%Cp Inf 00066
  829. +"Did %l really think %ra could even reach the bottom of Gehennom?
  830. +The Amulet will be much safer with me."
  831. +%E
  832. +%Cp Inf 00067
  833. +"None of your fellow %gp will survive my wrath.  This I promise."
  834. +%E
  835. +%Cp Inf 00068
  836. +"For your sins, you will die today!"
  837. +%E
  838. +%Cp Inf 00069
  839. +"You will never have %o, and soon, you will lose your life."
  840. +%E
  841. +%Cc Inf 00070
  842. +As you pick up %o, you feel the presence of %d clearer
  843. +than ever.  The power of %d encompasses your soul, and you instantly
  844. +understand why your Cult was searching for %O, and why
  845. +%n of %D wanted to destroy %oi.
  846. +
  847. +You must return to %l at once.  With %O,
  848. +the Cult will be more powerful than ever!
  849. +%E [You feel the power of %d as you touch %O; return to %l with %oi.]
  850. +%Cc Inf 00071
  851. +Very good, My pawn.  Thou hast finally reached here.  But where is
  852. +Mine %Ot that was entrusted to thee?  Thou wast told to bring %oi here.
  853. +For thy sake, I hope thou hast not lost it!
  854. +
  855. +Return with %O and invoke My name here, and do not falter.
  856. +%E [Fetch %o and invoke %oi on My high altar.]
  857. +%Cc Inf 00072
  858. +"My pawn, thou hast done well.  Now listen carefully, for the time
  859. +for thy final test has come.
  860. +
  861. +"A deity who wields the Amulet of Yendor can claim dominion over
  862. +the gods of the heaven, the position that is Mine by right.  But I am
  863. +no longer welcome among them, so I must take My place by force.
  864. +
  865. +"%OC that thou carriest is a vessel for My power, and now I shall
  866. +make %oi the vessel for the Amulet's true power as well.  Carrying %oi
  867. +will allow thee to journey to the Astral Plane in the heaven.  There,
  868. +the false gods reside.
  869. +
  870. +"Find the weakest among them and invoke Mine %Ot in their temple.
  871. +I will take their place, and all will bow to My rule, as they should.
  872. +
  873. +"Which deity is the weakest, thou must find out thyself.  Perhaps My
  874. +servants can advise you."
  875. +%E [Travel to Astral Plane and convert one of the high altars.]
  876. +# Note: in this message, %a and %d refer
  877. +# to one of the aligned gods at random.
  878. +# Consequently, "Moloch" is typed directly,
  879. +# which may break hypothetical aligned Infidels.
  880. +%Cc Inf 00073
  881. +"My %S, we all pray for thy success on thy quest.  The false gods
  882. +posess power beyond any mere mortal, and even with Moloch's help
  883. +overthrowing one of them will be a challenge.  Chose thine opponent wisely.
  884. +
  885. +"I'll offer thee an advice.  Last night, I had a vision.  There was
  886. +a great battle in the heaven; the forces of our Lord Moloch were besieging
  887. +a fortress of %d.  But %dj %a minions held their
  888. +ground for thirty days and nights and, sadly, the fortress was not taken.
  889. +
  890. +"The meaning here is clear: when in thy mission thou reachest the heaven,
  891. +challenging %d will likely be futile.  Keep this in mind."
  892. +%E [You should avoid invoking %o on the %a high altar.]
  893. +%Cc Inf 00080
  894. +%nC falls to %ni knees.  With %ni last breath, %nh whispers:
  895. +
  896. +    "Don't... think you've won just yet.  I am but one servant of
  897. +    %D out of many, and other gods are...
  898. +    after you as well.  You will... never reach %d alive.
  899. +    The justice will..."
  900. +
  901. +A ray of bright light pierces the dawning sky, and %ns body is gone.
  902. +%E [%nC of %D dies, but others are after the Amulet.]
  903. +%Cc Inf 00081
  904. +"%pC, you are victorous!  Well done.  %dC is pleased
  905. +by your success.  All of us are proud of you as well.
  906. +
  907. +"You must now continue on your original mission.  But along with
  908. +the Amulet, you must also deliver %O to %ds Sanctum.
  909. +Such is %dJ will, and such is %dJ plan.
  910. +
  911. +"When you reach the high altar, the final phase of the plan will be
  912. +revealed to you.  Remember to keep %o on you
  913. +at all times!  If %oh's lost, all our preparations will be ruined."
  914. +%E [You must bring %O to %d along with the Amulet.]
  915. +%Cc Inf 00082
  916. +"You're %Os keeper now, but %d alone is %oj owner.
  917. +You must bring %oh to %dI along with the Amulet of Yendor.
  918. +%Z await your return through
  919. +the magic portal that brought you here."
  920. +%E [%OC is your responsibility now.  Bring it to %d along with the Amulet.]
  921. +%Cp Inf 00090
  922. +"Welcome back, my %S.  Have you found your way to Sanctum yet?"
  923. +%E
  924. +# Note: in this message, %a and %d refer
  925. +# to one of the aligned gods at random.
  926. +# Consequently, "Moloch" is typed directly,
  927. +# which may break hypothetical aligned Infidels.
  928. +%Cc Inf 00091
  929. +"Congratulations, %p!  We are closer than ever to the ultimate victory.
  930. +
  931. +"As Moloch has told you, you must now bring %O to one of the high altars
  932. +on the Astral Plane.  It's hard to say which deity will be more susceptible
  933. +to Moloch's power, but in all my years fending off non-believers,
  934. +I have noticed that %ap are unusually resistant to my clerical magic.
  935. +
  936. +"Perhaps that extends to %d %diself, as well."
  937. +%E [You should avoid invoking %o on the %a high altar.]
  938. +#
  939.  #  Knight
  940.  #
  941.  %Cc Kni 00001
  942. diff --git c/doc/Guidebook.mn w/doc/Guidebook.mn
  943. index bad63a8..2db07e8 100644
  944. --- c/doc/Guidebook.mn
  945. +++ w/doc/Guidebook.mn
  946. @@ -121,6 +121,11 @@ and neutralize poisons; and with their instruments, they can divine a
  947.  being's state of health or sickness.  Their medical practice earns them
  948.  quite reasonable amounts of money, with which they enter the dungeon.
  949.  .pg
  950. +\fIInfidels\fP are cultists of the evil god Moloch.  They are quite
  951. +proficient in black magics, but less so in the physical combat.  As an
  952. +Infidel, your goal is not to retrieve the Amulet, but to return it to its
  953. +hiding place within Gehennom.
  954. +.pg
  955.  \fIKnights\fP are distinguished from the common skirmisher by their
  956.  devotion to the ideals of chivalry and by the surpassing excellence of
  957.  their armor.
  958. diff --git c/doc/Guidebook.tex w/doc/Guidebook.tex
  959. index c34f6fa..6bc65ca 100644
  960. --- c/doc/Guidebook.tex
  961. +++ w/doc/Guidebook.tex
  962. @@ -139,6 +139,12 @@ of health or sickness.  Their medical practice earns them quite reasonable
  963.  amounts of money, with which they enter the dungeon.
  964.  %.pg
  965.  %
  966. +\item[\bb{Infidels}]%
  967. +are cultists of the evil god Moloch.  They are quite proficient in black
  968. +magics, but less so in the physical combat.  As an Infidel, your goal is not
  969. +to retrieve the Amulet, but to return it to its hiding place within Gehennom.
  970. +%.pg
  971. +%
  972.  \item[\bb{Knights}]%
  973.  are distinguished from the common skirmisher by their
  974.  devotion to the ideals of chivalry and by the surpassing excellence of
  975. diff --git c/include/artifact.h w/include/artifact.h
  976. index 4e5193f..49fddb6 100644
  977. --- c/include/artifact.h
  978. +++ w/include/artifact.h
  979. @@ -66,7 +66,8 @@ enum invoke_prop_types {
  980.      LEV_TELE,
  981.      CREATE_PORTAL,
  982.      ENLIGHTENING,
  983. -    CREATE_AMMO
  984. +    CREATE_AMMO,
  985. +    CHANNEL
  986.  };
  987.  
  988.  #endif /* ARTIFACT_H */
  989. diff --git c/include/artilist.h w/include/artilist.h
  990. index d1b1ef6..f7de910 100644
  991. --- c/include/artilist.h
  992. +++ w/include/artilist.h
  993. @@ -29,6 +29,7 @@ static const char *artifact_names[] = {
  994.  #define     FIRE(a,b)   {0,AD_FIRE,a,b}
  995.  #define     ELEC(a,b)   {0,AD_ELEC,a,b}         /* electrical shock */
  996.  #define     STUN(a,b)   {0,AD_STUN,a,b}         /* magical attack */
  997. +#define     DREN(a,b)   {0,AD_DREN,a,b}         /* drains energy */
  998.  /* clang-format on */
  999.  
  1000.  STATIC_OVL NEARDATA struct artifact artilist[] = {
  1001. @@ -163,6 +164,12 @@ STATIC_OVL NEARDATA struct artifact artilist[] = {
  1002.        PHYS(5, 0), DFNS(AD_BLND), NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 1500L,
  1003.        NO_COLOR),
  1004.  
  1005. +    /* The energy drain only works if the artifact kills its victim.
  1006. +     * Also increases sacrifice value while wielded. */
  1007. +    A("Secespita", KNIFE, (SPFX_RESTR | SPFX_ATTK), 0, 0,
  1008. +      DREN(5, 1), NO_DFNS, NO_CARY, 0, A_CHAOTIC, PM_INFIDEL, NON_PM,
  1009. +      1000L, NO_COLOR),
  1010. +
  1011.      /*
  1012.       *      The artifacts for the quest dungeon, all self-willed.
  1013.       */
  1014. @@ -197,6 +204,13 @@ A("The Palantir of Westernesse",        CRYSTAL_BALL,
  1015.        0, 0, DRLI(0, 0), DRLI(0, 0), NO_CARY, HEALING, A_NEUTRAL, PM_HEALER,
  1016.        NON_PM, 5000L, NO_COLOR),
  1017.  
  1018. +    /* Also confers energy regeneration,
  1019. +     * but only to those in good standing with Moloch. */
  1020. +    A("The Idol of Moloch", FIGURINE,
  1021. +      (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), SPFX_HSPDAM, 0,
  1022. +      NO_ATTK, NO_DFNS, CARY(AD_MAGM), CHANNEL, A_CHAOTIC, PM_INFIDEL, NON_PM,
  1023. +      4000L, NO_COLOR),
  1024. +
  1025.      A("The Magic Mirror of Merlin", MIRROR,
  1026.        (SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), SPFX_ESP, 0,
  1027.        NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM, 1500L,
  1028. diff --git c/include/context.h w/include/context.h
  1029. index c24da8d..f876f18 100644
  1030. --- c/include/context.h
  1031. +++ w/include/context.h
  1032. @@ -118,6 +118,9 @@ struct context_info {
  1033.      long next_attrib_check; /* next attribute check */
  1034.      long stethoscope_move;
  1035.      short stethoscope_movement;
  1036. +    long next_moloch_offering; /* Moloch demands regular sacrifices */
  1037. +    char inf_aligns; /* random alignment permutation number for Infidels */
  1038. +    boolean coward; /* restrict Infidel Elbereth penalty to once per move */
  1039.      boolean travel;  /* find way automatically to u.tx,u.ty */
  1040.      boolean travel1; /* first travel step */
  1041.      boolean forcefight;
  1042. diff --git c/include/extern.h w/include/extern.h
  1043. index a1b32f7..97f3d73 100644
  1044. --- c/include/extern.h
  1045. +++ w/include/extern.h
  1046. @@ -48,6 +48,7 @@ E boolean FDECL(snuff_candle, (struct obj *));
  1047.  E boolean FDECL(snuff_lit, (struct obj *));
  1048.  E boolean FDECL(catch_lit, (struct obj *));
  1049.  E void FDECL(use_unicorn_horn, (struct obj *));
  1050. +E void FDECL(use_figurine, (struct obj **));
  1051.  E boolean FDECL(tinnable, (struct obj *));
  1052.  E void NDECL(reset_trapset);
  1053.  E void FDECL(fig_transform, (ANY_P *, long));
  1054. @@ -70,6 +71,7 @@ E boolean FDECL(confers_luck, (struct obj *));
  1055.  E boolean FDECL(arti_reflects, (struct obj *));
  1056.  E boolean FDECL(shade_glare, (struct obj *));
  1057.  E boolean FDECL(restrict_name, (struct obj *, const char *));
  1058. +E boolean FDECL(attacks, (int, struct obj *));
  1059.  E boolean FDECL(defends, (int, struct obj *));
  1060.  E boolean FDECL(defends_when_carried, (int, struct obj *));
  1061.  E boolean FDECL(protects, (struct obj *, BOOLEAN_P));
  1062. @@ -485,6 +487,7 @@ E void NDECL(cancel_don);
  1063.  E int FDECL(stop_donning, (struct obj *));
  1064.  E int NDECL(Armor_off);
  1065.  E int NDECL(Armor_gone);
  1066. +E void FDECL(check_wings, (BOOLEAN_P));
  1067.  E int NDECL(Helmet_off);
  1068.  E int NDECL(Gloves_off);
  1069.  E int NDECL(Boots_on);
  1070. @@ -500,7 +503,7 @@ E void FDECL(Blindf_on, (struct obj *));
  1071.  E void FDECL(Blindf_off, (struct obj *));
  1072.  E int NDECL(dotakeoff);
  1073.  E int NDECL(doremring);
  1074. -E int FDECL(cursed, (struct obj *));
  1075. +E int FDECL(cursed, (struct obj *, BOOLEAN_P));
  1076.  E int FDECL(armoroff, (struct obj *));
  1077.  E int FDECL(canwearobj, (struct obj *, long *, BOOLEAN_P));
  1078.  E int NDECL(dowear);
  1079. @@ -1516,7 +1519,7 @@ E boolean FDECL(big_little_match, (int, int));
  1080.  E const char *FDECL(locomotion, (const struct permonst *, const char *));
  1081.  E const char *FDECL(stagger, (const struct permonst *, const char *));
  1082.  E const char *FDECL(on_fire, (struct permonst *, struct attack *));
  1083. -E const struct permonst *FDECL(raceptr, (struct monst *));
  1084. +E struct permonst *FDECL(raceptr, (struct monst *));
  1085.  E boolean FDECL(olfaction, (struct permonst *));
  1086.  
  1087.  /* ### monmove.c ### */
  1088. @@ -1996,6 +1999,8 @@ E boolean NDECL(stuck_in_wall);
  1089.  #ifdef USE_TRAMPOLI
  1090.  E int NDECL(prayer_done);
  1091.  #endif
  1092. +E void FDECL(god_zaps_you, (ALIGNTYP_P));
  1093. +E void FDECL(godvoice, (ALIGNTYP_P, const char *));
  1094.  E int NDECL(dosacrifice);
  1095.  E boolean FDECL(can_pray, (BOOLEAN_P));
  1096.  E int NDECL(dopray);
  1097. @@ -2006,6 +2011,7 @@ E const char *FDECL(a_gname_at, (XCHAR_P x, XCHAR_P y));
  1098.  E const char *FDECL(align_gname, (ALIGNTYP_P));
  1099.  E const char *FDECL(halu_gname, (ALIGNTYP_P));
  1100.  E const char *FDECL(align_gtitle, (ALIGNTYP_P));
  1101. +E aligntyp FDECL(inf_align, (int));
  1102.  E void FDECL(altar_wrath, (int, int));
  1103.  
  1104.  /* ### priest.c ### */
  1105. @@ -2163,6 +2169,7 @@ E int FDECL(rnz, (int));
  1106.  
  1107.  /* ### role.c ### */
  1108.  
  1109. +E int FDECL(special_alignment, (int, int));
  1110.  E boolean FDECL(validrole, (int));
  1111.  E boolean FDECL(validrace, (int, int));
  1112.  E boolean FDECL(validgend, (int, int, int));
  1113. diff --git c/include/mondata.h w/include/mondata.h
  1114. index 155ebfa..f793271 100644
  1115. --- c/include/mondata.h
  1116. +++ w/include/mondata.h
  1117. @@ -30,6 +30,9 @@
  1118.  #define is_lminion(mon) \
  1119.      (is_minion((mon)->data) && mon_aligntyp(mon) == A_LAWFUL)
  1120.  #define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L)
  1121. +/* flight blocked by most body armor */
  1122. +#define big_wings(ptr) ((ptr) == &mons[PM_WINGED_GARGOYLE] \
  1123. +                        || (ptr) == &mons[PM_DEMON])
  1124.  #define is_floater(ptr) ((ptr)->mlet == S_EYE || (ptr)->mlet == S_LIGHT)
  1125.  /* clinger: piercers, mimics, wumpus -- generally don't fall down holes */
  1126.  #define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L)
  1127. @@ -97,6 +100,8 @@
  1128.  #define carnivorous(ptr) (((ptr)->mflags1 & M1_CARNIVORE) != 0L)
  1129.  #define herbivorous(ptr) (((ptr)->mflags1 & M1_HERBIVORE) != 0L)
  1130.  #define metallivorous(ptr) (((ptr)->mflags1 & M1_METALLIVORE) != 0L)
  1131. +#define inediate(ptr) (((ptr)->mflags1 & (M1_CARNIVORE | M1_HERBIVORE \
  1132. +                                          | M1_METALLIVORE)) == 0L)
  1133.  #define polyok(ptr) (((ptr)->mflags2 & M2_NOPOLY) == 0L)
  1134.  #define is_shapeshifter(ptr) (((ptr)->mflags2 & M2_SHAPESHIFTER) != 0L)
  1135.  #define is_undead(ptr) (((ptr)->mflags2 & M2_UNDEAD) != 0L)
  1136. diff --git c/include/monflag.h w/include/monflag.h
  1137. index f430ced..10dd08b 100644
  1138. --- c/include/monflag.h
  1139. +++ w/include/monflag.h
  1140. @@ -174,6 +174,7 @@
  1141.  #define MH_DWARF M2_DWARF
  1142.  #define MH_GNOME M2_GNOME
  1143.  #define MH_ORC M2_ORC
  1144. +#define MH_DEMON M2_DEMON
  1145.  
  1146.  /* for mons[].geno (constant during game) */
  1147.  #define G_UNIQ 0x1000     /* generated only once */
  1148. diff --git c/include/patchlevel.h w/include/patchlevel.h
  1149. index 36bc437..77ed7bb 100644
  1150. --- c/include/patchlevel.h
  1151. +++ w/include/patchlevel.h
  1152. @@ -14,7 +14,7 @@
  1153.   * Incrementing EDITLEVEL can be used to force invalidation of old bones
  1154.   * and save files.
  1155.   */
  1156. -#define EDITLEVEL 0
  1157. +#define EDITLEVEL 1
  1158.  
  1159.  #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
  1160.  #define COPYRIGHT_BANNER_B \
  1161. diff --git c/include/qtext.h w/include/qtext.h
  1162. index 7529384..9a11583 100644
  1163. --- c/include/qtext.h
  1164. +++ w/include/qtext.h
  1165. @@ -64,7 +64,7 @@ struct qtlists {
  1166.  #define QT_FIRSTTIME 1
  1167.  #define QT_NEXTTIME 2
  1168.  #define QT_OTHERTIME 3
  1169. -
  1170. +#define QT_ALTSTART 4    /* alternate game start message (optional) */
  1171.  #define QT_GUARDTALK 5   /* 5 random things guards say before quest */
  1172.  #define QT_GUARDTALK2 10 /* 5 random things guards say after quest */
  1173.  
  1174. @@ -94,6 +94,11 @@ struct qtlists {
  1175.  
  1176.  #define QT_GOTIT 70
  1177.  
  1178. +/* For Infidels: Moloch's dialogue */
  1179. +#define QT_MOLOCH_1 71 /* offered Amulet, no Idol */
  1180. +#define QT_MOLOCH_2 72 /* offered Amulet, got Idol */
  1181. +#define QT_MOLOCH_3 73 /* high priest's altar hint */
  1182. +
  1183.  #define QT_KILLEDNEM 80
  1184.  #define QT_OFFEREDIT 81
  1185.  #define QT_OFFEREDIT2 82
  1186. diff --git c/include/you.h w/include/you.h
  1187. index ad178a2..72ec45f 100644
  1188. --- c/include/you.h
  1189. +++ w/include/you.h
  1190. @@ -48,14 +48,13 @@ struct u_event {
  1191.      Bitfield(uopened_dbridge, 1);   /* opened the drawbridge */
  1192.      Bitfield(invoked, 1);           /* invoked Gate to the Sanctum level */
  1193.      Bitfield(gehennom_entered, 1);  /* entered Gehennom via Valley */
  1194. -    Bitfield(uhand_of_elbereth, 2); /* became Hand of Elbereth */
  1195. +    Bitfield(uhand_of_elbereth, 3); /* became Hand of Elbereth */
  1196.      Bitfield(udemigod, 1);          /* killed the wiz */
  1197. -    Bitfield(uvibrated, 1);         /* stepped on "vibrating square" */
  1198.      Bitfield(ascended, 1);          /* has offered the Amulet */
  1199.  };
  1200.  
  1201.  struct u_achieve {
  1202. -    Bitfield(amulet, 1);  /* touched Amulet */
  1203. +    Bitfield(amulet, 1);  /* touched (for Infidels: offered) Amulet */
  1204.      Bitfield(bell, 1);    /* touched Bell */
  1205.      Bitfield(book, 1);    /* touched Book */
  1206.      Bitfield(menorah, 1); /* touched Candelabrum */
  1207. @@ -66,6 +65,7 @@ struct u_achieve {
  1208.      Bitfield(finish_sokoban, 1);  /* obtained the sokoban prize */
  1209.  
  1210.      Bitfield(killed_medusa, 1);
  1211. +    Bitfield(vibrating_square, 1); /* stepped on "vibrating square" */
  1212.  };
  1213.  
  1214.  struct u_realtime {
  1215. @@ -219,6 +219,7 @@ struct Race {
  1216.  };
  1217.  
  1218.  extern const struct Race races[]; /* Table of available races */
  1219. +extern struct Race race_demon;    /* used in pray.c */
  1220.  extern struct Race urace;
  1221.  #define Race_if(X) (urace.malenum == (X))
  1222.  #define Race_switch (urace.malenum)
  1223. diff --git c/include/youprop.h w/include/youprop.h
  1224. index c9656aa..c0f41a5 100644
  1225. --- c/include/youprop.h
  1226. +++ w/include/youprop.h
  1227. @@ -227,11 +227,13 @@
  1228.  #define HFlying u.uprops[FLYING].intrinsic
  1229.  #define EFlying u.uprops[FLYING].extrinsic
  1230.  /* BFlying has I_SPECIAL set if levitating or trapped in the floor or both,
  1231. -   FROMOUTSIDE set if inside solid rock (or in water on Plane of Water) */
  1232. +   FROMOUTSIDE set if inside solid rock (or in water on Plane of Water)
  1233. +   W_ARM set if in big_wings() form and wearing blocking body armor
  1234. +   (the last one obviously won't block the steed from flying) */
  1235.  #define BFlying u.uprops[FLYING].blocked
  1236. -#define Flying                                                      \
  1237. -    ((HFlying || EFlying || (u.usteed && is_flyer(u.usteed->data))) \
  1238. -     && !BFlying)
  1239. +#define Flying                                                           \
  1240. +    (((HFlying || EFlying) && !BFlying                                   \
  1241. +      || u.usteed && is_flyer(u.usteed->data)) && !(BFlying & ~W_ARMOR))
  1242.  /* May touch surface; does not override any others */
  1243.  
  1244.  #define EWwalking u.uprops[WWALKING].extrinsic
  1245. @@ -372,6 +374,6 @@
  1246.     redundant but allows the function calls to be skipped most of the time */
  1247.  #define Unaware (multi < 0 && (unconscious() || is_fainted()))
  1248.  
  1249. -#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(youmonst.data))
  1250. +#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(raceptr(&youmonst)))
  1251.  
  1252.  #endif /* YOUPROP_H */
  1253. diff --git c/src/allmain.c w/src/allmain.c
  1254. index 5111c69..8ea4087 100644
  1255. --- c/src/allmain.c
  1256. +++ w/src/allmain.c
  1257. @@ -226,7 +226,13 @@ boolean resuming;
  1258.                          && ((wtcap < MOD_ENCUMBER
  1259.                               && (!(moves % ((MAXULEV + 8 - u.ulevel)
  1260.                                              * (Role_if(PM_WIZARD) ? 3 : 4)
  1261. -                                            / 6)))) || Energy_regeneration)) {
  1262. +                                            / 6)))) || Energy_regeneration
  1263. +                    /* the Idol grants energy regen to piously unaligned;
  1264. +                     * it really shouldn't be restricted to Infidels,
  1265. +                     * but so far we have no other unaligned roles */
  1266. +                            || Role_if(PM_INFIDEL) && u.uhave.questart
  1267. +                               && u.ualign.type == A_NONE
  1268. +                               && u.ualign.record > rn2(20))) {
  1269.                          u.uen += rn1(
  1270.                              (int) (ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1, 1);
  1271.                          if (u.uen > u.uenmax)
  1272. @@ -236,6 +242,48 @@ boolean resuming;
  1273.                              interrupt_multi("You feel full of energy.");
  1274.                      }
  1275.  
  1276. +                    /* Moloch demands regular sacrifices! */
  1277. +                    if (context.next_moloch_offering <= moves) {
  1278. +                        if (context.next_moloch_offering == moves
  1279. +                            && (u.ualign.type == A_NONE
  1280. +                                || u.ualignbase[A_CURRENT] == A_NONE)) {
  1281. +                            You_feel("%s urge to perform a sacrifice.",
  1282. +                                     u.ualign.type == A_NONE ? "an"
  1283. +                                                             : "a faint");
  1284. +                            stop_occupation();
  1285. +                        }
  1286. +                        if (u.ualign.type == A_NONE && !rn2(10)
  1287. +                            && rn2(moves - context.next_moloch_offering
  1288. +                                   + 1000) >= 1000) {
  1289. +                            if (u.ualign.record > -99)
  1290. +                                adjalign(-1);
  1291. +                            if (u.ualign.record < -10 && !rn2(u.ugangr + 1)
  1292. +                                && rn2(-u.ualign.record + 90) >= 100) {
  1293. +                                char *angry = (char *) 0;
  1294. +                                u.ugangr++;
  1295. +                                /* avoid repetitive messages */
  1296. +                                switch (u.ugangr) {
  1297. +                                /* same values as in cmd.c */
  1298. +                                case 1:
  1299. +                                    angry = "";
  1300. +                                    break;
  1301. +                                case 4:
  1302. +                                    angry = "very ";
  1303. +                                    break;
  1304. +                                case 7:
  1305. +                                    angry = "extremely ";
  1306. +                                    break;
  1307. +                                }
  1308. +                                if (angry) {
  1309. +                                    You_feel("that %s is %sangry at your "
  1310. +                                             "lack of offerings.", u_gname(),
  1311. +                                             angry);
  1312. +                                    stop_occupation();
  1313. +                                }
  1314. +                            }
  1315. +                        }
  1316. +                    }
  1317. +
  1318.                      if (!u.uinvulnerable) {
  1319.                          if (Teleportation && !rn2(85)) {
  1320.                              xchar old_ux = u.ux, old_uy = u.uy;
  1321. @@ -336,6 +384,7 @@ boolean resuming;
  1322.              /* when/if hero escapes from lava, he can't just stay there */
  1323.              else if (!u.umoved)
  1324.                  (void) pooleffects(FALSE);
  1325. +            context.coward = FALSE;
  1326.  
  1327.          } /* actual time passed */
  1328.  
  1329. @@ -590,6 +639,9 @@ newgame()
  1330.      context.next_attrib_check = 600L; /* arbitrary first setting */
  1331.      context.tribute.enabled = TRUE;   /* turn on 3.6 tributes    */
  1332.      context.tribute.tributesz = sizeof(struct tribute_info);
  1333. +    context.inf_aligns = rn2(6);      /* randomness for the Infidel role */
  1334. +    context.next_moloch_offering = 6000; /* give a grace period before
  1335. +                                          * the first sacrifice */
  1336.  
  1337.      for (i = LOW_PM; i < NUMMONS; i++)
  1338.          mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;
  1339. diff --git c/src/apply.c w/src/apply.c
  1340. index e77984d..a7fd5e2 100644
  1341. --- c/src/apply.c
  1342. +++ w/src/apply.c
  1343. @@ -22,7 +22,6 @@ STATIC_DCL void FDECL(use_lamp, (struct obj *));
  1344.  STATIC_DCL void FDECL(light_cocktail, (struct obj **));
  1345.  STATIC_PTR void FDECL(display_jump_positions, (int));
  1346.  STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
  1347. -STATIC_DCL void FDECL(use_figurine, (struct obj **));
  1348.  STATIC_DCL void FDECL(use_grease, (struct obj *));
  1349.  STATIC_DCL void FDECL(use_trap, (struct obj *));
  1350.  STATIC_DCL void FDECL(use_stone, (struct obj *));
  1351. @@ -2105,6 +2104,7 @@ long timeout;
  1352.      boolean cansee_spot, silent, okay_spot;
  1353.      boolean redraw = FALSE;
  1354.      boolean suppress_see = FALSE;
  1355. +    boolean idol = figurine && figurine->oartifact == ART_IDOL_OF_MOLOCH;
  1356.      char monnambuf[BUFSZ], carriedby[BUFSZ];
  1357.  
  1358.      if (!figurine) {
  1359. @@ -2115,7 +2115,8 @@ long timeout;
  1360.      okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0);
  1361.      if (figurine->where == OBJ_INVENT || figurine->where == OBJ_MINVENT)
  1362.          okay_spot = enexto(&cc, cc.x, cc.y, &mons[figurine->corpsenm]);
  1363. -    if (!okay_spot || !figurine_location_checks(figurine, &cc, TRUE)) {
  1364. +    if (idol && figurine->age > timeout || !okay_spot
  1365. +        || !figurine_location_checks(figurine, &cc, TRUE)) {
  1366.          /* reset the timer to try again later */
  1367.          (void) start_timer((long) rnd(5000), TIMER_OBJECT, FIG_TRANSFORM,
  1368.                             obj_to_any(figurine));
  1369. @@ -2159,9 +2160,14 @@ long timeout;
  1370.  
  1371.          case OBJ_FLOOR:
  1372.              if (cansee_spot && !silent) {
  1373. -                if (suppress_see)
  1374. +                if (idol) {
  1375. +                    if (!suppress_see)
  1376. +                        You_see("a cloud of %s mist coagulate "
  1377. +                                "into the shape of %s%s!",
  1378. +                                hcolor("crimson"), monnambuf, and_vanish);
  1379. +                } else if (suppress_see) {
  1380.                      pline("%s suddenly vanishes!", an(xname(figurine)));
  1381. -                else
  1382. +                }  else
  1383.                      You_see("a figurine transform into %s%s!", monnambuf,
  1384.                              and_vanish);
  1385.                  redraw = TRUE; /* update figurine's map location */
  1386. @@ -2197,12 +2203,20 @@ long timeout;
  1387.              break;
  1388.          }
  1389.      }
  1390. -    /* free figurine now */
  1391. -    if (carried(figurine)) {
  1392. -        useup(figurine);
  1393. +    if (idol) {
  1394. +        long cooldown = rnz(100);
  1395. +        figurine->age = timeout + cooldown;
  1396. +        /* still cursed */
  1397. +        (void) start_timer((long) rnd(9000) + cooldown, TIMER_OBJECT,
  1398. +                           FIG_TRANSFORM, obj_to_any(figurine));
  1399.      } else {
  1400. -        obj_extract_self(figurine);
  1401. -        obfree(figurine, (struct obj *) 0);
  1402. +        /* free figurine now */
  1403. +        if (carried(figurine)) {
  1404. +            useup(figurine);
  1405. +        } else {
  1406. +            obj_extract_self(figurine);
  1407. +            obfree(figurine, (struct obj *) 0);
  1408. +        }
  1409.      }
  1410.      if (redraw)
  1411.          newsym(cc.x, cc.y);
  1412. @@ -2244,14 +2258,26 @@ boolean quietly;
  1413.      return TRUE;
  1414.  }
  1415.  
  1416. -STATIC_OVL void
  1417. +void
  1418.  use_figurine(optr)
  1419.  struct obj **optr;
  1420.  {
  1421.      register struct obj *obj = *optr;
  1422. +    boolean idol = obj->oartifact == ART_IDOL_OF_MOLOCH;
  1423.      xchar x, y;
  1424.      coord cc;
  1425. +    char *release_figurine;
  1426.  
  1427. +    if (idol) {
  1428. +        /* copied from artifact.c */
  1429. +        if (obj->age > monstermoves) {
  1430. +            You_feel("that %s %s ignoring you.", the(xname(obj)),
  1431. +                     otense(obj, "are"));
  1432. +            obj->age += (long) d(3, 10);
  1433. +            return;
  1434. +        }
  1435. +        obj->age = monstermoves + rnz(100);
  1436. +    }
  1437.      if (u.uswallow) {
  1438.          /* can't activate a figurine while swallowed */
  1439.          if (!figurine_location_checks(obj, (coord *) 0, FALSE))
  1440. @@ -2268,17 +2294,33 @@ struct obj **optr;
  1441.      /* Passing FALSE arg here will result in messages displayed */
  1442.      if (!figurine_location_checks(obj, &cc, FALSE))
  1443.          return;
  1444. -    You("%s and it %stransforms.",
  1445. -        (u.dx || u.dy) ? "set the figurine beside you"
  1446. -                       : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
  1447. -                          || is_pool(cc.x, cc.y))
  1448. -                             ? "release the figurine"
  1449. -                             : (u.dz < 0 ? "toss the figurine into the air"
  1450. -                                         : "set the figurine on the ground"),
  1451. -        Blind ? "supposedly " : "");
  1452. +    if (u.dx || u.dy)
  1453. +        release_figurine = "set the figurine beside you";
  1454. +    else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
  1455. +             || is_pool(cc.x, cc.y))
  1456. +        release_figurine = "release the figurine";
  1457. +    else if (u.dz < 0)
  1458. +        release_figurine = "toss the figurine into the air";
  1459. +    else
  1460. +        release_figurine = "set the figurine on the ground";
  1461. +    if (idol) {
  1462. +        if (Blind)
  1463. +            You("%s and feel an unholy aura emanate from it.",
  1464. +                release_figurine);
  1465. +        else
  1466. +            You("%s and a cloud of %s mist arises from it.",
  1467. +                release_figurine, hcolor("crimson"));
  1468. +    } else
  1469. +        You("%s and it %stransforms.", release_figurine,
  1470. +            Blind ? "supposedly " : "");
  1471.      (void) make_familiar(obj, cc.x, cc.y, FALSE);
  1472. -    (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
  1473. -    useup(obj);
  1474. +    if (idol) {
  1475. +        freeinv(obj);
  1476. +        place_object(obj, cc.x, cc.y);
  1477. +    } else {
  1478. +        (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
  1479. +        useup(obj);
  1480. +    }
  1481.      if (Blind)
  1482.          map_invisible(cc.x, cc.y);
  1483.      *optr = 0;
  1484. @@ -3595,7 +3637,7 @@ doapply()
  1485.      case BLINDFOLD:
  1486.      case LENSES:
  1487.          if (obj == ublindf) {
  1488. -            if (!cursed(obj))
  1489. +            if (!cursed(obj, FALSE))
  1490.                  Blindf_off(obj);
  1491.          } else if (!ublindf) {
  1492.              Blindf_on(obj);
  1493. diff --git c/src/artifact.c w/src/artifact.c
  1494. index 03573fe..4616e65 100644
  1495. --- c/src/artifact.c
  1496. +++ w/src/artifact.c
  1497. @@ -6,6 +6,7 @@
  1498.  #include "hack.h"
  1499.  #include "artifact.h"
  1500.  #include "artilist.h"
  1501. +#include "qtext.h"
  1502.  
  1503.  /*
  1504.   * Note:  both artilist[] and artiexist[] have a dummy element #0,
  1505. @@ -50,7 +51,7 @@ static boolean artiexist[1 + NROFARTIFACTS + 1];
  1506.  STATIC_OVL xchar artidisco[NROFARTIFACTS];
  1507.  
  1508.  STATIC_DCL void NDECL(hack_artifacts);
  1509. -STATIC_DCL boolean FDECL(attacks, (int, struct obj *));
  1510. +STATIC_DCL void FDECL(fix_artifact, (struct obj *));
  1511.  
  1512.  /* handle some special cases; must be called after u_init() */
  1513.  STATIC_OVL void
  1514. @@ -102,6 +103,19 @@ int fd;
  1515.      hack_artifacts(); /* redo non-saved special cases */
  1516.  }
  1517.  
  1518. +/* Some artifacts may need additional tweaking when created.
  1519. + * Called when the artifact is christened.
  1520. + */
  1521. +STATIC_DCL void
  1522. +fix_artifact(otmp)
  1523. +struct obj *otmp;
  1524. +{
  1525. +    if (otmp->oartifact == ART_IDOL_OF_MOLOCH) {
  1526. +        set_corpsenm(otmp, PM_HORNED_DEVIL);
  1527. +        otmp->spe = 0;
  1528. +    }
  1529. +}
  1530. +
  1531.  const char *
  1532.  artiname(artinum)
  1533.  int artinum;
  1534. @@ -129,8 +143,8 @@ aligntyp alignment; /* target alignment, or A_NONE */
  1535.  {
  1536.      const struct artifact *a;
  1537.      int m, n, altn;
  1538. -    boolean by_align = (alignment != A_NONE);
  1539. -    short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
  1540. +    boolean by_align = alignment != A_NONE || !otmp;
  1541. +    short o_typ = by_align ? 0 : otmp->otyp;
  1542.      boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
  1543.      short eligible[NROFARTIFACTS];
  1544.  
  1545. @@ -199,6 +213,7 @@ aligntyp alignment; /* target alignment, or A_NONE */
  1546.              otmp = oname(otmp, a->name);
  1547.              otmp->oartifact = m;
  1548.              artiexist[m] = TRUE;
  1549. +            fix_artifact(otmp);
  1550.          }
  1551.      } else {
  1552.          /* nothing appropriate could be found; return original object */
  1553. @@ -271,6 +286,8 @@ boolean mod;
  1554.                  if (otmp->otyp == RIN_INCREASE_DAMAGE)
  1555.                      otmp->spe = 0;
  1556.                  artiexist[m] = mod;
  1557. +                if (mod)
  1558. +                    fix_artifact(otmp);
  1559.                  break;
  1560.              }
  1561.      return;
  1562. @@ -404,7 +421,7 @@ const char *name;
  1563.      return FALSE;
  1564.  }
  1565.  
  1566. -STATIC_OVL boolean
  1567. +boolean
  1568.  attacks(adtyp, otmp)
  1569.  int adtyp;
  1570.  struct obj *otmp;
  1571. @@ -799,6 +816,8 @@ struct monst *mtmp;
  1572.              return !(yours ? Poison_resistance : resists_poison(mtmp));
  1573.          case AD_DRLI:
  1574.              return !(yours ? Drain_resistance : resists_drli(mtmp));
  1575. +        case AD_DREN:
  1576. +            return !nonliving(ptr);
  1577.          case AD_STON:
  1578.              return !(yours ? Stone_resistance : resists_ston(mtmp));
  1579.          default:
  1580. @@ -1602,6 +1621,89 @@ struct obj *obj;
  1581.              nhUse(otmp);
  1582.              break;
  1583.          }
  1584. +        case CHANNEL:
  1585. +            /* Should this break atheist conduct?  Currently it doesn't,
  1586. +             * under the excuse of being necessary to ascend.
  1587. +             * But still, we're channeling a god's power here... */
  1588. +            if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
  1589. +                aligntyp altar_align = Amask2align(levl[u.ux][u.uy].altarmask
  1590. +                                                   & AM_MASK);
  1591. +                boolean high_altar = (Is_astralevel(&u.uz)
  1592. +                                      || Is_sanctum(&u.uz))
  1593. +                                     && (levl[u.ux][u.uy].altarmask
  1594. +                                         & AM_SHRINE);
  1595. +                if (!Blind)
  1596. +                    pline("Tendrils of %s mist seep out of %s "
  1597. +                          "and into the altar below...",
  1598. +                          hcolor("crimson"), the(xname(obj)));
  1599. +                else
  1600. +                    You_feel("something flow from %s.", the(xname(obj)));
  1601. +                if (altar_align == A_NONE) {
  1602. +                    if (high_altar && Role_if(PM_INFIDEL)
  1603. +                        && u.uachieve.amulet && !obj->spe) {
  1604. +                        godvoice(A_NONE, (char *) 0);
  1605. +                        qt_pager(QT_MOLOCH_2);
  1606. +                        You_feel("strange energies envelop %s.",
  1607. +                                 the(xname(obj)));
  1608. +                        obj->spe = 1;
  1609. +                        u.uhave.amulet = 1;
  1610. +                        break;
  1611. +                    }
  1612. +                    if (!Blind)
  1613. +                        pline_The("altar glows for a moment.");
  1614. +                    /* nothing happens */
  1615. +                    break;
  1616. +                }
  1617. +                if (high_altar) {
  1618. +                    /* messages yoinked from pray.c */
  1619. +                    You("sense a conflict between %s and %s.",
  1620. +                        align_gname(A_NONE), a_gname());
  1621. +                    if (obj->spe && altar_align == inf_align(1)) {
  1622. +                        You_feel("the power of %s increase.",
  1623. +                                 align_gname(A_NONE));
  1624. +                    } else {
  1625. +                        pline("%s feel the power of %s decrease.",
  1626. +                              u.ualign.type == A_NONE ? "Unluckily, you"
  1627. +                                                      : "You",
  1628. +                              align_gname(A_NONE));
  1629. +                        godvoice(altar_align, "So, mortal!  You dare "
  1630. +                                              "desecrate my High Temple!");
  1631. +                        god_zaps_you(altar_align);
  1632. +                        break;
  1633. +                    }
  1634. +                }
  1635. +                levl[u.ux][u.uy].altarmask &= AM_SHRINE;
  1636. +                levl[u.ux][u.uy].altarmask |= AM_NONE;
  1637. +                if (!Blind)
  1638. +                    pline_The("altar glows %s.", hcolor(NH_RED));
  1639. +                if (!high_altar) {
  1640. +                    /* the Idol does all the work for you,
  1641. +                     * so you don't get a luck increase;
  1642. +                     * but you don't get a hostile minion, either */
  1643. +                    struct monst *pri = findpriest(temple_occupied(u.urooms));
  1644. +                    if (pri && mon_aligntyp(pri) != A_NONE)
  1645. +                        angry_priest();
  1646. +                } else {
  1647. +                    /* At this point, the player must be an Infidel.
  1648. +                     * Should we still check for opposite alignment?
  1649. +                     * Currently, Moloch doesn't care. */
  1650. +                    adjalign(10);
  1651. +                    u.uachieve.ascended = 1;
  1652. +                    pline1("A sinister laughter echoes through the temple, "
  1653. +                           "and you're bathed in darkness...");
  1654. +                    godvoice(A_NONE, "My pawn, thou hast done well!");
  1655. +                    display_nhwindow(WIN_MESSAGE, FALSE);
  1656. +                    verbalize("In return for thy service, "
  1657. +                              "I grant thee a part of My domain!");
  1658. +                    You("ascend to the status of Demon %s...",
  1659. +                        flags.female ? "Lady" : "Lord");
  1660. +                    done(ASCENDED);
  1661. +                }
  1662. +            } else {
  1663. +                obj->age = 0; /* will be set below */
  1664. +                use_figurine(&obj);
  1665. +            }
  1666. +            break;
  1667.          }
  1668.      } else {
  1669.          long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
  1670. diff --git c/src/attrib.c w/src/attrib.c
  1671. index 028eebf..94ba766 100644
  1672. --- c/src/attrib.c
  1673. +++ w/src/attrib.c
  1674. @@ -41,6 +41,11 @@ static const struct innate {
  1675.                   { 15, &(HWarning), "sensitive", "" },
  1676.                   { 0, 0, 0, 0 } },
  1677.  
  1678. +  inf_abil[] = { { 1, &(HFire_resistance), "", "" },
  1679. +                 { 15, &(HWarning), "sensitive", "" },
  1680. +                 { 20, &(HShock_resistance), "inured", "softened" },
  1681. +                 { 0, 0, 0, 0 } },
  1682. +
  1683.    kni_abil[] = { { 7, &(HFast), "quick", "slow" }, { 0, 0, 0, 0 } },
  1684.  
  1685.    mon_abil[] = { { 1, &(HFast), "", "" },
  1686. @@ -101,6 +106,15 @@ static const struct innate {
  1687.                   { 1, &HPoison_resistance, "", "" },
  1688.                   { 0, 0, 0, 0 } },
  1689.  
  1690. +  dem_abil[] = { { 1, &HInfravision, "", "" },
  1691. +                 { 1, &HFire_resistance, "", "" },
  1692. +                 { 1, &HPoison_resistance, "", "" },
  1693. +                 { 1, &HDrain_resistance, "", "" },
  1694. +                 { 1, &HSee_invisible, "", "" },
  1695. +                 { 1, &HFlying, "", "" },
  1696. +                 /* also inediate */
  1697. +                 { 0, 0, 0, 0 } },
  1698. +
  1699.    hum_abil[] = { { 0, 0, 0, 0 } };
  1700.  
  1701.  STATIC_DCL void NDECL(exerper);
  1702. @@ -706,6 +720,7 @@ int r;
  1703.          { PM_BARBARIAN, bar_abil },
  1704.          { PM_CAVEMAN, cav_abil },
  1705.          { PM_HEALER, hea_abil },
  1706. +        { PM_INFIDEL, inf_abil },
  1707.          { PM_KNIGHT, kni_abil },
  1708.          { PM_MONK, mon_abil },
  1709.          { PM_PRIEST, pri_abil },
  1710. @@ -747,6 +762,9 @@ long frommask;
  1711.          case PM_ORC:
  1712.              abil = orc_abil;
  1713.              break;
  1714. +        case PM_DEMON:
  1715. +            abil = dem_abil;
  1716. +            break;
  1717.          case PM_HUMAN:
  1718.              abil = hum_abil;
  1719.              break;
  1720. @@ -800,6 +818,8 @@ int propidx;
  1721.          return FROM_LYCN;
  1722.      if (propidx == FAST && Very_fast)
  1723.          return FROM_NONE; /* can't become very fast innately */
  1724. +    if (propidx == FLYING && (BFlying & W_ARMOR))
  1725. +        return FROM_NONE; /* not from form, as that is blocked */
  1726.      if ((innateness = innately(&u.uprops[propidx].intrinsic)) != FROM_NONE)
  1727.          return innateness;
  1728.      if (propidx == JUMPING && Role_if(PM_KNIGHT)
  1729. diff --git c/src/botl.c w/src/botl.c
  1730. index 4c7dbf3..f841d63 100644
  1731. --- c/src/botl.c
  1732. +++ w/src/botl.c
  1733. @@ -84,9 +84,10 @@ do_statusline1()
  1734.              ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS),
  1735.              ACURR(A_CHA));
  1736.      Sprintf(nb = eos(nb),
  1737. -            (u.ualign.type == A_CHAOTIC)
  1738. -                ? "  Chaotic"
  1739. -                : (u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
  1740. +            (u.ualign.type == A_NONE) ? "  Unaligned"
  1741. +                : (u.ualign.type == A_CHAOTIC) ? "  Chaotic"
  1742. +                    : (u.ualign.type == A_NEUTRAL) ? "  Neutral"
  1743. +                        : "  Lawful");
  1744.  #ifdef SCORE_ON_BOTL
  1745.      if (flags.showscore)
  1746.          Sprintf(nb = eos(nb), " S:%ld", botl_score());
  1747. @@ -623,11 +624,13 @@ bot_via_windowport()
  1748.      blstats[idx][BL_CH].a.a_int = ACURR(A_CHA);
  1749.  
  1750.      /* Alignment */
  1751. -    Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_CHAOTIC)
  1752. -                                          ? "Chaotic"
  1753. -                                          : (u.ualign.type == A_NEUTRAL)
  1754. -                                               ? "Neutral"
  1755. -                                               : "Lawful");
  1756. +    Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_NONE)
  1757. +                                           ? "Unaligned"
  1758. +                                           : (u.ualign.type == A_CHAOTIC)
  1759. +                                               ? "Chaotic"
  1760. +                                               : (u.ualign.type == A_NEUTRAL)
  1761. +                                                   ? "Neutral"
  1762. +                                                   : "Lawful");
  1763.  
  1764.      /* Score */
  1765.      blstats[idx][BL_SCORE].a.a_long =
  1766. diff --git c/src/cmd.c w/src/cmd.c
  1767. index 6b28524..3214d2a 100644
  1768. --- c/src/cmd.c
  1769. +++ w/src/cmd.c
  1770. @@ -1833,7 +1833,7 @@ int unused_mode UNUSED;
  1771.  int final;
  1772.  {
  1773.      const char *role_titl, *rank_titl;
  1774. -    int innategend, difgend, difalgn;
  1775. +    int innategend, difgend, difalgn, difrace;
  1776.      char buf[BUFSZ], tmpbuf[BUFSZ];
  1777.  
  1778.      /* note that if poly'd, we need to use u.mfemale instead of flags.female
  1779. @@ -1911,12 +1911,14 @@ int final;
  1780.         trailing "and" on all three aligned entries but looks too verbose] */
  1781.      Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
  1782.      if (u.ualign.type != A_LAWFUL)
  1783. -        Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
  1784. -                align_str(A_LAWFUL));
  1785. +        Sprintf(eos(buf), " %s (%s)%s", align_gname(A_LAWFUL),
  1786. +                align_str(A_LAWFUL),
  1787. +                (u.ualign.type != A_NONE) ? " and" : ",");
  1788.      if (u.ualign.type != A_NEUTRAL)
  1789.          Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
  1790.                  align_str(A_NEUTRAL),
  1791. -                (u.ualign.type != A_CHAOTIC) ? " and" : "");
  1792. +                (u.ualign.type == A_NONE) ? ", and" /* oxford comma */
  1793. +                : (u.ualign.type != A_CHAOTIC) ? " and" : "");
  1794.      if (u.ualign.type != A_CHAOTIC)
  1795.          Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
  1796.                  align_str(A_CHAOTIC));
  1797. @@ -1931,12 +1933,26 @@ int final;
  1798.      difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
  1799.                 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
  1800.                    ? 2 : 0));
  1801. +    difrace = urace.malenum != races[flags.initrace].malenum;
  1802.      if (difalgn & 1) { /* have temporary alignment so report permanent one */
  1803.          Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
  1804.          you_are(buf, "");
  1805.          difalgn &= ~1; /* suppress helm from "started out <foo>" message */
  1806.      }
  1807. -    if (difgend || difalgn) { /* sex change or perm align change or both */
  1808. +    if (difrace) { /* permanent race change (Inf crowning) */
  1809. +        buf[0] = '\0';
  1810. +        if (difalgn) {
  1811. +            Strcat(buf, align_str(u.ualignbase[A_ORIGINAL]));
  1812. +            Strcat(buf, " ");
  1813. +        }
  1814. +        if (difgend) {
  1815. +            Strcat(buf, genders[flags.initgend].adj);
  1816. +            Strcat(buf, " ");
  1817. +        }
  1818. +        Strcat(buf, races[flags.initrace].noun);
  1819. +        Sprintf(buf, " You started out as %s.", an(buf));
  1820. +        enlght_out(buf);
  1821. +    } else if (difgend || difalgn) { /* sex change or perm align change */
  1822.          Sprintf(buf, " You started out %s%s%s.",
  1823.                  difgend ? genders[flags.initgend].adj : "",
  1824.                  (difgend && difalgn) ? " and " : "",
  1825. @@ -2494,6 +2510,25 @@ int final;
  1826.              enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
  1827.          }
  1828.      }
  1829. +    /* In case the player missed the "urge to perform a sacrifice",
  1830. +     * put a reminder here. */
  1831. +    if (u.ualign.type == A_NONE) {
  1832. +        long due = moves - context.next_moloch_offering;
  1833. +        if (due < 0) {
  1834. +            if (wizard) {
  1835. +                Sprintf(buf, "%ld turns until your next "
  1836. +                        "mandatory sacrifice to ", -due);
  1837. +                you_have(buf, u_gname());
  1838. +            }
  1839. +        } else {
  1840. +            if (wizard && due > 0)
  1841. +                Sprintf(buf, "%ld turns late for your "
  1842. +                        "next sacrifice to ", due);
  1843. +            else
  1844. +                Strcpy(buf, "due for a sacrifice to ");
  1845. +            you_are(buf, u_gname());
  1846. +        }
  1847. +    }
  1848.      /* hunger/nutrition */
  1849.      if (Hunger) {
  1850.          if (magic || cause_known(HUNGER))
  1851. @@ -2624,9 +2659,10 @@ int final;
  1852.      enlght_out(final ? "Final Attributes:" : "Current Attributes:");
  1853.  
  1854.      if (u.uevent.uhand_of_elbereth) {
  1855. -        static const char *const hofe_titles[3] = { "the Hand of Elbereth",
  1856. +        static const char *const hofe_titles[4] = { "the Hand of Elbereth",
  1857.                                                      "the Envoy of Balance",
  1858. -                                                    "the Glory of Arioch" };
  1859. +                                                    "the Glory of Arioch",
  1860. +                                                    "a demon of Moloch" };
  1861.          you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
  1862.      }
  1863.  
  1864. @@ -2795,7 +2831,7 @@ int final;
  1865.          BLevitation = save_BLev;
  1866.      }
  1867.      /* actively flying handled earlier as a status condition */
  1868. -    if (BFlying) { /* flight is blocked */
  1869. +    if (BFlying && !Flying) { /* flight is blocked */
  1870.          long save_BFly = BFlying;
  1871.  
  1872.          BFlying = 0L;
  1873. @@ -2817,7 +2853,9 @@ int final;
  1874.                               ? if_surroundings_permitted
  1875.                               /* two or more of levitation, surroundings,
  1876.                                  and being trapped in the floor */
  1877. -                             : " if circumstances permitted",
  1878. +                             : (save_BFly == W_ARM)
  1879. +                                ? " if your wings weren't confined"
  1880. +                                : " if circumstances permitted",
  1881.                      "");
  1882.          }
  1883.          BFlying = save_BFly;
  1884. diff --git c/src/do.c w/src/do.c
  1885. index 8bbed39..bb3e53b 100644
  1886. --- c/src/do.c
  1887. +++ w/src/do.c
  1888. @@ -1295,10 +1295,12 @@ boolean at_stairs, falling, portal;
  1889.       *   -1   11.46  12.50  12.5
  1890.       *   -2    5.21   4.17   0.0
  1891.       *   -3    2.08   0.0    0.0
  1892. +     *
  1893. +     *   Infidels (unaligned) are spared from the mysterious force.
  1894.       */
  1895.      if (Inhell && up && u.uhave.amulet && !newdungeon && !portal
  1896.          && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
  1897. -        if (!rn2(4)) {
  1898. +        if (u.ualign.type != A_NONE && !rn2(4)) {
  1899.              int odds = 3 + (int) u.ualign.type,   /* 2..4 */
  1900.                  diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
  1901.  
  1902. @@ -1707,7 +1709,8 @@ final_level()
  1903.      create_mplayers(rn1(4, 3), TRUE);
  1904.  
  1905.      /* create a guardian angel next to player, if worthy */
  1906. -    gain_guardian_angel();
  1907. +    if (u.ualign.type != A_NONE)
  1908. +        gain_guardian_angel();
  1909.  }
  1910.  
  1911.  static char *dfr_pre_msg = 0,  /* pline() before level change */
  1912. diff --git c/src/do_wear.c w/src/do_wear.c
  1913. index b48c69d..d220c94 100644
  1914. --- c/src/do_wear.c
  1915. +++ w/src/do_wear.c
  1916. @@ -414,7 +414,7 @@ Helmet_on(VOID_ARGS)
  1917.             by hero falling onto a polymorph trap or into water (emergency
  1918.             disrobe) or maybe lava (probably not, helm isn't 'organic') */
  1919.          uchangealign((u.ualign.type != A_NEUTRAL)
  1920. -                         ? -u.ualign.type
  1921. +                         ? -sgn(u.ualign.type)
  1922.                           : (uarmh->o_id % 2) ? A_CHAOTIC : A_LAWFUL,
  1923.                       1);
  1924.          /* makeknown(HELM_OF_OPPOSITE_ALIGNMENT); -- below, after Tobjnam() */
  1925. @@ -696,6 +696,7 @@ Armor_on(VOID_ARGS)
  1926.       */
  1927.      if (uarm) /* no known instances of !uarm here but play it safe */
  1928.          uarm->known = 1; /* suit's +/- evident because of status line AC */
  1929. +    check_wings(FALSE);
  1930.      return 0;
  1931.  }
  1932.  
  1933. @@ -705,6 +706,7 @@ Armor_off(VOID_ARGS)
  1934.      context.takeoff.mask &= ~W_ARM;
  1935.      setworn((struct obj *) 0, W_ARM);
  1936.      context.takeoff.cancelled_don = FALSE;
  1937. +    check_wings(FALSE);
  1938.      return 0;
  1939.  }
  1940.  
  1941. @@ -720,9 +722,44 @@ Armor_gone()
  1942.      context.takeoff.mask &= ~W_ARM;
  1943.      setnotworn(uarm);
  1944.      context.takeoff.cancelled_don = FALSE;
  1945. +    check_wings(FALSE);
  1946.      return 0;
  1947.  }
  1948.  
  1949. +/* Some monster forms' flight is blocked by most body armor. */
  1950. +void
  1951. +check_wings(silent)
  1952. +boolean silent; /* we assume a wardrobe change if false */
  1953. +{
  1954. +    static struct obj *last_worn_armor;
  1955. +    boolean old_flying = Flying;
  1956. +
  1957. +    BFlying &= ~W_ARM;
  1958. +    if (!big_wings(raceptr(&youmonst)))
  1959. +        return;
  1960. +
  1961. +    if (!uarm) {
  1962. +        if (!silent && Flying && !old_flying)
  1963. +            You("spread your wings and take flight.");
  1964. +    } else if (Is_dragon_scales(uarm)) {
  1965. +        if (!silent && uarm != last_worn_armor)
  1966. +            You("arrange the scales around your wings.");
  1967. +    } else if (uarm->otyp == LEATHER_JACKET) {
  1968. +        if (!silent && uarm != last_worn_armor)
  1969. +            pline1("This jacket seems to have holes for wings.");
  1970. +    } else {
  1971. +        BFlying |= W_ARM;
  1972. +        if (!silent)
  1973. +            You("fold your wings under your suit.");
  1974. +    }
  1975. +
  1976. +    if (uarm)
  1977. +        last_worn_armor = uarm;
  1978. +
  1979. +    if (Flying != old_flying)
  1980. +        context.botl = TRUE;
  1981. +}
  1982. +
  1983.  STATIC_OVL void
  1984.  Amulet_on()
  1985.  {
  1986. @@ -1546,31 +1583,35 @@ doremring()
  1987.  
  1988.  /* Check if something worn is cursed _and_ unremovable. */
  1989.  int
  1990. -cursed(otmp)
  1991. +cursed(otmp, silent)
  1992.  struct obj *otmp;
  1993. +boolean silent;
  1994.  {
  1995.      if (!otmp) {
  1996.          impossible("cursed without otmp");
  1997.          return 0;
  1998.      }
  1999. -    /* Curses, like chickens, come home to roost. */
  2000. -    if ((otmp == uwep) ? welded(otmp) : (int) otmp->cursed) {
  2001. -        boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
  2002. -                              || otmp->otyp == LENSES || otmp->quan > 1L);
  2003. -
  2004. -        /* might be trying again after applying grease to hands */
  2005. -        if (Glib && otmp->bknown
  2006. -            /* for weapon, we'll only get here via 'A )' */
  2007. -            && (uarmg ? (otmp == uwep)
  2008. -                      : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
  2009. -            pline("Despite your slippery %s, you can't.",
  2010. -                  fingers_or_gloves(TRUE));
  2011. -        else
  2012. -            You("can't.  %s cursed.", use_plural ? "They are" : "It is");
  2013. -        set_bknown(otmp, 1);
  2014. +    /* Inf are immune to curses. */
  2015. +    if (Role_if(PM_INFIDEL) || !otmp->cursed || otmp == uwep && !welded(otmp))
  2016. +        return 0;
  2017. +    if (silent)
  2018.          return 1;
  2019. -    }
  2020. -    return 0;
  2021. +
  2022. +    /* Curses, like chickens, come home to roost. */
  2023. +    boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
  2024. +                          || otmp->otyp == LENSES || otmp->quan > 1L);
  2025. +
  2026. +    /* might be trying again after applying grease to hands */
  2027. +    if (Glib && otmp->bknown
  2028. +        /* for weapon, we'll only get here via 'A )' */
  2029. +        && (uarmg ? (otmp == uwep)
  2030. +            : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
  2031. +        pline("Despite your slippery %s, you can't.",
  2032. +              fingers_or_gloves(TRUE));
  2033. +    else
  2034. +        You("can't.  %s cursed.", use_plural ? "They are" : "It is");
  2035. +    set_bknown(otmp, 1);
  2036. +    return 1;
  2037.  }
  2038.  
  2039.  int
  2040. @@ -1581,7 +1622,7 @@ struct obj *otmp;
  2041.      int delay = -objects[otmp->otyp].oc_delay;
  2042.      const char *what = 0;
  2043.  
  2044. -    if (cursed(otmp))
  2045. +    if (cursed(otmp, FALSE))
  2046.          return 0;
  2047.      /* this used to make assumptions about which types of armor had
  2048.         delays and which didn't; now both are handled for all types */
  2049. @@ -2280,13 +2321,13 @@ int otyp;
  2050.          /* reasons ring can't be removed match those checked by select_off();
  2051.             limbless case has extra checks because ordinarily it's temporary */
  2052.          if (nolimbs(youmonst.data) && uamul
  2053. -            && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed)
  2054. +            && uamul->otyp == AMULET_OF_UNCHANGING && cursed(uamul, TRUE))
  2055.              return uamul;
  2056.          if (welded(uwep) && (ring == uright || bimanual(uwep)))
  2057.              return uwep;
  2058. -        if (uarmg && uarmg->cursed)
  2059. +        if (uarmg && cursed(uarmg, TRUE))
  2060.              return uarmg;
  2061. -        if (ring->cursed)
  2062. +        if (cursed(ring, TRUE))
  2063.              return ring;
  2064.          /* normally outermost layer is processed first, but slippery gloves
  2065.             wears off quickly so uncurse ring itself before handling those */
  2066. @@ -2395,7 +2436,7 @@ register struct obj *otmp;
  2067.          ; /* some items can be removed even when cursed */
  2068.      } else {
  2069.          /* otherwise, this is fundamental */
  2070. -        if (cursed(otmp))
  2071. +        if (cursed(otmp, FALSE))
  2072.              return 0;
  2073.      }
  2074.  
  2075. @@ -2442,7 +2483,7 @@ do_takeoff()
  2076.  
  2077.      context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */
  2078.      if (doff->what == W_WEP) {
  2079. -        if (!cursed(uwep)) {
  2080. +        if (!cursed(uwep, FALSE)) {
  2081.              setuwep((struct obj *) 0);
  2082.              You("are empty %s.", body_part(HANDED));
  2083.              u.twoweap = FALSE;
  2084. @@ -2456,46 +2497,46 @@ do_takeoff()
  2085.          You("no longer have ammunition readied.");
  2086.      } else if (doff->what == WORN_ARMOR) {
  2087.          otmp = uarm;
  2088. -        if (!cursed(otmp))
  2089. +        if (!cursed(otmp, FALSE))
  2090.              (void) Armor_off();
  2091.      } else if (doff->what == WORN_CLOAK) {
  2092.          otmp = uarmc;
  2093. -        if (!cursed(otmp))
  2094. +        if (!cursed(otmp, FALSE))
  2095.              (void) Cloak_off();
  2096.      } else if (doff->what == WORN_BOOTS) {
  2097.          otmp = uarmf;
  2098. -        if (!cursed(otmp))
  2099. +        if (!cursed(otmp, FALSE))
  2100.              (void) Boots_off();
  2101.      } else if (doff->what == WORN_GLOVES) {
  2102.          otmp = uarmg;
  2103. -        if (!cursed(otmp))
  2104. +        if (!cursed(otmp, FALSE))
  2105.              (void) Gloves_off();
  2106.      } else if (doff->what == WORN_HELMET) {
  2107.          otmp = uarmh;
  2108. -        if (!cursed(otmp))
  2109. +        if (!cursed(otmp, FALSE))
  2110.              (void) Helmet_off();
  2111.      } else if (doff->what == WORN_SHIELD) {
  2112.          otmp = uarms;
  2113. -        if (!cursed(otmp))
  2114. +        if (!cursed(otmp, FALSE))
  2115.              (void) Shield_off();
  2116.      } else if (doff->what == WORN_SHIRT) {
  2117.          otmp = uarmu;
  2118. -        if (!cursed(otmp))
  2119. +        if (!cursed(otmp, FALSE))
  2120.              (void) Shirt_off();
  2121.      } else if (doff->what == WORN_AMUL) {
  2122.          otmp = uamul;
  2123. -        if (!cursed(otmp))
  2124. +        if (!cursed(otmp, FALSE))
  2125.              Amulet_off();
  2126.      } else if (doff->what == LEFT_RING) {
  2127.          otmp = uleft;
  2128. -        if (!cursed(otmp))
  2129. +        if (!cursed(otmp, FALSE))
  2130.              Ring_off(uleft);
  2131.      } else if (doff->what == RIGHT_RING) {
  2132.          otmp = uright;
  2133. -        if (!cursed(otmp))
  2134. +        if (!cursed(otmp, FALSE))
  2135.              Ring_off(uright);
  2136.      } else if (doff->what == WORN_BLINDF) {
  2137. -        if (!cursed(ublindf))
  2138. +        if (!cursed(ublindf, FALSE))
  2139.              Blindf_off(ublindf);
  2140.      } else {
  2141.          impossible("do_takeoff: taking off %lx", doff->what);
  2142. diff --git c/src/dog.c w/src/dog.c
  2143. index 5c50eb6..feccd33 100644
  2144. --- c/src/dog.c
  2145. +++ w/src/dog.c
  2146. @@ -75,10 +75,16 @@ boolean quietly;
  2147.      struct permonst *pm;
  2148.      struct monst *mtmp = 0;
  2149.      int chance, trycnt = 100;
  2150. +    boolean idol = otmp && otmp->oartifact == ART_IDOL_OF_MOLOCH;
  2151.  
  2152.      do {
  2153.          if (otmp) { /* figurine; otherwise spell */
  2154.              int mndx = otmp->corpsenm;
  2155. +            if (idol) {
  2156. +                mndx = ndemon(A_NONE);
  2157. +                if (mndx == NON_PM) /* just in case */
  2158. +                    continue;
  2159. +            }
  2160.  
  2161.              pm = &mons[mndx];
  2162.              /* activating a figurine provides one way to exceed the
  2163. @@ -86,10 +92,14 @@ boolean quietly;
  2164.                 it has a special limit (erinys, Nazgul) */
  2165.              if ((mvitals[mndx].mvflags & G_EXTINCT)
  2166.                  && mbirth_limit(mndx) != MAXMONNO) {
  2167. -                if (!quietly)
  2168. +                if (!quietly) {
  2169.                      /* have just been given "You <do something with>
  2170.                         the figurine and it transforms." message */
  2171. -                    pline("... into a pile of dust.");
  2172. +                    if (!idol)
  2173. +                        pline("... into a pile of dust.");
  2174. +                    else if (!Blind)
  2175. +                        pline_The("cloud disperses.");
  2176. +                }
  2177.                  break; /* mtmp is null */
  2178.              }
  2179.          } else if (!rn2(3)) {
  2180. @@ -103,10 +113,16 @@ boolean quietly;
  2181.              }
  2182.          }
  2183.  
  2184. -        mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
  2185. +        mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER
  2186. +                                 | (!idol * NO_MINVENT));
  2187.          if (otmp && !mtmp) { /* monster was genocided or square occupied */
  2188. -            if (!quietly)
  2189. -                pline_The("figurine writhes and then shatters into pieces!");
  2190. +            if (!quietly) {
  2191. +                if (!idol)
  2192. +                    pline_The("figurine writhes and then shatters "
  2193. +                              "into pieces!");
  2194. +                else if (!Blind)
  2195. +                    pline_The("cloud disperses.");
  2196. +            }
  2197.              break;
  2198.          }
  2199.      } while (!mtmp && --trycnt > 0);
  2200. @@ -114,6 +130,14 @@ boolean quietly;
  2201.      if (!mtmp)
  2202.          return (struct monst *) 0;
  2203.  
  2204. +    if (idol && !quietly && !Blind) {
  2205. +        pline_The("mist coagulates into the shape of %s%s.",
  2206. +                  x_monnam(mtmp, ARTICLE_A, (char *) 0, SUPPRESS_IT
  2207. +                           | SUPPRESS_INVISIBLE | SUPPRESS_SADDLE
  2208. +                           | SUPPRESS_NAME, FALSE),
  2209. +                  canspotmon(mtmp) ? "" : " and vanishes");
  2210. +    }
  2211. +
  2212.      if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
  2213.          return (struct monst *) 0;
  2214.  
  2215. @@ -134,7 +158,7 @@ boolean quietly;
  2216.              }
  2217.          }
  2218.          /* if figurine has been named, give same name to the monster */
  2219. -        if (has_oname(otmp))
  2220. +        if (has_oname(otmp) && !idol)
  2221.              mtmp = christen_monst(mtmp, ONAME(otmp));
  2222.      }
  2223.      set_malign(mtmp); /* more alignment changes */
  2224. @@ -551,6 +575,19 @@ long nmv; /* number of moves */
  2225.          m_unleash(mtmp, FALSE);
  2226.      }
  2227.  
  2228. +    /* maybe pick up the abandoned Amulet */
  2229. +    if (mtmp->data == &mons[PM_AGENT] && !mtmp->mpeaceful
  2230. +        && !mon_has_amulet(mtmp) && rn2(imv + 1) > 300) {
  2231. +        struct obj *otmp;
  2232. +        for (otmp = level.objlist; otmp; otmp = otmp->nobj)
  2233. +            if (otmp->otyp == AMULET_OF_YENDOR
  2234. +                || otmp->otyp == FAKE_AMULET_OF_YENDOR) {
  2235. +                obj_extract_self(otmp);
  2236. +                (void) mpickobj(mtmp, otmp);
  2237. +                break;
  2238. +            }
  2239. +    }
  2240. +
  2241.      /* recover lost hit points */
  2242.      if (!regenerates(mtmp->data))
  2243.          imv /= 20;
  2244. @@ -923,7 +960,7 @@ register struct obj *obj;
  2245.          /* monsters with conflicting structures cannot be tamed */
  2246.          || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
  2247.          || is_covetous(mtmp->data) || is_human(mtmp->data)
  2248. -        || (is_demon(mtmp->data) && !is_demon(youmonst.data))
  2249. +        || (is_demon(mtmp->data) && !is_demon(raceptr(&youmonst)))
  2250.          || (obj && dogfood(mtmp, obj) >= MANFOOD))
  2251.          return FALSE;
  2252.  
  2253. diff --git c/src/dothrow.c w/src/dothrow.c
  2254. index c1a415a..d3ffd8f 100644
  2255. --- c/src/dothrow.c
  2256. +++ w/src/dothrow.c
  2257. @@ -115,6 +115,7 @@ int shotlimit;
  2258.          /* some roles don't get a volley bonus until becoming expert */
  2259.          weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST)
  2260.                           || (Role_if(PM_HEALER) && skill != P_KNIFE)
  2261. +                         || (Role_if(PM_INFIDEL) && skill != P_DAGGER)
  2262.                           || (Role_if(PM_TOURIST) && skill != -P_DART)
  2263.                           /* poor dexterity also inhibits multishot */
  2264.                           || Fumbling || ACURR(A_DEX) <= 6);
  2265. @@ -1804,7 +1805,7 @@ register struct monst *mon;
  2266.  register struct obj *obj;
  2267.  {
  2268.      char buf[BUFSZ];
  2269. -    boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
  2270. +    boolean is_buddy = sgn(mon->data->maligntyp) == u.ualign.type;
  2271.      boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
  2272.      int ret = 0;
  2273.      static NEARDATA const char nogood[] = " is not interested in your junk.";
  2274. diff --git c/src/dungeon.c w/src/dungeon.c
  2275. index 27b7481..1eedd62 100644
  2276. --- c/src/dungeon.c
  2277. +++ w/src/dungeon.c
  2278. @@ -1173,7 +1173,8 @@ boolean at_stairs;
  2279.          /* Taking an up dungeon branch. */
  2280.          /* KMH -- Upwards branches are okay if not level 1 */
  2281.          /* (Just make sure it doesn't go above depth 1) */
  2282. -        if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
  2283. +        if (!u.uz.dnum && u.uz.dlevel == 1
  2284. +            && !(u.uhave.amulet && u.uachieve.amulet))
  2285.              done(ESCAPED);
  2286.          else
  2287.              goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  2288. @@ -2998,8 +2999,11 @@ boolean printdun;
  2289.              else
  2290.                  ADDNTOBUF("temple", mptr->feat.ntemple);
  2291.  
  2292. -            /* only print out altar's god if they are all to your god */
  2293. -            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
  2294. +            /* only print out altar's god if they are all to your god
  2295. +             * For Infidels, only print Moloch if there's exactly one altar;
  2296. +             * this is a technical resriction (i.e. I'm too lazy to fix it) */
  2297. +            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type
  2298. +                && (u.ualign.type != A_NONE || mptr->feat.naltar == 1))
  2299.                  Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
  2300.          }
  2301.          ADDNTOBUF("throne", mptr->feat.nthrone);
  2302. diff --git c/src/eat.c w/src/eat.c
  2303. index 5e2aa1a..8ca11ae 100644
  2304. --- c/src/eat.c
  2305. +++ w/src/eat.c
  2306. @@ -2797,10 +2797,7 @@ gethungry()
  2307.         will need to wear an Amulet of Unchanging so still burn a small
  2308.         amount of nutrition in the 'moves % 20' ring/amulet check below */
  2309.      if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
  2310. -        && (carnivorous(youmonst.data)
  2311. -            || herbivorous(youmonst.data)
  2312. -            || metallivorous(youmonst.data))
  2313. -        && !Slow_digestion)
  2314. +        && !inediate(raceptr(&youmonst)) && !Slow_digestion)
  2315.          u.uhunger--; /* ordinary food consumption */
  2316.  
  2317.      if (moves % 2) { /* odd turns */
  2318. diff --git c/src/end.c w/src/end.c
  2319. index 4df88ce..a63ea9f 100644
  2320. --- c/src/end.c
  2321. +++ w/src/end.c
  2322. @@ -925,6 +925,8 @@ struct obj *list; /* inventory or container contents */
  2323.          } else if (obj->oartifact) {
  2324.              continue;
  2325.          } else if (obj->oclass == AMULET_CLASS) {
  2326. +            if (Role_if(PM_INFIDEL) && obj->otyp == AMULET_OF_YENDOR)
  2327. +                continue; /* starting inventory */
  2328.              i = obj->otyp - FIRST_AMULET;
  2329.              if (!amulets[i].count) {
  2330.                  amulets[i].count = obj->quan;
  2331. @@ -1478,7 +1480,9 @@ int how;
  2332.                  ? (const char *) ((flags.female && urole.name.f)
  2333.                      ? urole.name.f
  2334.                      : urole.name.m)
  2335. -                : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2336. +                : Role_if(PM_INFIDEL) /* can only ascend via Moloch */
  2337. +                 ? (const char *) (flags.female ? "Demon Lady" : "Demon Lord")
  2338. +                 : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2339.      dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
  2340.      dump_forward_putstr(endwin, 0, "", done_stopprint);
  2341.  
  2342. diff --git c/src/engrave.c w/src/engrave.c
  2343. index b001855..975b538 100644
  2344. --- c/src/engrave.c
  2345. +++ w/src/engrave.c
  2346. @@ -431,7 +431,8 @@ int
  2347.  freehand()
  2348.  {
  2349.      return (!uwep || !welded(uwep)
  2350. -            || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
  2351. +            || (!bimanual(uwep)
  2352. +                && (!uarms || !cursed(uarms, TRUE))));
  2353.  }
  2354.  
  2355.  static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
  2356. @@ -504,7 +505,7 @@ doengrave()
  2357.      maxelen = BUFSZ - 1;
  2358.      if (oep)
  2359.          oetype = oep->engr_type;
  2360. -    if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
  2361. +    if (is_demon(raceptr(&youmonst)) || youmonst.data->mlet == S_VAMPIRE)
  2362.          type = ENGR_BLOOD;
  2363.  
  2364.      /* Can the adventurer engrave at all? */
  2365. diff --git c/src/exper.c w/src/exper.c
  2366. index 9b96b5c..fc4cf1e 100644
  2367. --- c/src/exper.c
  2368. +++ w/src/exper.c
  2369. @@ -32,6 +32,7 @@ int en;
  2370.      case PM_WIZARD:
  2371.          return (2 * en);
  2372.      case PM_HEALER:
  2373. +    case PM_INFIDEL:
  2374.      case PM_KNIGHT:
  2375.          return ((3 * en) / 2);
  2376.      case PM_BARBARIAN:
  2377. diff --git c/src/explode.c w/src/explode.c
  2378. index 31ba7c7..3f933b1 100644
  2379. --- c/src/explode.c
  2380. +++ w/src/explode.c
  2381. @@ -185,7 +185,7 @@ int expltype;
  2382.                  case AD_DISN:
  2383.                      explmask[i][j] = (olet == WAND_CLASS)
  2384.                                           ? !!(nonliving(youmonst.data)
  2385. -                                              || is_demon(youmonst.data))
  2386. +                                              || is_demon(raceptr(&youmonst)))
  2387.                                           : !!Disint_resistance;
  2388.                      break;
  2389.                  case AD_ELEC:
  2390. diff --git c/src/hack.c w/src/hack.c
  2391. index 79fe740..da4bd69 100644
  2392. --- c/src/hack.c
  2393. +++ w/src/hack.c
  2394. @@ -2012,7 +2012,7 @@ invocation_message()
  2395.              Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
  2396.  
  2397.          You_feel("a strange vibration %s.", buf);
  2398. -        u.uevent.uvibrated = 1;
  2399. +        u.uachieve.vibrating_square = 1;
  2400.          if (otmp && otmp->spe == 7 && otmp->lamplit)
  2401.              pline("%s %s!", The(xname(otmp)),
  2402.                    Blind ? "throbs palpably" : "glows with a strange light");
  2403. @@ -2053,7 +2053,7 @@ switch_terrain()
  2404.          /* [minor bug: we don't know whether this is beginning flight or
  2405.             resuming it; that could be tracked so that this message could
  2406.             be adjusted to "resume flying", but isn't worth the effort...] */
  2407. -        if (Flying)
  2408. +        if (Flying && !was_flying)
  2409.              You("start flying.");
  2410.      }
  2411.      if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
  2412. diff --git c/src/invent.c w/src/invent.c
  2413. index 7e7e3b2..c0b87c1 100644
  2414. --- c/src/invent.c
  2415. +++ w/src/invent.c
  2416. @@ -813,7 +813,8 @@ struct obj *obj;
  2417.          if (u.uhave.amulet)
  2418.              impossible("already have amulet?");
  2419.          u.uhave.amulet = 1;
  2420. -        u.uachieve.amulet = 1;
  2421. +        if (!Role_if(PM_INFIDEL))
  2422. +            u.uachieve.amulet = 1;
  2423.      } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
  2424.          if (u.uhave.menorah)
  2425.              impossible("already have candelabrum?");
  2426. @@ -834,6 +835,8 @@ struct obj *obj;
  2427.              if (u.uhave.questart)
  2428.                  impossible("already have quest artifact?");
  2429.              u.uhave.questart = 1;
  2430. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2431. +                u.uhave.amulet = 1;
  2432.              artitouch(obj);
  2433.          }
  2434.          set_artifact_intrinsic(obj, 1, W_ART);
  2435. @@ -1132,6 +1135,8 @@ struct obj *obj;
  2436.              if (!u.uhave.questart)
  2437.                  impossible("don't have quest artifact?");
  2438.              u.uhave.questart = 0;
  2439. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2440. +                u.uhave.amulet = 0;
  2441.          }
  2442.          set_artifact_intrinsic(obj, 0, W_ART);
  2443.      }
  2444. @@ -1181,6 +1186,7 @@ register struct obj *obj;
  2445.      boolean update_map;
  2446.  
  2447.      if (obj->otyp == AMULET_OF_YENDOR
  2448. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
  2449.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  2450.          || obj->otyp == BELL_OF_OPENING
  2451.          || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  2452. @@ -1601,10 +1607,11 @@ register const char *let, *word;
  2453.               || (!strncmp(word, "rub on the stone", 16)
  2454.                   && *let == GEM_CLASS && otmp->dknown
  2455.                   && objects[otyp].oc_name_known)
  2456. -             /* suppress corpses on astral, amulets elsewhere */
  2457. +             /* suppress corpses on astral (or sanctum), amulets elsewhere */
  2458.               || (!strcmp(word, "sacrifice")
  2459.                   /* (!astral && amulet) || (astral && !amulet) */
  2460. -                 && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
  2461. +                 && ((!Is_astralevel(&u.uz) && !Is_sanctum(&u.uz))
  2462. +                     ^ (otmp->oclass != AMULET_CLASS)))
  2463.               /* suppress container being stashed into */
  2464.               || (!strcmp(word, "stash") && !ck_bag(otmp))
  2465.               /* worn armor (shirt, suit) covered by worn armor (suit, cloak)
  2466. diff --git c/src/makemon.c w/src/makemon.c
  2467. index 3145ad6..271806a 100644
  2468. --- c/src/makemon.c
  2469. +++ w/src/makemon.c
  2470. @@ -185,7 +185,7 @@ register struct monst *mtmp;
  2471.              (void) mongets(mtmp, (mm != PM_ETTIN) ? BOULDER : CLUB);
  2472.          break;
  2473.      case S_HUMAN:
  2474. -        if (is_mercenary(ptr)) {
  2475. +        if (is_mercenary(ptr) || mm == PM_TEMPLAR) {
  2476.              w1 = w2 = 0;
  2477.              switch (mm) {
  2478.              case PM_WATCHMAN:
  2479. @@ -204,6 +204,7 @@ register struct monst *mtmp;
  2480.                  break;
  2481.              case PM_CAPTAIN:
  2482.              case PM_WATCH_CAPTAIN:
  2483. +            case PM_TEMPLAR:
  2484.                  w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
  2485.                  break;
  2486.              default:
  2487. @@ -266,11 +267,20 @@ register struct monst *mtmp;
  2488.          } else if (mm == PM_NINJA) { /* extra quest villains */
  2489.              (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
  2490.              (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
  2491. +        } else if (mm == PM_CHAMPION) {
  2492. +            (void) mongets(mtmp, rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE);
  2493. +            (void) mongets(mtmp, rn2(3) ? RING_MAIL : CHAIN_MAIL);
  2494. +        } else if (mm == PM_AGENT) {
  2495. +            (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : DAGGER);
  2496. +            if (!rn2(3))
  2497. +                (void) mongets(mtmp, LEATHER_ARMOR);
  2498. +            (void) mongets(mtmp, POT_INVISIBILITY);
  2499.          } else if (ptr->msound == MS_GUARDIAN) {
  2500.              /* quest "guardians" */
  2501.              switch (mm) {
  2502.              case PM_STUDENT:
  2503.              case PM_ATTENDANT:
  2504. +            case PM_CULTIST:
  2505.              case PM_ABBOT:
  2506.              case PM_ACOLYTE:
  2507.              case PM_GUIDE:
  2508. @@ -588,7 +598,7 @@ register struct monst *mtmp;
  2509.       */
  2510.      switch (ptr->mlet) {
  2511.      case S_HUMAN:
  2512. -        if (is_mercenary(ptr)) {
  2513. +        if (is_mercenary(ptr) || monsndx(ptr) == PM_TEMPLAR) {
  2514.              register int mac;
  2515.  
  2516.              switch (monsndx(ptr)) {
  2517. @@ -613,6 +623,9 @@ register struct monst *mtmp;
  2518.              case PM_WATCH_CAPTAIN:
  2519.                  mac = -2;
  2520.                  break;
  2521. +            case PM_TEMPLAR:
  2522. +                mac = -3;
  2523. +                break;
  2524.              default:
  2525.                  impossible("odd mercenary %d?", monsndx(ptr));
  2526.                  mac = 0;
  2527. @@ -655,6 +668,10 @@ register struct monst *mtmp;
  2528.              } else if (ptr == &mons[PM_WATCHMAN]) {
  2529.                  if (rn2(3)) /* most watchmen carry a whistle */
  2530.                      (void) mongets(mtmp, TIN_WHISTLE);
  2531. +            } else if (ptr == &mons[PM_TEMPLAR]) {
  2532. +                if (rn2(3)) /* being in a holy order has its benefits */
  2533. +                    (void) mongets(mtmp, rn2(4) ? POT_HEALING
  2534. +                                                : POT_EXTRA_HEALING);
  2535.              } else if (ptr == &mons[PM_GUARD]) {
  2536.                  /* if hero teleports out of a vault while being confronted
  2537.                     by the vault's guard, there is a shrill whistling sound,
  2538. @@ -695,6 +712,22 @@ register struct monst *mtmp;
  2539.              mkmonmoney(mtmp, (long) rn1(10, 20));
  2540.          } else if (quest_mon_represents_role(ptr, PM_MONK)) {
  2541.              (void) mongets(mtmp, rn2(11) ? ROBE : CLOAK_OF_MAGIC_RESISTANCE);
  2542. +        } else if (ptr == &mons[PM_PREACHER_OF_MOLOCH]) {
  2543. +            (void) mongets(mtmp, QUARTERSTAFF);
  2544. +            (void) mongets(mtmp, rn2(3) ? ROBE : CLOAK_OF_PROTECTION);
  2545. +        } else if (ptr == &mons[PM_PALADIN]) {
  2546. +            otmp = mksobj(MORNING_STAR, FALSE, FALSE);
  2547. +            otmp->blessed = otmp->oerodeproof = 1;
  2548. +            otmp->spe = rn1(3, 3);
  2549. +            (void) mpickobj(mtmp, otmp);
  2550. +            /* the Paladin wears no helmet
  2551. +             * because she looks cooler without a helmet */
  2552. +            (void) mongets(mtmp, LEATHER_GLOVES);
  2553. +            (void) mongets(mtmp, SHIELD_OF_REFLECTION);
  2554. +            (void) mongets(mtmp, LEATHER_CLOAK);
  2555. +            (void) mongets(mtmp, CRYSTAL_PLATE_MAIL);
  2556. +            (void) mongets(mtmp, HIGH_BOOTS);
  2557. +            (void) mongets(mtmp, POT_SPEED);
  2558.          }
  2559.          break;
  2560.      case S_NYMPH:
  2561. @@ -1269,7 +1302,7 @@ int mmflags;
  2562.              mtmp->mpeaceful = FALSE;
  2563.          break;
  2564.      case S_UNICORN:
  2565. -        if (is_unicorn(ptr) && sgn(u.ualign.type) == sgn(ptr->maligntyp))
  2566. +        if (is_unicorn(ptr) && u.ualign.type == sgn(ptr->maligntyp))
  2567.              mtmp->mpeaceful = TRUE;
  2568.          break;
  2569.      case S_BAT:
  2570. @@ -1365,6 +1398,13 @@ int mmflags;
  2571.                                ? !eminp->renegade
  2572.                                : eminp->renegade;
  2573.      }
  2574. +    /* these monsters are normally affiliated with a deity */
  2575. +    if ((mndx == PM_PALADIN || mndx == PM_TEMPLAR || mndx == PM_CHAMPION
  2576. +         || mndx == PM_AGENT) && !(mmflags & MM_EMIN)) {
  2577. +        newemin(mtmp);
  2578. +        mtmp->isminion = 1;
  2579. +        EMIN(mtmp)->min_align = sgn(ptr->maligntyp);
  2580. +    }
  2581.      set_malign(mtmp); /* having finished peaceful changes */
  2582.      if (anymon && !(mmflags & MM_NOGRP)) {
  2583.          if ((ptr->geno & G_SGROUP) && rn2(2)) {
  2584. @@ -2007,7 +2047,11 @@ register struct permonst *ptr;
  2585.  
  2586.      if (always_peaceful(ptr))
  2587.          return TRUE;
  2588. -    if (always_hostile(ptr))
  2589. +    /* Major demons will sometimes be peaceful to unaligned Infidels.
  2590. +     * They must pass this 50% check, then the 50% check for chaotics
  2591. +     * being non-hostile to unaligned, then the usual check for coaligned.
  2592. +     * For crowned Infidels, the last two checks are bypassed. */
  2593. +    if (always_hostile(ptr) && (ual != A_NONE || !is_demon(ptr) || rn2(2)))
  2594.          return FALSE;
  2595.      if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
  2596.          return TRUE;
  2597. @@ -2024,8 +2068,12 @@ register struct permonst *ptr;
  2598.      if (sgn(mal) != sgn(ual))
  2599.          return FALSE;
  2600.  
  2601. -    /* Negative monster hostile to player with Amulet. */
  2602. -    if (mal < A_NEUTRAL && u.uhave.amulet)
  2603. +    /* Not all chaotics support Moloch.  This goes especially for elves. */
  2604. +    if (ual == A_NONE && (is_elf(ptr) || rn2(2)))
  2605. +        return FALSE;
  2606. +
  2607. +    /* Chaotic monsters hostile to players with Amulet, except Infidels. */
  2608. +    if (mal < A_NEUTRAL && u.uhave.amulet && ual != A_NONE)
  2609.          return FALSE;
  2610.  
  2611.      /* minions are hostile to players that have strayed at all */
  2612. @@ -2070,7 +2118,7 @@ struct monst *mtmp;
  2613.              mal *= 5;
  2614.      }
  2615.  
  2616. -    coaligned = (sgn(mal) == sgn(u.ualign.type));
  2617. +    coaligned = (sgn(mal) == u.ualign.type);
  2618.      if (mtmp->data->msound == MS_LEADER) {
  2619.          mtmp->malign = -20;
  2620.      } else if (mal == A_NONE) {
  2621. @@ -2078,6 +2126,8 @@ struct monst *mtmp;
  2622.              mtmp->malign = 0;
  2623.          else
  2624.              mtmp->malign = 20; /* really hostile */
  2625. +        if (u.ualign.type == A_NONE)
  2626. +            mtmp->malign -= 20; /* reverse */
  2627.      } else if (always_peaceful(mtmp->data)) {
  2628.          int absmal = abs(mal);
  2629.          if (mtmp->mpeaceful)
  2630. diff --git c/src/mcastu.c w/src/mcastu.c
  2631. index 1b2fb63..3c1402a 100644
  2632. --- c/src/mcastu.c
  2633. +++ w/src/mcastu.c
  2634. @@ -377,7 +377,7 @@ int spellnum;
  2635.      switch (spellnum) {
  2636.      case MGC_DEATH_TOUCH:
  2637.          pline("Oh no, %s's using the touch of death!", mhe(mtmp));
  2638. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  2639. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  2640.              You("seem no deader than before.");
  2641.          } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
  2642.              if (Hallucination) {
  2643. diff --git c/src/mhitu.c w/src/mhitu.c
  2644. index 849ddb1..cbb24de 100644
  2645. --- c/src/mhitu.c
  2646. +++ w/src/mhitu.c
  2647. @@ -589,7 +589,7 @@ register struct monst *mtmp;
  2648.      /*  Special demon handling code */
  2649.      if ((mtmp->cham == NON_PM) && is_demon(mdat) && !range2
  2650.          && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS]
  2651. -        && mtmp->data != &mons[PM_INCUBUS])
  2652. +        && mtmp->data != &mons[PM_INCUBUS] && mtmp->data != &mons[PM_DEMON])
  2653.          if (!mtmp->mcan && !rn2(13))
  2654.              (void) msummon(mtmp);
  2655.  
  2656. diff --git c/src/minion.c w/src/minion.c
  2657. index 4277b45..5624a22 100644
  2658. --- c/src/minion.c
  2659. +++ w/src/minion.c
  2660. @@ -261,7 +261,7 @@ register struct monst *mtmp;
  2661.          }
  2662.          newsym(mtmp->mx, mtmp->my);
  2663.      }
  2664. -    if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
  2665. +    if (is_demon(raceptr(&youmonst))) { /* Won't blackmail their own. */
  2666.          if (!Deaf)
  2667.              pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
  2668.                    flags.female ? "Sister" : "Brother");
  2669. diff --git c/src/mon.c w/src/mon.c
  2670. index 4f0a13d..7d85d8b 100644
  2671. --- c/src/mon.c
  2672. +++ w/src/mon.c
  2673. @@ -2472,7 +2472,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2674.      }
  2675.      if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
  2676.          change_luck(-1);
  2677. -    if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
  2678. +    if (is_unicorn(mdat) && u.ualign.type == sgn(mdat->maligntyp)) {
  2679.          change_luck(-5);
  2680.          You_feel("guilty...");
  2681.      }
  2682. @@ -2500,7 +2500,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2683.          /* cancel divine protection for killing your priest */
  2684.          if (p_coaligned(mtmp))
  2685.              u.ublessed = 0;
  2686. -        if (mdat->maligntyp == A_NONE)
  2687. +        else if (mdat->maligntyp == A_NONE)
  2688.              adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
  2689.      } else if (mtmp->mtame) {
  2690.          adjalign(-15); /* bad!! */
  2691. @@ -2905,7 +2905,8 @@ boolean via_attack;
  2692.             it's intentionally larger than the 1s and 2s that are normally
  2693.             given for this sort of thing. */
  2694.          /* reduce to 3 (average) when alignment is already very low */
  2695. -        adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2696. +        if (u.ualign.type != A_NONE)
  2697. +            adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2698.  
  2699.          if (!Blind)
  2700.              pline("The engraving beneath you fades.");
  2701. diff --git c/src/mondata.c w/src/mondata.c
  2702. index fae34e8..7d20930 100644
  2703. --- c/src/mondata.c
  2704. +++ w/src/mondata.c
  2705. @@ -97,7 +97,7 @@ boolean
  2706.  resists_drli(mon)
  2707.  struct monst *mon;
  2708.  {
  2709. -    struct permonst *ptr = mon->data;
  2710. +    struct permonst *ptr = raceptr(mon); /* handle demonic race */
  2711.      struct obj *wep;
  2712.  
  2713.      if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
  2714. @@ -421,8 +421,7 @@ register struct permonst *ptr;
  2715.      return (boolean) (bigmonst(ptr)
  2716.                        || (ptr->msize > MZ_SMALL && !humanoid(ptr))
  2717.                        /* special cases of humanoids that cannot wear suits */
  2718. -                      || ptr == &mons[PM_MARILITH]
  2719. -                      || ptr == &mons[PM_WINGED_GARGOYLE]);
  2720. +                      || ptr == &mons[PM_MARILITH]);
  2721.  }
  2722.  
  2723.  /* creature sticks other creatures it hits */
  2724. @@ -1077,7 +1076,7 @@ int montyp1, montyp2;
  2725.   * Returns correct pointer for non-polymorphed and polymorphed
  2726.   * player.  It does not return a pointer to player role character.
  2727.   */
  2728. -const struct permonst *
  2729. +struct permonst *
  2730.  raceptr(mtmp)
  2731.  struct monst *mtmp;
  2732.  {
  2733. diff --git c/src/monmove.c w/src/monmove.c
  2734. index cd6ca98..9abc779 100644
  2735. --- c/src/monmove.c
  2736. +++ w/src/monmove.c
  2737. @@ -344,6 +344,14 @@ int *inrange, *nearby, *scared;
  2738.                      || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
  2739.          *scared = 1;
  2740.          monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
  2741. +        if (u.ualign.type == A_NONE && !context.coward
  2742. +            && sengr_at("Elbereth", seescaryx, seescaryy, TRUE)) {
  2743. +            /* Followers of Moloch aren't supposed
  2744. +             * to hide behind other gods. */
  2745. +            You_feel("like a coward.");
  2746. +            context.coward = TRUE; /* once per move */
  2747. +            adjalign(-5);
  2748. +        }
  2749.      } else
  2750.          *scared = 0;
  2751.  }
  2752. @@ -927,6 +935,9 @@ register int after;
  2753.                      > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
  2754.              appr = -1;
  2755.  
  2756. +        if (monsndx(ptr) == PM_AGENT && mon_has_amulet(mtmp))
  2757. +            appr = -1; /* objective secured, retreat */
  2758. +
  2759.          if (!should_see && can_track(ptr)) {
  2760.              register coord *cp;
  2761.  
  2762. diff --git c/src/monst.c w/src/monst.c
  2763. index 6b8a5f7..de919f5 100644
  2764. --- c/src/monst.c
  2765. +++ w/src/monst.c
  2766. @@ -2139,6 +2139,27 @@ struct permonst _mons2[] = {
  2767.          M1_HUMANOID | M1_POIS | M1_REGEN | M1_OMNIVORE,
  2768.          M2_NOPOLY | M2_WERE | M2_HOSTILE | M2_HUMAN | M2_COLLECT,
  2769.          M3_INFRAVISIBLE, 6, CLR_ORANGE),
  2770. +    /* Only generated when playing as Infidel.
  2771. +     * Has emin, so always appears as a "champion of [deity]".
  2772. +     * Note: the difficulty is purposefully lowered. */
  2773. +    MON("champion", S_HUMAN, LVL(12, 12, 6, 10, 0), (G_NOGEN | G_NOHELL | 2),
  2774. +        A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
  2775. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2776. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
  2777. +        M1_HUMANOID | M1_OMNIVORE,
  2778. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_NASTY | M2_STRONG | M2_COLLECT,
  2779. +        M3_INFRAVISIBLE, 6, CLR_GRAY),
  2780. +    /* Only generated when playing as Infidel.
  2781. +     * Has emin, so always appears as an "agent of [deity]".
  2782. +     * Note: the difficulty is purposefully lowered. */
  2783. +    MON("agent", S_HUMAN, LVL(6, 18, 10, 10, -7), (G_NOGEN | G_NOHELL | 3),
  2784. +        A(ATTK(AT_WEAP, AD_SAMU, 1, 4), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  2785. +          ATTK(AT_CLAW, AD_SAMU, 1, 1), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  2786. +          NO_ATTK, NO_ATTK),
  2787. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  2788. +        M1_HUMANOID | M1_OMNIVORE | M1_TPORT,
  2789. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STALK | M2_STRONG | M2_COLLECT,
  2790. +        M3_INFRAVISIBLE, 6, CLR_BLACK),
  2791.      MON("elf", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, /* for corpses */
  2792.          A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2793.            NO_ATTK),
  2794. @@ -2607,6 +2628,14 @@ struct permonst _mons2[] = {
  2795.          SIZ(1500, 400, MS_DJINNI, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  2796.          M1_HUMANOID | M1_FLY | M1_POIS, M2_NOPOLY | M2_STALK | M2_COLLECT,
  2797.          M3_INFRAVISIBLE, 8, CLR_YELLOW),
  2798. +    /* racial monster for crowned Infidels */
  2799. +    MON("demon", S_DEMON, LVL(10, 12, 10, 10, A_NONE), (G_NOGEN | G_NOCORPSE),
  2800. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_STNG, AD_DRST, 2, 4),
  2801. +          NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
  2802. +        SIZ(WT_HUMAN, 400, MS_GRUNT, MZ_HUMAN), MR_FIRE | MR_POISON, 0,
  2803. +        M1_HUMANOID | M1_FLY | M1_SEE_INVIS | M1_POIS,
  2804. +        M2_NOPOLY | M2_DEMON | M2_STALK | M2_HOSTILE | M2_COLLECT,
  2805. +        M3_INFRAVISIBLE | M3_INFRAVISION, 13, CLR_RED),
  2806.      /*
  2807.       * sea monsters
  2808.       */
  2809. @@ -2757,6 +2786,13 @@ struct permonst _mons2[] = {
  2810.          M1_HUMANOID | M1_OMNIVORE,
  2811.          M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  2812.          12, HI_DOMESTIC),
  2813. +    MON("infidel", S_HUMAN, LVL(10, 12, 10, 2, A_NONE), G_NOGEN,
  2814. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2815. +          NO_ATTK),
  2816. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_FIRE, 0,
  2817. +        M1_HUMANOID | M1_OMNIVORE,
  2818. +        M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  2819. +        12, HI_DOMESTIC),
  2820.      MON("knight", S_HUMAN, LVL(10, 12, 10, 1, 3), G_NOGEN,
  2821.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2822.            NO_ATTK, NO_ATTK, NO_ATTK),
  2823. @@ -2884,6 +2920,17 @@ struct permonst _mons2[] = {
  2824.          M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
  2825.              | M2_COLLECT | M2_MAGIC,
  2826.          M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
  2827. +    /* apparently she should be a "preacheress" if female,
  2828. +     * but that word just sounds silly, imo */
  2829. +    MON("preacher of Moloch", S_HUMAN, LVL(20, 12, 0, 40, A_NONE),
  2830. +        (G_NOGEN | G_UNIQ),
  2831. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK,
  2832. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2833. +        SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_FIRE | MR_ELEC, 0,
  2834. +        M1_HUMANOID | M1_OMNIVORE,
  2835. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT
  2836. +            | M2_MAGIC,
  2837. +        M3_CLOSE | M3_INFRAVISIBLE, 23, CLR_RED),
  2838.      MON("King Arthur", S_HUMAN, LVL(20, 12, 0, 40, 20), (G_NOGEN | G_UNIQ),
  2839.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2840.            NO_ATTK, NO_ATTK, NO_ATTK),
  2841. @@ -3026,6 +3073,18 @@ struct permonst _mons2[] = {
  2842.              | M2_HOSTILE | M2_NASTY | M2_MALE | M2_JEWELS | M2_COLLECT,
  2843.          M3_WANTSARTI | M3_WAITFORU | M3_INFRAVISION | M3_INFRAVISIBLE,
  2844.          23, CLR_GRAY),
  2845. +    /* Has emin, so always appears as the "Paladin of [deity]". */
  2846. +    MON("Paladin", S_HUMAN, LVL(24, 12, 0, 50, 20),
  2847. +        (G_NOGEN | G_UNIQ | G_NOCORPSE),
  2848. +        A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_STUN, 2, 6),
  2849. +          ATTK(AT_MAGC, AD_CLRC, 1, 8), ATTK(AT_CLAW, AD_SAMU, 1, 6),
  2850. +          NO_ATTK, NO_ATTK),
  2851. +        SIZ(WT_HUMAN, 400, MS_NEMESIS, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  2852. +        M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
  2853. +        M2_NOPOLY | M2_HUMAN | M2_MINION | M2_LORD | M2_STRONG | M2_FEMALE
  2854. +            | M2_STALK | M2_HOSTILE | M2_NASTY | M2_COLLECT | M2_MAGIC,
  2855. +        M3_WANTSARTI | M3_WANTSAMUL | M3_WAITFORU | M3_INFRAVISIBLE,
  2856. +        29, HI_GOLD),
  2857.      MON("Ixoth", S_DRAGON, LVL(15, 12, -1, 20, -14), (G_NOGEN | G_UNIQ),
  2858.          A(ATTK(AT_BREA, AD_FIRE, 8, 6), ATTK(AT_BITE, AD_PHYS, 4, 8),
  2859.            ATTK(AT_MAGC, AD_SPEL, 0, 0), ATTK(AT_CLAW, AD_PHYS, 2, 4),
  2860. @@ -3148,6 +3207,21 @@ struct permonst _mons2[] = {
  2861.          M1_HUMANOID | M1_OMNIVORE,
  2862.          M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  2863.          M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  2864. +    /* Has emin, so always appears as a "templar of [deity]". */
  2865. +    MON("templar", S_HUMAN, LVL(12, 10, 10, 20, 10), G_NOGEN,
  2866. +        A(ATTK(AT_WEAP, AD_PHYS, 3, 4), ATTK(AT_WEAP, AD_PHYS, 3, 4), NO_ATTK,
  2867. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2868. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  2869. +        M1_HUMANOID | M1_OMNIVORE,
  2870. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STRONG | M2_COLLECT,
  2871. +        M3_INFRAVISIBLE, 14, CLR_BLUE),
  2872. +    MON("cultist", S_HUMAN, LVL(5, 12, 10, 10, A_NONE), G_NOGEN,
  2873. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2874. +          NO_ATTK),
  2875. +        SIZ(WT_HUMAN, 400, MS_GUARDIAN, MZ_HUMAN), MR_FIRE, 0,
  2876. +        M1_HUMANOID | M1_OMNIVORE,
  2877. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  2878. +        M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  2879.      MON("page", S_HUMAN, LVL(5, 12, 10, 10, 3), G_NOGEN,
  2880.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2881.            NO_ATTK, NO_ATTK, NO_ATTK),
  2882. diff --git c/src/mplayer.c w/src/mplayer.c
  2883. index 2dba08e..b65f708 100644
  2884. --- c/src/mplayer.c
  2885. +++ w/src/mplayer.c
  2886. @@ -195,6 +195,16 @@ register boolean special;
  2887.              if (rn2(2))
  2888.                  shield = STRANGE_OBJECT;
  2889.              break;
  2890. +        case PM_INFIDEL:
  2891. +            if (!rn2(4))
  2892. +                weapon = CRYSKNIFE;
  2893. +            if (rn2(3))
  2894. +                cloak = CLOAK_OF_PROTECTION;
  2895. +            if (rn2(4))
  2896. +                helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
  2897. +            if (rn2(2))
  2898. +                shield = STRANGE_OBJECT;
  2899. +            break;
  2900.          case PM_KNIGHT:
  2901.              if (rn2(4))
  2902.                  weapon = LONG_SWORD;
  2903. diff --git c/src/muse.c w/src/muse.c
  2904. index 2dfb92f..6062690 100644
  2905. --- c/src/muse.c
  2906. +++ w/src/muse.c
  2907. @@ -2091,6 +2091,9 @@ struct obj *obj;
  2908.              return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
  2909.          if (typ == AMULET_OF_REFLECTION)
  2910.              return TRUE;
  2911. +        if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
  2912. +            return (boolean) (mon->data == &mons[PM_AGENT]
  2913. +                              && !mon_has_amulet(mon));
  2914.          break;
  2915.      case TOOL_CLASS:
  2916.          if (typ == PICK_AXE)
  2917. diff --git c/src/pickup.c w/src/pickup.c
  2918. index 76f35aa..21133f5 100644
  2919. --- c/src/pickup.c
  2920. +++ w/src/pickup.c
  2921. @@ -2150,6 +2150,7 @@ register struct obj *obj;
  2922.          pline_The("stone%s won't leave your person.", plur(obj->quan));
  2923.          return 0;
  2924.      } else if (obj->otyp == AMULET_OF_YENDOR
  2925. +               || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
  2926.                 || obj->otyp == CANDELABRUM_OF_INVOCATION
  2927.                 || obj->otyp == BELL_OF_OPENING
  2928.                 || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  2929. diff --git c/src/polyself.c w/src/polyself.c
  2930. index b053091..7fa7e3f 100644
  2931. --- c/src/polyself.c
  2932. +++ w/src/polyself.c
  2933. @@ -42,8 +42,10 @@ void
  2934.  set_uasmon()
  2935.  {
  2936.      struct permonst *mdat = &mons[u.umonnum];
  2937. +    struct permonst *racedat; /* for infravision, flying */
  2938.  
  2939.      set_mon_data(&youmonst, mdat);
  2940. +    racedat = raceptr(&youmonst);
  2941.  
  2942.  #define PROPSET(PropIndx, ON)                          \
  2943.      do {                                               \
  2944. @@ -81,7 +83,7 @@ set_uasmon()
  2945.      PROPSET(SEE_INVIS, perceives(mdat));
  2946.      PROPSET(TELEPAT, telepathic(mdat));
  2947.      /* note that Infravision uses mons[race] rather than usual mons[role] */
  2948. -    PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum]));
  2949. +    PROPSET(INFRAVISION, infravision(racedat));
  2950.      PROPSET(INVIS, pm_invisible(mdat));
  2951.      PROPSET(TELEPORT, can_teleport(mdat));
  2952.      PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
  2953. @@ -89,7 +91,9 @@ set_uasmon()
  2954.      /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
  2955.         suppress flying for it so that enlightenment doesn't confusingly
  2956.         show latent flight capability always blocked by levitation */
  2957. -    PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
  2958. +    /* this property also checks race instead of role */
  2959. +    PROPSET(FLYING, (is_flyer(racedat) && !is_floater(racedat)));
  2960. +    check_wings(TRUE);
  2961.      PROPSET(SWIMMING, is_swimmer(mdat));
  2962.      /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
  2963.         key off of it but include different monster forms...] */
  2964. diff --git c/src/potion.c w/src/potion.c
  2965. index c6dffc5..fe19946 100644
  2966. --- c/src/potion.c
  2967. +++ w/src/potion.c
  2968. @@ -648,8 +648,9 @@ register struct obj *otmp;
  2969.              break;
  2970.          }
  2971.          unkn++;
  2972. -        if (is_undead(youmonst.data) || is_demon(youmonst.data)
  2973. -            || u.ualign.type == A_CHAOTIC) {
  2974. +        if (is_undead(youmonst.data) || is_demon(raceptr(&youmonst))
  2975. +            || u.ualign.type <= A_CHAOTIC) {
  2976. +            int dice = (u.ualign.type == A_NONE) ? 4 : 2;
  2977.              if (otmp->blessed) {
  2978.                  pline("This burns like %s!", hliquid("acid"));
  2979.                  exercise(A_CON, FALSE);
  2980. @@ -660,11 +661,11 @@ register struct obj *otmp;
  2981.                          you_unwere(FALSE);
  2982.                      set_ulycn(NON_PM); /* cure lycanthropy */
  2983.                  }
  2984. -                losehp(Maybe_Half_Phys(d(2, 6)), "potion of holy water",
  2985. +                losehp(Maybe_Half_Phys(d(dice, 6)), "potion of holy water",
  2986.                         KILLED_BY_AN);
  2987.              } else if (otmp->cursed) {
  2988.                  You_feel("quite proud of yourself.");
  2989. -                healup(d(2, 6), 0, 0, 0);
  2990. +                healup(d(dice, 6), 0, 0, 0);
  2991.                  if (u.ulycn >= LOW_PM && !Upolyd)
  2992.                      you_were();
  2993.                  exercise(A_CON, TRUE);
  2994. diff --git c/src/pray.c w/src/pray.c
  2995. index 79369fc..81877ee 100644
  2996. --- c/src/pray.c
  2997. +++ w/src/pray.c
  2998. @@ -3,6 +3,7 @@
  2999.  /* NetHack may be freely redistributed.  See license for details. */
  3000.  
  3001.  #include "hack.h"
  3002. +#include "qtext.h"
  3003.  
  3004.  STATIC_PTR int NDECL(prayer_done);
  3005.  STATIC_DCL struct obj *NDECL(worst_cursed_item);
  3006. @@ -12,8 +13,6 @@ STATIC_DCL void FDECL(angrygods, (ALIGNTYP_P));
  3007.  STATIC_DCL void FDECL(at_your_feet, (const char *));
  3008.  STATIC_DCL void NDECL(gcrownu);
  3009.  STATIC_DCL void FDECL(pleased, (ALIGNTYP_P));
  3010. -STATIC_DCL void FDECL(godvoice, (ALIGNTYP_P, const char *));
  3011. -STATIC_DCL void FDECL(god_zaps_you, (ALIGNTYP_P));
  3012.  STATIC_DCL void FDECL(fry_by_god, (ALIGNTYP_P, BOOLEAN_P));
  3013.  STATIC_DCL void FDECL(gods_angry, (ALIGNTYP_P));
  3014.  STATIC_DCL void FDECL(gods_upset, (ALIGNTYP_P));
  3015. @@ -22,7 +21,8 @@ STATIC_DCL boolean FDECL(water_prayer, (BOOLEAN_P));
  3016.  STATIC_DCL boolean FDECL(blocked_boulder, (int, int));
  3017.  
  3018.  /* simplify a few tests */
  3019. -#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) && (obj)->cursed)
  3020. +#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) \
  3021. +                              && cursed(obj, TRUE))
  3022.  
  3023.  /*
  3024.   * Logic behind deities and altars and such:
  3025. @@ -50,7 +50,7 @@ static const char *godvoices[] = {
  3026.  /* values calculated when prayer starts, and used when completed */
  3027.  static aligntyp p_aligntyp;
  3028.  static int p_trouble;
  3029. -static int p_type; /* (-1)-3: (-1)=really naughty, 3=really good */
  3030. +static int p_type; /* (-2)-3: (-1)=really naughty, 3=really good */
  3031.  
  3032.  #define PIOUS 20
  3033.  #define DEVOUT 14
  3034. @@ -221,10 +221,11 @@ in_trouble()
  3035.          if (welded(uwep))
  3036.              return TROUBLE_UNUSEABLE_HANDS;
  3037.          if (Upolyd && nohands(youmonst.data)
  3038. -            && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed)))
  3039. +            && (!Unchanging || ((otmp = unchanger()) != 0
  3040. +                                && cursed(otmp, TRUE))))
  3041.              return TROUBLE_UNUSEABLE_HANDS;
  3042.      }
  3043. -    if (Blindfolded && ublindf->cursed)
  3044. +    if (Blindfolded && cursed(ublindf, TRUE))
  3045.          return TROUBLE_CURSED_BLINDFOLD;
  3046.  
  3047.      /*
  3048. @@ -274,6 +275,14 @@ worst_cursed_item()
  3049.  {
  3050.      register struct obj *otmp;
  3051.  
  3052. +    /* Infidels are immune to curses, but a cursed luckstone is still bad */
  3053. +    if (Role_if(PM_INFIDEL)) {
  3054. +        for (otmp = invent; otmp; otmp = otmp->nobj)
  3055. +            if (confers_luck(otmp) && otmp->cursed)
  3056. +                return otmp;
  3057. +        return (struct obj *) 0;
  3058. +    }
  3059. +
  3060.      /* if strained or worse, check for loadstone first */
  3061.      if (near_capacity() >= HVY_ENCUMBER) {
  3062.          for (otmp = invent; otmp; otmp = otmp->nobj)
  3063. @@ -452,7 +461,7 @@ int trouble;
  3064.              if (!Unchanging) {
  3065.                  Your("shape becomes uncertain.");
  3066.                  rehumanize(); /* "You return to {normal} form." */
  3067. -            } else if ((otmp = unchanger()) != 0 && otmp->cursed) {
  3068. +            } else if ((otmp = unchanger()) != 0 && cursed(otmp, TRUE)) {
  3069.                  /* otmp is an amulet of unchanging */
  3070.                  goto decurse;
  3071.              }
  3072. @@ -497,7 +506,7 @@ int trouble;
  3073.          if (otmp == uarmg && Glib) {
  3074.              make_glib(0);
  3075.              Your("%s are no longer slippery.", gloves_simple_name(uarmg));
  3076. -            if (!otmp->cursed)
  3077. +            if (!cursed(otmp, TRUE))
  3078.                  break;
  3079.          }
  3080.          if (!Blind || (otmp == ublindf && Blindfolded_only)) {
  3081. @@ -578,7 +587,7 @@ int trouble;
  3082.   * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
  3083.   * Divine wrath, dungeon walls, and armor follow the same principle.
  3084.   */
  3085. -STATIC_OVL void
  3086. +void
  3087.  god_zaps_you(resp_god)
  3088.  aligntyp resp_god;
  3089.  {
  3090. @@ -771,10 +780,13 @@ gcrownu()
  3091.  
  3092.      HSee_invisible |= FROMOUTSIDE;
  3093.      HFire_resistance |= FROMOUTSIDE;
  3094. -    HCold_resistance |= FROMOUTSIDE;
  3095. -    HShock_resistance |= FROMOUTSIDE;
  3096. -    HSleep_resistance |= FROMOUTSIDE;
  3097.      HPoison_resistance |= FROMOUTSIDE;
  3098. +    if (u.ualign.type != A_NONE) {
  3099. +        /* demons don't get all the intrinsics */
  3100. +        HCold_resistance |= FROMOUTSIDE;
  3101. +        HShock_resistance |= FROMOUTSIDE;
  3102. +        HSleep_resistance |= FROMOUTSIDE;
  3103. +    }
  3104.      godvoice(u.ualign.type, (char *) 0);
  3105.  
  3106.      class_gift = STRANGE_OBJECT;
  3107. @@ -815,6 +827,17 @@ gcrownu()
  3108.                     || class_gift != STRANGE_OBJECT) ? "take lives"
  3109.                    : "steal souls");
  3110.          break;
  3111. +    case A_NONE:
  3112. +        u.uevent.uhand_of_elbereth = 4;
  3113. +        verbalize("I grant thee the gift of Demonhood!");
  3114. +        class_gift = SPE_FIREBALL; /* no special weapon */
  3115. +        if (Upolyd)
  3116. +            rehumanize(); /* return to human/orcish form -- not a demon yet */
  3117. +        pline1("Wings sprout from your back and you grow a barbed tail!");
  3118. +        urace = race_demon;
  3119. +        set_uasmon();
  3120. +        retouch_equipment(2); /* silver */
  3121. +        break;
  3122.      }
  3123.  
  3124.      if (objects[class_gift].oc_class == SPBOOK_CLASS) {
  3125. @@ -892,6 +915,9 @@ gcrownu()
  3126.              discover_artifact(ART_STORMBRINGER);
  3127.          break;
  3128.      }
  3129. +    case A_NONE:
  3130. +        /* nothing to do */
  3131. +        break;
  3132.      default:
  3133.          obj = 0; /* lint */
  3134.          break;
  3135. @@ -1131,6 +1157,8 @@ aligntyp g_align;
  3136.                  You("are surrounded by %s aura.", an(hcolor(NH_LIGHT_BLUE)));
  3137.              for (otmp = invent; otmp; otmp = otmp->nobj) {
  3138.                  if (otmp->cursed
  3139. +                    /* Inf benefit from wearing cursed armor */
  3140. +                    && !(Role_if(PM_INFIDEL) && (otmp->owornmask & W_ARMOR))
  3141.                      && (otmp != uarmh /* [see worst_cursed_item()] */
  3142.                          || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)) {
  3143.                      if (!Blind) {
  3144. @@ -1259,7 +1287,7 @@ boolean bless_water;
  3145.      return (boolean) (changed > 0L);
  3146.  }
  3147.  
  3148. -STATIC_OVL void
  3149. +void
  3150.  godvoice(g_align, words)
  3151.  aligntyp g_align;
  3152.  const char *words;
  3153. @@ -1357,6 +1385,9 @@ dosacrifice()
  3154.      if (otmp->otyp == CORPSE) {
  3155.          register struct permonst *ptr = &mons[otmp->corpsenm];
  3156.          struct monst *mtmp;
  3157. +        /* is this a conversion attempt? */
  3158. +        boolean to_other_god =  ugod_is_angry() && !your_race(ptr)
  3159. +                                && u.ualign.type != altaralign;
  3160.  
  3161.          /* KMH, conduct */
  3162.          u.uconduct.gnostic++;
  3163. @@ -1367,29 +1398,45 @@ dosacrifice()
  3164.          if (rider_corpse_revival(otmp, FALSE))
  3165.              return 1;
  3166.  
  3167. -        if (otmp->corpsenm == PM_ACID_BLOB
  3168. +        if (otmp->corpsenm == PM_ACID_BLOB || your_race(ptr)
  3169.              || (monstermoves <= peek_at_iced_corpse_age(otmp) + 50)) {
  3170.              value = mons[otmp->corpsenm].difficulty + 1;
  3171. +            /* Not demons--no demon corpses */
  3172. +            if (is_undead(ptr) && u.ualign.type > A_CHAOTIC)
  3173. +                value += 1;
  3174. +            if (is_unicorn(ptr))
  3175. +                value += 3;
  3176. +            if (uwep && uwep->oartifact == ART_SECESPITA)
  3177. +                value += value / 2;
  3178.              if (otmp->oeaten)
  3179.                  value = eaten_stat(value, otmp);
  3180. +            /* even cross-aligned sacrifices will count,
  3181. +             * as long as they're ultimately to Moloch */
  3182. +            if (u.ualign.type == A_NONE && !to_other_god) {
  3183. +                long new_timeout = moves + value * 500;
  3184. +                if (context.next_moloch_offering < new_timeout)
  3185. +                    context.next_moloch_offering = new_timeout;
  3186. +            }
  3187.          }
  3188.  
  3189.          if (your_race(ptr)) {
  3190. -            if (is_demon(youmonst.data)) {
  3191. +            if (is_demon(raceptr(&youmonst))) {
  3192.                  You("find the idea very satisfying.");
  3193.                  exercise(A_WIS, TRUE);
  3194. -            } else if (u.ualign.type != A_CHAOTIC) {
  3195. +            } else if (u.ualign.type > A_CHAOTIC) {
  3196.                  pline("You'll regret this infamous offense!");
  3197.                  exercise(A_WIS, FALSE);
  3198.              }
  3199.  
  3200.              if (highaltar
  3201. -                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)) {
  3202. +                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)
  3203. +                && (altaralign != A_NONE || u.ualign.type != A_NONE)) {
  3204.                  goto desecrate_high_altar;
  3205.              } else if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
  3206.                  /* curse the lawful/neutral altar */
  3207.                  pline_The("altar is stained with %s blood.", urace.adj);
  3208. -                levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
  3209. +                levl[u.ux][u.uy].altarmask = u.ualign.type == A_NONE
  3210. +                                             ? AM_NONE : AM_CHAOTIC;
  3211.                  angry_priest();
  3212.              } else {
  3213.                  struct monst *dmon;
  3214. @@ -1409,7 +1456,7 @@ dosacrifice()
  3215.                  } else {
  3216.                      /* either you're chaotic or altar is Moloch's or both */
  3217.                      pline_The("blood covers the altar!");
  3218. -                    change_luck(altaralign == A_NONE ? -2 : 2);
  3219. +                    change_luck(altaralign == u.ualign.type ? 2 : -2);
  3220.                      demonless_msg = "blood coagulates";
  3221.                  }
  3222.                  if ((pm = dlord(altaralign)) != NON_PM
  3223. @@ -1433,7 +1480,7 @@ dosacrifice()
  3224.                      pline_The("%s.", demonless_msg);
  3225.              }
  3226.  
  3227. -            if (u.ualign.type != A_CHAOTIC) {
  3228. +            if (u.ualign.type > A_CHAOTIC) {
  3229.                  adjalign(-5);
  3230.                  u.ugangr += 3;
  3231.                  (void) adjattrib(A_WIS, -1, TRUE);
  3232. @@ -1449,17 +1496,17 @@ dosacrifice()
  3233.              return 1;
  3234.          } else if (has_omonst(otmp)
  3235.                     && (mtmp = get_mtraits(otmp, FALSE)) != 0
  3236. -                   && mtmp->mtame) {
  3237. +                   && mtmp->mtame
  3238. +                   /* Moloch is OK with sacrificing pets,
  3239. +                    * but make sure we're offering to him */
  3240. +                   && (u.ualign.type != A_NONE || to_other_god)) {
  3241.                  /* mtmp is a temporary pointer to a tame monster's attributes,
  3242.                   * not a real monster */
  3243.              pline("So this is how you repay loyalty?");
  3244.              adjalign(-3);
  3245.              value = -1;
  3246.              HAggravate_monster |= FROMOUTSIDE;
  3247. -        } else if (is_undead(ptr)) { /* Not demons--no demon corpses */
  3248. -            if (u.ualign.type != A_CHAOTIC)
  3249. -                value += 1;
  3250. -        } else if (is_unicorn(ptr)) {
  3251. +        } else if (is_unicorn(ptr) && value /* fresh */) {
  3252.              int unicalign = sgn(ptr->maligntyp);
  3253.  
  3254.              if (unicalign == altaralign) {
  3255. @@ -1479,7 +1526,7 @@ dosacrifice()
  3256.                  else
  3257.                      You_feel("you are thoroughly on the right path.");
  3258.                  adjalign(5);
  3259. -                value += 3;
  3260. +                /* value += 3; -- now applied above */
  3261.              } else if (unicalign == u.ualign.type) {
  3262.                  /* When sacrificing unicorn of your alignment to altar not of
  3263.                   * your alignment, your god gets angry and it's a conversion.
  3264. @@ -1491,7 +1538,7 @@ dosacrifice()
  3265.                   * and different from the altar's.  It's an ordinary (well,
  3266.                   * with a bonus) sacrifice on a cross-aligned altar.
  3267.                   */
  3268. -                value += 3;
  3269. +                /* value += 3; -- now applied above */
  3270.              }
  3271.          }
  3272.      } /* corpse */
  3273. @@ -1499,7 +1546,7 @@ dosacrifice()
  3274.      if (otmp->otyp == AMULET_OF_YENDOR) {
  3275.          if (!highaltar) {
  3276.   too_soon:
  3277. -            if (altaralign == A_NONE && Inhell)
  3278. +            if (altaralign == A_NONE && u.ualign.type != A_NONE && Inhell)
  3279.                  /* hero has left Moloch's Sanctum so is in the process
  3280.                     of getting away with the Amulet (outside of Gehennom,
  3281.                     fall through to the "ashamed" feedback) */
  3282. @@ -1510,7 +1557,9 @@ dosacrifice()
  3283.                              ? "homesick"
  3284.                              /* if on track, give a big hint */
  3285.                              : (altaralign == u.ualign.type)
  3286. -                               ? "an urge to return to the surface"
  3287. +                               ? (Role_if(PM_INFIDEL)
  3288. +                                  ? "an urge to descend deeper"
  3289. +                                  : "an urge to return to the surface")
  3290.                                 /* else headed towards celestial disgrace */
  3291.                                 : "ashamed");
  3292.              return 1;
  3293. @@ -1526,6 +1575,33 @@ dosacrifice()
  3294.              You("offer the Amulet of Yendor to %s...", a_gname());
  3295.              if (altaralign == A_NONE) {
  3296.                  /* Moloch's high altar */
  3297. +                if (Role_if(PM_INFIDEL)) {
  3298. +                    /* Infidels still have an ascension run,
  3299. +                     * they just carry a different McGuffin */
  3300. +                    u.uevent.ascended = 0;
  3301. +                    u.uachieve.amulet = 1;
  3302. +                    otmp = find_quest_artifact(1 << OBJ_INVENT);
  3303. +                    godvoice(A_NONE, (char *) 0);
  3304. +                    if (!otmp)
  3305. +                        qt_pager(QT_MOLOCH_1);
  3306. +                    else {
  3307. +                        qt_pager(QT_MOLOCH_2);
  3308. +                        if (otmp->where == OBJ_CONTAINED) {
  3309. +                            /* the Idol cannot be contained now,
  3310. +                             * so we have to remove it */
  3311. +                            obj_extract_self(otmp);
  3312. +                            (void) hold_another_object(otmp, "Oops!",
  3313. +                                                       (const char *) 0,
  3314. +                                                       (const char *) 0);
  3315. +                        }
  3316. +                        You_feel("strange energies envelop %s.",
  3317. +                                 the(xname(otmp)));
  3318. +                        otmp->spe = 1;
  3319. +                        if (otmp->where == OBJ_INVENT)
  3320. +                            u.uhave.amulet = 1;
  3321. +                    }
  3322. +                    return 1;
  3323. +                }
  3324.                  if (u.ualign.record > -99)
  3325.                      u.ualign.record = -99;
  3326.                  /*[apparently shrug/snarl can be sensed without being seen]*/
  3327. @@ -1582,8 +1658,10 @@ dosacrifice()
  3328.              if (Deaf)
  3329.                  pline("Oh, no."); /* didn't hear thunderclap */
  3330.              change_luck(-3);
  3331. -            adjalign(-1);
  3332. -            u.ugangr += 3;
  3333. +            if (u.ualign.type != A_NONE) {
  3334. +                adjalign(-1);
  3335. +                u.ugangr += 3;
  3336. +            }
  3337.              value = -3;
  3338.          }
  3339.      } /* fake Amulet */
  3340. @@ -1617,9 +1695,10 @@ dosacrifice()
  3341.          if (u.ualign.type != altaralign) {
  3342.              /* Is this a conversion ? */
  3343.              /* An unaligned altar in Gehennom will always elicit rejection. */
  3344. +            /* Infidels will also never be accepted. */
  3345.              if (ugod_is_angry() || (altaralign == A_NONE && Inhell)) {
  3346.                  if (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL]
  3347. -                    && altaralign != A_NONE) {
  3348. +                    && altaralign != A_NONE && !Role_if(PM_INFIDEL)) {
  3349.                      You("have a strong feeling that %s is angry...",
  3350.                          u_gname());
  3351.                      consume_offering(otmp);
  3352. @@ -1644,7 +1723,11 @@ dosacrifice()
  3353.                  consume_offering(otmp);
  3354.                  You("sense a conflict between %s and %s.", u_gname(),
  3355.                      a_gname());
  3356. -                if (rn2(8 + u.ulevel) > 5) {
  3357. +                if (rn2(8 + u.ulevel) > 5
  3358. +                    /* Infidels have difficulty converting altars. */
  3359. +                    && !(u.ualign.type == A_NONE
  3360. +                         && !(Role_if(PM_INFIDEL) && u.uhave.questart)
  3361. +                         && depth(&u.uz) < depth(&valley_level) && rn2(5))) {
  3362.                      struct monst *pri;
  3363.                      You_feel("the power of %s increase.", u_gname());
  3364.                      exercise(A_WIS, TRUE);
  3365. @@ -1659,9 +1742,11 @@ dosacrifice()
  3366.                          pline_The("altar glows %s.",
  3367.                                    hcolor((u.ualign.type == A_LAWFUL)
  3368.                                              ? NH_WHITE
  3369. -                                            : u.ualign.type
  3370. -                                               ? NH_BLACK
  3371. -                                               : (const char *) "gray"));
  3372. +                                            : u.ualign.type == A_NONE
  3373. +                                                ? NH_RED
  3374. +                                                : u.ualign.type
  3375. +                                                    ? NH_BLACK
  3376. +                                                    : (const char *) "gray"));
  3377.  
  3378.                      if (rnl(u.ulevel) > 6 && u.ualign.record > 0
  3379.                          && rnd(u.ualign.record) > (3 * ALIGNLIM) / 4)
  3380. @@ -1686,8 +1771,9 @@ dosacrifice()
  3381.          consume_offering(otmp);
  3382.          /* OK, you get brownie points. */
  3383.          if (u.ugangr) {
  3384. -            u.ugangr -= ((value * (u.ualign.type == A_CHAOTIC ? 2 : 3))
  3385. -                         / MAXVALUE);
  3386. +            u.ugangr -= ((value * (u.ualign.type == A_NONE ? 3
  3387. +                                   : u.ualign.type == A_CHAOTIC ? 4 : 6))
  3388. +                         / (MAXVALUE * 2));
  3389.              if (u.ugangr < 0)
  3390.                  u.ugangr = 0;
  3391.              if (u.ugangr != saved_anger) {
  3392. @@ -1719,7 +1805,7 @@ dosacrifice()
  3393.              adjalign(value);
  3394.              You_feel("partially absolved.");
  3395.          } else if (u.ublesscnt > 0) {
  3396. -            u.ublesscnt -= ((value * (u.ualign.type == A_CHAOTIC ? 500 : 300))
  3397. +            u.ublesscnt -= ((value * (u.ualign.type <= A_CHAOTIC ? 500 : 300))
  3398.                              / MAXVALUE);
  3399.              if (u.ublesscnt < 0)
  3400.                  u.ublesscnt = 0;
  3401. @@ -1799,7 +1885,7 @@ boolean praying; /* false means no messages should be given */
  3402.      p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type;
  3403.      p_trouble = in_trouble();
  3404.  
  3405. -    if (is_demon(youmonst.data) && (p_aligntyp != A_CHAOTIC)) {
  3406. +    if (is_demon(raceptr(&youmonst)) && (p_aligntyp > A_CHAOTIC)) {
  3407.          if (praying)
  3408.              pline_The("very idea of praying to a %s god is repugnant to you.",
  3409.                        p_aligntyp ? "lawful" : "neutral");
  3410. @@ -1830,13 +1916,16 @@ boolean praying; /* false means no messages should be given */
  3411.      }
  3412.  
  3413.      if (is_undead(youmonst.data) && !Inhell
  3414. -        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && !rn2(10))))
  3415. +        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && praying
  3416. +                                       && !rn2(10))))
  3417.          p_type = -1;
  3418. -    /* Note:  when !praying, the random factor for neutrals makes the
  3419. -       return value a non-deterministic approximation for enlightenment.
  3420. -       This case should be uncommon enough to live with... */
  3421.  
  3422. -    return !praying ? (boolean) (p_type == 3 && !Inhell) : TRUE;
  3423. +    if (p_aligntyp == A_NONE && !on_altar()
  3424. +        && depth(&u.uz) < depth(&valley_level)
  3425. +        && !(Role_if(PM_INFIDEL) && u.uhave.questart) && praying && rn2(5))
  3426. +        p_type = -2; /* Moloch can't hear you */
  3427. +
  3428. +    return praying || p_type == 3 && (!Inhell || u.ualign.type == A_NONE);
  3429.  }
  3430.  
  3431.  /* #pray commmand */
  3432. @@ -1870,7 +1959,7 @@ dopray()
  3433.      nomovemsg = "You finish your prayer.";
  3434.      afternmv = prayer_done;
  3435.  
  3436. -    if (p_type == 3 && !Inhell) {
  3437. +    if (p_type == 3 && (!Inhell || u.ualign.type == A_NONE)) {
  3438.          /* if you've been true to your god you can't die while you pray */
  3439.          if (!Blind)
  3440.              You("are surrounded by a shimmering light.");
  3441. @@ -1899,7 +1988,13 @@ prayer_done() /* M. Stephenson (1.0.3b) */
  3442.          exercise(A_CON, FALSE);
  3443.          return 1;
  3444.      }
  3445. -    if (Inhell) {
  3446. +    if (p_type == -2) {
  3447. +        pline("Unfortunately, this close to the surface %s can't hear you.",
  3448. +              align_gname(alignment));
  3449. +        /* no further effects */
  3450. +        return 0;
  3451. +    }
  3452. +    if (Inhell && u.ualign.type != A_NONE) {
  3453.          pline("Since you are in Gehennom, %s can't help you.",
  3454.                align_gname(alignment));
  3455.          /* haltingly aligned is least likely to anger */
  3456. @@ -1977,7 +2072,7 @@ doturn()
  3457.          return (u.uconduct.gnostic == 1);
  3458.      }
  3459.      if ((u.ualign.type != A_CHAOTIC
  3460. -         && (is_demon(youmonst.data) || is_undead(youmonst.data)))
  3461. +         && (is_demon(raceptr(&youmonst)) || is_undead(youmonst.data)))
  3462.          || u.ugangr > 6) { /* "Die, mortal!" */
  3463.          pline("For some reason, %s seems to ignore you.", Gname);
  3464.          aggravate();
  3465. @@ -2211,6 +2306,9 @@ aligntyp alignment;
  3466.      const char *gnam, *result = "god";
  3467.  
  3468.      switch (alignment) {
  3469. +    case A_NONE:
  3470. +        gnam = Moloch;
  3471. +        break;
  3472.      case A_LAWFUL:
  3473.          gnam = urole.lgod;
  3474.          break;
  3475. @@ -2229,6 +2327,23 @@ aligntyp alignment;
  3476.      return result;
  3477.  }
  3478.  
  3479. +/* return an alignment from a (lawful, neutral, chaotic) permutation
  3480. + * randomly chosen at game start; only relevant to Infidels */
  3481. +aligntyp
  3482. +inf_align(num)
  3483. +int num; /* 1..3 */
  3484. +{
  3485. +    aligntyp first, other;
  3486. +    first = context.inf_aligns % 3 - 1;
  3487. +    if (num == 1)
  3488. +        return first;
  3489. +    other = (context.inf_aligns + num) % 2;
  3490. +    if (other <= first)
  3491. +        other--;
  3492. +    return other;
  3493. +
  3494. +}
  3495. +
  3496.  void
  3497.  altar_wrath(x, y)
  3498.  register int x, y;
  3499. diff --git c/src/priest.c w/src/priest.c
  3500. index ab20a8d..92700f3 100644
  3501. --- c/src/priest.c
  3502. +++ w/src/priest.c
  3503. @@ -4,6 +4,7 @@
  3504.  
  3505.  #include "hack.h"
  3506.  #include "mfndpos.h"
  3507. +#include "qtext.h"
  3508.  
  3509.  /* these match the categorizations shown by enlightenment */
  3510.  #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
  3511. @@ -253,7 +254,7 @@ boolean sanctum; /* is it the seat of the high priest? */
  3512.  
  3513.          /* now his/her goodies... */
  3514.          if (sanctum && EPRI(priest)->shralign == A_NONE
  3515. -            && on_level(&sanctum_level, &u.uz)) {
  3516. +            && on_level(&sanctum_level, &u.uz) && !Role_if(PM_INFIDEL)) {
  3517.              (void) mongets(priest, AMULET_OF_YENDOR);
  3518.          }
  3519.          /* 2 to 4 spellbooks */
  3520. @@ -391,7 +392,7 @@ int roomno;
  3521.  {
  3522.      struct monst *priest, *mtmp;
  3523.      struct epri *epri_p;
  3524. -    boolean shrined, sanctum, can_speak;
  3525. +    boolean shrined, sanctum, can_speak, call_guards;
  3526.      long *this_time, *other_time;
  3527.      const char *msg1, *msg2;
  3528.      char buf[BUFSZ];
  3529. @@ -408,6 +409,7 @@ int roomno;
  3530.          sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
  3531.                     && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  3532.          can_speak = (priest->mcanmove && !priest->msleeping);
  3533. +        call_guards = FALSE;
  3534.          if (can_speak && !Deaf && moves >= epri_p->intone_time) {
  3535.              unsigned save_priest = priest->ispriest;
  3536.  
  3537. @@ -425,11 +427,20 @@ int roomno;
  3538.              epri_p->enter_time = 0L;
  3539.          }
  3540.          msg1 = msg2 = 0;
  3541. -        if (sanctum && Is_sanctum(&u.uz)) {
  3542. +        if ((sanctum && Is_sanctum(&u.uz) || u.ualign.type == A_NONE)
  3543. +            && !p_coaligned(priest)) {
  3544. +            /* either a non-Infidel in the Sanctum, or an Infidel in any
  3545. +             * non-Moloch temple; either way, the priest is not happy */
  3546.              if (priest->mpeaceful) {
  3547.                  /* first time inside */
  3548. -                msg1 = "Infidel, you have entered Moloch's Sanctum!";
  3549. -                msg2 = "Be gone!";
  3550. +                if (u.ualign.type == A_NONE) {
  3551. +                    msg1 = "Begone, infidel!";
  3552. +                    msg2 = "This place is barred for your cult!";
  3553. +                    call_guards = in_town(priest->mx, priest->my);
  3554. +                } else {
  3555. +                    msg1 = "Infidel, you have entered Moloch's Sanctum!";
  3556. +                    msg2 = "Be gone!";
  3557. +                }
  3558.                  priest->mpeaceful = 0;
  3559.                  /* became angry voluntarily; no penalty for attacking him */
  3560.                  set_malign(priest);
  3561. @@ -448,6 +459,11 @@ int roomno;
  3562.                  verbalize1(msg2);
  3563.              epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
  3564.          }
  3565. +        /* for Infidels, visiting the Minetown temple is a very bad idea */
  3566. +        if (call_guards) {
  3567. +            pline("%s calls for guards!", Monnam(priest));
  3568. +            (void) angry_guards(FALSE);
  3569. +        }
  3570.          if (!sanctum) {
  3571.              if (!shrined || !p_coaligned(priest)
  3572.                  || u.ualign.record <= ALGN_SINNED) {
  3573. @@ -549,7 +565,8 @@ register struct monst *priest;
  3574.  
  3575.      /* priests don't chat unless peaceful and in their own temple */
  3576.      if (!inhistemple(priest) || !priest->mpeaceful
  3577. -        || !priest->mcanmove || priest->msleeping) {
  3578. +        || !priest->mcanmove || priest->msleeping
  3579. +        || u.ualign.type == A_NONE && !coaligned) {
  3580.          static const char *cranky_msg[3] = {
  3581.              "Thou wouldst have words, eh?  I'll give thee a word or two!",
  3582.              "Talk?  Here is what I have to say!",
  3583. @@ -576,7 +593,15 @@ register struct monst *priest;
  3584.          return;
  3585.      }
  3586.      if (!money_cnt(invent)) {
  3587. -        if (coaligned && !strayed) {
  3588. +        if (Role_if(PM_INFIDEL) && u.uachieve.amulet
  3589. +            && priest->data == &mons[PM_HIGH_PRIEST] && Is_sanctum(&u.uz)) {
  3590. +            /* give a hint about the correct high altar */
  3591. +            aligntyp saved_align = u.ualignbase[A_ORIGINAL];
  3592. +            /* a hack for displaying a different god's name in the message */
  3593. +            u.ualignbase[A_ORIGINAL] = inf_align(3);
  3594. +            qt_pager(QT_MOLOCH_3);
  3595. +            u.ualignbase[A_ORIGINAL] = saved_align;
  3596. +        } else if (coaligned && !strayed) {
  3597.              long pmoney = money_cnt(priest->minvent);
  3598.              if (pmoney > 0L) {
  3599.                  /* Note: two bits is actually 25 cents.  Hmm. */
  3600. diff --git c/src/quest.c w/src/quest.c
  3601. index df4b831..6dcc687 100644
  3602. --- c/src/quest.c
  3603. +++ w/src/quest.c
  3604. @@ -219,9 +219,17 @@ finish_quest(obj)
  3605.  struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
  3606.  {
  3607.      struct obj *otmp;
  3608. +    aligntyp saved_align;
  3609.  
  3610. -    if (u.uhave.amulet) { /* unlikely but not impossible */
  3611. -        qt_pager(QT_HASAMULET);
  3612. +    if (u.uachieve.amulet) { /* unlikely but not impossible */
  3613. +        if (Role_if(PM_INFIDEL)) {
  3614. +            saved_align = u.ualignbase[A_ORIGINAL];
  3615. +            /* a hack for displaying a different god's name in the message */
  3616. +            u.ualignbase[A_ORIGINAL] = inf_align(2);
  3617. +            qt_pager(QT_HASAMULET);
  3618. +            u.ualignbase[A_ORIGINAL] = saved_align;
  3619. +        } else
  3620. +            qt_pager(QT_HASAMULET);
  3621.          /* leader IDs the real amulet but ignores any fakes */
  3622.          if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
  3623.              fully_identify_obj(otmp);
  3624. @@ -255,7 +263,7 @@ chat_with_leader()
  3625.       */
  3626.      if (Qstat(got_thanks)) {
  3627.          /* Rule 1: You've gone back with/without the amulet. */
  3628. -        if (u.uhave.amulet)
  3629. +        if (u.uachieve.amulet)
  3630.              finish_quest((struct obj *) 0);
  3631.  
  3632.          /* Rule 2: You've gone back before going for the amulet. */
  3633. diff --git c/src/questpgr.c w/src/questpgr.c
  3634. index 5c04c6c..3bd8b65 100644
  3635. --- c/src/questpgr.c
  3636. +++ w/src/questpgr.c
  3637. @@ -599,7 +599,7 @@ void
  3638.  com_pager(msgnum)
  3639.  int msgnum;
  3640.  {
  3641. -    struct qtmsg *qt_msg;
  3642. +    struct qtmsg *qt_msg, *alt_qt_msg;
  3643.  
  3644.      if (skip_pager(TRUE))
  3645.          return;
  3646. @@ -609,6 +609,10 @@ int msgnum;
  3647.          return;
  3648.      }
  3649.  
  3650. +    /* optional alternate game start message; currently only Inf use it */
  3651. +    if (msgnum == 1 && (alt_qt_msg = msg_in(qt_list.chrole, QT_ALTSTART)))
  3652. +        qt_msg = alt_qt_msg;
  3653. +
  3654.      (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
  3655.      if (qt_msg->delivery == 'p')
  3656.          deliver_by_pline(qt_msg);
  3657. diff --git c/src/read.c w/src/read.c
  3658. index aaa3341..f3bc78a 100644
  3659. --- c/src/read.c
  3660. +++ w/src/read.c
  3661. @@ -1118,6 +1118,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
  3662.                  uncurse(otmp);
  3663.              otmp->known = 1;
  3664.              setworn(otmp, W_ARM);
  3665. +            check_wings(TRUE);
  3666.              if (otmp->unpaid)
  3667.                  alter_cost(otmp, 0L); /* shop bill */
  3668.              break;
  3669. @@ -2150,7 +2151,9 @@ do_class_genocide()
  3670.                          /* non-leader/nemesis/guardian role-specific monster
  3671.                             */
  3672.                          && (i != PM_NINJA /* nuisance */
  3673. -                            || Role_if(PM_SAMURAI))) {
  3674. +                            || Role_if(PM_SAMURAI))
  3675. +                        && (i != PM_TEMPLAR && i != PM_CHAMPION
  3676. +                            && i != PM_AGENT || Role_if(PM_INFIDEL))) {
  3677.                          boolean named, uniq;
  3678.  
  3679.                          named = type_is_pname(&mons[i]) ? TRUE : FALSE;
  3680. diff --git c/src/restore.c w/src/restore.c
  3681. index 8c8703b..db63e00 100644
  3682. --- c/src/restore.c
  3683. +++ w/src/restore.c
  3684. @@ -596,11 +596,11 @@ unsigned int *stuckid, *steedid;
  3685.      mread(fd, (genericptr_t) &sysflags, sizeof(struct sysflag));
  3686.  #endif
  3687.  
  3688. -    role_init(); /* Reset the initial role, race, gender, and alignment */
  3689.  #ifdef AMII_GRAPHICS
  3690.      amii_setpens(amii_numcolors); /* use colors from save file */
  3691.  #endif
  3692.      mread(fd, (genericptr_t) &u, sizeof(struct you));
  3693. +    role_init(); /* Reset the initial role, race, gender, and alignment */
  3694.  
  3695.  #define ReadTimebuf(foo)                   \
  3696.      mread(fd, (genericptr_t) timebuf, 14); \
  3697. diff --git c/src/role.c w/src/role.c
  3698. index f263609..394bf23 100644
  3699. --- c/src/role.c
  3700. +++ w/src/role.c
  3701. @@ -192,6 +192,47 @@ const struct Role roles[] = {
  3702.        A_WIS,
  3703.        SPE_CURE_SICKNESS,
  3704.        -4 },
  3705. +    { { "Infidel", 0 },
  3706. +      { { "Apostate", 0 },
  3707. +        { "Heathen", 0 },
  3708. +        { "Heretic", 0 },
  3709. +        { "Idolater", "Idolatress" },
  3710. +        { "Cultist", 0 },
  3711. +        { "Splanchomancer", 0 },
  3712. +        { "Maleficus", "Malefica" },
  3713. +        { "Demonologist", 0 },
  3714. +        { "Heresiarch", 0 } },
  3715. +      0, 0, 0, /* uses a random role's pantheon */
  3716. +      "Inf",
  3717. +      "the Hidden Temple",
  3718. +      "the Howling Forest",
  3719. +      PM_INFIDEL,
  3720. +      NON_PM,
  3721. +      PM_HOMUNCULUS,
  3722. +      PM_PREACHER_OF_MOLOCH,
  3723. +      PM_CULTIST,
  3724. +      PM_PALADIN,
  3725. +      PM_AGENT,
  3726. +      PM_CHAMPION,
  3727. +      S_DOG,
  3728. +      S_UNICORN,
  3729. +      ART_IDOL_OF_MOLOCH,                         /* actually unaligned */
  3730. +      MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
  3731. +      /* Str Int Wis Dex Con Cha */
  3732. +      { 7, 7, 10, 7, 7, 7 },
  3733. +      { 20, 10, 25, 15, 20, 10 },
  3734. +      /* Init   Lower  Higher */
  3735. +      { 10, 0, 0, 8, 1, 0 }, /* Hit points */
  3736. +      { 4, 3, 0, 1, 0, 2 },
  3737. +      10, /* Energy */
  3738. +      10,
  3739. +      3,
  3740. +      1,
  3741. +      2,
  3742. +      10,
  3743. +      A_WIS,
  3744. +      SPE_FIREBALL,
  3745. +      -4 },
  3746.      { { "Knight", 0 },
  3747.        { { "Gallant", 0 },
  3748.          { "Esquire", 0 },
  3749. @@ -725,6 +766,29 @@ const struct Race races[] = {
  3750.      { 0, 0, 0, 0 }
  3751.  };
  3752.  
  3753. +/* Special race for crowned Infidels. */
  3754. +struct Race race_demon = {
  3755. +    "demon",
  3756. +    "demonic",
  3757. +    "demonkind",
  3758. +    "Dem",
  3759. +    { 0, 0 },
  3760. +    PM_DEMON,
  3761. +    NON_PM,
  3762. +    NON_PM,
  3763. +    NON_PM,
  3764. +    MH_DEMON | ROLE_MALE | ROLE_FEMALE, /* not available at start */
  3765. +    MH_DEMON,
  3766. +    MH_DEMON,
  3767. +    MH_HUMAN | MH_ELF | MH_DWARF | MH_GNOME,
  3768. +    /*  Str    Int Wis Dex Con Cha */
  3769. +    { 3, 3, 3, 3, 3, 3 },
  3770. +    { STR18(100), 18, 18, 20, 20, 18 },
  3771. +    /* Init   Lower  Higher */
  3772. +    { 8, 0, 0, 8, 4, 0 }, /* Hit points */
  3773. +    { 4, 0, 6, 0, 6, 0 }  /* Energy */
  3774. +};
  3775. +
  3776.  /* The player's race, created at runtime from initial
  3777.   * choices.  This may be munged in role_init().
  3778.   */
  3779. @@ -779,6 +843,16 @@ STATIC_DCL int FDECL(race_alignmentcount, (int));
  3780.  /* used by str2XXX() */
  3781.  static char NEARDATA randomstr[] = "random";
  3782.  
  3783. +/* Inf are listed as chaotic above, but actually are unaligned. */
  3784. +int
  3785. +special_alignment(rolenum, alignnum)
  3786. +int rolenum, alignnum;
  3787. +{
  3788. +    if (roles[rolenum].malenum == PM_INFIDEL)
  3789. +        return 3; /* aligns[unaligned] */
  3790. +    return alignnum;
  3791. +}
  3792. +
  3793.  boolean
  3794.  validrole(rolenum)
  3795.  int rolenum;
  3796. @@ -1503,12 +1577,12 @@ int buflen, rolenum, racenum, gendnum, alignnum;
  3797.          if ((racenum >= 0) && (aligncount > 1)) {
  3798.              if (donefirst)
  3799.                  Strcat(buf, " ");
  3800. -            Strcat(buf, aligns[alignnum].adj);
  3801. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  3802.              donefirst = TRUE;
  3803.          } else {
  3804.              if (donefirst)
  3805.                  Strcat(buf, " ");
  3806. -            Strcat(buf, aligns[alignnum].adj);
  3807. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  3808.              donefirst = TRUE;
  3809.          }
  3810.      } else {
  3811. @@ -1800,6 +1874,7 @@ winid where;
  3812.              a = 2; /* alings[chaotic] */
  3813.          /* [c never forces gender] */
  3814.      }
  3815. +    a = special_alignment(r, a); /* special case (Infidel) */
  3816.      /* [g and a don't constrain anything sufficiently
  3817.         to narrow something done to a single choice] */
  3818.  
  3819. @@ -1935,6 +2010,7 @@ boolean preselect;
  3820.                  a = 1; /* aligns[neutral] */
  3821.              else if (allowmask == AM_CHAOTIC)
  3822.                  a = 2; /* aligns[chaotic] */
  3823. +            a = special_alignment(r, a); /* special case (Infidel) */
  3824.              if (a >= 0)
  3825.                  constrainer = "role";
  3826.          }
  3827. @@ -2010,7 +2086,7 @@ boolean preselect;
  3828.  void
  3829.  role_init()
  3830.  {
  3831. -    int alignmnt;
  3832. +    int alignmnt, malignmnt;
  3833.      struct permonst *pm;
  3834.  
  3835.      /* Strip the role letter out of the player name.
  3836. @@ -2049,11 +2125,18 @@ role_init()
  3837.      if (!validalign(flags.initrole, flags.initrace, flags.initalign))
  3838.          /* Pick a random alignment */
  3839.          flags.initalign = randalign(flags.initrole, flags.initrace);
  3840. -    alignmnt = aligns[flags.initalign].value;
  3841. +    /* Infidels are actually unaligned */
  3842. +    flags.initalign = special_alignment(flags.initrole, flags.initalign);
  3843. +    alignmnt = malignmnt = aligns[flags.initalign].value;
  3844. +    if (alignmnt != A_NONE)
  3845. +        malignmnt *= 3;
  3846.  
  3847.      /* Initialize urole and urace */
  3848.      urole = roles[flags.initrole];
  3849. -    urace = races[flags.initrace];
  3850. +    if (u.uevent.uhand_of_elbereth == 4) /* crowned as a demon */
  3851. +        urace = race_demon;
  3852. +    else
  3853. +        urace = races[flags.initrace];
  3854.  
  3855.      /* Fix up the quest leader */
  3856.      if (urole.ldrnum != NON_PM) {
  3857. @@ -2061,7 +2144,7 @@ role_init()
  3858.          pm->msound = MS_LEADER;
  3859.          pm->mflags2 |= (M2_PEACEFUL);
  3860.          pm->mflags3 |= M3_CLOSE;
  3861. -        pm->maligntyp = alignmnt * 3;
  3862. +        pm->maligntyp = malignmnt;
  3863.          /* if gender is random, we choose it now instead of waiting
  3864.             until the leader monster is created */
  3865.          quest_status.ldrgend =
  3866. @@ -2074,7 +2157,7 @@ role_init()
  3867.      if (urole.guardnum != NON_PM) {
  3868.          pm = &mons[urole.guardnum];
  3869.          pm->mflags2 |= (M2_PEACEFUL);
  3870. -        pm->maligntyp = alignmnt * 3;
  3871. +        pm->maligntyp = malignmnt;
  3872.      }
  3873.  
  3874.      /* Fix up the quest nemesis */
  3875. @@ -2091,6 +2174,14 @@ role_init()
  3876.                                     : is_male(pm) ? 0 : (rn2(100) < 50);
  3877.      }
  3878.  
  3879. +    /* Enable special Inf enemies */
  3880. +    if (Role_if(PM_INFIDEL)) {
  3881. +        if (urole.enemy1num != NON_PM)
  3882. +            mons[urole.enemy1num].geno &= ~G_NOGEN;
  3883. +        if (urole.enemy2num != NON_PM)
  3884. +            mons[urole.enemy2num].geno &= ~G_NOGEN;
  3885. +    }
  3886. +
  3887.      /* Fix up the god names */
  3888.      if (flags.pantheon == -1) {             /* new game */
  3889.          flags.pantheon = flags.initrole;    /* use own gods */
  3890. diff --git c/src/shk.c w/src/shk.c
  3891. index 6772da4..91c75f8 100644
  3892. --- c/src/shk.c
  3893. +++ w/src/shk.c
  3894. @@ -4776,7 +4776,7 @@ boolean altusage; /* used as a verbalized exclamation:  \"Cad! ...\" */
  3895.  {
  3896.      const char *res = 0;
  3897.  
  3898. -    switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
  3899. +    switch (is_demon(raceptr(&youmonst)) ? 3 : poly_gender()) {
  3900.      case 0:
  3901.          res = "cad";
  3902.          break;
  3903. diff --git c/src/sp_lev.c w/src/sp_lev.c
  3904. index 2c5628f..4817839 100644
  3905. --- c/src/sp_lev.c
  3906. +++ w/src/sp_lev.c
  3907. @@ -1624,6 +1624,14 @@ struct mkroom *croom;
  3908.          && (Race_if(PM_DWARF) || Race_if(PM_GNOME)) && rn2(3))
  3909.          pm = (struct permonst *) 0;
  3910.  
  3911. +    /* Make Sanctum monsters more friendly to Infidels */
  3912. +    if (u.ualign.type == A_NONE && Is_sanctum(&u.uz) && m->peaceful == 0)
  3913. +        m->peaceful = 1;
  3914. +    /* OTOH, the Astral shouldn't be easy; but the multitude of
  3915. +     * renegade minions of Moloch is still silly */
  3916. +    if (Role_if(PM_INFIDEL) && Is_astralevel(&u.uz) && amask == AM_NONE)
  3917. +        amask = Align2amask(rn1(3, -1));
  3918. +
  3919.      if (pm) {
  3920.          int loc = pm_to_humidity(pm);
  3921.          /* If water-liking monster, first try is without DRY */
  3922. diff --git c/src/spell.c w/src/spell.c
  3923. index 9cbb9a4..1981718 100644
  3924. --- c/src/spell.c
  3925. +++ w/src/spell.c
  3926. @@ -54,6 +54,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  3927.   *      Bar abhor magic (Conan finds it "interferes with his animal instincts")
  3928.   *      Cav are ignorant to magic
  3929.   *      Hea are very aware of healing magic through medical research
  3930. + *      Inf learned a lot of black magic from their cult
  3931.   *      Kni are moderately aware of healing from Paladin training
  3932.   *      Mon use magic to attack and defend in lieu of weapons and armor
  3933.   *      Pri are very aware of healing magic through theological research
  3934. @@ -74,6 +75,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  3935.   *      Bar fugue/berserker (SPE_HASTE_SELF)
  3936.   *      Cav born to dig (SPE_DIG)
  3937.   *      Hea to heal (SPE_CURE_SICKNESS)
  3938. + *      Inf to channel hellfire (SPE_FIREBALL)
  3939.   *      Kni to turn back evil (SPE_TURN_UNDEAD)
  3940.   *      Mon to preserve their abilities (SPE_RESTORE_ABILITY)
  3941.   *      Pri to bless (SPE_REMOVE_CURSE)
  3942. @@ -1741,6 +1743,25 @@ int spell;
  3943.      if (uarmf && is_metallic(uarmf))
  3944.          splcaster += uarmfbon;
  3945.  
  3946. +    /* Infidels have a special penalty for wearing blessed armor. */
  3947. +    if (Role_if(PM_INFIDEL)) {
  3948. +        static struct obj **const armor[] = { &uarm, &uarmc, &uarmh, &uarms,
  3949. +                                              &uarmg, &uarmf, &uarmu };
  3950. +        int penalty = 0;
  3951. +        int i;
  3952. +
  3953. +        for (i = 0; i < SIZE(armor); i++) {
  3954. +            if (!*armor[i])
  3955. +                continue;
  3956. +            if ((*armor[i])->blessed)
  3957. +                penalty += 2;
  3958. +            else if ((*armor[i])->cursed)
  3959. +                penalty--;
  3960. +        }
  3961. +        if (penalty > 0)
  3962. +            splcaster += penalty;
  3963. +    }
  3964. +
  3965.      if (spellid(spell) == urole.spelspec)
  3966.          splcaster += urole.spelsbon;
  3967.  
  3968. diff --git c/src/teleport.c w/src/teleport.c
  3969. index 23af60a..27a86cd 100644
  3970. --- c/src/teleport.c
  3971. +++ w/src/teleport.c
  3972. @@ -842,12 +842,25 @@ level_tele()
  3973.  
  3974.                  newlevel.dnum = destdnum;
  3975.                  newlevel.dlevel = destlev;
  3976. -                if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
  3977. +                if (In_endgame(&newlevel) && !In_endgame(&u.uz)
  3978. +                    && !u.uhave.amulet) {
  3979.                      struct obj *amu;
  3980.  
  3981. -                    if (!u.uhave.amulet
  3982. -                        && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
  3983. -                               != 0) {
  3984. +                    if (!Role_if(PM_INFIDEL)) {
  3985. +                        amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE);
  3986. +                    } else if (amu = find_quest_artifact(1 << OBJ_INVENT)) {
  3987. +                        obj_extract_self(amu); /* may be contained */
  3988. +                        amu->spe = 1;
  3989. +                    } else {
  3990. +                        const char *idol = artiname(ART_IDOL_OF_MOLOCH);
  3991. +                        amu = mksobj(FIGURINE, TRUE, FALSE);
  3992. +                        artifact_exists(amu, idol, TRUE);
  3993. +                        new_oname(amu, strlen(idol) + 1);
  3994. +                        Strcpy(ONAME(amu), idol);
  3995. +                        amu->spe = 1;
  3996. +                    }
  3997. +
  3998. +                    if (amu) {
  3999.                          /* ordinarily we'd use hold_another_object()
  4000.                             for something like this, but we don't want
  4001.                             fumbling or already full pack to interfere */
  4002. diff --git c/src/u_init.c w/src/u_init.c
  4003. index 77e7445..f19db59 100644
  4004. --- c/src/u_init.c
  4005. +++ w/src/u_init.c
  4006. @@ -21,6 +21,7 @@ STATIC_DCL boolean FDECL(restricted_spell_discipline, (int));
  4007.  #define UNDEF_TYP 0
  4008.  #define UNDEF_SPE '\177'
  4009.  #define UNDEF_BLESS 2
  4010. +#define CURSED 3
  4011.  
  4012.  /*
  4013.   *      Initial inventory for the various roles.
  4014. @@ -70,6 +71,19 @@ static struct trobj Healer[] = {
  4015.      { APPLE, 0, FOOD_CLASS, 5, 0 },
  4016.      { 0, 0, 0, 0, 0 }
  4017.  };
  4018. +static struct trobj Infidel[] = {
  4019. +    { AMULET_OF_YENDOR, 0, AMULET_CLASS, 1, 0 },
  4020. +    { DAGGER, 1, WEAPON_CLASS, 1, 0 },
  4021. +    { LEATHER_JACKET, 1, ARMOR_CLASS, 1, CURSED },
  4022. +    { CLOAK_OF_PROTECTION, 0, ARMOR_CLASS, 1, CURSED },
  4023. +    { POT_WATER, 0, POTION_CLASS, 3, CURSED },
  4024. +    { SPE_DRAIN_LIFE, 0, SPBOOK_CLASS, 1, 0 },
  4025. +    { UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, 0 },
  4026. +    { FIRE_HORN, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  4027. +    { MAGIC_MARKER, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  4028. +    { 0, 0, 0, 0, 0 }
  4029. +
  4030. +};
  4031.  static struct trobj Knight[] = {
  4032.      { LONG_SWORD, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  4033.      { LANCE, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  4034. @@ -324,6 +338,30 @@ static const struct def_skill Skill_H[] = {
  4035.      { P_BARE_HANDED_COMBAT, P_BASIC },
  4036.      { P_NONE, 0 }
  4037.  };
  4038. +static const struct def_skill Skill_Inf[] = {
  4039. +    { P_DAGGER, P_EXPERT },
  4040. +    { P_KNIFE, P_EXPERT },
  4041. +    { P_SHORT_SWORD, P_SKILLED },
  4042. +    { P_BROAD_SWORD, P_BASIC },
  4043. +    { P_SCIMITAR, P_SKILLED },
  4044. +    { P_SABER, P_BASIC },
  4045. +    { P_CLUB, P_BASIC },
  4046. +    { P_HAMMER, P_BASIC },
  4047. +    { P_QUARTERSTAFF, P_SKILLED },
  4048. +    { P_POLEARMS, P_SKILLED },
  4049. +    { P_SPEAR, P_BASIC },
  4050. +    { P_SLING, P_BASIC },
  4051. +    { P_CROSSBOW, P_SKILLED },
  4052. +    { P_DART, P_BASIC },
  4053. +    { P_WHIP, P_SKILLED },
  4054. +    { P_ATTACK_SPELL, P_EXPERT },
  4055. +    { P_DIVINATION_SPELL, P_SKILLED },
  4056. +    { P_ENCHANTMENT_SPELL, P_BASIC },
  4057. +    { P_CLERIC_SPELL, P_EXPERT },
  4058. +    { P_BARE_HANDED_COMBAT, P_SKILLED },
  4059. +    { P_RIDING, P_SKILLED },
  4060. +    { P_NONE, 0 }
  4061. +};
  4062.  static const struct def_skill Skill_K[] = {
  4063.      { P_DAGGER, P_BASIC },
  4064.      { P_KNIFE, P_BASIC },
  4065. @@ -701,6 +739,12 @@ u_init()
  4066.          knows_object(POT_FULL_HEALING);
  4067.          skill_init(Skill_H);
  4068.          break;
  4069. +    case PM_INFIDEL:
  4070. +        u.umoney0 = rn1(251, 250);
  4071. +        ini_inv(Infidel);
  4072. +        knows_object(SCR_CHARGING); /* that's what the marker is for */
  4073. +        skill_init(Skill_Inf);
  4074. +        break;
  4075.      case PM_KNIGHT:
  4076.          ini_inv(Knight);
  4077.          knows_class(WEAPON_CLASS);
  4078. @@ -927,6 +971,9 @@ int otyp;
  4079.      case PM_HEALER:
  4080.          skills = Skill_H;
  4081.          break;
  4082. +    case PM_INFIDEL:
  4083. +        skills = Skill_Inf;
  4084. +        break;
  4085.      case PM_KNIGHT:
  4086.          skills = Skill_K;
  4087.          break;
  4088. @@ -1014,6 +1061,8 @@ register struct trobj *trop;
  4089.                     || (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
  4090.                     /* wizard patch -- they already have one */
  4091.                     || (otyp == SPE_FORCE_BOLT && Role_if(PM_WIZARD))
  4092. +                   /* same for infidels */
  4093. +                   || (otyp == SPE_DRAIN_LIFE && Role_if(PM_INFIDEL))
  4094.                     /* powerful spells are either useless to
  4095.                        low level players or unbalancing; also
  4096.                        spells in restricted skill categories */
  4097. @@ -1086,7 +1135,7 @@ register struct trobj *trop;
  4098.                  obj->cknown = obj->lknown = 1;
  4099.                  obj->otrapped = 0;
  4100.              }
  4101. -            obj->cursed = 0;
  4102. +            obj->cursed = (trop->trbless == CURSED);
  4103.              if (obj->opoisoned && u.ualign.type != A_CHAOTIC)
  4104.                  obj->opoisoned = 0;
  4105.              if (obj->oclass == WEAPON_CLASS || obj->oclass == TOOL_CLASS) {
  4106. @@ -1096,10 +1145,14 @@ register struct trobj *trop;
  4107.                         && obj->otyp != FLINT) {
  4108.                  obj->quan = 1L;
  4109.              }
  4110. +            if (Role_if(PM_INFIDEL) && obj->oclass == ARMOR_CLASS) {
  4111. +                /* Infidels are used to playing with fire */
  4112. +                obj->oerodeproof = 1;
  4113. +            }
  4114.              if (trop->trspe != UNDEF_SPE)
  4115.                  obj->spe = trop->trspe;
  4116.              if (trop->trbless != UNDEF_BLESS)
  4117. -                obj->blessed = trop->trbless;
  4118. +                obj->blessed = (trop->trbless == 1);
  4119.          }
  4120.          /* defined after setting otyp+quan + blessedness */
  4121.          obj->owt = weight(obj);
  4122. diff --git c/src/uhitm.c w/src/uhitm.c
  4123. index 2eedb18..d0eec28 100644
  4124. --- c/src/uhitm.c
  4125. +++ w/src/uhitm.c
  4126. @@ -20,7 +20,7 @@ STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
  4127.  STATIC_DCL void FDECL(start_engulf, (struct monst *));
  4128.  STATIC_DCL void NDECL(end_engulf);
  4129.  STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
  4130. -STATIC_DCL boolean FDECL(hmonas, (struct monst *));
  4131. +STATIC_DCL boolean FDECL(hmonas, (struct monst *, int, boolean));
  4132.  STATIC_DCL void FDECL(nohandglow, (struct monst *));
  4133.  STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
  4134.  
  4135. @@ -438,7 +438,7 @@ register struct monst *mtmp;
  4136.      }
  4137.  
  4138.      if (Upolyd)
  4139. -        (void) hmonas(mtmp);
  4140. +        (void) hmonas(mtmp, NON_PM, TRUE);
  4141.      else
  4142.          (void) hitum(mtmp, youmonst.data->mattk);
  4143.      mtmp->mstrategy &= ~STRAT_WAITMASK;
  4144. @@ -641,6 +641,20 @@ struct attack *uattk;
  4145.          if (mhit)
  4146.              (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
  4147.      }
  4148. +
  4149. +    /* your race may grant extra attacks */
  4150. +    if (!Upolyd && malive) {
  4151. +        int i;
  4152. +        int race = (flags.female && urace.femalenum != NON_PM)
  4153. +                   ? urace.femalenum : urace.malenum;
  4154. +        struct attack *attacks = mons[race].mattk;
  4155. +        for (i = 0; i < NATTK; i++) {
  4156. +            if (attacks[i].aatyp != AT_WEAP && attacks[i].aatyp != AT_NONE) {
  4157. +                malive = hmonas(mon, race, FALSE);
  4158. +                break;
  4159. +            }
  4160. +        }
  4161. +    }
  4162.      return malive;
  4163.  }
  4164.  
  4165. @@ -1327,6 +1341,15 @@ int dieroll;
  4166.                  pline("%s appears confused.", Monnam(mon));
  4167.          }
  4168.      }
  4169. +    if (DEADMONSTER(mon) && attacks(AD_DREN, obj)
  4170. +        && !nonliving(mdat) && u.uen < u.uenmax) {
  4171. +        int energy = mon->m_lev + 1;
  4172. +        energy += rn2(energy);
  4173. +        pline_The("ritual knife captures the evanescent life force.");
  4174. +        u.uen += energy;
  4175. +        if (u.uen > u.uenmax)
  4176. +            u.uen = u.uenmax;
  4177. +    }
  4178.      if (unpoisonmsg)
  4179.          Your("%s %s no longer poisoned.", saved_oname,
  4180.               vtense(saved_oname, "are"));
  4181. @@ -1643,7 +1666,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
  4182.  
  4183.      if (is_demon(youmonst.data) && !rn2(13) && !uwep
  4184.          && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
  4185. -        && u.umonnum != PM_BALROG) {
  4186. +        && u.umonnum != PM_BALROG && u.umonnum != PM_DEMON) {
  4187.          demonpet();
  4188.          return 0;
  4189.      }
  4190. @@ -2346,12 +2369,14 @@ boolean wouldhavehit;
  4191.  
  4192.  /* attack monster as a monster; returns True if mon survives */
  4193.  STATIC_OVL boolean
  4194. -hmonas(mon)
  4195. +hmonas(mon, as, weapon_attacks)
  4196.  register struct monst *mon;
  4197. +int as;
  4198. +boolean weapon_attacks; /* skip weapon attacks if false */
  4199.  {
  4200.      struct attack *mattk, alt_attk;
  4201.      struct obj *weapon, **originalweapon;
  4202. -    boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
  4203. +    boolean altwep = FALSE, weapon_used = !weapon_attacks, odd_claw = TRUE;
  4204.      int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
  4205.      int dieroll, multi_claw = 0;
  4206.  
  4207. @@ -2360,8 +2385,11 @@ register struct monst *mon;
  4208.         whether silver ring causes successful hit */
  4209.      for (i = 0; i < NATTK; i++) {
  4210.          sum[i] = 0;
  4211. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4212. -        if (mattk->aatyp == AT_WEAP
  4213. +        if (as != NON_PM)
  4214. +            mattk = &mons[as].mattk[i];
  4215. +        else
  4216. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4217. +        if (mattk->aatyp == AT_WEAP && weapon_attacks
  4218.              || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
  4219.              ++multi_claw;
  4220.      }
  4221. @@ -2369,11 +2397,16 @@ register struct monst *mon;
  4222.  
  4223.      for (i = 0; i < NATTK; i++) {
  4224.          /* sum[i] = 0; -- now done above */
  4225. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4226. +        if (as != NON_PM)
  4227. +            mattk = &mons[as].mattk[i];
  4228. +        else
  4229. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4230.          weapon = 0;
  4231.          switch (mattk->aatyp) {
  4232.          case AT_WEAP:
  4233.              /* if (!uwep) goto weaponless; */
  4234. +            if (!weapon_attacks)
  4235. +                continue;
  4236.   use_weapon:
  4237.              odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
  4238.              /* if we've already hit with a two-handed weapon, we don't
  4239. diff --git c/src/weapon.c w/src/weapon.c
  4240. index 1027409..573c050 100644
  4241. --- c/src/weapon.c
  4242. +++ w/src/weapon.c
  4243. @@ -1610,6 +1610,8 @@ const struct def_skill *class_skill;
  4244.      /* set skills for magic */
  4245.      if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
  4246.          P_SKILL(P_HEALING_SPELL) = P_BASIC;
  4247. +    } else if (Role_if(PM_INFIDEL)) {
  4248. +        P_SKILL(P_ATTACK_SPELL) = P_BASIC;
  4249.      } else if (Role_if(PM_PRIEST)) {
  4250.          P_SKILL(P_CLERIC_SPELL) = P_BASIC;
  4251.      } else if (Role_if(PM_WIZARD)) {
  4252. diff --git c/src/wield.c w/src/wield.c
  4253. index 18c276a..07b7ca3 100644
  4254. --- c/src/wield.c
  4255. +++ w/src/wield.c
  4256. @@ -64,6 +64,8 @@ STATIC_DCL int FDECL(ready_weapon, (struct obj *));
  4257.  /* used by welded(), and also while wielding */
  4258.  #define will_weld(optr) \
  4259.      ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
  4260. +/* Infidels are immune to curses */
  4261. +#define will_weld_to_you(optr) (will_weld(optr) && !Role_if(PM_INFIDEL))
  4262.  
  4263.  /*** Functions that place a given item in a slot ***/
  4264.  /* Proper usage includes:
  4265. @@ -160,7 +162,7 @@ struct obj *wep;
  4266.      } else {
  4267.          /* Weapon WILL be wielded after this point */
  4268.          res++;
  4269. -        if (will_weld(wep)) {
  4270. +        if (will_weld_to_you(wep)) {
  4271.              const char *tmp = xname(wep), *thestr = "The ";
  4272.  
  4273.              if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
  4274. @@ -575,7 +577,7 @@ const char *verb; /* "rub",&c */
  4275.      } else {
  4276.          struct obj *oldwep = uwep;
  4277.  
  4278. -        if (will_weld(obj)) {
  4279. +        if (will_weld_to_you(obj)) {
  4280.              /* hope none of ready_weapon()'s early returns apply here... */
  4281.              (void) ready_weapon(obj);
  4282.          } else {
  4283. @@ -858,7 +860,7 @@ int
  4284.  welded(obj)
  4285.  register struct obj *obj;
  4286.  {
  4287. -    if (obj && obj == uwep && will_weld(obj)) {
  4288. +    if (obj && obj == uwep && will_weld_to_you(obj)) {
  4289.          set_bknown(obj, 1);
  4290.          return 1;
  4291.      }
  4292. diff --git c/src/wizard.c w/src/wizard.c
  4293. index b1dae1e..fd7281e 100644
  4294. --- c/src/wizard.c
  4295. +++ w/src/wizard.c
  4296. @@ -66,7 +66,9 @@ amulet()
  4297.          return;
  4298.  #endif
  4299.      if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR)
  4300. -         || ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
  4301. +         || ((amu = uwep) != 0 && (amu->otyp == AMULET_OF_YENDOR
  4302. +                                   || amu->oartifact == ART_IDOL_OF_MOLOCH
  4303. +                                      && amu->spe)))
  4304.          && !rn2(15)) {
  4305.          for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  4306.              if (ttmp->ttyp == MAGIC_PORTAL) {
  4307. @@ -106,7 +108,8 @@ register struct monst *mtmp;
  4308.      register struct obj *otmp;
  4309.  
  4310.      for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
  4311. -        if (otmp->otyp == AMULET_OF_YENDOR)
  4312. +        if (otmp->otyp == AMULET_OF_YENDOR
  4313. +            || otmp->oartifact == ART_IDOL_OF_MOLOCH && otmp->spe)
  4314.              return 1;
  4315.      return 0;
  4316.  }
  4317. diff --git c/src/worn.c w/src/worn.c
  4318. index 1a966b7..db2b27d 100644
  4319. --- c/src/worn.c
  4320. +++ w/src/worn.c
  4321. @@ -578,6 +578,10 @@ boolean racialexception;
  4322.                  continue;
  4323.              if (racialexception && (racial_exception(mon, obj) < 1))
  4324.                  continue;
  4325. +            /* monsters won't sacrifice flight for AC */
  4326. +            if (big_wings(mon->data) && !Is_dragon_scales(obj)
  4327. +                && obj->otyp != LEATHER_JACKET)
  4328. +                continue;
  4329.              break;
  4330.          }
  4331.          if (obj->owornmask)
  4332. diff --git c/src/zap.c w/src/zap.c
  4333. index 1c7a5de..2784f34 100644
  4334. --- c/src/zap.c
  4335. +++ w/src/zap.c
  4336. @@ -1182,6 +1182,7 @@ struct obj *obj;
  4337.  int ochance, achance; /* percent chance for ordinary objects, artifacts */
  4338.  {
  4339.      if (obj->otyp == AMULET_OF_YENDOR
  4340. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
  4341.          || obj->otyp == SPE_BOOK_OF_THE_DEAD
  4342.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  4343.          || obj->otyp == BELL_OF_OPENING
  4344. @@ -2446,7 +2447,7 @@ boolean ordinary;
  4345.  
  4346.      case WAN_DEATH:
  4347.      case SPE_FINGER_OF_DEATH:
  4348. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  4349. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  4350.              pline((obj->otyp == WAN_DEATH)
  4351.                        ? "The wand shoots an apparently harmless beam at you."
  4352.                        : "You seem no deader than before.");
  4353. @@ -3838,7 +3839,7 @@ xchar sx, sy;
  4354.                  (void) destroy_arm(uarmc);
  4355.              if (uarmu)
  4356.                  (void) destroy_arm(uarmu);
  4357. -        } else if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  4358. +        } else if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  4359.              shieldeff(sx, sy);
  4360.              You("seem unaffected.");
  4361.              break;
  4362. diff --git c/sys/amiga/Makefile.agc w/sys/amiga/Makefile.agc
  4363. index 47040b5..b13632e 100644
  4364. --- c/sys/amiga/Makefile.agc
  4365. +++ w/sys/amiga/Makefile.agc
  4366. @@ -228,6 +228,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  4367.     $(SLIB)Hea-strt.lev
  4368.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  4369.  
  4370. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  4371. +   $(SLIB)Inf-strt.lev
  4372. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  4373. +
  4374.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  4375.     $(SLIB)Kni-strt.lev
  4376.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  4377. @@ -264,7 +268,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  4378.     $(SLIB)Wiz-strt.lev
  4379.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  4380.  
  4381. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  4382. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  4383.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  4384.         $(VDFILES) $(WDFILES)
  4385.  
  4386. @@ -843,6 +847,10 @@ $(HDFILES1):   $(SLIB)Hea-goal.lev
  4387.  
  4388.  $(SLIB)Hea-goal.lev:   $(DAT)Healer.des $(SBIN)lev_comp
  4389.  
  4390. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  4391. +
  4392. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  4393. +
  4394.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  4395.  
  4396.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  4397. diff --git c/sys/amiga/Makefile.ami w/sys/amiga/Makefile.ami
  4398. index 14b1298..6fefee5 100644
  4399. --- c/sys/amiga/Makefile.ami
  4400. +++ w/sys/amiga/Makefile.ami
  4401. @@ -435,6 +435,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  4402.     $(SLIB)Hea-strt.lev
  4403.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  4404.  
  4405. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  4406. +   $(SLIB)Inf-strt.lev
  4407. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  4408. +
  4409.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  4410.     $(SLIB)Kni-strt.lev
  4411.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  4412. @@ -471,7 +475,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  4413.     $(SLIB)Wiz-strt.lev
  4414.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  4415.  
  4416. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  4417. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  4418.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  4419.         $(VDFILES) $(WDFILES)
  4420.  
  4421. @@ -1148,6 +1152,12 @@ $(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp
  4422.  #SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des
  4423.  #none
  4424.  
  4425. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  4426. +
  4427. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  4428. +#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Infidel.des
  4429. +#none
  4430. +
  4431.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  4432.  
  4433.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  4434. diff --git c/sys/msdos/Makefile.BC w/sys/msdos/Makefile.BC
  4435. index ce0756a..5476f58 100644
  4436. --- c/sys/msdos/Makefile.BC
  4437. +++ w/sys/msdos/Makefile.BC
  4438. @@ -718,7 +718,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  4439.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  4440.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  4441.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  4442. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  4443. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  4444.  
  4445.  #
  4446.  # Utility Objects.
  4447. @@ -976,6 +976,7 @@ $(DAT)\sp_lev.tag: $(U)utility.tag $(SPLEVDES)
  4448.     $(U)lev_comp barb.des
  4449.     $(U)lev_comp caveman.des
  4450.     $(U)lev_comp healer.des
  4451. +   $(U)lev_comp infidel.des
  4452.     $(U)lev_comp knight.des
  4453.     $(U)lev_comp monk.des
  4454.     $(U)lev_comp priest.des
  4455. diff --git c/sys/msdos/Makefile.GCC w/sys/msdos/Makefile.GCC
  4456. index 4693bda..579f11a 100644
  4457. --- c/sys/msdos/Makefile.GCC
  4458. +++ w/sys/msdos/Makefile.GCC
  4459. @@ -1016,7 +1016,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  4460.     $(DAT)/caveman.des   $(DAT)/healer.des   $(DAT)/knight.des \
  4461.     $(DAT)/monk.des      $(DAT)/priest.des   $(DAT)/ranger.des \
  4462.     $(DAT)/rogue.des     $(DAT)/samurai.des  $(DAT)/tourist.des \
  4463. -   $(DAT)/valkyrie.des  $(DAT)/wizard.des
  4464. +   $(DAT)/valkyrie.des  $(DAT)/wizard.des $(DAT)/infidel.des
  4465.     @$(subst /,\,cd $(DAT))
  4466.     @$(subst /,\,$(U)lev_comp bigroom.des)
  4467.     @$(subst /,\,$(U)lev_comp castle.des)
  4468. @@ -1033,6 +1033,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  4469.     @$(subst /,\,$(U)lev_comp barb.des)
  4470.     @$(subst /,\,$(U)lev_comp caveman.des)
  4471.     @$(subst /,\,$(U)lev_comp healer.des)
  4472. +   @$(subst /,\,$(U)lev_comp infidel.des)
  4473.     @$(subst /,\,$(U)lev_comp knight.des)
  4474.     @$(subst /,\,$(U)lev_comp monk.des)
  4475.     @$(subst /,\,$(U)lev_comp priest.des)
  4476. diff --git c/sys/msdos/Makefile.MSC w/sys/msdos/Makefile.MSC
  4477. index b7d827a..b605dcc 100644
  4478. --- c/sys/msdos/Makefile.MSC
  4479. +++ w/sys/msdos/Makefile.MSC
  4480. @@ -148,7 +148,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  4481.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  4482.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  4483.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  4484. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  4485. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  4486.  
  4487.  VGAOBJ      = vidvga.o
  4488.  
  4489. @@ -428,6 +428,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(SPLEVDES)
  4490.     $(U)lev_comp barb.des
  4491.     $(U)lev_comp caveman.des
  4492.     $(U)lev_comp healer.des
  4493. +   $(U)lev_comp infidel.des
  4494.     $(U)lev_comp knight.des
  4495.     $(U)lev_comp monk.des
  4496.     $(U)lev_comp priest.des
  4497. @@ -973,6 +974,11 @@ nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(DAT)\options \
  4498.     echo HEA-GOAL.LEV  >>dlb.lst
  4499.     echo HEA-LOCA.LEV  >>dlb.lst
  4500.     echo HEA-STRT.LEV  >>dlb.lst
  4501. +   echo INF-FILA.LEV  >>dlb.lst
  4502. +   echo INF-FILB.LEV  >>dlb.lst
  4503. +   echo INF-GOAL.LEV  >>dlb.lst
  4504. +   echo INF-LOCA.LEV  >>dlb.lst
  4505. +   echo INF-STRT.LEV  >>dlb.lst
  4506.     echo JUIBLEX.LEV   >>dlb.lst
  4507.     echo KNI-FILA.LEV  >>dlb.lst
  4508.     echo KNI-FILB.LEV  >>dlb.lst
  4509. diff --git c/sys/os2/Makefile.os2 w/sys/os2/Makefile.os2
  4510. index 4afcf0f..9ddaad5 100644
  4511. --- c/sys/os2/Makefile.os2
  4512. +++ w/sys/os2/Makefile.os2
  4513. @@ -1280,6 +1280,7 @@ AFILES = $(GAMEDIR)\Arc-goal.lev
  4514.  BFILES = $(GAMEDIR)\Bar-goal.lev
  4515.  CFILES = $(GAMEDIR)\Cav-goal.lev
  4516.  HFILES = $(GAMEDIR)\Hea-goal.lev
  4517. +IFILES = $(GAMEDIR)\Inf-goal.lev
  4518.  KFILES = $(GAMEDIR)\Kni-goal.lev
  4519.  MFILES = $(GAMEDIR)\Mon-goal.lev
  4520.  PFILES = $(GAMEDIR)\Pri-goal.lev
  4521. @@ -1290,7 +1291,7 @@ TFILES = $(GAMEDIR)\Tou-goal.lev
  4522.  VFILES = $(GAMEDIR)\Val-goal.lev
  4523.  WFILES = $(GAMEDIR)\Wiz-goal.lev
  4524.  
  4525. -XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(KFILES) $(MFILES) \
  4526. +XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(IFILES) $(KFILES) $(MFILES) \
  4527.      $(PFILES) $(RANFILES) $(RFILES) $(SFILES) $(TFILES) $(VFILES) $(WFILES)
  4528.  
  4529.  spec_lev : $(GAMEDIR)\astral.lev $(GAMEDIR)\bigrm-1.lev $(GAMEDIR)\castle.lev \
  4530. @@ -1389,6 +1390,8 @@ $(CFILES) : $(DAT)\Caveman.des $(TEMP)\lev_comp.exe
  4531.     $(MAKEB) QQ=Cav QF=Caveman do_quest
  4532.  $(HFILES) : $(DAT)\Healer.des $(TEMP)\lev_comp.exe
  4533.     $(MAKEB) QQ=Hea QF=Healer do_quest
  4534. +$(IFILES) : $(DAT)\Infidel.des $(TEMP)\lev_comp.exe
  4535. +   $(MAKEB) QQ=Inf QF=Infidel do_quest
  4536.  $(KFILES) : $(DAT)\Knight.des $(TEMP)\lev_comp.exe
  4537.     $(MAKEB) QQ=Kni QF=Knight do_quest
  4538.  $(MFILES) : $(DAT)\Monk.des $(TEMP)\lev_comp.exe
  4539. diff --git c/sys/unix/Makefile.dat w/sys/unix/Makefile.dat
  4540. index 00f6043..c6bb10d 100644
  4541. --- c/sys/unix/Makefile.dat
  4542. +++ w/sys/unix/Makefile.dat
  4543. @@ -145,11 +145,12 @@ spec_levs: ../util/lev_comp \
  4544.  quest_levs: ../util/lev_comp \
  4545.     Arch.des Barb.des Caveman.des Healer.des Knight.des Monk.des \
  4546.     Priest.des Ranger.des Rogue.des Samurai.des Tourist.des Valkyrie.des \
  4547. -   Wizard.des
  4548. +   Wizard.des Infidel.des
  4549.     ../util/lev_comp Arch.des
  4550.     ../util/lev_comp Barb.des
  4551.     ../util/lev_comp Caveman.des
  4552.     ../util/lev_comp Healer.des
  4553. +   ../util/lev_comp Infidel.des
  4554.     ../util/lev_comp Knight.des
  4555.     ../util/lev_comp Monk.des
  4556.     ../util/lev_comp Priest.des
  4557. diff --git c/sys/unix/NetHack.xcodeproj/project.pbxproj w/sys/unix/NetHack.xcodeproj/project.pbxproj
  4558. index fdee884..d0db85a 100644
  4559. --- c/sys/unix/NetHack.xcodeproj/project.pbxproj
  4560. +++ w/sys/unix/NetHack.xcodeproj/project.pbxproj
  4561. @@ -1310,6 +1310,7 @@
  4562.                 "$(NH_DAT_DIR)/Barb.des",
  4563.                 "$(NH_DAT_DIR)/Caveman.des",
  4564.                 "$(NH_DAT_DIR)/Healer.des",
  4565. +               "$(NH_DAT_DIR)/Infidel.des",
  4566.                 "$(NH_DAT_DIR)/Knight.des",
  4567.                 "$(NH_DAT_DIR)/Monk.des",
  4568.                 "$(NH_DAT_DIR)/Priest.des",
  4569. @@ -1328,7 +1329,7 @@
  4570.             );
  4571.             runOnlyForDeploymentPostprocessing = 0;
  4572.             shellPath = /bin/sh;
  4573. -           shellScript = "cd ${NH_DAT_DIR}\n${NH_UTIL_DIR}/lev_comp Arch.des\n${NH_UTIL_DIR}/lev_comp Barb.des\n${NH_UTIL_DIR}/lev_comp Caveman.des\n${NH_UTIL_DIR}/lev_comp Healer.des\n${NH_UTIL_DIR}/lev_comp Knight.des\n${NH_UTIL_DIR}/lev_comp Monk.des\n${NH_UTIL_DIR}/lev_comp Priest.des\n${NH_UTIL_DIR}/lev_comp Ranger.des\n${NH_UTIL_DIR}/lev_comp Rogue.des\n${NH_UTIL_DIR}/lev_comp Samurai.des\n${NH_UTIL_DIR}/lev_comp Tourist.des\n${NH_UTIL_DIR}/lev_comp Valkyrie.des\n${NH_UTIL_DIR}/lev_comp Wizard.des\ntouch quest_levs\n";
  4574. +           shellScript = "cd ${NH_DAT_DIR}\n${NH_UTIL_DIR}/lev_comp Arch.des\n${NH_UTIL_DIR}/lev_comp Barb.des\n${NH_UTIL_DIR}/lev_comp Caveman.des\n${NH_UTIL_DIR}/lev_comp Healer.des\n${NH_UTIL_DIR}/lev_comp Infidel.des\n${NH_UTIL_DIR}/lev_comp Knight.des\n${NH_UTIL_DIR}/lev_comp Monk.des\n${NH_UTIL_DIR}/lev_comp Priest.des\n${NH_UTIL_DIR}/lev_comp Ranger.des\n${NH_UTIL_DIR}/lev_comp Rogue.des\n${NH_UTIL_DIR}/lev_comp Samurai.des\n${NH_UTIL_DIR}/lev_comp Tourist.des\n${NH_UTIL_DIR}/lev_comp Valkyrie.des\n${NH_UTIL_DIR}/lev_comp Wizard.des\ntouch quest_levs\n";
  4575.         };
  4576.         317E7C4E21A3697300F6E4E5 /* Build options and headers */ = {
  4577.             isa = PBXShellScriptBuildPhase;
  4578. @@ -1472,6 +1473,11 @@
  4579.                 "$(NH_DAT_DIR)/Hea-goal.lev",
  4580.                 "$(NH_DAT_DIR)/Hea-loca.lev",
  4581.                 "$(NH_DAT_DIR)/Hea-strt.lev",
  4582. +               "$(NH_DAT_DIR)/Inf-fila.lev",
  4583. +               "$(NH_DAT_DIR)/Inf-filb.lev",
  4584. +               "$(NH_DAT_DIR)/Inf-goal.lev",
  4585. +               "$(NH_DAT_DIR)/Inf-loca.lev",
  4586. +               "$(NH_DAT_DIR)/Inf-strt.lev",
  4587.                 "$(NH_DAT_DIR)/Kni-fila.lev",
  4588.                 "$(NH_DAT_DIR)/Kni-filb.lev",
  4589.                 "$(NH_DAT_DIR)/Kni-goal.lev",
  4590. diff --git c/sys/vms/Makefile.dat w/sys/vms/Makefile.dat
  4591. index e74eb95..dea0fb8 100644
  4592. --- c/sys/vms/Makefile.dat
  4593. +++ w/sys/vms/Makefile.dat
  4594. @@ -31,7 +31,7 @@ VARDAT    = data.;,rumors.;,quest.dat;,oracles.;,options.;,\
  4595.  DUNGEON = dungeon.;
  4596.  X11TILES= x11tiles.;
  4597.  # note: the level lists need to be space separated for use as-is by $(LEVCOMP)
  4598. -QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Knight.des \
  4599. +QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Infidel.des Knight.des \
  4600.     Monk.des Priest.des Ranger.des Rogue.des Samurai.des Tourist.des \
  4601.     Valkyrie.des Wizard.des
  4602.  SPECLEVS  = bigroom.des castle.des endgame.des gehennom.des knox.des \
  4603. diff --git c/sys/vms/install.com w/sys/vms/install.com
  4604. index 09f6f83..5172e41 100755
  4605. --- c/sys/vms/install.com
  4606. +++ w/sys/vms/install.com
  4607. @@ -45,7 +45,7 @@ $ spec_input = "bigroom.des castle.des endgame.des " -
  4608.            + "gehennom.des knox.des medusa.des mines.des " -
  4609.            + "oracle.des sokoban.des tower.des yendor.des"
  4610.  $  qstl_files = "%%%-GOAL.LEV,%%%-FIL%.LEV,%%%-LOCA.LEV,%%%-STRT.LEV"
  4611. -$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des " -
  4612. +$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des Infidel.des " -
  4613.            + "Knight.des Monk.des Priest.des Ranger.des Rogue.des " -
  4614.            + "Samurai.des Tourist.des Wizard.des Valkyrie.des"
  4615.  $  dngn_files = "DUNGEON."
  4616. diff --git c/sys/wince/bootstrp.mak w/sys/wince/bootstrp.mak
  4617. index 5d92dc7..dcd3a46 100644
  4618. --- c/sys/wince/bootstrp.mak
  4619. +++ w/sys/wince/bootstrp.mak
  4620. @@ -244,7 +244,8 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  4621.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  4622.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  4623.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  4624. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  4625. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  4626. +   $(DAT)\infidel.des
  4627.     cd $(DAT)
  4628.     $(U)lev_comp bigroom.des
  4629.     $(U)lev_comp castle.des
  4630. @@ -261,6 +262,7 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  4631.     $(U)lev_comp barb.des
  4632.     $(U)lev_comp caveman.des
  4633.     $(U)lev_comp healer.des
  4634. +   $(U)lev_comp infidel.des
  4635.     $(U)lev_comp knight.des
  4636.     $(U)lev_comp monk.des
  4637.     $(U)lev_comp priest.des
  4638. diff --git c/sys/winnt/Makefile.msc w/sys/winnt/Makefile.msc
  4639. index 8bd5086..5e172cf 100644
  4640. --- c/sys/winnt/Makefile.msc
  4641. +++ w/sys/winnt/Makefile.msc
  4642. @@ -711,7 +711,8 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  4643.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  4644.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  4645.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  4646. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  4647. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  4648. +        $(DAT)\infidel.des
  4649.     cd $(DAT)
  4650.     $(U)levcomp bigroom.des
  4651.     $(U)levcomp castle.des
  4652. @@ -728,6 +729,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  4653.     $(U)levcomp barb.des
  4654.     $(U)levcomp caveman.des
  4655.     $(U)levcomp healer.des
  4656. +   $(U)levcomp infidel.des
  4657.     $(U)levcomp knight.des
  4658.     $(U)levcomp monk.des
  4659.     $(U)levcomp priest.des
  4660. diff --git c/util/lev_main.c w/util/lev_main.c
  4661. index 8bcfc83..15a487f 100644
  4662. --- c/util/lev_main.c
  4663. +++ w/util/lev_main.c
  4664. @@ -250,7 +250,8 @@ char **argv;
  4665.          ":dat:Wizard.des",  ":dat:bigroom.des",  ":dat:castle.des",
  4666.          ":dat:endgame.des", ":dat:gehennom.des", ":dat:knox.des",
  4667.          ":dat:medusa.des",  ":dat:mines.des",    ":dat:oracle.des",
  4668. -        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des"
  4669. +        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des",
  4670. +        ":dat:Infidel.des"
  4671.      };
  4672.  
  4673.      argc = SIZE(mac_argv);
  4674. diff --git c/win/tty/wintty.c w/win/tty/wintty.c
  4675. index d7ffec6..d5c18bb 100644
  4676. --- c/win/tty/wintty.c
  4677. +++ w/win/tty/wintty.c
  4678. @@ -929,6 +929,7 @@ tty_player_selection()
  4679.       */
  4680.      getconfirmation = (picksomething && pick4u != 'a' && !flags.randomall);
  4681.      while (getconfirmation) {
  4682. +        int real_algn = special_alignment(ROLE, ALGN);
  4683.          tty_clear_nhwindow(BASE_WINDOW);
  4684.          role_selection_prolog(ROLE_NONE, BASE_WINDOW);
  4685.          win = create_nhwindow(NHW_MENU);
  4686. @@ -941,7 +942,7 @@ tty_player_selection()
  4687.              Sprintf(plbuf, " %s", genders[GEND].adj);
  4688.          else
  4689.              *plbuf = '\0'; /* omit redundant gender */
  4690. -        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[ALGN].adj, plbuf,
  4691. +        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[real_algn].adj, plbuf,
  4692.                  races[RACE].adj,
  4693.                  (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f
  4694.                                                    : roles[ROLE].name.m);
  4695. diff --git c/win/win32/vs2017/files.props w/win/win32/vs2017/files.props
  4696. index 483ec1e..5a12ab8 100644
  4697. --- c/win/win32/vs2017/files.props
  4698. +++ w/win/win32/vs2017/files.props
  4699. @@ -35,6 +35,7 @@
  4700.      <Desfiles Include = "endgame.des"/>
  4701.      <Desfiles Include = "gehennom.des"/>
  4702.      <Desfiles Include = "healer.des"/>
  4703. +    <Desfiles Include = "infidel.des"/>
  4704.      <Desfiles Include = "knight.des"/>
  4705.      <Desfiles Include = "knox.des"/>
  4706.      <Desfiles Include = "medusa.des"/>
  4707. @@ -128,6 +129,11 @@
  4708.      <Levfiles Include = "hea-goal.lev"/>
  4709.      <Levfiles Include = "hea-loca.lev"/>
  4710.      <Levfiles Include = "hea-strt.lev"/>
  4711. +    <Levfiles Include = "inf-fila.lev"/>
  4712. +    <Levfiles Include = "inf-filb.lev"/>
  4713. +    <Levfiles Include = "inf-goal.lev"/>
  4714. +    <Levfiles Include = "inf-loca.lev"/>
  4715. +    <Levfiles Include = "inf-strt.lev"/>
  4716.      <Levfiles Include = "kni-fila.lev"/>
  4717.      <Levfiles Include = "kni-filb.lev"/>
  4718.      <Levfiles Include = "kni-goal.lev"/>
Add Comment
Please, Sign In to add comment