Guest User

NetHack Infidel role patch

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