Guest User

NetHack Infidel role patch v1.1

a guest
Mar 9th, 2020
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 185.89 KB | None | 0 0
  1. diff --git c/Files w/Files
  2. index 9d40931..2d7e194 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 ef41914..d21b9b9 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 3a28fe0..3977436 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 9133878..39aa85e 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..bba4477 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. +        && 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..e0a6db4 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. diff --git c/src/dungeon.c w/src/dungeon.c
  2266. index 27b7481..1eedd62 100644
  2267. --- c/src/dungeon.c
  2268. +++ w/src/dungeon.c
  2269. @@ -1173,7 +1173,8 @@ boolean at_stairs;
  2270.          /* Taking an up dungeon branch. */
  2271.          /* KMH -- Upwards branches are okay if not level 1 */
  2272.          /* (Just make sure it doesn't go above depth 1) */
  2273. -        if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
  2274. +        if (!u.uz.dnum && u.uz.dlevel == 1
  2275. +            && !(u.uhave.amulet && u.uachieve.amulet))
  2276.              done(ESCAPED);
  2277.          else
  2278.              goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  2279. @@ -2998,8 +2999,11 @@ boolean printdun;
  2280.              else
  2281.                  ADDNTOBUF("temple", mptr->feat.ntemple);
  2282.  
  2283. -            /* only print out altar's god if they are all to your god */
  2284. -            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
  2285. +            /* only print out altar's god if they are all to your god
  2286. +             * For Infidels, only print Moloch if there's exactly one altar;
  2287. +             * this is a technical resriction (i.e. I'm too lazy to fix it) */
  2288. +            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type
  2289. +                && (u.ualign.type != A_NONE || mptr->feat.naltar == 1))
  2290.                  Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
  2291.          }
  2292.          ADDNTOBUF("throne", mptr->feat.nthrone);
  2293. diff --git c/src/eat.c w/src/eat.c
  2294. index 5e2aa1a..8ca11ae 100644
  2295. --- c/src/eat.c
  2296. +++ w/src/eat.c
  2297. @@ -2797,10 +2797,7 @@ gethungry()
  2298.         will need to wear an Amulet of Unchanging so still burn a small
  2299.         amount of nutrition in the 'moves % 20' ring/amulet check below */
  2300.      if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
  2301. -        && (carnivorous(youmonst.data)
  2302. -            || herbivorous(youmonst.data)
  2303. -            || metallivorous(youmonst.data))
  2304. -        && !Slow_digestion)
  2305. +        && !inediate(raceptr(&youmonst)) && !Slow_digestion)
  2306.          u.uhunger--; /* ordinary food consumption */
  2307.  
  2308.      if (moves % 2) { /* odd turns */
  2309. diff --git c/src/end.c w/src/end.c
  2310. index 4df88ce..a63ea9f 100644
  2311. --- c/src/end.c
  2312. +++ w/src/end.c
  2313. @@ -925,6 +925,8 @@ struct obj *list; /* inventory or container contents */
  2314.          } else if (obj->oartifact) {
  2315.              continue;
  2316.          } else if (obj->oclass == AMULET_CLASS) {
  2317. +            if (Role_if(PM_INFIDEL) && obj->otyp == AMULET_OF_YENDOR)
  2318. +                continue; /* starting inventory */
  2319.              i = obj->otyp - FIRST_AMULET;
  2320.              if (!amulets[i].count) {
  2321.                  amulets[i].count = obj->quan;
  2322. @@ -1478,7 +1480,9 @@ int how;
  2323.                  ? (const char *) ((flags.female && urole.name.f)
  2324.                      ? urole.name.f
  2325.                      : urole.name.m)
  2326. -                : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2327. +                : Role_if(PM_INFIDEL) /* can only ascend via Moloch */
  2328. +                 ? (const char *) (flags.female ? "Demon Lady" : "Demon Lord")
  2329. +                 : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2330.      dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
  2331.      dump_forward_putstr(endwin, 0, "", done_stopprint);
  2332.  
  2333. diff --git c/src/engrave.c w/src/engrave.c
  2334. index b001855..975b538 100644
  2335. --- c/src/engrave.c
  2336. +++ w/src/engrave.c
  2337. @@ -431,7 +431,8 @@ int
  2338.  freehand()
  2339.  {
  2340.      return (!uwep || !welded(uwep)
  2341. -            || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
  2342. +            || (!bimanual(uwep)
  2343. +                && (!uarms || !cursed(uarms, TRUE))));
  2344.  }
  2345.  
  2346.  static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
  2347. @@ -504,7 +505,7 @@ doengrave()
  2348.      maxelen = BUFSZ - 1;
  2349.      if (oep)
  2350.          oetype = oep->engr_type;
  2351. -    if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
  2352. +    if (is_demon(raceptr(&youmonst)) || youmonst.data->mlet == S_VAMPIRE)
  2353.          type = ENGR_BLOOD;
  2354.  
  2355.      /* Can the adventurer engrave at all? */
  2356. diff --git c/src/exper.c w/src/exper.c
  2357. index 9b96b5c..fc4cf1e 100644
  2358. --- c/src/exper.c
  2359. +++ w/src/exper.c
  2360. @@ -32,6 +32,7 @@ int en;
  2361.      case PM_WIZARD:
  2362.          return (2 * en);
  2363.      case PM_HEALER:
  2364. +    case PM_INFIDEL:
  2365.      case PM_KNIGHT:
  2366.          return ((3 * en) / 2);
  2367.      case PM_BARBARIAN:
  2368. diff --git c/src/explode.c w/src/explode.c
  2369. index 31ba7c7..3f933b1 100644
  2370. --- c/src/explode.c
  2371. +++ w/src/explode.c
  2372. @@ -185,7 +185,7 @@ int expltype;
  2373.                  case AD_DISN:
  2374.                      explmask[i][j] = (olet == WAND_CLASS)
  2375.                                           ? !!(nonliving(youmonst.data)
  2376. -                                              || is_demon(youmonst.data))
  2377. +                                              || is_demon(raceptr(&youmonst)))
  2378.                                           : !!Disint_resistance;
  2379.                      break;
  2380.                  case AD_ELEC:
  2381. diff --git c/src/hack.c w/src/hack.c
  2382. index 79fe740..da4bd69 100644
  2383. --- c/src/hack.c
  2384. +++ w/src/hack.c
  2385. @@ -2012,7 +2012,7 @@ invocation_message()
  2386.              Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
  2387.  
  2388.          You_feel("a strange vibration %s.", buf);
  2389. -        u.uevent.uvibrated = 1;
  2390. +        u.uachieve.vibrating_square = 1;
  2391.          if (otmp && otmp->spe == 7 && otmp->lamplit)
  2392.              pline("%s %s!", The(xname(otmp)),
  2393.                    Blind ? "throbs palpably" : "glows with a strange light");
  2394. @@ -2053,7 +2053,7 @@ switch_terrain()
  2395.          /* [minor bug: we don't know whether this is beginning flight or
  2396.             resuming it; that could be tracked so that this message could
  2397.             be adjusted to "resume flying", but isn't worth the effort...] */
  2398. -        if (Flying)
  2399. +        if (Flying && !was_flying)
  2400.              You("start flying.");
  2401.      }
  2402.      if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
  2403. diff --git c/src/invent.c w/src/invent.c
  2404. index 7e7e3b2..c0b87c1 100644
  2405. --- c/src/invent.c
  2406. +++ w/src/invent.c
  2407. @@ -813,7 +813,8 @@ struct obj *obj;
  2408.          if (u.uhave.amulet)
  2409.              impossible("already have amulet?");
  2410.          u.uhave.amulet = 1;
  2411. -        u.uachieve.amulet = 1;
  2412. +        if (!Role_if(PM_INFIDEL))
  2413. +            u.uachieve.amulet = 1;
  2414.      } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
  2415.          if (u.uhave.menorah)
  2416.              impossible("already have candelabrum?");
  2417. @@ -834,6 +835,8 @@ struct obj *obj;
  2418.              if (u.uhave.questart)
  2419.                  impossible("already have quest artifact?");
  2420.              u.uhave.questart = 1;
  2421. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2422. +                u.uhave.amulet = 1;
  2423.              artitouch(obj);
  2424.          }
  2425.          set_artifact_intrinsic(obj, 1, W_ART);
  2426. @@ -1132,6 +1135,8 @@ struct obj *obj;
  2427.              if (!u.uhave.questart)
  2428.                  impossible("don't have quest artifact?");
  2429.              u.uhave.questart = 0;
  2430. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2431. +                u.uhave.amulet = 0;
  2432.          }
  2433.          set_artifact_intrinsic(obj, 0, W_ART);
  2434.      }
  2435. @@ -1181,6 +1186,7 @@ register struct obj *obj;
  2436.      boolean update_map;
  2437.  
  2438.      if (obj->otyp == AMULET_OF_YENDOR
  2439. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
  2440.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  2441.          || obj->otyp == BELL_OF_OPENING
  2442.          || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  2443. @@ -1601,10 +1607,11 @@ register const char *let, *word;
  2444.               || (!strncmp(word, "rub on the stone", 16)
  2445.                   && *let == GEM_CLASS && otmp->dknown
  2446.                   && objects[otyp].oc_name_known)
  2447. -             /* suppress corpses on astral, amulets elsewhere */
  2448. +             /* suppress corpses on astral (or sanctum), amulets elsewhere */
  2449.               || (!strcmp(word, "sacrifice")
  2450.                   /* (!astral && amulet) || (astral && !amulet) */
  2451. -                 && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
  2452. +                 && ((!Is_astralevel(&u.uz) && !Is_sanctum(&u.uz))
  2453. +                     ^ (otmp->oclass != AMULET_CLASS)))
  2454.               /* suppress container being stashed into */
  2455.               || (!strcmp(word, "stash") && !ck_bag(otmp))
  2456.               /* worn armor (shirt, suit) covered by worn armor (suit, cloak)
  2457. diff --git c/src/makemon.c w/src/makemon.c
  2458. index 3145ad6..271806a 100644
  2459. --- c/src/makemon.c
  2460. +++ w/src/makemon.c
  2461. @@ -185,7 +185,7 @@ register struct monst *mtmp;
  2462.              (void) mongets(mtmp, (mm != PM_ETTIN) ? BOULDER : CLUB);
  2463.          break;
  2464.      case S_HUMAN:
  2465. -        if (is_mercenary(ptr)) {
  2466. +        if (is_mercenary(ptr) || mm == PM_TEMPLAR) {
  2467.              w1 = w2 = 0;
  2468.              switch (mm) {
  2469.              case PM_WATCHMAN:
  2470. @@ -204,6 +204,7 @@ register struct monst *mtmp;
  2471.                  break;
  2472.              case PM_CAPTAIN:
  2473.              case PM_WATCH_CAPTAIN:
  2474. +            case PM_TEMPLAR:
  2475.                  w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
  2476.                  break;
  2477.              default:
  2478. @@ -266,11 +267,20 @@ register struct monst *mtmp;
  2479.          } else if (mm == PM_NINJA) { /* extra quest villains */
  2480.              (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
  2481.              (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
  2482. +        } else if (mm == PM_CHAMPION) {
  2483. +            (void) mongets(mtmp, rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE);
  2484. +            (void) mongets(mtmp, rn2(3) ? RING_MAIL : CHAIN_MAIL);
  2485. +        } else if (mm == PM_AGENT) {
  2486. +            (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : DAGGER);
  2487. +            if (!rn2(3))
  2488. +                (void) mongets(mtmp, LEATHER_ARMOR);
  2489. +            (void) mongets(mtmp, POT_INVISIBILITY);
  2490.          } else if (ptr->msound == MS_GUARDIAN) {
  2491.              /* quest "guardians" */
  2492.              switch (mm) {
  2493.              case PM_STUDENT:
  2494.              case PM_ATTENDANT:
  2495. +            case PM_CULTIST:
  2496.              case PM_ABBOT:
  2497.              case PM_ACOLYTE:
  2498.              case PM_GUIDE:
  2499. @@ -588,7 +598,7 @@ register struct monst *mtmp;
  2500.       */
  2501.      switch (ptr->mlet) {
  2502.      case S_HUMAN:
  2503. -        if (is_mercenary(ptr)) {
  2504. +        if (is_mercenary(ptr) || monsndx(ptr) == PM_TEMPLAR) {
  2505.              register int mac;
  2506.  
  2507.              switch (monsndx(ptr)) {
  2508. @@ -613,6 +623,9 @@ register struct monst *mtmp;
  2509.              case PM_WATCH_CAPTAIN:
  2510.                  mac = -2;
  2511.                  break;
  2512. +            case PM_TEMPLAR:
  2513. +                mac = -3;
  2514. +                break;
  2515.              default:
  2516.                  impossible("odd mercenary %d?", monsndx(ptr));
  2517.                  mac = 0;
  2518. @@ -655,6 +668,10 @@ register struct monst *mtmp;
  2519.              } else if (ptr == &mons[PM_WATCHMAN]) {
  2520.                  if (rn2(3)) /* most watchmen carry a whistle */
  2521.                      (void) mongets(mtmp, TIN_WHISTLE);
  2522. +            } else if (ptr == &mons[PM_TEMPLAR]) {
  2523. +                if (rn2(3)) /* being in a holy order has its benefits */
  2524. +                    (void) mongets(mtmp, rn2(4) ? POT_HEALING
  2525. +                                                : POT_EXTRA_HEALING);
  2526.              } else if (ptr == &mons[PM_GUARD]) {
  2527.                  /* if hero teleports out of a vault while being confronted
  2528.                     by the vault's guard, there is a shrill whistling sound,
  2529. @@ -695,6 +712,22 @@ register struct monst *mtmp;
  2530.              mkmonmoney(mtmp, (long) rn1(10, 20));
  2531.          } else if (quest_mon_represents_role(ptr, PM_MONK)) {
  2532.              (void) mongets(mtmp, rn2(11) ? ROBE : CLOAK_OF_MAGIC_RESISTANCE);
  2533. +        } else if (ptr == &mons[PM_PREACHER_OF_MOLOCH]) {
  2534. +            (void) mongets(mtmp, QUARTERSTAFF);
  2535. +            (void) mongets(mtmp, rn2(3) ? ROBE : CLOAK_OF_PROTECTION);
  2536. +        } else if (ptr == &mons[PM_PALADIN]) {
  2537. +            otmp = mksobj(MORNING_STAR, FALSE, FALSE);
  2538. +            otmp->blessed = otmp->oerodeproof = 1;
  2539. +            otmp->spe = rn1(3, 3);
  2540. +            (void) mpickobj(mtmp, otmp);
  2541. +            /* the Paladin wears no helmet
  2542. +             * because she looks cooler without a helmet */
  2543. +            (void) mongets(mtmp, LEATHER_GLOVES);
  2544. +            (void) mongets(mtmp, SHIELD_OF_REFLECTION);
  2545. +            (void) mongets(mtmp, LEATHER_CLOAK);
  2546. +            (void) mongets(mtmp, CRYSTAL_PLATE_MAIL);
  2547. +            (void) mongets(mtmp, HIGH_BOOTS);
  2548. +            (void) mongets(mtmp, POT_SPEED);
  2549.          }
  2550.          break;
  2551.      case S_NYMPH:
  2552. @@ -1269,7 +1302,7 @@ int mmflags;
  2553.              mtmp->mpeaceful = FALSE;
  2554.          break;
  2555.      case S_UNICORN:
  2556. -        if (is_unicorn(ptr) && sgn(u.ualign.type) == sgn(ptr->maligntyp))
  2557. +        if (is_unicorn(ptr) && u.ualign.type == sgn(ptr->maligntyp))
  2558.              mtmp->mpeaceful = TRUE;
  2559.          break;
  2560.      case S_BAT:
  2561. @@ -1365,6 +1398,13 @@ int mmflags;
  2562.                                ? !eminp->renegade
  2563.                                : eminp->renegade;
  2564.      }
  2565. +    /* these monsters are normally affiliated with a deity */
  2566. +    if ((mndx == PM_PALADIN || mndx == PM_TEMPLAR || mndx == PM_CHAMPION
  2567. +         || mndx == PM_AGENT) && !(mmflags & MM_EMIN)) {
  2568. +        newemin(mtmp);
  2569. +        mtmp->isminion = 1;
  2570. +        EMIN(mtmp)->min_align = sgn(ptr->maligntyp);
  2571. +    }
  2572.      set_malign(mtmp); /* having finished peaceful changes */
  2573.      if (anymon && !(mmflags & MM_NOGRP)) {
  2574.          if ((ptr->geno & G_SGROUP) && rn2(2)) {
  2575. @@ -2007,7 +2047,11 @@ register struct permonst *ptr;
  2576.  
  2577.      if (always_peaceful(ptr))
  2578.          return TRUE;
  2579. -    if (always_hostile(ptr))
  2580. +    /* Major demons will sometimes be peaceful to unaligned Infidels.
  2581. +     * They must pass this 50% check, then the 50% check for chaotics
  2582. +     * being non-hostile to unaligned, then the usual check for coaligned.
  2583. +     * For crowned Infidels, the last two checks are bypassed. */
  2584. +    if (always_hostile(ptr) && (ual != A_NONE || !is_demon(ptr) || rn2(2)))
  2585.          return FALSE;
  2586.      if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
  2587.          return TRUE;
  2588. @@ -2024,8 +2068,12 @@ register struct permonst *ptr;
  2589.      if (sgn(mal) != sgn(ual))
  2590.          return FALSE;
  2591.  
  2592. -    /* Negative monster hostile to player with Amulet. */
  2593. -    if (mal < A_NEUTRAL && u.uhave.amulet)
  2594. +    /* Not all chaotics support Moloch.  This goes especially for elves. */
  2595. +    if (ual == A_NONE && (is_elf(ptr) || rn2(2)))
  2596. +        return FALSE;
  2597. +
  2598. +    /* Chaotic monsters hostile to players with Amulet, except Infidels. */
  2599. +    if (mal < A_NEUTRAL && u.uhave.amulet && ual != A_NONE)
  2600.          return FALSE;
  2601.  
  2602.      /* minions are hostile to players that have strayed at all */
  2603. @@ -2070,7 +2118,7 @@ struct monst *mtmp;
  2604.              mal *= 5;
  2605.      }
  2606.  
  2607. -    coaligned = (sgn(mal) == sgn(u.ualign.type));
  2608. +    coaligned = (sgn(mal) == u.ualign.type);
  2609.      if (mtmp->data->msound == MS_LEADER) {
  2610.          mtmp->malign = -20;
  2611.      } else if (mal == A_NONE) {
  2612. @@ -2078,6 +2126,8 @@ struct monst *mtmp;
  2613.              mtmp->malign = 0;
  2614.          else
  2615.              mtmp->malign = 20; /* really hostile */
  2616. +        if (u.ualign.type == A_NONE)
  2617. +            mtmp->malign -= 20; /* reverse */
  2618.      } else if (always_peaceful(mtmp->data)) {
  2619.          int absmal = abs(mal);
  2620.          if (mtmp->mpeaceful)
  2621. diff --git c/src/mcastu.c w/src/mcastu.c
  2622. index 1b2fb63..3c1402a 100644
  2623. --- c/src/mcastu.c
  2624. +++ w/src/mcastu.c
  2625. @@ -377,7 +377,7 @@ int spellnum;
  2626.      switch (spellnum) {
  2627.      case MGC_DEATH_TOUCH:
  2628.          pline("Oh no, %s's using the touch of death!", mhe(mtmp));
  2629. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  2630. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  2631.              You("seem no deader than before.");
  2632.          } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
  2633.              if (Hallucination) {
  2634. diff --git c/src/mhitu.c w/src/mhitu.c
  2635. index 849ddb1..cbb24de 100644
  2636. --- c/src/mhitu.c
  2637. +++ w/src/mhitu.c
  2638. @@ -589,7 +589,7 @@ register struct monst *mtmp;
  2639.      /*  Special demon handling code */
  2640.      if ((mtmp->cham == NON_PM) && is_demon(mdat) && !range2
  2641.          && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS]
  2642. -        && mtmp->data != &mons[PM_INCUBUS])
  2643. +        && mtmp->data != &mons[PM_INCUBUS] && mtmp->data != &mons[PM_DEMON])
  2644.          if (!mtmp->mcan && !rn2(13))
  2645.              (void) msummon(mtmp);
  2646.  
  2647. diff --git c/src/minion.c w/src/minion.c
  2648. index 4277b45..5624a22 100644
  2649. --- c/src/minion.c
  2650. +++ w/src/minion.c
  2651. @@ -261,7 +261,7 @@ register struct monst *mtmp;
  2652.          }
  2653.          newsym(mtmp->mx, mtmp->my);
  2654.      }
  2655. -    if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
  2656. +    if (is_demon(raceptr(&youmonst))) { /* Won't blackmail their own. */
  2657.          if (!Deaf)
  2658.              pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
  2659.                    flags.female ? "Sister" : "Brother");
  2660. diff --git c/src/mon.c w/src/mon.c
  2661. index 4f0a13d..7d85d8b 100644
  2662. --- c/src/mon.c
  2663. +++ w/src/mon.c
  2664. @@ -2472,7 +2472,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2665.      }
  2666.      if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
  2667.          change_luck(-1);
  2668. -    if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
  2669. +    if (is_unicorn(mdat) && u.ualign.type == sgn(mdat->maligntyp)) {
  2670.          change_luck(-5);
  2671.          You_feel("guilty...");
  2672.      }
  2673. @@ -2500,7 +2500,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2674.          /* cancel divine protection for killing your priest */
  2675.          if (p_coaligned(mtmp))
  2676.              u.ublessed = 0;
  2677. -        if (mdat->maligntyp == A_NONE)
  2678. +        else if (mdat->maligntyp == A_NONE)
  2679.              adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
  2680.      } else if (mtmp->mtame) {
  2681.          adjalign(-15); /* bad!! */
  2682. @@ -2905,7 +2905,8 @@ boolean via_attack;
  2683.             it's intentionally larger than the 1s and 2s that are normally
  2684.             given for this sort of thing. */
  2685.          /* reduce to 3 (average) when alignment is already very low */
  2686. -        adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2687. +        if (u.ualign.type != A_NONE)
  2688. +            adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2689.  
  2690.          if (!Blind)
  2691.              pline("The engraving beneath you fades.");
  2692. diff --git c/src/mondata.c w/src/mondata.c
  2693. index fae34e8..7d20930 100644
  2694. --- c/src/mondata.c
  2695. +++ w/src/mondata.c
  2696. @@ -97,7 +97,7 @@ boolean
  2697.  resists_drli(mon)
  2698.  struct monst *mon;
  2699.  {
  2700. -    struct permonst *ptr = mon->data;
  2701. +    struct permonst *ptr = raceptr(mon); /* handle demonic race */
  2702.      struct obj *wep;
  2703.  
  2704.      if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
  2705. @@ -421,8 +421,7 @@ register struct permonst *ptr;
  2706.      return (boolean) (bigmonst(ptr)
  2707.                        || (ptr->msize > MZ_SMALL && !humanoid(ptr))
  2708.                        /* special cases of humanoids that cannot wear suits */
  2709. -                      || ptr == &mons[PM_MARILITH]
  2710. -                      || ptr == &mons[PM_WINGED_GARGOYLE]);
  2711. +                      || ptr == &mons[PM_MARILITH]);
  2712.  }
  2713.  
  2714.  /* creature sticks other creatures it hits */
  2715. @@ -1077,7 +1076,7 @@ int montyp1, montyp2;
  2716.   * Returns correct pointer for non-polymorphed and polymorphed
  2717.   * player.  It does not return a pointer to player role character.
  2718.   */
  2719. -const struct permonst *
  2720. +struct permonst *
  2721.  raceptr(mtmp)
  2722.  struct monst *mtmp;
  2723.  {
  2724. diff --git c/src/monmove.c w/src/monmove.c
  2725. index cd6ca98..9abc779 100644
  2726. --- c/src/monmove.c
  2727. +++ w/src/monmove.c
  2728. @@ -344,6 +344,14 @@ int *inrange, *nearby, *scared;
  2729.                      || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
  2730.          *scared = 1;
  2731.          monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
  2732. +        if (u.ualign.type == A_NONE && !context.coward
  2733. +            && sengr_at("Elbereth", seescaryx, seescaryy, TRUE)) {
  2734. +            /* Followers of Moloch aren't supposed
  2735. +             * to hide behind other gods. */
  2736. +            You_feel("like a coward.");
  2737. +            context.coward = TRUE; /* once per move */
  2738. +            adjalign(-5);
  2739. +        }
  2740.      } else
  2741.          *scared = 0;
  2742.  }
  2743. @@ -927,6 +935,9 @@ register int after;
  2744.                      > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
  2745.              appr = -1;
  2746.  
  2747. +        if (monsndx(ptr) == PM_AGENT && mon_has_amulet(mtmp))
  2748. +            appr = -1; /* objective secured, retreat */
  2749. +
  2750.          if (!should_see && can_track(ptr)) {
  2751.              register coord *cp;
  2752.  
  2753. diff --git c/src/monst.c w/src/monst.c
  2754. index 6b8a5f7..de919f5 100644
  2755. --- c/src/monst.c
  2756. +++ w/src/monst.c
  2757. @@ -2139,6 +2139,27 @@ struct permonst _mons2[] = {
  2758.          M1_HUMANOID | M1_POIS | M1_REGEN | M1_OMNIVORE,
  2759.          M2_NOPOLY | M2_WERE | M2_HOSTILE | M2_HUMAN | M2_COLLECT,
  2760.          M3_INFRAVISIBLE, 6, CLR_ORANGE),
  2761. +    /* Only generated when playing as Infidel.
  2762. +     * Has emin, so always appears as a "champion of [deity]".
  2763. +     * Note: the difficulty is purposefully lowered. */
  2764. +    MON("champion", S_HUMAN, LVL(12, 12, 6, 10, 0), (G_NOGEN | G_NOHELL | 2),
  2765. +        A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
  2766. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2767. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
  2768. +        M1_HUMANOID | M1_OMNIVORE,
  2769. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_NASTY | M2_STRONG | M2_COLLECT,
  2770. +        M3_INFRAVISIBLE, 6, CLR_GRAY),
  2771. +    /* Only generated when playing as Infidel.
  2772. +     * Has emin, so always appears as an "agent of [deity]".
  2773. +     * Note: the difficulty is purposefully lowered. */
  2774. +    MON("agent", S_HUMAN, LVL(6, 18, 10, 10, -7), (G_NOGEN | G_NOHELL | 3),
  2775. +        A(ATTK(AT_WEAP, AD_SAMU, 1, 4), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  2776. +          ATTK(AT_CLAW, AD_SAMU, 1, 1), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  2777. +          NO_ATTK, NO_ATTK),
  2778. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  2779. +        M1_HUMANOID | M1_OMNIVORE | M1_TPORT,
  2780. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STALK | M2_STRONG | M2_COLLECT,
  2781. +        M3_INFRAVISIBLE, 6, CLR_BLACK),
  2782.      MON("elf", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, /* for corpses */
  2783.          A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2784.            NO_ATTK),
  2785. @@ -2607,6 +2628,14 @@ struct permonst _mons2[] = {
  2786.          SIZ(1500, 400, MS_DJINNI, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  2787.          M1_HUMANOID | M1_FLY | M1_POIS, M2_NOPOLY | M2_STALK | M2_COLLECT,
  2788.          M3_INFRAVISIBLE, 8, CLR_YELLOW),
  2789. +    /* racial monster for crowned Infidels */
  2790. +    MON("demon", S_DEMON, LVL(10, 12, 10, 10, A_NONE), (G_NOGEN | G_NOCORPSE),
  2791. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_STNG, AD_DRST, 2, 4),
  2792. +          NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
  2793. +        SIZ(WT_HUMAN, 400, MS_GRUNT, MZ_HUMAN), MR_FIRE | MR_POISON, 0,
  2794. +        M1_HUMANOID | M1_FLY | M1_SEE_INVIS | M1_POIS,
  2795. +        M2_NOPOLY | M2_DEMON | M2_STALK | M2_HOSTILE | M2_COLLECT,
  2796. +        M3_INFRAVISIBLE | M3_INFRAVISION, 13, CLR_RED),
  2797.      /*
  2798.       * sea monsters
  2799.       */
  2800. @@ -2757,6 +2786,13 @@ struct permonst _mons2[] = {
  2801.          M1_HUMANOID | M1_OMNIVORE,
  2802.          M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  2803.          12, HI_DOMESTIC),
  2804. +    MON("infidel", S_HUMAN, LVL(10, 12, 10, 2, A_NONE), G_NOGEN,
  2805. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2806. +          NO_ATTK),
  2807. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_FIRE, 0,
  2808. +        M1_HUMANOID | M1_OMNIVORE,
  2809. +        M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  2810. +        12, HI_DOMESTIC),
  2811.      MON("knight", S_HUMAN, LVL(10, 12, 10, 1, 3), G_NOGEN,
  2812.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2813.            NO_ATTK, NO_ATTK, NO_ATTK),
  2814. @@ -2884,6 +2920,17 @@ struct permonst _mons2[] = {
  2815.          M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
  2816.              | M2_COLLECT | M2_MAGIC,
  2817.          M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
  2818. +    /* apparently she should be a "preacheress" if female,
  2819. +     * but that word just sounds silly, imo */
  2820. +    MON("preacher of Moloch", S_HUMAN, LVL(20, 12, 0, 40, A_NONE),
  2821. +        (G_NOGEN | G_UNIQ),
  2822. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK,
  2823. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2824. +        SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_FIRE | MR_ELEC, 0,
  2825. +        M1_HUMANOID | M1_OMNIVORE,
  2826. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT
  2827. +            | M2_MAGIC,
  2828. +        M3_CLOSE | M3_INFRAVISIBLE, 23, CLR_RED),
  2829.      MON("King Arthur", S_HUMAN, LVL(20, 12, 0, 40, 20), (G_NOGEN | G_UNIQ),
  2830.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2831.            NO_ATTK, NO_ATTK, NO_ATTK),
  2832. @@ -3026,6 +3073,18 @@ struct permonst _mons2[] = {
  2833.              | M2_HOSTILE | M2_NASTY | M2_MALE | M2_JEWELS | M2_COLLECT,
  2834.          M3_WANTSARTI | M3_WAITFORU | M3_INFRAVISION | M3_INFRAVISIBLE,
  2835.          23, CLR_GRAY),
  2836. +    /* Has emin, so always appears as the "Paladin of [deity]". */
  2837. +    MON("Paladin", S_HUMAN, LVL(24, 12, 0, 50, 20),
  2838. +        (G_NOGEN | G_UNIQ | G_NOCORPSE),
  2839. +        A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_STUN, 2, 6),
  2840. +          ATTK(AT_MAGC, AD_CLRC, 1, 8), ATTK(AT_CLAW, AD_SAMU, 1, 6),
  2841. +          NO_ATTK, NO_ATTK),
  2842. +        SIZ(WT_HUMAN, 400, MS_NEMESIS, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  2843. +        M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
  2844. +        M2_NOPOLY | M2_HUMAN | M2_MINION | M2_LORD | M2_STRONG | M2_FEMALE
  2845. +            | M2_STALK | M2_HOSTILE | M2_NASTY | M2_COLLECT | M2_MAGIC,
  2846. +        M3_WANTSARTI | M3_WANTSAMUL | M3_WAITFORU | M3_INFRAVISIBLE,
  2847. +        29, HI_GOLD),
  2848.      MON("Ixoth", S_DRAGON, LVL(15, 12, -1, 20, -14), (G_NOGEN | G_UNIQ),
  2849.          A(ATTK(AT_BREA, AD_FIRE, 8, 6), ATTK(AT_BITE, AD_PHYS, 4, 8),
  2850.            ATTK(AT_MAGC, AD_SPEL, 0, 0), ATTK(AT_CLAW, AD_PHYS, 2, 4),
  2851. @@ -3148,6 +3207,21 @@ struct permonst _mons2[] = {
  2852.          M1_HUMANOID | M1_OMNIVORE,
  2853.          M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  2854.          M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  2855. +    /* Has emin, so always appears as a "templar of [deity]". */
  2856. +    MON("templar", S_HUMAN, LVL(12, 10, 10, 20, 10), G_NOGEN,
  2857. +        A(ATTK(AT_WEAP, AD_PHYS, 3, 4), ATTK(AT_WEAP, AD_PHYS, 3, 4), NO_ATTK,
  2858. +          NO_ATTK, NO_ATTK, NO_ATTK),
  2859. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  2860. +        M1_HUMANOID | M1_OMNIVORE,
  2861. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STRONG | M2_COLLECT,
  2862. +        M3_INFRAVISIBLE, 14, CLR_BLUE),
  2863. +    MON("cultist", S_HUMAN, LVL(5, 12, 10, 10, A_NONE), G_NOGEN,
  2864. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  2865. +          NO_ATTK),
  2866. +        SIZ(WT_HUMAN, 400, MS_GUARDIAN, MZ_HUMAN), MR_FIRE, 0,
  2867. +        M1_HUMANOID | M1_OMNIVORE,
  2868. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  2869. +        M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  2870.      MON("page", S_HUMAN, LVL(5, 12, 10, 10, 3), G_NOGEN,
  2871.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  2872.            NO_ATTK, NO_ATTK, NO_ATTK),
  2873. diff --git c/src/mplayer.c w/src/mplayer.c
  2874. index 2dba08e..b65f708 100644
  2875. --- c/src/mplayer.c
  2876. +++ w/src/mplayer.c
  2877. @@ -195,6 +195,16 @@ register boolean special;
  2878.              if (rn2(2))
  2879.                  shield = STRANGE_OBJECT;
  2880.              break;
  2881. +        case PM_INFIDEL:
  2882. +            if (!rn2(4))
  2883. +                weapon = CRYSKNIFE;
  2884. +            if (rn2(3))
  2885. +                cloak = CLOAK_OF_PROTECTION;
  2886. +            if (rn2(4))
  2887. +                helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
  2888. +            if (rn2(2))
  2889. +                shield = STRANGE_OBJECT;
  2890. +            break;
  2891.          case PM_KNIGHT:
  2892.              if (rn2(4))
  2893.                  weapon = LONG_SWORD;
  2894. diff --git c/src/muse.c w/src/muse.c
  2895. index 2dfb92f..6062690 100644
  2896. --- c/src/muse.c
  2897. +++ w/src/muse.c
  2898. @@ -2091,6 +2091,9 @@ struct obj *obj;
  2899.              return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
  2900.          if (typ == AMULET_OF_REFLECTION)
  2901.              return TRUE;
  2902. +        if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
  2903. +            return (boolean) (mon->data == &mons[PM_AGENT]
  2904. +                              && !mon_has_amulet(mon));
  2905.          break;
  2906.      case TOOL_CLASS:
  2907.          if (typ == PICK_AXE)
  2908. diff --git c/src/pickup.c w/src/pickup.c
  2909. index 76f35aa..21133f5 100644
  2910. --- c/src/pickup.c
  2911. +++ w/src/pickup.c
  2912. @@ -2150,6 +2150,7 @@ register struct obj *obj;
  2913.          pline_The("stone%s won't leave your person.", plur(obj->quan));
  2914.          return 0;
  2915.      } else if (obj->otyp == AMULET_OF_YENDOR
  2916. +               || Role_if(PM_INFIDEL) && is_quest_artifact(obj) && obj->spe
  2917.                 || obj->otyp == CANDELABRUM_OF_INVOCATION
  2918.                 || obj->otyp == BELL_OF_OPENING
  2919.                 || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  2920. diff --git c/src/polyself.c w/src/polyself.c
  2921. index b053091..7fa7e3f 100644
  2922. --- c/src/polyself.c
  2923. +++ w/src/polyself.c
  2924. @@ -42,8 +42,10 @@ void
  2925.  set_uasmon()
  2926.  {
  2927.      struct permonst *mdat = &mons[u.umonnum];
  2928. +    struct permonst *racedat; /* for infravision, flying */
  2929.  
  2930.      set_mon_data(&youmonst, mdat);
  2931. +    racedat = raceptr(&youmonst);
  2932.  
  2933.  #define PROPSET(PropIndx, ON)                          \
  2934.      do {                                               \
  2935. @@ -81,7 +83,7 @@ set_uasmon()
  2936.      PROPSET(SEE_INVIS, perceives(mdat));
  2937.      PROPSET(TELEPAT, telepathic(mdat));
  2938.      /* note that Infravision uses mons[race] rather than usual mons[role] */
  2939. -    PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum]));
  2940. +    PROPSET(INFRAVISION, infravision(racedat));
  2941.      PROPSET(INVIS, pm_invisible(mdat));
  2942.      PROPSET(TELEPORT, can_teleport(mdat));
  2943.      PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
  2944. @@ -89,7 +91,9 @@ set_uasmon()
  2945.      /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
  2946.         suppress flying for it so that enlightenment doesn't confusingly
  2947.         show latent flight capability always blocked by levitation */
  2948. -    PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
  2949. +    /* this property also checks race instead of role */
  2950. +    PROPSET(FLYING, (is_flyer(racedat) && !is_floater(racedat)));
  2951. +    check_wings(TRUE);
  2952.      PROPSET(SWIMMING, is_swimmer(mdat));
  2953.      /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
  2954.         key off of it but include different monster forms...] */
  2955. diff --git c/src/potion.c w/src/potion.c
  2956. index c6dffc5..fe19946 100644
  2957. --- c/src/potion.c
  2958. +++ w/src/potion.c
  2959. @@ -648,8 +648,9 @@ register struct obj *otmp;
  2960.              break;
  2961.          }
  2962.          unkn++;
  2963. -        if (is_undead(youmonst.data) || is_demon(youmonst.data)
  2964. -            || u.ualign.type == A_CHAOTIC) {
  2965. +        if (is_undead(youmonst.data) || is_demon(raceptr(&youmonst))
  2966. +            || u.ualign.type <= A_CHAOTIC) {
  2967. +            int dice = (u.ualign.type == A_NONE) ? 4 : 2;
  2968.              if (otmp->blessed) {
  2969.                  pline("This burns like %s!", hliquid("acid"));
  2970.                  exercise(A_CON, FALSE);
  2971. @@ -660,11 +661,11 @@ register struct obj *otmp;
  2972.                          you_unwere(FALSE);
  2973.                      set_ulycn(NON_PM); /* cure lycanthropy */
  2974.                  }
  2975. -                losehp(Maybe_Half_Phys(d(2, 6)), "potion of holy water",
  2976. +                losehp(Maybe_Half_Phys(d(dice, 6)), "potion of holy water",
  2977.                         KILLED_BY_AN);
  2978.              } else if (otmp->cursed) {
  2979.                  You_feel("quite proud of yourself.");
  2980. -                healup(d(2, 6), 0, 0, 0);
  2981. +                healup(d(dice, 6), 0, 0, 0);
  2982.                  if (u.ulycn >= LOW_PM && !Upolyd)
  2983.                      you_were();
  2984.                  exercise(A_CON, TRUE);
  2985. diff --git c/src/pray.c w/src/pray.c
  2986. index 79369fc..d6bdf22 100644
  2987. --- c/src/pray.c
  2988. +++ w/src/pray.c
  2989. @@ -3,6 +3,7 @@
  2990.  /* NetHack may be freely redistributed.  See license for details. */
  2991.  
  2992.  #include "hack.h"
  2993. +#include "qtext.h"
  2994.  
  2995.  STATIC_PTR int NDECL(prayer_done);
  2996.  STATIC_DCL struct obj *NDECL(worst_cursed_item);
  2997. @@ -12,8 +13,6 @@ STATIC_DCL void FDECL(angrygods, (ALIGNTYP_P));
  2998.  STATIC_DCL void FDECL(at_your_feet, (const char *));
  2999.  STATIC_DCL void NDECL(gcrownu);
  3000.  STATIC_DCL void FDECL(pleased, (ALIGNTYP_P));
  3001. -STATIC_DCL void FDECL(godvoice, (ALIGNTYP_P, const char *));
  3002. -STATIC_DCL void FDECL(god_zaps_you, (ALIGNTYP_P));
  3003.  STATIC_DCL void FDECL(fry_by_god, (ALIGNTYP_P, BOOLEAN_P));
  3004.  STATIC_DCL void FDECL(gods_angry, (ALIGNTYP_P));
  3005.  STATIC_DCL void FDECL(gods_upset, (ALIGNTYP_P));
  3006. @@ -22,7 +21,8 @@ STATIC_DCL boolean FDECL(water_prayer, (BOOLEAN_P));
  3007.  STATIC_DCL boolean FDECL(blocked_boulder, (int, int));
  3008.  
  3009.  /* simplify a few tests */
  3010. -#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) && (obj)->cursed)
  3011. +#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) \
  3012. +                              && cursed(obj, TRUE))
  3013.  
  3014.  /*
  3015.   * Logic behind deities and altars and such:
  3016. @@ -50,7 +50,7 @@ static const char *godvoices[] = {
  3017.  /* values calculated when prayer starts, and used when completed */
  3018.  static aligntyp p_aligntyp;
  3019.  static int p_trouble;
  3020. -static int p_type; /* (-1)-3: (-1)=really naughty, 3=really good */
  3021. +static int p_type; /* (-2)-3: (-1)=really naughty, 3=really good */
  3022.  
  3023.  #define PIOUS 20
  3024.  #define DEVOUT 14
  3025. @@ -221,10 +221,11 @@ in_trouble()
  3026.          if (welded(uwep))
  3027.              return TROUBLE_UNUSEABLE_HANDS;
  3028.          if (Upolyd && nohands(youmonst.data)
  3029. -            && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed)))
  3030. +            && (!Unchanging || ((otmp = unchanger()) != 0
  3031. +                                && cursed(otmp, TRUE))))
  3032.              return TROUBLE_UNUSEABLE_HANDS;
  3033.      }
  3034. -    if (Blindfolded && ublindf->cursed)
  3035. +    if (Blindfolded && cursed(ublindf, TRUE))
  3036.          return TROUBLE_CURSED_BLINDFOLD;
  3037.  
  3038.      /*
  3039. @@ -274,6 +275,14 @@ worst_cursed_item()
  3040.  {
  3041.      register struct obj *otmp;
  3042.  
  3043. +    /* Infidels are immune to curses, but a cursed luckstone is still bad */
  3044. +    if(Role_if(PM_INFIDEL)) {
  3045. +        for (otmp = invent; otmp; otmp = otmp->nobj)
  3046. +            if (confers_luck(otmp) && otmp->cursed)
  3047. +                return otmp;
  3048. +        return (struct obj *) 0;
  3049. +    }
  3050. +
  3051.      /* if strained or worse, check for loadstone first */
  3052.      if (near_capacity() >= HVY_ENCUMBER) {
  3053.          for (otmp = invent; otmp; otmp = otmp->nobj)
  3054. @@ -452,7 +461,7 @@ int trouble;
  3055.              if (!Unchanging) {
  3056.                  Your("shape becomes uncertain.");
  3057.                  rehumanize(); /* "You return to {normal} form." */
  3058. -            } else if ((otmp = unchanger()) != 0 && otmp->cursed) {
  3059. +            } else if ((otmp = unchanger()) != 0 && cursed(otmp, TRUE)) {
  3060.                  /* otmp is an amulet of unchanging */
  3061.                  goto decurse;
  3062.              }
  3063. @@ -497,7 +506,7 @@ int trouble;
  3064.          if (otmp == uarmg && Glib) {
  3065.              make_glib(0);
  3066.              Your("%s are no longer slippery.", gloves_simple_name(uarmg));
  3067. -            if (!otmp->cursed)
  3068. +            if (!cursed(otmp, TRUE))
  3069.                  break;
  3070.          }
  3071.          if (!Blind || (otmp == ublindf && Blindfolded_only)) {
  3072. @@ -578,7 +587,7 @@ int trouble;
  3073.   * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
  3074.   * Divine wrath, dungeon walls, and armor follow the same principle.
  3075.   */
  3076. -STATIC_OVL void
  3077. +void
  3078.  god_zaps_you(resp_god)
  3079.  aligntyp resp_god;
  3080.  {
  3081. @@ -771,10 +780,13 @@ gcrownu()
  3082.  
  3083.      HSee_invisible |= FROMOUTSIDE;
  3084.      HFire_resistance |= FROMOUTSIDE;
  3085. -    HCold_resistance |= FROMOUTSIDE;
  3086. -    HShock_resistance |= FROMOUTSIDE;
  3087. -    HSleep_resistance |= FROMOUTSIDE;
  3088.      HPoison_resistance |= FROMOUTSIDE;
  3089. +    if (u.ualign.type != A_NONE) {
  3090. +        /* demons don't get all the intrinsics */
  3091. +        HCold_resistance |= FROMOUTSIDE;
  3092. +        HShock_resistance |= FROMOUTSIDE;
  3093. +        HSleep_resistance |= FROMOUTSIDE;
  3094. +    }
  3095.      godvoice(u.ualign.type, (char *) 0);
  3096.  
  3097.      class_gift = STRANGE_OBJECT;
  3098. @@ -815,6 +827,17 @@ gcrownu()
  3099.                     || class_gift != STRANGE_OBJECT) ? "take lives"
  3100.                    : "steal souls");
  3101.          break;
  3102. +    case A_NONE:
  3103. +        u.uevent.uhand_of_elbereth = 4;
  3104. +        verbalize("I grant thee the gift of Demonhood!");
  3105. +        class_gift = SPE_FIREBALL; /* no special weapon */
  3106. +        if (Upolyd)
  3107. +            rehumanize(); /* return to human/orcish form -- not a demon yet */
  3108. +        pline1("Wings sprout from your back and you grow a barbed tail!");
  3109. +        urace = race_demon;
  3110. +        set_uasmon();
  3111. +        retouch_equipment(2); /* silver */
  3112. +        break;
  3113.      }
  3114.  
  3115.      if (objects[class_gift].oc_class == SPBOOK_CLASS) {
  3116. @@ -892,6 +915,9 @@ gcrownu()
  3117.              discover_artifact(ART_STORMBRINGER);
  3118.          break;
  3119.      }
  3120. +    case A_NONE:
  3121. +        /* nothing to do */
  3122. +        break;
  3123.      default:
  3124.          obj = 0; /* lint */
  3125.          break;
  3126. @@ -1131,6 +1157,8 @@ aligntyp g_align;
  3127.                  You("are surrounded by %s aura.", an(hcolor(NH_LIGHT_BLUE)));
  3128.              for (otmp = invent; otmp; otmp = otmp->nobj) {
  3129.                  if (otmp->cursed
  3130. +                    /* Inf benefit from wearing cursed armor */
  3131. +                    && !(Role_if(PM_INFIDEL) && (otmp->owornmask & W_ARMOR))
  3132.                      && (otmp != uarmh /* [see worst_cursed_item()] */
  3133.                          || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)) {
  3134.                      if (!Blind) {
  3135. @@ -1259,7 +1287,7 @@ boolean bless_water;
  3136.      return (boolean) (changed > 0L);
  3137.  }
  3138.  
  3139. -STATIC_OVL void
  3140. +void
  3141.  godvoice(g_align, words)
  3142.  aligntyp g_align;
  3143.  const char *words;
  3144. @@ -1357,6 +1385,9 @@ dosacrifice()
  3145.      if (otmp->otyp == CORPSE) {
  3146.          register struct permonst *ptr = &mons[otmp->corpsenm];
  3147.          struct monst *mtmp;
  3148. +        /* is this a conversion attempt? */
  3149. +        boolean to_other_god =  ugod_is_angry() && !your_race(ptr)
  3150. +                                && u.ualign.type != altaralign;
  3151.  
  3152.          /* KMH, conduct */
  3153.          u.uconduct.gnostic++;
  3154. @@ -1367,29 +1398,45 @@ dosacrifice()
  3155.          if (rider_corpse_revival(otmp, FALSE))
  3156.              return 1;
  3157.  
  3158. -        if (otmp->corpsenm == PM_ACID_BLOB
  3159. +        if (otmp->corpsenm == PM_ACID_BLOB || your_race(ptr)
  3160.              || (monstermoves <= peek_at_iced_corpse_age(otmp) + 50)) {
  3161.              value = mons[otmp->corpsenm].difficulty + 1;
  3162. +            /* Not demons--no demon corpses */
  3163. +            if (is_undead(ptr) && u.ualign.type > A_CHAOTIC)
  3164. +                value += 1;
  3165. +            if (is_unicorn(ptr))
  3166. +                value += 3;
  3167. +            if (uwep && uwep->oartifact == ART_SECESPITA)
  3168. +                value += value / 2;
  3169.              if (otmp->oeaten)
  3170.                  value = eaten_stat(value, otmp);
  3171. +            /* even cross-aligned sacrifices will count,
  3172. +             * as long as they're ultimately to Moloch */
  3173. +            if (u.ualign.type == A_NONE && !to_other_god) {
  3174. +                long new_timeout = moves + value * 500;
  3175. +                if (context.next_moloch_offering < new_timeout)
  3176. +                    context.next_moloch_offering = new_timeout;
  3177. +            }
  3178.          }
  3179.  
  3180.          if (your_race(ptr)) {
  3181. -            if (is_demon(youmonst.data)) {
  3182. +            if (is_demon(raceptr(&youmonst))) {
  3183.                  You("find the idea very satisfying.");
  3184.                  exercise(A_WIS, TRUE);
  3185. -            } else if (u.ualign.type != A_CHAOTIC) {
  3186. +            } else if (u.ualign.type > A_CHAOTIC) {
  3187.                  pline("You'll regret this infamous offense!");
  3188.                  exercise(A_WIS, FALSE);
  3189.              }
  3190.  
  3191.              if (highaltar
  3192. -                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)) {
  3193. +                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)
  3194. +                && (altaralign != A_NONE || u.ualign.type != A_NONE)) {
  3195.                  goto desecrate_high_altar;
  3196.              } else if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
  3197.                  /* curse the lawful/neutral altar */
  3198.                  pline_The("altar is stained with %s blood.", urace.adj);
  3199. -                levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
  3200. +                levl[u.ux][u.uy].altarmask = u.ualign.type == A_NONE
  3201. +                                             ? AM_NONE : AM_CHAOTIC;
  3202.                  angry_priest();
  3203.              } else {
  3204.                  struct monst *dmon;
  3205. @@ -1409,7 +1456,7 @@ dosacrifice()
  3206.                  } else {
  3207.                      /* either you're chaotic or altar is Moloch's or both */
  3208.                      pline_The("blood covers the altar!");
  3209. -                    change_luck(altaralign == A_NONE ? -2 : 2);
  3210. +                    change_luck(altaralign == u.ualign.type ? 2 : -2);
  3211.                      demonless_msg = "blood coagulates";
  3212.                  }
  3213.                  if ((pm = dlord(altaralign)) != NON_PM
  3214. @@ -1433,7 +1480,7 @@ dosacrifice()
  3215.                      pline_The("%s.", demonless_msg);
  3216.              }
  3217.  
  3218. -            if (u.ualign.type != A_CHAOTIC) {
  3219. +            if (u.ualign.type > A_CHAOTIC) {
  3220.                  adjalign(-5);
  3221.                  u.ugangr += 3;
  3222.                  (void) adjattrib(A_WIS, -1, TRUE);
  3223. @@ -1449,17 +1496,17 @@ dosacrifice()
  3224.              return 1;
  3225.          } else if (has_omonst(otmp)
  3226.                     && (mtmp = get_mtraits(otmp, FALSE)) != 0
  3227. -                   && mtmp->mtame) {
  3228. +                   && mtmp->mtame
  3229. +                   /* Moloch is OK with sacrificing pets,
  3230. +                    * but make sure we're offering to him */
  3231. +                   && (u.ualign.type != A_NONE || to_other_god)) {
  3232.                  /* mtmp is a temporary pointer to a tame monster's attributes,
  3233.                   * not a real monster */
  3234.              pline("So this is how you repay loyalty?");
  3235.              adjalign(-3);
  3236.              value = -1;
  3237.              HAggravate_monster |= FROMOUTSIDE;
  3238. -        } else if (is_undead(ptr)) { /* Not demons--no demon corpses */
  3239. -            if (u.ualign.type != A_CHAOTIC)
  3240. -                value += 1;
  3241. -        } else if (is_unicorn(ptr)) {
  3242. +        } else if (is_unicorn(ptr) && value /* fresh */) {
  3243.              int unicalign = sgn(ptr->maligntyp);
  3244.  
  3245.              if (unicalign == altaralign) {
  3246. @@ -1479,7 +1526,7 @@ dosacrifice()
  3247.                  else
  3248.                      You_feel("you are thoroughly on the right path.");
  3249.                  adjalign(5);
  3250. -                value += 3;
  3251. +                /* value += 3; -- now applied above */
  3252.              } else if (unicalign == u.ualign.type) {
  3253.                  /* When sacrificing unicorn of your alignment to altar not of
  3254.                   * your alignment, your god gets angry and it's a conversion.
  3255. @@ -1491,7 +1538,7 @@ dosacrifice()
  3256.                   * and different from the altar's.  It's an ordinary (well,
  3257.                   * with a bonus) sacrifice on a cross-aligned altar.
  3258.                   */
  3259. -                value += 3;
  3260. +                /* value += 3; -- now applied above */
  3261.              }
  3262.          }
  3263.      } /* corpse */
  3264. @@ -1499,7 +1546,7 @@ dosacrifice()
  3265.      if (otmp->otyp == AMULET_OF_YENDOR) {
  3266.          if (!highaltar) {
  3267.   too_soon:
  3268. -            if (altaralign == A_NONE && Inhell)
  3269. +            if (altaralign == A_NONE && u.ualign.type != A_NONE && Inhell)
  3270.                  /* hero has left Moloch's Sanctum so is in the process
  3271.                     of getting away with the Amulet (outside of Gehennom,
  3272.                     fall through to the "ashamed" feedback) */
  3273. @@ -1510,7 +1557,9 @@ dosacrifice()
  3274.                              ? "homesick"
  3275.                              /* if on track, give a big hint */
  3276.                              : (altaralign == u.ualign.type)
  3277. -                               ? "an urge to return to the surface"
  3278. +                               ? (Role_if(PM_INFIDEL)
  3279. +                                  ? "an urge to descend deeper"
  3280. +                                  : "an urge to return to the surface")
  3281.                                 /* else headed towards celestial disgrace */
  3282.                                 : "ashamed");
  3283.              return 1;
  3284. @@ -1526,6 +1575,33 @@ dosacrifice()
  3285.              You("offer the Amulet of Yendor to %s...", a_gname());
  3286.              if (altaralign == A_NONE) {
  3287.                  /* Moloch's high altar */
  3288. +                if (Role_if(PM_INFIDEL)) {
  3289. +                    /* Infidels still have an ascension run,
  3290. +                     * they just carry a different McGuffin */
  3291. +                    u.uevent.ascended = 0;
  3292. +                    u.uachieve.amulet = 1;
  3293. +                    otmp = find_quest_artifact(1 << OBJ_INVENT);
  3294. +                    godvoice(A_NONE, (char *) 0);
  3295. +                    if (!otmp)
  3296. +                        qt_pager(QT_MOLOCH_1);
  3297. +                    else {
  3298. +                        qt_pager(QT_MOLOCH_2);
  3299. +                        if (otmp->where == OBJ_CONTAINED) {
  3300. +                            /* the Idol cannot be contained now,
  3301. +                             * so we have to remove it */
  3302. +                            obj_extract_self(otmp);
  3303. +                            (void) hold_another_object(otmp, "Oops!",
  3304. +                                                       (const char *) 0,
  3305. +                                                       (const char *) 0);
  3306. +                        }
  3307. +                        You_feel("strange energies envelop %s.",
  3308. +                                 the(xname(otmp)));
  3309. +                        otmp->spe = 1;
  3310. +                        if (otmp->where == OBJ_INVENT)
  3311. +                            u.uhave.amulet = 1;
  3312. +                    }
  3313. +                    return 1;
  3314. +                }
  3315.                  if (u.ualign.record > -99)
  3316.                      u.ualign.record = -99;
  3317.                  /*[apparently shrug/snarl can be sensed without being seen]*/
  3318. @@ -1582,8 +1658,10 @@ dosacrifice()
  3319.              if (Deaf)
  3320.                  pline("Oh, no."); /* didn't hear thunderclap */
  3321.              change_luck(-3);
  3322. -            adjalign(-1);
  3323. -            u.ugangr += 3;
  3324. +            if (u.ualign.type != A_NONE) {
  3325. +                adjalign(-1);
  3326. +                u.ugangr += 3;
  3327. +            }
  3328.              value = -3;
  3329.          }
  3330.      } /* fake Amulet */
  3331. @@ -1617,9 +1695,10 @@ dosacrifice()
  3332.          if (u.ualign.type != altaralign) {
  3333.              /* Is this a conversion ? */
  3334.              /* An unaligned altar in Gehennom will always elicit rejection. */
  3335. +            /* Infidels will also never be accepted. */
  3336.              if (ugod_is_angry() || (altaralign == A_NONE && Inhell)) {
  3337.                  if (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL]
  3338. -                    && altaralign != A_NONE) {
  3339. +                    && altaralign != A_NONE && !Role_if(PM_INFIDEL)) {
  3340.                      You("have a strong feeling that %s is angry...",
  3341.                          u_gname());
  3342.                      consume_offering(otmp);
  3343. @@ -1644,7 +1723,11 @@ dosacrifice()
  3344.                  consume_offering(otmp);
  3345.                  You("sense a conflict between %s and %s.", u_gname(),
  3346.                      a_gname());
  3347. -                if (rn2(8 + u.ulevel) > 5) {
  3348. +                if (rn2(8 + u.ulevel) > 5
  3349. +                    /* Infidels have difficulty converting altars. */
  3350. +                    && !(u.ualign.type == A_NONE
  3351. +                         && !(Role_if(PM_INFIDEL) && u.uhave.questart)
  3352. +                         && depth(&u.uz) < depth(&valley_level) && rn2(5))) {
  3353.                      struct monst *pri;
  3354.                      You_feel("the power of %s increase.", u_gname());
  3355.                      exercise(A_WIS, TRUE);
  3356. @@ -1659,9 +1742,11 @@ dosacrifice()
  3357.                          pline_The("altar glows %s.",
  3358.                                    hcolor((u.ualign.type == A_LAWFUL)
  3359.                                              ? NH_WHITE
  3360. -                                            : u.ualign.type
  3361. -                                               ? NH_BLACK
  3362. -                                               : (const char *) "gray"));
  3363. +                                            : u.ualign.type == A_NONE
  3364. +                                                ? NH_RED
  3365. +                                                : u.ualign.type
  3366. +                                                    ? NH_BLACK
  3367. +                                                    : (const char *) "gray"));
  3368.  
  3369.                      if (rnl(u.ulevel) > 6 && u.ualign.record > 0
  3370.                          && rnd(u.ualign.record) > (3 * ALIGNLIM) / 4)
  3371. @@ -1686,8 +1771,9 @@ dosacrifice()
  3372.          consume_offering(otmp);
  3373.          /* OK, you get brownie points. */
  3374.          if (u.ugangr) {
  3375. -            u.ugangr -= ((value * (u.ualign.type == A_CHAOTIC ? 2 : 3))
  3376. -                         / MAXVALUE);
  3377. +            u.ugangr -= ((value * (u.ualign.type == A_NONE ? 3
  3378. +                                   : u.ualign.type == A_CHAOTIC ? 4 : 6))
  3379. +                         / (MAXVALUE * 2));
  3380.              if (u.ugangr < 0)
  3381.                  u.ugangr = 0;
  3382.              if (u.ugangr != saved_anger) {
  3383. @@ -1719,7 +1805,7 @@ dosacrifice()
  3384.              adjalign(value);
  3385.              You_feel("partially absolved.");
  3386.          } else if (u.ublesscnt > 0) {
  3387. -            u.ublesscnt -= ((value * (u.ualign.type == A_CHAOTIC ? 500 : 300))
  3388. +            u.ublesscnt -= ((value * (u.ualign.type <= A_CHAOTIC ? 500 : 300))
  3389.                              / MAXVALUE);
  3390.              if (u.ublesscnt < 0)
  3391.                  u.ublesscnt = 0;
  3392. @@ -1799,7 +1885,7 @@ boolean praying; /* false means no messages should be given */
  3393.      p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type;
  3394.      p_trouble = in_trouble();
  3395.  
  3396. -    if (is_demon(youmonst.data) && (p_aligntyp != A_CHAOTIC)) {
  3397. +    if (is_demon(raceptr(&youmonst)) && (p_aligntyp > A_CHAOTIC)) {
  3398.          if (praying)
  3399.              pline_The("very idea of praying to a %s god is repugnant to you.",
  3400.                        p_aligntyp ? "lawful" : "neutral");
  3401. @@ -1830,13 +1916,16 @@ boolean praying; /* false means no messages should be given */
  3402.      }
  3403.  
  3404.      if (is_undead(youmonst.data) && !Inhell
  3405. -        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && !rn2(10))))
  3406. +        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && praying
  3407. +                                       && !rn2(10))))
  3408.          p_type = -1;
  3409. -    /* Note:  when !praying, the random factor for neutrals makes the
  3410. -       return value a non-deterministic approximation for enlightenment.
  3411. -       This case should be uncommon enough to live with... */
  3412.  
  3413. -    return !praying ? (boolean) (p_type == 3 && !Inhell) : TRUE;
  3414. +    if (p_aligntyp == A_NONE && !on_altar()
  3415. +        && depth(&u.uz) < depth(&valley_level)
  3416. +        && !(Role_if(PM_INFIDEL) && u.uhave.questart) && praying && rn2(5))
  3417. +        p_type = -2; /* Moloch can't hear you */
  3418. +
  3419. +    return praying || p_type == 3 && (!Inhell || u.ualign.type == A_NONE);
  3420.  }
  3421.  
  3422.  /* #pray commmand */
  3423. @@ -1870,7 +1959,7 @@ dopray()
  3424.      nomovemsg = "You finish your prayer.";
  3425.      afternmv = prayer_done;
  3426.  
  3427. -    if (p_type == 3 && !Inhell) {
  3428. +    if (p_type == 3 && (!Inhell || u.ualign.type == A_NONE)) {
  3429.          /* if you've been true to your god you can't die while you pray */
  3430.          if (!Blind)
  3431.              You("are surrounded by a shimmering light.");
  3432. @@ -1899,7 +1988,13 @@ prayer_done() /* M. Stephenson (1.0.3b) */
  3433.          exercise(A_CON, FALSE);
  3434.          return 1;
  3435.      }
  3436. -    if (Inhell) {
  3437. +    if (p_type == -2) {
  3438. +        pline("Unfortunately, this close to the surface %s can't hear you.",
  3439. +              align_gname(alignment));
  3440. +        /* no further effects */
  3441. +        return 0;
  3442. +    }
  3443. +    if (Inhell && u.ualign.type != A_NONE) {
  3444.          pline("Since you are in Gehennom, %s can't help you.",
  3445.                align_gname(alignment));
  3446.          /* haltingly aligned is least likely to anger */
  3447. @@ -1977,7 +2072,7 @@ doturn()
  3448.          return (u.uconduct.gnostic == 1);
  3449.      }
  3450.      if ((u.ualign.type != A_CHAOTIC
  3451. -         && (is_demon(youmonst.data) || is_undead(youmonst.data)))
  3452. +         && (is_demon(raceptr(&youmonst)) || is_undead(youmonst.data)))
  3453.          || u.ugangr > 6) { /* "Die, mortal!" */
  3454.          pline("For some reason, %s seems to ignore you.", Gname);
  3455.          aggravate();
  3456. @@ -2211,6 +2306,9 @@ aligntyp alignment;
  3457.      const char *gnam, *result = "god";
  3458.  
  3459.      switch (alignment) {
  3460. +    case A_NONE:
  3461. +        gnam = Moloch;
  3462. +        break;
  3463.      case A_LAWFUL:
  3464.          gnam = urole.lgod;
  3465.          break;
  3466. @@ -2229,6 +2327,23 @@ aligntyp alignment;
  3467.      return result;
  3468.  }
  3469.  
  3470. +/* return an alignment from a (lawful, neutral, chaotic) permutation
  3471. + * randomly chosen at game start; only relevant to Infidels */
  3472. +aligntyp
  3473. +inf_align(num)
  3474. +int num; /* 1..3 */
  3475. +{
  3476. +    aligntyp first, other;
  3477. +    first = context.inf_aligns % 3 - 1;
  3478. +    if (num == 1)
  3479. +        return first;
  3480. +    other = (context.inf_aligns + num) % 2;
  3481. +    if (other <= first)
  3482. +        other--;
  3483. +    return other;
  3484. +
  3485. +}
  3486. +
  3487.  void
  3488.  altar_wrath(x, y)
  3489.  register int x, y;
  3490. diff --git c/src/priest.c w/src/priest.c
  3491. index ab20a8d..92700f3 100644
  3492. --- c/src/priest.c
  3493. +++ w/src/priest.c
  3494. @@ -4,6 +4,7 @@
  3495.  
  3496.  #include "hack.h"
  3497.  #include "mfndpos.h"
  3498. +#include "qtext.h"
  3499.  
  3500.  /* these match the categorizations shown by enlightenment */
  3501.  #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
  3502. @@ -253,7 +254,7 @@ boolean sanctum; /* is it the seat of the high priest? */
  3503.  
  3504.          /* now his/her goodies... */
  3505.          if (sanctum && EPRI(priest)->shralign == A_NONE
  3506. -            && on_level(&sanctum_level, &u.uz)) {
  3507. +            && on_level(&sanctum_level, &u.uz) && !Role_if(PM_INFIDEL)) {
  3508.              (void) mongets(priest, AMULET_OF_YENDOR);
  3509.          }
  3510.          /* 2 to 4 spellbooks */
  3511. @@ -391,7 +392,7 @@ int roomno;
  3512.  {
  3513.      struct monst *priest, *mtmp;
  3514.      struct epri *epri_p;
  3515. -    boolean shrined, sanctum, can_speak;
  3516. +    boolean shrined, sanctum, can_speak, call_guards;
  3517.      long *this_time, *other_time;
  3518.      const char *msg1, *msg2;
  3519.      char buf[BUFSZ];
  3520. @@ -408,6 +409,7 @@ int roomno;
  3521.          sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
  3522.                     && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  3523.          can_speak = (priest->mcanmove && !priest->msleeping);
  3524. +        call_guards = FALSE;
  3525.          if (can_speak && !Deaf && moves >= epri_p->intone_time) {
  3526.              unsigned save_priest = priest->ispriest;
  3527.  
  3528. @@ -425,11 +427,20 @@ int roomno;
  3529.              epri_p->enter_time = 0L;
  3530.          }
  3531.          msg1 = msg2 = 0;
  3532. -        if (sanctum && Is_sanctum(&u.uz)) {
  3533. +        if ((sanctum && Is_sanctum(&u.uz) || u.ualign.type == A_NONE)
  3534. +            && !p_coaligned(priest)) {
  3535. +            /* either a non-Infidel in the Sanctum, or an Infidel in any
  3536. +             * non-Moloch temple; either way, the priest is not happy */
  3537.              if (priest->mpeaceful) {
  3538.                  /* first time inside */
  3539. -                msg1 = "Infidel, you have entered Moloch's Sanctum!";
  3540. -                msg2 = "Be gone!";
  3541. +                if (u.ualign.type == A_NONE) {
  3542. +                    msg1 = "Begone, infidel!";
  3543. +                    msg2 = "This place is barred for your cult!";
  3544. +                    call_guards = in_town(priest->mx, priest->my);
  3545. +                } else {
  3546. +                    msg1 = "Infidel, you have entered Moloch's Sanctum!";
  3547. +                    msg2 = "Be gone!";
  3548. +                }
  3549.                  priest->mpeaceful = 0;
  3550.                  /* became angry voluntarily; no penalty for attacking him */
  3551.                  set_malign(priest);
  3552. @@ -448,6 +459,11 @@ int roomno;
  3553.                  verbalize1(msg2);
  3554.              epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
  3555.          }
  3556. +        /* for Infidels, visiting the Minetown temple is a very bad idea */
  3557. +        if (call_guards) {
  3558. +            pline("%s calls for guards!", Monnam(priest));
  3559. +            (void) angry_guards(FALSE);
  3560. +        }
  3561.          if (!sanctum) {
  3562.              if (!shrined || !p_coaligned(priest)
  3563.                  || u.ualign.record <= ALGN_SINNED) {
  3564. @@ -549,7 +565,8 @@ register struct monst *priest;
  3565.  
  3566.      /* priests don't chat unless peaceful and in their own temple */
  3567.      if (!inhistemple(priest) || !priest->mpeaceful
  3568. -        || !priest->mcanmove || priest->msleeping) {
  3569. +        || !priest->mcanmove || priest->msleeping
  3570. +        || u.ualign.type == A_NONE && !coaligned) {
  3571.          static const char *cranky_msg[3] = {
  3572.              "Thou wouldst have words, eh?  I'll give thee a word or two!",
  3573.              "Talk?  Here is what I have to say!",
  3574. @@ -576,7 +593,15 @@ register struct monst *priest;
  3575.          return;
  3576.      }
  3577.      if (!money_cnt(invent)) {
  3578. -        if (coaligned && !strayed) {
  3579. +        if (Role_if(PM_INFIDEL) && u.uachieve.amulet
  3580. +            && priest->data == &mons[PM_HIGH_PRIEST] && Is_sanctum(&u.uz)) {
  3581. +            /* give a hint about the correct high altar */
  3582. +            aligntyp saved_align = u.ualignbase[A_ORIGINAL];
  3583. +            /* a hack for displaying a different god's name in the message */
  3584. +            u.ualignbase[A_ORIGINAL] = inf_align(3);
  3585. +            qt_pager(QT_MOLOCH_3);
  3586. +            u.ualignbase[A_ORIGINAL] = saved_align;
  3587. +        } else if (coaligned && !strayed) {
  3588.              long pmoney = money_cnt(priest->minvent);
  3589.              if (pmoney > 0L) {
  3590.                  /* Note: two bits is actually 25 cents.  Hmm. */
  3591. diff --git c/src/quest.c w/src/quest.c
  3592. index df4b831..6dcc687 100644
  3593. --- c/src/quest.c
  3594. +++ w/src/quest.c
  3595. @@ -219,9 +219,17 @@ finish_quest(obj)
  3596.  struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
  3597.  {
  3598.      struct obj *otmp;
  3599. +    aligntyp saved_align;
  3600.  
  3601. -    if (u.uhave.amulet) { /* unlikely but not impossible */
  3602. -        qt_pager(QT_HASAMULET);
  3603. +    if (u.uachieve.amulet) { /* unlikely but not impossible */
  3604. +        if (Role_if(PM_INFIDEL)) {
  3605. +            saved_align = u.ualignbase[A_ORIGINAL];
  3606. +            /* a hack for displaying a different god's name in the message */
  3607. +            u.ualignbase[A_ORIGINAL] = inf_align(2);
  3608. +            qt_pager(QT_HASAMULET);
  3609. +            u.ualignbase[A_ORIGINAL] = saved_align;
  3610. +        } else
  3611. +            qt_pager(QT_HASAMULET);
  3612.          /* leader IDs the real amulet but ignores any fakes */
  3613.          if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
  3614.              fully_identify_obj(otmp);
  3615. @@ -255,7 +263,7 @@ chat_with_leader()
  3616.       */
  3617.      if (Qstat(got_thanks)) {
  3618.          /* Rule 1: You've gone back with/without the amulet. */
  3619. -        if (u.uhave.amulet)
  3620. +        if (u.uachieve.amulet)
  3621.              finish_quest((struct obj *) 0);
  3622.  
  3623.          /* Rule 2: You've gone back before going for the amulet. */
  3624. diff --git c/src/questpgr.c w/src/questpgr.c
  3625. index 5c04c6c..3bd8b65 100644
  3626. --- c/src/questpgr.c
  3627. +++ w/src/questpgr.c
  3628. @@ -599,7 +599,7 @@ void
  3629.  com_pager(msgnum)
  3630.  int msgnum;
  3631.  {
  3632. -    struct qtmsg *qt_msg;
  3633. +    struct qtmsg *qt_msg, *alt_qt_msg;
  3634.  
  3635.      if (skip_pager(TRUE))
  3636.          return;
  3637. @@ -609,6 +609,10 @@ int msgnum;
  3638.          return;
  3639.      }
  3640.  
  3641. +    /* optional alternate game start message; currently only Inf use it */
  3642. +    if (msgnum == 1 && (alt_qt_msg = msg_in(qt_list.chrole, QT_ALTSTART)))
  3643. +        qt_msg = alt_qt_msg;
  3644. +
  3645.      (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
  3646.      if (qt_msg->delivery == 'p')
  3647.          deliver_by_pline(qt_msg);
  3648. diff --git c/src/read.c w/src/read.c
  3649. index aaa3341..f3bc78a 100644
  3650. --- c/src/read.c
  3651. +++ w/src/read.c
  3652. @@ -1118,6 +1118,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
  3653.                  uncurse(otmp);
  3654.              otmp->known = 1;
  3655.              setworn(otmp, W_ARM);
  3656. +            check_wings(TRUE);
  3657.              if (otmp->unpaid)
  3658.                  alter_cost(otmp, 0L); /* shop bill */
  3659.              break;
  3660. @@ -2150,7 +2151,9 @@ do_class_genocide()
  3661.                          /* non-leader/nemesis/guardian role-specific monster
  3662.                             */
  3663.                          && (i != PM_NINJA /* nuisance */
  3664. -                            || Role_if(PM_SAMURAI))) {
  3665. +                            || Role_if(PM_SAMURAI))
  3666. +                        && (i != PM_TEMPLAR && i != PM_CHAMPION
  3667. +                            && i != PM_AGENT || Role_if(PM_INFIDEL))) {
  3668.                          boolean named, uniq;
  3669.  
  3670.                          named = type_is_pname(&mons[i]) ? TRUE : FALSE;
  3671. diff --git c/src/role.c w/src/role.c
  3672. index f263609..1cc0bee 100644
  3673. --- c/src/role.c
  3674. +++ w/src/role.c
  3675. @@ -192,6 +192,47 @@ const struct Role roles[] = {
  3676.        A_WIS,
  3677.        SPE_CURE_SICKNESS,
  3678.        -4 },
  3679. +    { { "Infidel", 0 },
  3680. +      { { "Apostate", 0 },
  3681. +        { "Heathen", 0 },
  3682. +        { "Heretic", 0 },
  3683. +        { "Idolater", "Idolatress" },
  3684. +        { "Cultist", 0 },
  3685. +        { "Splanchomancer", 0 },
  3686. +        { "Maleficus", "Malefica" },
  3687. +        { "Demonologist", 0 },
  3688. +        { "Heresiarch", 0 } },
  3689. +      0, 0, 0, /* uses a random role's pantheon */
  3690. +      "Inf",
  3691. +      "the Hidden Temple",
  3692. +      "the Howling Forest",
  3693. +      PM_INFIDEL,
  3694. +      NON_PM,
  3695. +      PM_HOMUNCULUS,
  3696. +      PM_PREACHER_OF_MOLOCH,
  3697. +      PM_CULTIST,
  3698. +      PM_PALADIN,
  3699. +      PM_AGENT,
  3700. +      PM_CHAMPION,
  3701. +      S_DOG,
  3702. +      S_UNICORN,
  3703. +      ART_IDOL_OF_MOLOCH,                         /* actually unaligned */
  3704. +      MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
  3705. +      /* Str Int Wis Dex Con Cha */
  3706. +      { 7, 7, 10, 7, 7, 7 },
  3707. +      { 20, 10, 25, 15, 20, 10 },
  3708. +      /* Init   Lower  Higher */
  3709. +      { 10, 0, 0, 8, 1, 0 }, /* Hit points */
  3710. +      { 4, 3, 0, 1, 0, 2 },
  3711. +      10, /* Energy */
  3712. +      10,
  3713. +      3,
  3714. +      1,
  3715. +      2,
  3716. +      10,
  3717. +      A_WIS,
  3718. +      SPE_FIREBALL,
  3719. +      -4 },
  3720.      { { "Knight", 0 },
  3721.        { { "Gallant", 0 },
  3722.          { "Esquire", 0 },
  3723. @@ -725,6 +766,29 @@ const struct Race races[] = {
  3724.      { 0, 0, 0, 0 }
  3725.  };
  3726.  
  3727. +/* Special race for crowned Infidels. */
  3728. +struct Race race_demon = {
  3729. +    "demon",
  3730. +    "demonic",
  3731. +    "demonkind",
  3732. +    "Dem",
  3733. +    { 0, 0 },
  3734. +    PM_DEMON,
  3735. +    NON_PM,
  3736. +    NON_PM,
  3737. +    NON_PM,
  3738. +    MH_DEMON | ROLE_MALE | ROLE_FEMALE, /* not available at start */
  3739. +    MH_DEMON,
  3740. +    MH_DEMON,
  3741. +    MH_HUMAN | MH_ELF | MH_DWARF | MH_GNOME,
  3742. +    /*  Str    Int Wis Dex Con Cha */
  3743. +    { 3, 3, 3, 3, 3, 3 },
  3744. +    { STR18(100), 18, 18, 20, 20, 18 },
  3745. +    /* Init   Lower  Higher */
  3746. +    { 8, 0, 0, 8, 4, 0 }, /* Hit points */
  3747. +    { 4, 0, 6, 0, 6, 0 }  /* Energy */
  3748. +};
  3749. +
  3750.  /* The player's race, created at runtime from initial
  3751.   * choices.  This may be munged in role_init().
  3752.   */
  3753. @@ -779,6 +843,16 @@ STATIC_DCL int FDECL(race_alignmentcount, (int));
  3754.  /* used by str2XXX() */
  3755.  static char NEARDATA randomstr[] = "random";
  3756.  
  3757. +/* Inf are listed as chaotic above, but actually are unaligned. */
  3758. +int
  3759. +special_alignment(rolenum, alignnum)
  3760. +int rolenum, alignnum;
  3761. +{
  3762. +    if (roles[rolenum].malenum == PM_INFIDEL)
  3763. +        return 3; /* aligns[unaligned] */
  3764. +    return alignnum;
  3765. +}
  3766. +
  3767.  boolean
  3768.  validrole(rolenum)
  3769.  int rolenum;
  3770. @@ -1503,12 +1577,12 @@ int buflen, rolenum, racenum, gendnum, alignnum;
  3771.          if ((racenum >= 0) && (aligncount > 1)) {
  3772.              if (donefirst)
  3773.                  Strcat(buf, " ");
  3774. -            Strcat(buf, aligns[alignnum].adj);
  3775. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  3776.              donefirst = TRUE;
  3777.          } else {
  3778.              if (donefirst)
  3779.                  Strcat(buf, " ");
  3780. -            Strcat(buf, aligns[alignnum].adj);
  3781. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  3782.              donefirst = TRUE;
  3783.          }
  3784.      } else {
  3785. @@ -1800,6 +1874,7 @@ winid where;
  3786.              a = 2; /* alings[chaotic] */
  3787.          /* [c never forces gender] */
  3788.      }
  3789. +    a = special_alignment(r, a); /* special case (Infidel) */
  3790.      /* [g and a don't constrain anything sufficiently
  3791.         to narrow something done to a single choice] */
  3792.  
  3793. @@ -1935,6 +2010,7 @@ boolean preselect;
  3794.                  a = 1; /* aligns[neutral] */
  3795.              else if (allowmask == AM_CHAOTIC)
  3796.                  a = 2; /* aligns[chaotic] */
  3797. +            a = special_alignment(r, a); /* special case (Infidel) */
  3798.              if (a >= 0)
  3799.                  constrainer = "role";
  3800.          }
  3801. @@ -2010,7 +2086,7 @@ boolean preselect;
  3802.  void
  3803.  role_init()
  3804.  {
  3805. -    int alignmnt;
  3806. +    int alignmnt, malignmnt;
  3807.      struct permonst *pm;
  3808.  
  3809.      /* Strip the role letter out of the player name.
  3810. @@ -2049,7 +2125,11 @@ role_init()
  3811.      if (!validalign(flags.initrole, flags.initrace, flags.initalign))
  3812.          /* Pick a random alignment */
  3813.          flags.initalign = randalign(flags.initrole, flags.initrace);
  3814. -    alignmnt = aligns[flags.initalign].value;
  3815. +    /* Infidels are actually unaligned */
  3816. +    flags.initalign = special_alignment(flags.initrole, flags.initalign);
  3817. +    alignmnt = malignmnt = aligns[flags.initalign].value;
  3818. +    if (alignmnt != A_NONE)
  3819. +        malignmnt *= 3;
  3820.  
  3821.      /* Initialize urole and urace */
  3822.      urole = roles[flags.initrole];
  3823. @@ -2061,7 +2141,7 @@ role_init()
  3824.          pm->msound = MS_LEADER;
  3825.          pm->mflags2 |= (M2_PEACEFUL);
  3826.          pm->mflags3 |= M3_CLOSE;
  3827. -        pm->maligntyp = alignmnt * 3;
  3828. +        pm->maligntyp = malignmnt;
  3829.          /* if gender is random, we choose it now instead of waiting
  3830.             until the leader monster is created */
  3831.          quest_status.ldrgend =
  3832. @@ -2074,7 +2154,7 @@ role_init()
  3833.      if (urole.guardnum != NON_PM) {
  3834.          pm = &mons[urole.guardnum];
  3835.          pm->mflags2 |= (M2_PEACEFUL);
  3836. -        pm->maligntyp = alignmnt * 3;
  3837. +        pm->maligntyp = malignmnt;
  3838.      }
  3839.  
  3840.      /* Fix up the quest nemesis */
  3841. @@ -2091,6 +2171,14 @@ role_init()
  3842.                                     : is_male(pm) ? 0 : (rn2(100) < 50);
  3843.      }
  3844.  
  3845. +    /* Enable special Inf enemies */
  3846. +    if (Role_if(PM_INFIDEL)) {
  3847. +        if (urole.enemy1num != NON_PM)
  3848. +            mons[urole.enemy1num].geno &= ~G_NOGEN;
  3849. +        if (urole.enemy2num != NON_PM)
  3850. +            mons[urole.enemy2num].geno &= ~G_NOGEN;
  3851. +    }
  3852. +
  3853.      /* Fix up the god names */
  3854.      if (flags.pantheon == -1) {             /* new game */
  3855.          flags.pantheon = flags.initrole;    /* use own gods */
  3856. diff --git c/src/shk.c w/src/shk.c
  3857. index 6772da4..91c75f8 100644
  3858. --- c/src/shk.c
  3859. +++ w/src/shk.c
  3860. @@ -4776,7 +4776,7 @@ boolean altusage; /* used as a verbalized exclamation:  \"Cad! ...\" */
  3861.  {
  3862.      const char *res = 0;
  3863.  
  3864. -    switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
  3865. +    switch (is_demon(raceptr(&youmonst)) ? 3 : poly_gender()) {
  3866.      case 0:
  3867.          res = "cad";
  3868.          break;
  3869. diff --git c/src/sp_lev.c w/src/sp_lev.c
  3870. index 2c5628f..4817839 100644
  3871. --- c/src/sp_lev.c
  3872. +++ w/src/sp_lev.c
  3873. @@ -1624,6 +1624,14 @@ struct mkroom *croom;
  3874.          && (Race_if(PM_DWARF) || Race_if(PM_GNOME)) && rn2(3))
  3875.          pm = (struct permonst *) 0;
  3876.  
  3877. +    /* Make Sanctum monsters more friendly to Infidels */
  3878. +    if (u.ualign.type == A_NONE && Is_sanctum(&u.uz) && m->peaceful == 0)
  3879. +        m->peaceful = 1;
  3880. +    /* OTOH, the Astral shouldn't be easy; but the multitude of
  3881. +     * renegade minions of Moloch is still silly */
  3882. +    if (Role_if(PM_INFIDEL) && Is_astralevel(&u.uz) && amask == AM_NONE)
  3883. +        amask = Align2amask(rn1(3, -1));
  3884. +
  3885.      if (pm) {
  3886.          int loc = pm_to_humidity(pm);
  3887.          /* If water-liking monster, first try is without DRY */
  3888. diff --git c/src/spell.c w/src/spell.c
  3889. index 9cbb9a4..1981718 100644
  3890. --- c/src/spell.c
  3891. +++ w/src/spell.c
  3892. @@ -54,6 +54,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  3893.   *      Bar abhor magic (Conan finds it "interferes with his animal instincts")
  3894.   *      Cav are ignorant to magic
  3895.   *      Hea are very aware of healing magic through medical research
  3896. + *      Inf learned a lot of black magic from their cult
  3897.   *      Kni are moderately aware of healing from Paladin training
  3898.   *      Mon use magic to attack and defend in lieu of weapons and armor
  3899.   *      Pri are very aware of healing magic through theological research
  3900. @@ -74,6 +75,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  3901.   *      Bar fugue/berserker (SPE_HASTE_SELF)
  3902.   *      Cav born to dig (SPE_DIG)
  3903.   *      Hea to heal (SPE_CURE_SICKNESS)
  3904. + *      Inf to channel hellfire (SPE_FIREBALL)
  3905.   *      Kni to turn back evil (SPE_TURN_UNDEAD)
  3906.   *      Mon to preserve their abilities (SPE_RESTORE_ABILITY)
  3907.   *      Pri to bless (SPE_REMOVE_CURSE)
  3908. @@ -1741,6 +1743,25 @@ int spell;
  3909.      if (uarmf && is_metallic(uarmf))
  3910.          splcaster += uarmfbon;
  3911.  
  3912. +    /* Infidels have a special penalty for wearing blessed armor. */
  3913. +    if (Role_if(PM_INFIDEL)) {
  3914. +        static struct obj **const armor[] = { &uarm, &uarmc, &uarmh, &uarms,
  3915. +                                              &uarmg, &uarmf, &uarmu };
  3916. +        int penalty = 0;
  3917. +        int i;
  3918. +
  3919. +        for (i = 0; i < SIZE(armor); i++) {
  3920. +            if (!*armor[i])
  3921. +                continue;
  3922. +            if ((*armor[i])->blessed)
  3923. +                penalty += 2;
  3924. +            else if ((*armor[i])->cursed)
  3925. +                penalty--;
  3926. +        }
  3927. +        if (penalty > 0)
  3928. +            splcaster += penalty;
  3929. +    }
  3930. +
  3931.      if (spellid(spell) == urole.spelspec)
  3932.          splcaster += urole.spelsbon;
  3933.  
  3934. diff --git c/src/teleport.c w/src/teleport.c
  3935. index 23af60a..27a86cd 100644
  3936. --- c/src/teleport.c
  3937. +++ w/src/teleport.c
  3938. @@ -842,12 +842,25 @@ level_tele()
  3939.  
  3940.                  newlevel.dnum = destdnum;
  3941.                  newlevel.dlevel = destlev;
  3942. -                if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
  3943. +                if (In_endgame(&newlevel) && !In_endgame(&u.uz)
  3944. +                    && !u.uhave.amulet) {
  3945.                      struct obj *amu;
  3946.  
  3947. -                    if (!u.uhave.amulet
  3948. -                        && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
  3949. -                               != 0) {
  3950. +                    if (!Role_if(PM_INFIDEL)) {
  3951. +                        amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE);
  3952. +                    } else if (amu = find_quest_artifact(1 << OBJ_INVENT)) {
  3953. +                        obj_extract_self(amu); /* may be contained */
  3954. +                        amu->spe = 1;
  3955. +                    } else {
  3956. +                        const char *idol = artiname(ART_IDOL_OF_MOLOCH);
  3957. +                        amu = mksobj(FIGURINE, TRUE, FALSE);
  3958. +                        artifact_exists(amu, idol, TRUE);
  3959. +                        new_oname(amu, strlen(idol) + 1);
  3960. +                        Strcpy(ONAME(amu), idol);
  3961. +                        amu->spe = 1;
  3962. +                    }
  3963. +
  3964. +                    if (amu) {
  3965.                          /* ordinarily we'd use hold_another_object()
  3966.                             for something like this, but we don't want
  3967.                             fumbling or already full pack to interfere */
  3968. diff --git c/src/u_init.c w/src/u_init.c
  3969. index 77e7445..f19db59 100644
  3970. --- c/src/u_init.c
  3971. +++ w/src/u_init.c
  3972. @@ -21,6 +21,7 @@ STATIC_DCL boolean FDECL(restricted_spell_discipline, (int));
  3973.  #define UNDEF_TYP 0
  3974.  #define UNDEF_SPE '\177'
  3975.  #define UNDEF_BLESS 2
  3976. +#define CURSED 3
  3977.  
  3978.  /*
  3979.   *      Initial inventory for the various roles.
  3980. @@ -70,6 +71,19 @@ static struct trobj Healer[] = {
  3981.      { APPLE, 0, FOOD_CLASS, 5, 0 },
  3982.      { 0, 0, 0, 0, 0 }
  3983.  };
  3984. +static struct trobj Infidel[] = {
  3985. +    { AMULET_OF_YENDOR, 0, AMULET_CLASS, 1, 0 },
  3986. +    { DAGGER, 1, WEAPON_CLASS, 1, 0 },
  3987. +    { LEATHER_JACKET, 1, ARMOR_CLASS, 1, CURSED },
  3988. +    { CLOAK_OF_PROTECTION, 0, ARMOR_CLASS, 1, CURSED },
  3989. +    { POT_WATER, 0, POTION_CLASS, 3, CURSED },
  3990. +    { SPE_DRAIN_LIFE, 0, SPBOOK_CLASS, 1, 0 },
  3991. +    { UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, 0 },
  3992. +    { FIRE_HORN, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  3993. +    { MAGIC_MARKER, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  3994. +    { 0, 0, 0, 0, 0 }
  3995. +
  3996. +};
  3997.  static struct trobj Knight[] = {
  3998.      { LONG_SWORD, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  3999.      { LANCE, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  4000. @@ -324,6 +338,30 @@ static const struct def_skill Skill_H[] = {
  4001.      { P_BARE_HANDED_COMBAT, P_BASIC },
  4002.      { P_NONE, 0 }
  4003.  };
  4004. +static const struct def_skill Skill_Inf[] = {
  4005. +    { P_DAGGER, P_EXPERT },
  4006. +    { P_KNIFE, P_EXPERT },
  4007. +    { P_SHORT_SWORD, P_SKILLED },
  4008. +    { P_BROAD_SWORD, P_BASIC },
  4009. +    { P_SCIMITAR, P_SKILLED },
  4010. +    { P_SABER, P_BASIC },
  4011. +    { P_CLUB, P_BASIC },
  4012. +    { P_HAMMER, P_BASIC },
  4013. +    { P_QUARTERSTAFF, P_SKILLED },
  4014. +    { P_POLEARMS, P_SKILLED },
  4015. +    { P_SPEAR, P_BASIC },
  4016. +    { P_SLING, P_BASIC },
  4017. +    { P_CROSSBOW, P_SKILLED },
  4018. +    { P_DART, P_BASIC },
  4019. +    { P_WHIP, P_SKILLED },
  4020. +    { P_ATTACK_SPELL, P_EXPERT },
  4021. +    { P_DIVINATION_SPELL, P_SKILLED },
  4022. +    { P_ENCHANTMENT_SPELL, P_BASIC },
  4023. +    { P_CLERIC_SPELL, P_EXPERT },
  4024. +    { P_BARE_HANDED_COMBAT, P_SKILLED },
  4025. +    { P_RIDING, P_SKILLED },
  4026. +    { P_NONE, 0 }
  4027. +};
  4028.  static const struct def_skill Skill_K[] = {
  4029.      { P_DAGGER, P_BASIC },
  4030.      { P_KNIFE, P_BASIC },
  4031. @@ -701,6 +739,12 @@ u_init()
  4032.          knows_object(POT_FULL_HEALING);
  4033.          skill_init(Skill_H);
  4034.          break;
  4035. +    case PM_INFIDEL:
  4036. +        u.umoney0 = rn1(251, 250);
  4037. +        ini_inv(Infidel);
  4038. +        knows_object(SCR_CHARGING); /* that's what the marker is for */
  4039. +        skill_init(Skill_Inf);
  4040. +        break;
  4041.      case PM_KNIGHT:
  4042.          ini_inv(Knight);
  4043.          knows_class(WEAPON_CLASS);
  4044. @@ -927,6 +971,9 @@ int otyp;
  4045.      case PM_HEALER:
  4046.          skills = Skill_H;
  4047.          break;
  4048. +    case PM_INFIDEL:
  4049. +        skills = Skill_Inf;
  4050. +        break;
  4051.      case PM_KNIGHT:
  4052.          skills = Skill_K;
  4053.          break;
  4054. @@ -1014,6 +1061,8 @@ register struct trobj *trop;
  4055.                     || (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
  4056.                     /* wizard patch -- they already have one */
  4057.                     || (otyp == SPE_FORCE_BOLT && Role_if(PM_WIZARD))
  4058. +                   /* same for infidels */
  4059. +                   || (otyp == SPE_DRAIN_LIFE && Role_if(PM_INFIDEL))
  4060.                     /* powerful spells are either useless to
  4061.                        low level players or unbalancing; also
  4062.                        spells in restricted skill categories */
  4063. @@ -1086,7 +1135,7 @@ register struct trobj *trop;
  4064.                  obj->cknown = obj->lknown = 1;
  4065.                  obj->otrapped = 0;
  4066.              }
  4067. -            obj->cursed = 0;
  4068. +            obj->cursed = (trop->trbless == CURSED);
  4069.              if (obj->opoisoned && u.ualign.type != A_CHAOTIC)
  4070.                  obj->opoisoned = 0;
  4071.              if (obj->oclass == WEAPON_CLASS || obj->oclass == TOOL_CLASS) {
  4072. @@ -1096,10 +1145,14 @@ register struct trobj *trop;
  4073.                         && obj->otyp != FLINT) {
  4074.                  obj->quan = 1L;
  4075.              }
  4076. +            if (Role_if(PM_INFIDEL) && obj->oclass == ARMOR_CLASS) {
  4077. +                /* Infidels are used to playing with fire */
  4078. +                obj->oerodeproof = 1;
  4079. +            }
  4080.              if (trop->trspe != UNDEF_SPE)
  4081.                  obj->spe = trop->trspe;
  4082.              if (trop->trbless != UNDEF_BLESS)
  4083. -                obj->blessed = trop->trbless;
  4084. +                obj->blessed = (trop->trbless == 1);
  4085.          }
  4086.          /* defined after setting otyp+quan + blessedness */
  4087.          obj->owt = weight(obj);
  4088. diff --git c/src/uhitm.c w/src/uhitm.c
  4089. index 2eedb18..d0eec28 100644
  4090. --- c/src/uhitm.c
  4091. +++ w/src/uhitm.c
  4092. @@ -20,7 +20,7 @@ STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
  4093.  STATIC_DCL void FDECL(start_engulf, (struct monst *));
  4094.  STATIC_DCL void NDECL(end_engulf);
  4095.  STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
  4096. -STATIC_DCL boolean FDECL(hmonas, (struct monst *));
  4097. +STATIC_DCL boolean FDECL(hmonas, (struct monst *, int, boolean));
  4098.  STATIC_DCL void FDECL(nohandglow, (struct monst *));
  4099.  STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
  4100.  
  4101. @@ -438,7 +438,7 @@ register struct monst *mtmp;
  4102.      }
  4103.  
  4104.      if (Upolyd)
  4105. -        (void) hmonas(mtmp);
  4106. +        (void) hmonas(mtmp, NON_PM, TRUE);
  4107.      else
  4108.          (void) hitum(mtmp, youmonst.data->mattk);
  4109.      mtmp->mstrategy &= ~STRAT_WAITMASK;
  4110. @@ -641,6 +641,20 @@ struct attack *uattk;
  4111.          if (mhit)
  4112.              (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
  4113.      }
  4114. +
  4115. +    /* your race may grant extra attacks */
  4116. +    if (!Upolyd && malive) {
  4117. +        int i;
  4118. +        int race = (flags.female && urace.femalenum != NON_PM)
  4119. +                   ? urace.femalenum : urace.malenum;
  4120. +        struct attack *attacks = mons[race].mattk;
  4121. +        for (i = 0; i < NATTK; i++) {
  4122. +            if (attacks[i].aatyp != AT_WEAP && attacks[i].aatyp != AT_NONE) {
  4123. +                malive = hmonas(mon, race, FALSE);
  4124. +                break;
  4125. +            }
  4126. +        }
  4127. +    }
  4128.      return malive;
  4129.  }
  4130.  
  4131. @@ -1327,6 +1341,15 @@ int dieroll;
  4132.                  pline("%s appears confused.", Monnam(mon));
  4133.          }
  4134.      }
  4135. +    if (DEADMONSTER(mon) && attacks(AD_DREN, obj)
  4136. +        && !nonliving(mdat) && u.uen < u.uenmax) {
  4137. +        int energy = mon->m_lev + 1;
  4138. +        energy += rn2(energy);
  4139. +        pline_The("ritual knife captures the evanescent life force.");
  4140. +        u.uen += energy;
  4141. +        if (u.uen > u.uenmax)
  4142. +            u.uen = u.uenmax;
  4143. +    }
  4144.      if (unpoisonmsg)
  4145.          Your("%s %s no longer poisoned.", saved_oname,
  4146.               vtense(saved_oname, "are"));
  4147. @@ -1643,7 +1666,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
  4148.  
  4149.      if (is_demon(youmonst.data) && !rn2(13) && !uwep
  4150.          && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
  4151. -        && u.umonnum != PM_BALROG) {
  4152. +        && u.umonnum != PM_BALROG && u.umonnum != PM_DEMON) {
  4153.          demonpet();
  4154.          return 0;
  4155.      }
  4156. @@ -2346,12 +2369,14 @@ boolean wouldhavehit;
  4157.  
  4158.  /* attack monster as a monster; returns True if mon survives */
  4159.  STATIC_OVL boolean
  4160. -hmonas(mon)
  4161. +hmonas(mon, as, weapon_attacks)
  4162.  register struct monst *mon;
  4163. +int as;
  4164. +boolean weapon_attacks; /* skip weapon attacks if false */
  4165.  {
  4166.      struct attack *mattk, alt_attk;
  4167.      struct obj *weapon, **originalweapon;
  4168. -    boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
  4169. +    boolean altwep = FALSE, weapon_used = !weapon_attacks, odd_claw = TRUE;
  4170.      int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
  4171.      int dieroll, multi_claw = 0;
  4172.  
  4173. @@ -2360,8 +2385,11 @@ register struct monst *mon;
  4174.         whether silver ring causes successful hit */
  4175.      for (i = 0; i < NATTK; i++) {
  4176.          sum[i] = 0;
  4177. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4178. -        if (mattk->aatyp == AT_WEAP
  4179. +        if (as != NON_PM)
  4180. +            mattk = &mons[as].mattk[i];
  4181. +        else
  4182. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4183. +        if (mattk->aatyp == AT_WEAP && weapon_attacks
  4184.              || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
  4185.              ++multi_claw;
  4186.      }
  4187. @@ -2369,11 +2397,16 @@ register struct monst *mon;
  4188.  
  4189.      for (i = 0; i < NATTK; i++) {
  4190.          /* sum[i] = 0; -- now done above */
  4191. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4192. +        if (as != NON_PM)
  4193. +            mattk = &mons[as].mattk[i];
  4194. +        else
  4195. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4196.          weapon = 0;
  4197.          switch (mattk->aatyp) {
  4198.          case AT_WEAP:
  4199.              /* if (!uwep) goto weaponless; */
  4200. +            if (!weapon_attacks)
  4201. +                continue;
  4202.   use_weapon:
  4203.              odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
  4204.              /* if we've already hit with a two-handed weapon, we don't
  4205. diff --git c/src/weapon.c w/src/weapon.c
  4206. index 1027409..573c050 100644
  4207. --- c/src/weapon.c
  4208. +++ w/src/weapon.c
  4209. @@ -1610,6 +1610,8 @@ const struct def_skill *class_skill;
  4210.      /* set skills for magic */
  4211.      if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
  4212.          P_SKILL(P_HEALING_SPELL) = P_BASIC;
  4213. +    } else if (Role_if(PM_INFIDEL)) {
  4214. +        P_SKILL(P_ATTACK_SPELL) = P_BASIC;
  4215.      } else if (Role_if(PM_PRIEST)) {
  4216.          P_SKILL(P_CLERIC_SPELL) = P_BASIC;
  4217.      } else if (Role_if(PM_WIZARD)) {
  4218. diff --git c/src/wield.c w/src/wield.c
  4219. index 18c276a..07b7ca3 100644
  4220. --- c/src/wield.c
  4221. +++ w/src/wield.c
  4222. @@ -64,6 +64,8 @@ STATIC_DCL int FDECL(ready_weapon, (struct obj *));
  4223.  /* used by welded(), and also while wielding */
  4224.  #define will_weld(optr) \
  4225.      ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
  4226. +/* Infidels are immune to curses */
  4227. +#define will_weld_to_you(optr) (will_weld(optr) && !Role_if(PM_INFIDEL))
  4228.  
  4229.  /*** Functions that place a given item in a slot ***/
  4230.  /* Proper usage includes:
  4231. @@ -160,7 +162,7 @@ struct obj *wep;
  4232.      } else {
  4233.          /* Weapon WILL be wielded after this point */
  4234.          res++;
  4235. -        if (will_weld(wep)) {
  4236. +        if (will_weld_to_you(wep)) {
  4237.              const char *tmp = xname(wep), *thestr = "The ";
  4238.  
  4239.              if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
  4240. @@ -575,7 +577,7 @@ const char *verb; /* "rub",&c */
  4241.      } else {
  4242.          struct obj *oldwep = uwep;
  4243.  
  4244. -        if (will_weld(obj)) {
  4245. +        if (will_weld_to_you(obj)) {
  4246.              /* hope none of ready_weapon()'s early returns apply here... */
  4247.              (void) ready_weapon(obj);
  4248.          } else {
  4249. @@ -858,7 +860,7 @@ int
  4250.  welded(obj)
  4251.  register struct obj *obj;
  4252.  {
  4253. -    if (obj && obj == uwep && will_weld(obj)) {
  4254. +    if (obj && obj == uwep && will_weld_to_you(obj)) {
  4255.          set_bknown(obj, 1);
  4256.          return 1;
  4257.      }
  4258. diff --git c/src/wizard.c w/src/wizard.c
  4259. index b1dae1e..fd7281e 100644
  4260. --- c/src/wizard.c
  4261. +++ w/src/wizard.c
  4262. @@ -66,7 +66,9 @@ amulet()
  4263.          return;
  4264.  #endif
  4265.      if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR)
  4266. -         || ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
  4267. +         || ((amu = uwep) != 0 && (amu->otyp == AMULET_OF_YENDOR
  4268. +                                   || amu->oartifact == ART_IDOL_OF_MOLOCH
  4269. +                                      && amu->spe)))
  4270.          && !rn2(15)) {
  4271.          for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  4272.              if (ttmp->ttyp == MAGIC_PORTAL) {
  4273. @@ -106,7 +108,8 @@ register struct monst *mtmp;
  4274.      register struct obj *otmp;
  4275.  
  4276.      for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
  4277. -        if (otmp->otyp == AMULET_OF_YENDOR)
  4278. +        if (otmp->otyp == AMULET_OF_YENDOR
  4279. +            || otmp->oartifact == ART_IDOL_OF_MOLOCH && otmp->spe)
  4280.              return 1;
  4281.      return 0;
  4282.  }
  4283. diff --git c/src/worn.c w/src/worn.c
  4284. index 1a966b7..db2b27d 100644
  4285. --- c/src/worn.c
  4286. +++ w/src/worn.c
  4287. @@ -578,6 +578,10 @@ boolean racialexception;
  4288.                  continue;
  4289.              if (racialexception && (racial_exception(mon, obj) < 1))
  4290.                  continue;
  4291. +            /* monsters won't sacrifice flight for AC */
  4292. +            if (big_wings(mon->data) && !Is_dragon_scales(obj)
  4293. +                && obj->otyp != LEATHER_JACKET)
  4294. +                continue;
  4295.              break;
  4296.          }
  4297.          if (obj->owornmask)
  4298. diff --git c/src/zap.c w/src/zap.c
  4299. index 1c7a5de..2784f34 100644
  4300. --- c/src/zap.c
  4301. +++ w/src/zap.c
  4302. @@ -1182,6 +1182,7 @@ struct obj *obj;
  4303.  int ochance, achance; /* percent chance for ordinary objects, artifacts */
  4304.  {
  4305.      if (obj->otyp == AMULET_OF_YENDOR
  4306. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
  4307.          || obj->otyp == SPE_BOOK_OF_THE_DEAD
  4308.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  4309.          || obj->otyp == BELL_OF_OPENING
  4310. @@ -2446,7 +2447,7 @@ boolean ordinary;
  4311.  
  4312.      case WAN_DEATH:
  4313.      case SPE_FINGER_OF_DEATH:
  4314. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  4315. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  4316.              pline((obj->otyp == WAN_DEATH)
  4317.                        ? "The wand shoots an apparently harmless beam at you."
  4318.                        : "You seem no deader than before.");
  4319. @@ -3838,7 +3839,7 @@ xchar sx, sy;
  4320.                  (void) destroy_arm(uarmc);
  4321.              if (uarmu)
  4322.                  (void) destroy_arm(uarmu);
  4323. -        } else if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  4324. +        } else if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  4325.              shieldeff(sx, sy);
  4326.              You("seem unaffected.");
  4327.              break;
  4328. diff --git c/sys/amiga/Makefile.agc w/sys/amiga/Makefile.agc
  4329. index 47040b5..b13632e 100644
  4330. --- c/sys/amiga/Makefile.agc
  4331. +++ w/sys/amiga/Makefile.agc
  4332. @@ -228,6 +228,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  4333.     $(SLIB)Hea-strt.lev
  4334.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  4335.  
  4336. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  4337. +   $(SLIB)Inf-strt.lev
  4338. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  4339. +
  4340.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  4341.     $(SLIB)Kni-strt.lev
  4342.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  4343. @@ -264,7 +268,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  4344.     $(SLIB)Wiz-strt.lev
  4345.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  4346.  
  4347. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  4348. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  4349.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  4350.         $(VDFILES) $(WDFILES)
  4351.  
  4352. @@ -843,6 +847,10 @@ $(HDFILES1):   $(SLIB)Hea-goal.lev
  4353.  
  4354.  $(SLIB)Hea-goal.lev:   $(DAT)Healer.des $(SBIN)lev_comp
  4355.  
  4356. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  4357. +
  4358. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  4359. +
  4360.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  4361.  
  4362.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  4363. diff --git c/sys/amiga/Makefile.ami w/sys/amiga/Makefile.ami
  4364. index 14b1298..6fefee5 100644
  4365. --- c/sys/amiga/Makefile.ami
  4366. +++ w/sys/amiga/Makefile.ami
  4367. @@ -435,6 +435,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  4368.     $(SLIB)Hea-strt.lev
  4369.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  4370.  
  4371. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  4372. +   $(SLIB)Inf-strt.lev
  4373. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  4374. +
  4375.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  4376.     $(SLIB)Kni-strt.lev
  4377.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  4378. @@ -471,7 +475,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  4379.     $(SLIB)Wiz-strt.lev
  4380.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  4381.  
  4382. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  4383. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  4384.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  4385.         $(VDFILES) $(WDFILES)
  4386.  
  4387. @@ -1148,6 +1152,12 @@ $(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp
  4388.  #SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des
  4389.  #none
  4390.  
  4391. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  4392. +
  4393. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  4394. +#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Infidel.des
  4395. +#none
  4396. +
  4397.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  4398.  
  4399.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  4400. diff --git c/sys/msdos/Makefile.BC w/sys/msdos/Makefile.BC
  4401. index ce0756a..5476f58 100644
  4402. --- c/sys/msdos/Makefile.BC
  4403. +++ w/sys/msdos/Makefile.BC
  4404. @@ -718,7 +718,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  4405.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  4406.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  4407.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  4408. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  4409. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  4410.  
  4411.  #
  4412.  # Utility Objects.
  4413. @@ -976,6 +976,7 @@ $(DAT)\sp_lev.tag: $(U)utility.tag $(SPLEVDES)
  4414.     $(U)lev_comp barb.des
  4415.     $(U)lev_comp caveman.des
  4416.     $(U)lev_comp healer.des
  4417. +   $(U)lev_comp infidel.des
  4418.     $(U)lev_comp knight.des
  4419.     $(U)lev_comp monk.des
  4420.     $(U)lev_comp priest.des
  4421. diff --git c/sys/msdos/Makefile.GCC w/sys/msdos/Makefile.GCC
  4422. index 4693bda..579f11a 100644
  4423. --- c/sys/msdos/Makefile.GCC
  4424. +++ w/sys/msdos/Makefile.GCC
  4425. @@ -1016,7 +1016,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  4426.     $(DAT)/caveman.des   $(DAT)/healer.des   $(DAT)/knight.des \
  4427.     $(DAT)/monk.des      $(DAT)/priest.des   $(DAT)/ranger.des \
  4428.     $(DAT)/rogue.des     $(DAT)/samurai.des  $(DAT)/tourist.des \
  4429. -   $(DAT)/valkyrie.des  $(DAT)/wizard.des
  4430. +   $(DAT)/valkyrie.des  $(DAT)/wizard.des $(DAT)/infidel.des
  4431.     @$(subst /,\,cd $(DAT))
  4432.     @$(subst /,\,$(U)lev_comp bigroom.des)
  4433.     @$(subst /,\,$(U)lev_comp castle.des)
  4434. @@ -1033,6 +1033,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  4435.     @$(subst /,\,$(U)lev_comp barb.des)
  4436.     @$(subst /,\,$(U)lev_comp caveman.des)
  4437.     @$(subst /,\,$(U)lev_comp healer.des)
  4438. +   @$(subst /,\,$(U)lev_comp infidel.des)
  4439.     @$(subst /,\,$(U)lev_comp knight.des)
  4440.     @$(subst /,\,$(U)lev_comp monk.des)
  4441.     @$(subst /,\,$(U)lev_comp priest.des)
  4442. diff --git c/sys/msdos/Makefile.MSC w/sys/msdos/Makefile.MSC
  4443. index b7d827a..b605dcc 100644
  4444. --- c/sys/msdos/Makefile.MSC
  4445. +++ w/sys/msdos/Makefile.MSC
  4446. @@ -148,7 +148,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  4447.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  4448.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  4449.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  4450. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  4451. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  4452.  
  4453.  VGAOBJ      = vidvga.o
  4454.  
  4455. @@ -428,6 +428,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(SPLEVDES)
  4456.     $(U)lev_comp barb.des
  4457.     $(U)lev_comp caveman.des
  4458.     $(U)lev_comp healer.des
  4459. +   $(U)lev_comp infidel.des
  4460.     $(U)lev_comp knight.des
  4461.     $(U)lev_comp monk.des
  4462.     $(U)lev_comp priest.des
  4463. @@ -973,6 +974,11 @@ nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(DAT)\options \
  4464.     echo HEA-GOAL.LEV  >>dlb.lst
  4465.     echo HEA-LOCA.LEV  >>dlb.lst
  4466.     echo HEA-STRT.LEV  >>dlb.lst
  4467. +   echo INF-FILA.LEV  >>dlb.lst
  4468. +   echo INF-FILB.LEV  >>dlb.lst
  4469. +   echo INF-GOAL.LEV  >>dlb.lst
  4470. +   echo INF-LOCA.LEV  >>dlb.lst
  4471. +   echo INF-STRT.LEV  >>dlb.lst
  4472.     echo JUIBLEX.LEV   >>dlb.lst
  4473.     echo KNI-FILA.LEV  >>dlb.lst
  4474.     echo KNI-FILB.LEV  >>dlb.lst
  4475. diff --git c/sys/os2/Makefile.os2 w/sys/os2/Makefile.os2
  4476. index 4afcf0f..9ddaad5 100644
  4477. --- c/sys/os2/Makefile.os2
  4478. +++ w/sys/os2/Makefile.os2
  4479. @@ -1280,6 +1280,7 @@ AFILES = $(GAMEDIR)\Arc-goal.lev
  4480.  BFILES = $(GAMEDIR)\Bar-goal.lev
  4481.  CFILES = $(GAMEDIR)\Cav-goal.lev
  4482.  HFILES = $(GAMEDIR)\Hea-goal.lev
  4483. +IFILES = $(GAMEDIR)\Inf-goal.lev
  4484.  KFILES = $(GAMEDIR)\Kni-goal.lev
  4485.  MFILES = $(GAMEDIR)\Mon-goal.lev
  4486.  PFILES = $(GAMEDIR)\Pri-goal.lev
  4487. @@ -1290,7 +1291,7 @@ TFILES = $(GAMEDIR)\Tou-goal.lev
  4488.  VFILES = $(GAMEDIR)\Val-goal.lev
  4489.  WFILES = $(GAMEDIR)\Wiz-goal.lev
  4490.  
  4491. -XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(KFILES) $(MFILES) \
  4492. +XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(IFILES) $(KFILES) $(MFILES) \
  4493.      $(PFILES) $(RANFILES) $(RFILES) $(SFILES) $(TFILES) $(VFILES) $(WFILES)
  4494.  
  4495.  spec_lev : $(GAMEDIR)\astral.lev $(GAMEDIR)\bigrm-1.lev $(GAMEDIR)\castle.lev \
  4496. @@ -1389,6 +1390,8 @@ $(CFILES) : $(DAT)\Caveman.des $(TEMP)\lev_comp.exe
  4497.     $(MAKEB) QQ=Cav QF=Caveman do_quest
  4498.  $(HFILES) : $(DAT)\Healer.des $(TEMP)\lev_comp.exe
  4499.     $(MAKEB) QQ=Hea QF=Healer do_quest
  4500. +$(IFILES) : $(DAT)\Infidel.des $(TEMP)\lev_comp.exe
  4501. +   $(MAKEB) QQ=Inf QF=Infidel do_quest
  4502.  $(KFILES) : $(DAT)\Knight.des $(TEMP)\lev_comp.exe
  4503.     $(MAKEB) QQ=Kni QF=Knight do_quest
  4504.  $(MFILES) : $(DAT)\Monk.des $(TEMP)\lev_comp.exe
  4505. diff --git c/sys/unix/Makefile.dat w/sys/unix/Makefile.dat
  4506. index 00f6043..c6bb10d 100644
  4507. --- c/sys/unix/Makefile.dat
  4508. +++ w/sys/unix/Makefile.dat
  4509. @@ -145,11 +145,12 @@ spec_levs: ../util/lev_comp \
  4510.  quest_levs: ../util/lev_comp \
  4511.     Arch.des Barb.des Caveman.des Healer.des Knight.des Monk.des \
  4512.     Priest.des Ranger.des Rogue.des Samurai.des Tourist.des Valkyrie.des \
  4513. -   Wizard.des
  4514. +   Wizard.des Infidel.des
  4515.     ../util/lev_comp Arch.des
  4516.     ../util/lev_comp Barb.des
  4517.     ../util/lev_comp Caveman.des
  4518.     ../util/lev_comp Healer.des
  4519. +   ../util/lev_comp Infidel.des
  4520.     ../util/lev_comp Knight.des
  4521.     ../util/lev_comp Monk.des
  4522.     ../util/lev_comp Priest.des
  4523. diff --git c/sys/unix/NetHack.xcodeproj/project.pbxproj w/sys/unix/NetHack.xcodeproj/project.pbxproj
  4524. index fdee884..d0db85a 100644
  4525. --- c/sys/unix/NetHack.xcodeproj/project.pbxproj
  4526. +++ w/sys/unix/NetHack.xcodeproj/project.pbxproj
  4527. @@ -1310,6 +1310,7 @@
  4528.                 "$(NH_DAT_DIR)/Barb.des",
  4529.                 "$(NH_DAT_DIR)/Caveman.des",
  4530.                 "$(NH_DAT_DIR)/Healer.des",
  4531. +               "$(NH_DAT_DIR)/Infidel.des",
  4532.                 "$(NH_DAT_DIR)/Knight.des",
  4533.                 "$(NH_DAT_DIR)/Monk.des",
  4534.                 "$(NH_DAT_DIR)/Priest.des",
  4535. @@ -1328,7 +1329,7 @@
  4536.             );
  4537.             runOnlyForDeploymentPostprocessing = 0;
  4538.             shellPath = /bin/sh;
  4539. -           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";
  4540. +           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";
  4541.         };
  4542.         317E7C4E21A3697300F6E4E5 /* Build options and headers */ = {
  4543.             isa = PBXShellScriptBuildPhase;
  4544. @@ -1472,6 +1473,11 @@
  4545.                 "$(NH_DAT_DIR)/Hea-goal.lev",
  4546.                 "$(NH_DAT_DIR)/Hea-loca.lev",
  4547.                 "$(NH_DAT_DIR)/Hea-strt.lev",
  4548. +               "$(NH_DAT_DIR)/Inf-fila.lev",
  4549. +               "$(NH_DAT_DIR)/Inf-filb.lev",
  4550. +               "$(NH_DAT_DIR)/Inf-goal.lev",
  4551. +               "$(NH_DAT_DIR)/Inf-loca.lev",
  4552. +               "$(NH_DAT_DIR)/Inf-strt.lev",
  4553.                 "$(NH_DAT_DIR)/Kni-fila.lev",
  4554.                 "$(NH_DAT_DIR)/Kni-filb.lev",
  4555.                 "$(NH_DAT_DIR)/Kni-goal.lev",
  4556. diff --git c/sys/vms/Makefile.dat w/sys/vms/Makefile.dat
  4557. index e74eb95..dea0fb8 100644
  4558. --- c/sys/vms/Makefile.dat
  4559. +++ w/sys/vms/Makefile.dat
  4560. @@ -31,7 +31,7 @@ VARDAT    = data.;,rumors.;,quest.dat;,oracles.;,options.;,\
  4561.  DUNGEON = dungeon.;
  4562.  X11TILES= x11tiles.;
  4563.  # note: the level lists need to be space separated for use as-is by $(LEVCOMP)
  4564. -QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Knight.des \
  4565. +QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Infidel.des Knight.des \
  4566.     Monk.des Priest.des Ranger.des Rogue.des Samurai.des Tourist.des \
  4567.     Valkyrie.des Wizard.des
  4568.  SPECLEVS  = bigroom.des castle.des endgame.des gehennom.des knox.des \
  4569. diff --git c/sys/vms/install.com w/sys/vms/install.com
  4570. index 09f6f83..5172e41 100755
  4571. --- c/sys/vms/install.com
  4572. +++ w/sys/vms/install.com
  4573. @@ -45,7 +45,7 @@ $ spec_input = "bigroom.des castle.des endgame.des " -
  4574.            + "gehennom.des knox.des medusa.des mines.des " -
  4575.            + "oracle.des sokoban.des tower.des yendor.des"
  4576.  $  qstl_files = "%%%-GOAL.LEV,%%%-FIL%.LEV,%%%-LOCA.LEV,%%%-STRT.LEV"
  4577. -$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des " -
  4578. +$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des Infidel.des " -
  4579.            + "Knight.des Monk.des Priest.des Ranger.des Rogue.des " -
  4580.            + "Samurai.des Tourist.des Wizard.des Valkyrie.des"
  4581.  $  dngn_files = "DUNGEON."
  4582. diff --git c/sys/wince/bootstrp.mak w/sys/wince/bootstrp.mak
  4583. index 5d92dc7..dcd3a46 100644
  4584. --- c/sys/wince/bootstrp.mak
  4585. +++ w/sys/wince/bootstrp.mak
  4586. @@ -244,7 +244,8 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  4587.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  4588.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  4589.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  4590. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  4591. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  4592. +   $(DAT)\infidel.des
  4593.     cd $(DAT)
  4594.     $(U)lev_comp bigroom.des
  4595.     $(U)lev_comp castle.des
  4596. @@ -261,6 +262,7 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  4597.     $(U)lev_comp barb.des
  4598.     $(U)lev_comp caveman.des
  4599.     $(U)lev_comp healer.des
  4600. +   $(U)lev_comp infidel.des
  4601.     $(U)lev_comp knight.des
  4602.     $(U)lev_comp monk.des
  4603.     $(U)lev_comp priest.des
  4604. diff --git c/sys/winnt/Makefile.msc w/sys/winnt/Makefile.msc
  4605. index 6421a70..c9438c6 100644
  4606. --- c/sys/winnt/Makefile.msc
  4607. +++ w/sys/winnt/Makefile.msc
  4608. @@ -711,7 +711,8 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  4609.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  4610.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  4611.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  4612. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  4613. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  4614. +        $(DAT)\infidel.des
  4615.     cd $(DAT)
  4616.     $(U)levcomp bigroom.des
  4617.     $(U)levcomp castle.des
  4618. @@ -728,6 +729,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  4619.     $(U)levcomp barb.des
  4620.     $(U)levcomp caveman.des
  4621.     $(U)levcomp healer.des
  4622. +   $(U)levcomp infidel.des
  4623.     $(U)levcomp knight.des
  4624.     $(U)levcomp monk.des
  4625.     $(U)levcomp priest.des
  4626. diff --git c/util/lev_main.c w/util/lev_main.c
  4627. index 8bcfc83..15a487f 100644
  4628. --- c/util/lev_main.c
  4629. +++ w/util/lev_main.c
  4630. @@ -250,7 +250,8 @@ char **argv;
  4631.          ":dat:Wizard.des",  ":dat:bigroom.des",  ":dat:castle.des",
  4632.          ":dat:endgame.des", ":dat:gehennom.des", ":dat:knox.des",
  4633.          ":dat:medusa.des",  ":dat:mines.des",    ":dat:oracle.des",
  4634. -        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des"
  4635. +        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des",
  4636. +        ":dat:Infidel.des"
  4637.      };
  4638.  
  4639.      argc = SIZE(mac_argv);
  4640. diff --git c/win/tty/wintty.c w/win/tty/wintty.c
  4641. index d7ffec6..d5c18bb 100644
  4642. --- c/win/tty/wintty.c
  4643. +++ w/win/tty/wintty.c
  4644. @@ -929,6 +929,7 @@ tty_player_selection()
  4645.       */
  4646.      getconfirmation = (picksomething && pick4u != 'a' && !flags.randomall);
  4647.      while (getconfirmation) {
  4648. +        int real_algn = special_alignment(ROLE, ALGN);
  4649.          tty_clear_nhwindow(BASE_WINDOW);
  4650.          role_selection_prolog(ROLE_NONE, BASE_WINDOW);
  4651.          win = create_nhwindow(NHW_MENU);
  4652. @@ -941,7 +942,7 @@ tty_player_selection()
  4653.              Sprintf(plbuf, " %s", genders[GEND].adj);
  4654.          else
  4655.              *plbuf = '\0'; /* omit redundant gender */
  4656. -        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[ALGN].adj, plbuf,
  4657. +        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[real_algn].adj, plbuf,
  4658.                  races[RACE].adj,
  4659.                  (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f
  4660.                                                    : roles[ROLE].name.m);
  4661. diff --git c/win/win32/vs2017/files.props w/win/win32/vs2017/files.props
  4662. index 483ec1e..5a12ab8 100644
  4663. --- c/win/win32/vs2017/files.props
  4664. +++ w/win/win32/vs2017/files.props
  4665. @@ -35,6 +35,7 @@
  4666.      <Desfiles Include = "endgame.des"/>
  4667.      <Desfiles Include = "gehennom.des"/>
  4668.      <Desfiles Include = "healer.des"/>
  4669. +    <Desfiles Include = "infidel.des"/>
  4670.      <Desfiles Include = "knight.des"/>
  4671.      <Desfiles Include = "knox.des"/>
  4672.      <Desfiles Include = "medusa.des"/>
  4673. @@ -128,6 +129,11 @@
  4674.      <Levfiles Include = "hea-goal.lev"/>
  4675.      <Levfiles Include = "hea-loca.lev"/>
  4676.      <Levfiles Include = "hea-strt.lev"/>
  4677. +    <Levfiles Include = "inf-fila.lev"/>
  4678. +    <Levfiles Include = "inf-filb.lev"/>
  4679. +    <Levfiles Include = "inf-goal.lev"/>
  4680. +    <Levfiles Include = "inf-loca.lev"/>
  4681. +    <Levfiles Include = "inf-strt.lev"/>
  4682.      <Levfiles Include = "kni-fila.lev"/>
  4683.      <Levfiles Include = "kni-filb.lev"/>
  4684.      <Levfiles Include = "kni-goal.lev"/>
Add Comment
Please, Sign In to add comment