Guest User

NetHack Infidel role patch v1.3

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