Guest User

NetHack Infidel role patch v1.4

a guest
Jul 13th, 2021
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 233.24 KB | None | 0 0
  1. diff --git a/Files b/Files
  2. index d81ad0c..96f9380 100644
  3. --- a/Files
  4. +++ b/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 a/dat/Infidel.des b/dat/Infidel.des
  15. new file mode 100644
  16. index 0000000..df7502e
  17. --- /dev/null
  18. +++ b/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 a/dat/data.base b/dat/data.base
  406. index 4046259..0c1b1c2 100644
  407. --- a/dat/data.base
  408. +++ b/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 a/dat/endgame.des b/dat/endgame.des
  539. index ebd9049..068247e 100644
  540. --- a/dat/endgame.des
  541. +++ b/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 heaven are located."
  548.  MESSAGE: "You sense alarm, hostility, and excitement in the air!"
  549.  GEOMETRY:center,center
  550.  MAP
  551. diff --git a/dat/gehennom.des b/dat/gehennom.des
  552. index 65fab4e..fcd2be7 100644
  553. --- a/dat/gehennom.des
  554. +++ b/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 a/dat/quest.txt b/dat/quest.txt
  564. index 269ec76..3a33eb3 100644
  565. --- a/dat/quest.txt
  566. +++ b/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.  %dC
  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 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 had 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 has 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 had 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 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 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 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 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. +    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 the 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 a/doc/Guidebook.mn b/doc/Guidebook.mn
  943. index bad63a8..2db07e8 100644
  944. --- a/doc/Guidebook.mn
  945. +++ b/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 a/doc/Guidebook.tex b/doc/Guidebook.tex
  959. index c34f6fa..6bc65ca 100644
  960. --- a/doc/Guidebook.tex
  961. +++ b/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 a/include/artifact.h b/include/artifact.h
  976. index 4e5193f..49fddb6 100644
  977. --- a/include/artifact.h
  978. +++ b/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 a/include/artilist.h b/include/artilist.h
  990. index d1b1ef6..ad4621c 100644
  991. --- a/include/artilist.h
  992. +++ b/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. @@ -266,6 +280,7 @@ A("The Palantir of Westernesse",        CRYSTAL_BALL,
  1029.  #undef FIRE
  1030.  #undef ELEC
  1031.  #undef STUN
  1032. +#undef DREN
  1033.  #endif
  1034.  
  1035.  /*artilist.h*/
  1036. diff --git a/include/context.h b/include/context.h
  1037. index c24da8d..f876f18 100644
  1038. --- a/include/context.h
  1039. +++ b/include/context.h
  1040. @@ -118,6 +118,9 @@ struct context_info {
  1041.      long next_attrib_check; /* next attribute check */
  1042.      long stethoscope_move;
  1043.      short stethoscope_movement;
  1044. +    long next_moloch_offering; /* Moloch demands regular sacrifices */
  1045. +    char inf_aligns; /* random alignment permutation number for Infidels */
  1046. +    boolean coward; /* restrict Infidel Elbereth penalty to once per move */
  1047.      boolean travel;  /* find way automatically to u.tx,u.ty */
  1048.      boolean travel1; /* first travel step */
  1049.      boolean forcefight;
  1050. diff --git a/include/extern.h b/include/extern.h
  1051. index a1b32f7..97f3d73 100644
  1052. --- a/include/extern.h
  1053. +++ b/include/extern.h
  1054. @@ -48,6 +48,7 @@ E boolean FDECL(snuff_candle, (struct obj *));
  1055.  E boolean FDECL(snuff_lit, (struct obj *));
  1056.  E boolean FDECL(catch_lit, (struct obj *));
  1057.  E void FDECL(use_unicorn_horn, (struct obj *));
  1058. +E void FDECL(use_figurine, (struct obj **));
  1059.  E boolean FDECL(tinnable, (struct obj *));
  1060.  E void NDECL(reset_trapset);
  1061.  E void FDECL(fig_transform, (ANY_P *, long));
  1062. @@ -70,6 +71,7 @@ E boolean FDECL(confers_luck, (struct obj *));
  1063.  E boolean FDECL(arti_reflects, (struct obj *));
  1064.  E boolean FDECL(shade_glare, (struct obj *));
  1065.  E boolean FDECL(restrict_name, (struct obj *, const char *));
  1066. +E boolean FDECL(attacks, (int, struct obj *));
  1067.  E boolean FDECL(defends, (int, struct obj *));
  1068.  E boolean FDECL(defends_when_carried, (int, struct obj *));
  1069.  E boolean FDECL(protects, (struct obj *, BOOLEAN_P));
  1070. @@ -485,6 +487,7 @@ E void NDECL(cancel_don);
  1071.  E int FDECL(stop_donning, (struct obj *));
  1072.  E int NDECL(Armor_off);
  1073.  E int NDECL(Armor_gone);
  1074. +E void FDECL(check_wings, (BOOLEAN_P));
  1075.  E int NDECL(Helmet_off);
  1076.  E int NDECL(Gloves_off);
  1077.  E int NDECL(Boots_on);
  1078. @@ -500,7 +503,7 @@ E void FDECL(Blindf_on, (struct obj *));
  1079.  E void FDECL(Blindf_off, (struct obj *));
  1080.  E int NDECL(dotakeoff);
  1081.  E int NDECL(doremring);
  1082. -E int FDECL(cursed, (struct obj *));
  1083. +E int FDECL(cursed, (struct obj *, BOOLEAN_P));
  1084.  E int FDECL(armoroff, (struct obj *));
  1085.  E int FDECL(canwearobj, (struct obj *, long *, BOOLEAN_P));
  1086.  E int NDECL(dowear);
  1087. @@ -1516,7 +1519,7 @@ E boolean FDECL(big_little_match, (int, int));
  1088.  E const char *FDECL(locomotion, (const struct permonst *, const char *));
  1089.  E const char *FDECL(stagger, (const struct permonst *, const char *));
  1090.  E const char *FDECL(on_fire, (struct permonst *, struct attack *));
  1091. -E const struct permonst *FDECL(raceptr, (struct monst *));
  1092. +E struct permonst *FDECL(raceptr, (struct monst *));
  1093.  E boolean FDECL(olfaction, (struct permonst *));
  1094.  
  1095.  /* ### monmove.c ### */
  1096. @@ -1996,6 +1999,8 @@ E boolean NDECL(stuck_in_wall);
  1097.  #ifdef USE_TRAMPOLI
  1098.  E int NDECL(prayer_done);
  1099.  #endif
  1100. +E void FDECL(god_zaps_you, (ALIGNTYP_P));
  1101. +E void FDECL(godvoice, (ALIGNTYP_P, const char *));
  1102.  E int NDECL(dosacrifice);
  1103.  E boolean FDECL(can_pray, (BOOLEAN_P));
  1104.  E int NDECL(dopray);
  1105. @@ -2006,6 +2011,7 @@ E const char *FDECL(a_gname_at, (XCHAR_P x, XCHAR_P y));
  1106.  E const char *FDECL(align_gname, (ALIGNTYP_P));
  1107.  E const char *FDECL(halu_gname, (ALIGNTYP_P));
  1108.  E const char *FDECL(align_gtitle, (ALIGNTYP_P));
  1109. +E aligntyp FDECL(inf_align, (int));
  1110.  E void FDECL(altar_wrath, (int, int));
  1111.  
  1112.  /* ### priest.c ### */
  1113. @@ -2163,6 +2169,7 @@ E int FDECL(rnz, (int));
  1114.  
  1115.  /* ### role.c ### */
  1116.  
  1117. +E int FDECL(special_alignment, (int, int));
  1118.  E boolean FDECL(validrole, (int));
  1119.  E boolean FDECL(validrace, (int, int));
  1120.  E boolean FDECL(validgend, (int, int, int));
  1121. diff --git a/include/mondata.h b/include/mondata.h
  1122. index 155ebfa..44e5ed7 100644
  1123. --- a/include/mondata.h
  1124. +++ b/include/mondata.h
  1125. @@ -30,6 +30,9 @@
  1126.  #define is_lminion(mon) \
  1127.      (is_minion((mon)->data) && mon_aligntyp(mon) == A_LAWFUL)
  1128.  #define is_flyer(ptr) (((ptr)->mflags1 & M1_FLY) != 0L)
  1129. +/* flight blocked by most body armor */
  1130. +#define big_wings(ptr) ((ptr) == &mons[PM_WINGED_GARGOYLE] \
  1131. +                        || (ptr) == &mons[PM_DEMON])
  1132.  #define is_floater(ptr) ((ptr)->mlet == S_EYE || (ptr)->mlet == S_LIGHT)
  1133.  /* clinger: piercers, mimics, wumpus -- generally don't fall down holes */
  1134.  #define is_clinger(ptr) (((ptr)->mflags1 & M1_CLING) != 0L)
  1135. @@ -97,6 +100,8 @@
  1136.  #define carnivorous(ptr) (((ptr)->mflags1 & M1_CARNIVORE) != 0L)
  1137.  #define herbivorous(ptr) (((ptr)->mflags1 & M1_HERBIVORE) != 0L)
  1138.  #define metallivorous(ptr) (((ptr)->mflags1 & M1_METALLIVORE) != 0L)
  1139. +#define inediate(ptr) (((ptr)->mflags1 & (M1_CARNIVORE | M1_HERBIVORE \
  1140. +                                          | M1_METALLIVORE)) == 0L)
  1141.  #define polyok(ptr) (((ptr)->mflags2 & M2_NOPOLY) == 0L)
  1142.  #define is_shapeshifter(ptr) (((ptr)->mflags2 & M2_SHAPESHIFTER) != 0L)
  1143.  #define is_undead(ptr) (((ptr)->mflags2 & M2_UNDEAD) != 0L)
  1144. @@ -160,9 +165,10 @@
  1145.  #define is_rider(ptr)                                      \
  1146.      ((ptr) == &mons[PM_DEATH] || (ptr) == &mons[PM_FAMINE] \
  1147.       || (ptr) == &mons[PM_PESTILENCE])
  1148. -#define is_placeholder(ptr)                             \
  1149. -    ((ptr) == &mons[PM_ORC] || (ptr) == &mons[PM_GIANT] \
  1150. -     || (ptr) == &mons[PM_ELF] || (ptr) == &mons[PM_HUMAN])
  1151. +#define is_placeholder(ptr)                                \
  1152. +    ((ptr) == &mons[PM_ORC] || (ptr) == &mons[PM_GIANT]    \
  1153. +     || (ptr) == &mons[PM_ELF] || (ptr) == &mons[PM_HUMAN] \
  1154. +     || (ptr) == &mons[PM_DEMON])
  1155.  /* return TRUE if the monster tends to revive */
  1156.  #define is_reviver(ptr) (is_rider(ptr) || (ptr)->mlet == S_TROLL)
  1157.  /* monsters whose corpses and statues need special handling;
  1158. diff --git a/include/monflag.h b/include/monflag.h
  1159. index f430ced..10dd08b 100644
  1160. --- a/include/monflag.h
  1161. +++ b/include/monflag.h
  1162. @@ -174,6 +174,7 @@
  1163.  #define MH_DWARF M2_DWARF
  1164.  #define MH_GNOME M2_GNOME
  1165.  #define MH_ORC M2_ORC
  1166. +#define MH_DEMON M2_DEMON
  1167.  
  1168.  /* for mons[].geno (constant during game) */
  1169.  #define G_UNIQ 0x1000     /* generated only once */
  1170. diff --git a/include/patchlevel.h b/include/patchlevel.h
  1171. index 36bc437..77ed7bb 100644
  1172. --- a/include/patchlevel.h
  1173. +++ b/include/patchlevel.h
  1174. @@ -14,7 +14,7 @@
  1175.   * Incrementing EDITLEVEL can be used to force invalidation of old bones
  1176.   * and save files.
  1177.   */
  1178. -#define EDITLEVEL 0
  1179. +#define EDITLEVEL 1
  1180.  
  1181.  #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
  1182.  #define COPYRIGHT_BANNER_B \
  1183. diff --git a/include/qtext.h b/include/qtext.h
  1184. index 7529384..9a11583 100644
  1185. --- a/include/qtext.h
  1186. +++ b/include/qtext.h
  1187. @@ -64,7 +64,7 @@ struct qtlists {
  1188.  #define QT_FIRSTTIME 1
  1189.  #define QT_NEXTTIME 2
  1190.  #define QT_OTHERTIME 3
  1191. -
  1192. +#define QT_ALTSTART 4    /* alternate game start message (optional) */
  1193.  #define QT_GUARDTALK 5   /* 5 random things guards say before quest */
  1194.  #define QT_GUARDTALK2 10 /* 5 random things guards say after quest */
  1195.  
  1196. @@ -94,6 +94,11 @@ struct qtlists {
  1197.  
  1198.  #define QT_GOTIT 70
  1199.  
  1200. +/* For Infidels: Moloch's dialogue */
  1201. +#define QT_MOLOCH_1 71 /* offered Amulet, no Idol */
  1202. +#define QT_MOLOCH_2 72 /* offered Amulet, got Idol */
  1203. +#define QT_MOLOCH_3 73 /* high priest's altar hint */
  1204. +
  1205.  #define QT_KILLEDNEM 80
  1206.  #define QT_OFFEREDIT 81
  1207.  #define QT_OFFEREDIT2 82
  1208. diff --git a/include/you.h b/include/you.h
  1209. index ad178a2..72ec45f 100644
  1210. --- a/include/you.h
  1211. +++ b/include/you.h
  1212. @@ -48,14 +48,13 @@ struct u_event {
  1213.      Bitfield(uopened_dbridge, 1);   /* opened the drawbridge */
  1214.      Bitfield(invoked, 1);           /* invoked Gate to the Sanctum level */
  1215.      Bitfield(gehennom_entered, 1);  /* entered Gehennom via Valley */
  1216. -    Bitfield(uhand_of_elbereth, 2); /* became Hand of Elbereth */
  1217. +    Bitfield(uhand_of_elbereth, 3); /* became Hand of Elbereth */
  1218.      Bitfield(udemigod, 1);          /* killed the wiz */
  1219. -    Bitfield(uvibrated, 1);         /* stepped on "vibrating square" */
  1220.      Bitfield(ascended, 1);          /* has offered the Amulet */
  1221.  };
  1222.  
  1223.  struct u_achieve {
  1224. -    Bitfield(amulet, 1);  /* touched Amulet */
  1225. +    Bitfield(amulet, 1);  /* touched (for Infidels: offered) Amulet */
  1226.      Bitfield(bell, 1);    /* touched Bell */
  1227.      Bitfield(book, 1);    /* touched Book */
  1228.      Bitfield(menorah, 1); /* touched Candelabrum */
  1229. @@ -66,6 +65,7 @@ struct u_achieve {
  1230.      Bitfield(finish_sokoban, 1);  /* obtained the sokoban prize */
  1231.  
  1232.      Bitfield(killed_medusa, 1);
  1233. +    Bitfield(vibrating_square, 1); /* stepped on "vibrating square" */
  1234.  };
  1235.  
  1236.  struct u_realtime {
  1237. @@ -219,6 +219,7 @@ struct Race {
  1238.  };
  1239.  
  1240.  extern const struct Race races[]; /* Table of available races */
  1241. +extern struct Race race_demon;    /* used in pray.c */
  1242.  extern struct Race urace;
  1243.  #define Race_if(X) (urace.malenum == (X))
  1244.  #define Race_switch (urace.malenum)
  1245. diff --git a/include/youprop.h b/include/youprop.h
  1246. index c9656aa..c0f41a5 100644
  1247. --- a/include/youprop.h
  1248. +++ b/include/youprop.h
  1249. @@ -227,11 +227,13 @@
  1250.  #define HFlying u.uprops[FLYING].intrinsic
  1251.  #define EFlying u.uprops[FLYING].extrinsic
  1252.  /* BFlying has I_SPECIAL set if levitating or trapped in the floor or both,
  1253. -   FROMOUTSIDE set if inside solid rock (or in water on Plane of Water) */
  1254. +   FROMOUTSIDE set if inside solid rock (or in water on Plane of Water)
  1255. +   W_ARM set if in big_wings() form and wearing blocking body armor
  1256. +   (the last one obviously won't block the steed from flying) */
  1257.  #define BFlying u.uprops[FLYING].blocked
  1258. -#define Flying                                                      \
  1259. -    ((HFlying || EFlying || (u.usteed && is_flyer(u.usteed->data))) \
  1260. -     && !BFlying)
  1261. +#define Flying                                                           \
  1262. +    (((HFlying || EFlying) && !BFlying                                   \
  1263. +      || u.usteed && is_flyer(u.usteed->data)) && !(BFlying & ~W_ARMOR))
  1264.  /* May touch surface; does not override any others */
  1265.  
  1266.  #define EWwalking u.uprops[WWALKING].extrinsic
  1267. @@ -372,6 +374,6 @@
  1268.     redundant but allows the function calls to be skipped most of the time */
  1269.  #define Unaware (multi < 0 && (unconscious() || is_fainted()))
  1270.  
  1271. -#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(youmonst.data))
  1272. +#define Hate_silver (u.ulycn >= LOW_PM || hates_silver(raceptr(&youmonst)))
  1273.  
  1274.  #endif /* YOUPROP_H */
  1275. diff --git a/src/allmain.c b/src/allmain.c
  1276. index 5111c69..2b16152 100644
  1277. --- a/src/allmain.c
  1278. +++ b/src/allmain.c
  1279. @@ -226,7 +226,13 @@ boolean resuming;
  1280.                          && ((wtcap < MOD_ENCUMBER
  1281.                               && (!(moves % ((MAXULEV + 8 - u.ulevel)
  1282.                                              * (Role_if(PM_WIZARD) ? 3 : 4)
  1283. -                                            / 6)))) || Energy_regeneration)) {
  1284. +                                            / 6)))) || Energy_regeneration
  1285. +                    /* the Idol grants energy regen to piously unaligned;
  1286. +                     * it really shouldn't be restricted to Infidels,
  1287. +                     * but so far we have no other unaligned roles */
  1288. +                            || Role_if(PM_INFIDEL) && u.uhave.questart
  1289. +                               && u.ualign.type == A_NONE
  1290. +                               && u.ualign.record > rn2(20))) {
  1291.                          u.uen += rn1(
  1292.                              (int) (ACURR(A_WIS) + ACURR(A_INT)) / 15 + 1, 1);
  1293.                          if (u.uen > u.uenmax)
  1294. @@ -236,6 +242,48 @@ boolean resuming;
  1295.                              interrupt_multi("You feel full of energy.");
  1296.                      }
  1297.  
  1298. +                    /* Moloch demands regular sacrifices! */
  1299. +                    if (context.next_moloch_offering <= moves) {
  1300. +                        if (context.next_moloch_offering == moves
  1301. +                            && (u.ualign.type == A_NONE
  1302. +                                || u.ualignbase[A_CURRENT] == A_NONE)) {
  1303. +                            You_feel("%s urge to perform a sacrifice.",
  1304. +                                     u.ualign.type == A_NONE ? "an"
  1305. +                                                             : "a faint");
  1306. +                            stop_occupation();
  1307. +                        }
  1308. +                        if (u.ualign.type == A_NONE && !rn2(10)
  1309. +                            && rn2(moves - context.next_moloch_offering
  1310. +                                   + 1000) >= 1000) {
  1311. +                            if (u.ualign.record > -99)
  1312. +                                adjalign(-1);
  1313. +                            if (u.ualign.record < -10 && !rn2(u.ugangr + 1)
  1314. +                                && rn2(-u.ualign.record + 90) >= 100) {
  1315. +                                char *angry = (char *) 0;
  1316. +                                u.ugangr++;
  1317. +                                /* avoid repetitive messages */
  1318. +                                switch (u.ugangr) {
  1319. +                                /* same values as in cmd.c */
  1320. +                                case 1:
  1321. +                                    angry = "";
  1322. +                                    break;
  1323. +                                case 4:
  1324. +                                    angry = "very ";
  1325. +                                    break;
  1326. +                                case 7:
  1327. +                                    angry = "extremely ";
  1328. +                                    break;
  1329. +                                }
  1330. +                                if (angry) {
  1331. +                                    You_feel("that %s is %sangry at your "
  1332. +                                             "lack of offerings.", u_gname(),
  1333. +                                             angry);
  1334. +                                    stop_occupation();
  1335. +                                }
  1336. +                            }
  1337. +                        }
  1338. +                    }
  1339. +
  1340.                      if (!u.uinvulnerable) {
  1341.                          if (Teleportation && !rn2(85)) {
  1342.                              xchar old_ux = u.ux, old_uy = u.uy;
  1343. @@ -336,6 +384,7 @@ boolean resuming;
  1344.              /* when/if hero escapes from lava, he can't just stay there */
  1345.              else if (!u.umoved)
  1346.                  (void) pooleffects(FALSE);
  1347. +            context.coward = FALSE;
  1348.  
  1349.          } /* actual time passed */
  1350.  
  1351. @@ -590,6 +639,9 @@ newgame()
  1352.      context.next_attrib_check = 600L; /* arbitrary first setting */
  1353.      context.tribute.enabled = TRUE;   /* turn on 3.6 tributes    */
  1354.      context.tribute.tributesz = sizeof(struct tribute_info);
  1355. +    context.inf_aligns = rn2(6);      /* randomness for the Infidel role */
  1356. +    context.next_moloch_offering = 6000; /* give a grace period before
  1357. +                                          * the first sacrifice */
  1358.  
  1359.      for (i = LOW_PM; i < NUMMONS; i++)
  1360.          mvitals[i].mvflags = mons[i].geno & G_NOCORPSE;
  1361. @@ -670,8 +722,11 @@ boolean new_game; /* false => restoring an old game */
  1362.       * restores it's only shown if different from its original value.
  1363.       */
  1364.      *buf = '\0';
  1365. -    if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT])
  1366. -        Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_ORIGINAL]));
  1367. +    if (new_game || u.ualignbase[A_ORIGINAL] != u.ualignbase[A_CURRENT]) {
  1368. +        if (new_game && u.ualignbase[A_CURRENT] == A_NONE)
  1369. +            Strcpy(buf, "n"); /* [You are a]n unaligned Infidel */
  1370. +        Sprintf(eos(buf), " %s", align_str(u.ualignbase[A_CURRENT]));
  1371. +    }
  1372.      if (!urole.name.f
  1373.          && (new_game
  1374.                  ? (urole.allow & ROLE_GENDMASK) == (ROLE_MALE | ROLE_FEMALE)
  1375. diff --git a/src/apply.c b/src/apply.c
  1376. index e77984d..5f70a41 100644
  1377. --- a/src/apply.c
  1378. +++ b/src/apply.c
  1379. @@ -22,7 +22,6 @@ STATIC_DCL void FDECL(use_lamp, (struct obj *));
  1380.  STATIC_DCL void FDECL(light_cocktail, (struct obj **));
  1381.  STATIC_PTR void FDECL(display_jump_positions, (int));
  1382.  STATIC_DCL void FDECL(use_tinning_kit, (struct obj *));
  1383. -STATIC_DCL void FDECL(use_figurine, (struct obj **));
  1384.  STATIC_DCL void FDECL(use_grease, (struct obj *));
  1385.  STATIC_DCL void FDECL(use_trap, (struct obj *));
  1386.  STATIC_DCL void FDECL(use_stone, (struct obj *));
  1387. @@ -2105,6 +2104,7 @@ long timeout;
  1388.      boolean cansee_spot, silent, okay_spot;
  1389.      boolean redraw = FALSE;
  1390.      boolean suppress_see = FALSE;
  1391. +    boolean idol = figurine && figurine->oartifact == ART_IDOL_OF_MOLOCH;
  1392.      char monnambuf[BUFSZ], carriedby[BUFSZ];
  1393.  
  1394.      if (!figurine) {
  1395. @@ -2115,7 +2115,8 @@ long timeout;
  1396.      okay_spot = get_obj_location(figurine, &cc.x, &cc.y, 0);
  1397.      if (figurine->where == OBJ_INVENT || figurine->where == OBJ_MINVENT)
  1398.          okay_spot = enexto(&cc, cc.x, cc.y, &mons[figurine->corpsenm]);
  1399. -    if (!okay_spot || !figurine_location_checks(figurine, &cc, TRUE)) {
  1400. +    if (idol && figurine->age > timeout || !okay_spot
  1401. +        || !figurine_location_checks(figurine, &cc, TRUE)) {
  1402.          /* reset the timer to try again later */
  1403.          (void) start_timer((long) rnd(5000), TIMER_OBJECT, FIG_TRANSFORM,
  1404.                             obj_to_any(figurine));
  1405. @@ -2159,9 +2160,14 @@ long timeout;
  1406.  
  1407.          case OBJ_FLOOR:
  1408.              if (cansee_spot && !silent) {
  1409. -                if (suppress_see)
  1410. +                if (idol) {
  1411. +                    if (!suppress_see)
  1412. +                        You_see("a cloud of %s mist coagulate "
  1413. +                                "into the shape of %s%s!",
  1414. +                                hcolor("crimson"), monnambuf, and_vanish);
  1415. +                } else if (suppress_see) {
  1416.                      pline("%s suddenly vanishes!", an(xname(figurine)));
  1417. -                else
  1418. +                }  else
  1419.                      You_see("a figurine transform into %s%s!", monnambuf,
  1420.                              and_vanish);
  1421.                  redraw = TRUE; /* update figurine's map location */
  1422. @@ -2197,12 +2203,20 @@ long timeout;
  1423.              break;
  1424.          }
  1425.      }
  1426. -    /* free figurine now */
  1427. -    if (carried(figurine)) {
  1428. -        useup(figurine);
  1429. +    if (idol) {
  1430. +        long cooldown = rnz(100);
  1431. +        figurine->age = timeout + cooldown;
  1432. +        /* still cursed */
  1433. +        (void) start_timer((long) rnd(9000) + cooldown, TIMER_OBJECT,
  1434. +                           FIG_TRANSFORM, obj_to_any(figurine));
  1435.      } else {
  1436. -        obj_extract_self(figurine);
  1437. -        obfree(figurine, (struct obj *) 0);
  1438. +        /* free figurine now */
  1439. +        if (carried(figurine)) {
  1440. +            useup(figurine);
  1441. +        } else {
  1442. +            obj_extract_self(figurine);
  1443. +            obfree(figurine, (struct obj *) 0);
  1444. +        }
  1445.      }
  1446.      if (redraw)
  1447.          newsym(cc.x, cc.y);
  1448. @@ -2244,14 +2258,25 @@ boolean quietly;
  1449.      return TRUE;
  1450.  }
  1451.  
  1452. -STATIC_OVL void
  1453. +void
  1454.  use_figurine(optr)
  1455.  struct obj **optr;
  1456.  {
  1457.      register struct obj *obj = *optr;
  1458. +    boolean idol = obj->oartifact == ART_IDOL_OF_MOLOCH;
  1459.      xchar x, y;
  1460.      coord cc;
  1461. -
  1462. +    char *release_figurine;
  1463. +
  1464. +    if (idol) {
  1465. +        /* copied from artifact.c */
  1466. +        if (obj->age > monstermoves) {
  1467. +            You_feel("that %s %s ignoring you.", the(xname(obj)),
  1468. +                     otense(obj, "are"));
  1469. +            obj->age += (long) d(3, 10);
  1470. +            return;
  1471. +        }
  1472. +    }
  1473.      if (u.uswallow) {
  1474.          /* can't activate a figurine while swallowed */
  1475.          if (!figurine_location_checks(obj, (coord *) 0, FALSE))
  1476. @@ -2268,17 +2293,34 @@ struct obj **optr;
  1477.      /* Passing FALSE arg here will result in messages displayed */
  1478.      if (!figurine_location_checks(obj, &cc, FALSE))
  1479.          return;
  1480. -    You("%s and it %stransforms.",
  1481. -        (u.dx || u.dy) ? "set the figurine beside you"
  1482. -                       : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
  1483. -                          || is_pool(cc.x, cc.y))
  1484. -                             ? "release the figurine"
  1485. -                             : (u.dz < 0 ? "toss the figurine into the air"
  1486. -                                         : "set the figurine on the ground"),
  1487. -        Blind ? "supposedly " : "");
  1488. +    if (u.dx || u.dy)
  1489. +        release_figurine = "set the figurine beside you";
  1490. +    else if (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
  1491. +             || is_pool(cc.x, cc.y))
  1492. +        release_figurine = "release the figurine";
  1493. +    else if (u.dz < 0)
  1494. +        release_figurine = "toss the figurine into the air";
  1495. +    else
  1496. +        release_figurine = "set the figurine on the ground";
  1497. +    if (idol) {
  1498. +        if (Blind)
  1499. +            You("%s and feel an unholy aura emanate from it.",
  1500. +                release_figurine);
  1501. +        else
  1502. +            You("%s and a cloud of %s mist arises from it.",
  1503. +                release_figurine, hcolor("crimson"));
  1504. +    } else
  1505. +        You("%s and it %stransforms.", release_figurine,
  1506. +            Blind ? "supposedly " : "");
  1507.      (void) make_familiar(obj, cc.x, cc.y, FALSE);
  1508. -    (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
  1509. -    useup(obj);
  1510. +    if (idol) {
  1511. +        obj->age = monstermoves + rnz(100);
  1512. +        freeinv(obj);
  1513. +        place_object(obj, cc.x, cc.y);
  1514. +    } else {
  1515. +        (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
  1516. +        useup(obj);
  1517. +    }
  1518.      if (Blind)
  1519.          map_invisible(cc.x, cc.y);
  1520.      *optr = 0;
  1521. @@ -3595,7 +3637,7 @@ doapply()
  1522.      case BLINDFOLD:
  1523.      case LENSES:
  1524.          if (obj == ublindf) {
  1525. -            if (!cursed(obj))
  1526. +            if (!cursed(obj, FALSE))
  1527.                  Blindf_off(obj);
  1528.          } else if (!ublindf) {
  1529.              Blindf_on(obj);
  1530. diff --git a/src/artifact.c b/src/artifact.c
  1531. index 03573fe..296adf4 100644
  1532. --- a/src/artifact.c
  1533. +++ b/src/artifact.c
  1534. @@ -6,6 +6,7 @@
  1535.  #include "hack.h"
  1536.  #include "artifact.h"
  1537.  #include "artilist.h"
  1538. +#include "qtext.h"
  1539.  
  1540.  /*
  1541.   * Note:  both artilist[] and artiexist[] have a dummy element #0,
  1542. @@ -50,7 +51,7 @@ static boolean artiexist[1 + NROFARTIFACTS + 1];
  1543.  STATIC_OVL xchar artidisco[NROFARTIFACTS];
  1544.  
  1545.  STATIC_DCL void NDECL(hack_artifacts);
  1546. -STATIC_DCL boolean FDECL(attacks, (int, struct obj *));
  1547. +STATIC_DCL void FDECL(fix_artifact, (struct obj *));
  1548.  
  1549.  /* handle some special cases; must be called after u_init() */
  1550.  STATIC_OVL void
  1551. @@ -102,6 +103,19 @@ int fd;
  1552.      hack_artifacts(); /* redo non-saved special cases */
  1553.  }
  1554.  
  1555. +/* Some artifacts may need additional tweaking when created.
  1556. + * Called when the artifact is christened.
  1557. + */
  1558. +STATIC_DCL void
  1559. +fix_artifact(otmp)
  1560. +struct obj *otmp;
  1561. +{
  1562. +    if (otmp->oartifact == ART_IDOL_OF_MOLOCH) {
  1563. +        set_corpsenm(otmp, PM_HORNED_DEVIL);
  1564. +        otmp->spe = 0;
  1565. +    }
  1566. +}
  1567. +
  1568.  const char *
  1569.  artiname(artinum)
  1570.  int artinum;
  1571. @@ -129,8 +143,8 @@ aligntyp alignment; /* target alignment, or A_NONE */
  1572.  {
  1573.      const struct artifact *a;
  1574.      int m, n, altn;
  1575. -    boolean by_align = (alignment != A_NONE);
  1576. -    short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
  1577. +    boolean by_align = alignment != A_NONE || !otmp;
  1578. +    short o_typ = by_align ? 0 : otmp->otyp;
  1579.      boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
  1580.      short eligible[NROFARTIFACTS];
  1581.  
  1582. @@ -199,6 +213,7 @@ aligntyp alignment; /* target alignment, or A_NONE */
  1583.              otmp = oname(otmp, a->name);
  1584.              otmp->oartifact = m;
  1585.              artiexist[m] = TRUE;
  1586. +            fix_artifact(otmp);
  1587.          }
  1588.      } else {
  1589.          /* nothing appropriate could be found; return original object */
  1590. @@ -271,6 +286,8 @@ boolean mod;
  1591.                  if (otmp->otyp == RIN_INCREASE_DAMAGE)
  1592.                      otmp->spe = 0;
  1593.                  artiexist[m] = mod;
  1594. +                if (mod)
  1595. +                    fix_artifact(otmp);
  1596.                  break;
  1597.              }
  1598.      return;
  1599. @@ -404,7 +421,7 @@ const char *name;
  1600.      return FALSE;
  1601.  }
  1602.  
  1603. -STATIC_OVL boolean
  1604. +boolean
  1605.  attacks(adtyp, otmp)
  1606.  int adtyp;
  1607.  struct obj *otmp;
  1608. @@ -799,6 +816,8 @@ struct monst *mtmp;
  1609.              return !(yours ? Poison_resistance : resists_poison(mtmp));
  1610.          case AD_DRLI:
  1611.              return !(yours ? Drain_resistance : resists_drli(mtmp));
  1612. +        case AD_DREN:
  1613. +            return !nonliving(ptr);
  1614.          case AD_STON:
  1615.              return !(yours ? Stone_resistance : resists_ston(mtmp));
  1616.          default:
  1617. @@ -1602,6 +1621,89 @@ struct obj *obj;
  1618.              nhUse(otmp);
  1619.              break;
  1620.          }
  1621. +        case CHANNEL:
  1622. +            /* Should this break atheist conduct?  Currently it doesn't,
  1623. +             * under the excuse of being necessary to ascend.
  1624. +             * But still, we're channeling a god's power here... */
  1625. +            if (IS_ALTAR(levl[u.ux][u.uy].typ)) {
  1626. +                aligntyp altar_align = Amask2align(levl[u.ux][u.uy].altarmask
  1627. +                                                   & AM_MASK);
  1628. +                boolean high_altar = (Is_astralevel(&u.uz)
  1629. +                                      || Is_sanctum(&u.uz))
  1630. +                                     && (levl[u.ux][u.uy].altarmask
  1631. +                                         & AM_SHRINE);
  1632. +                if (!Blind)
  1633. +                    pline("Tendrils of %s mist seep out of %s "
  1634. +                          "and into the altar below...",
  1635. +                          hcolor("crimson"), the(xname(obj)));
  1636. +                else
  1637. +                    You_feel("something flow from %s.", the(xname(obj)));
  1638. +                if (altar_align == A_NONE) {
  1639. +                    if (high_altar && Role_if(PM_INFIDEL)
  1640. +                        && u.uachieve.amulet && !obj->spe) {
  1641. +                        godvoice(A_NONE, (char *) 0);
  1642. +                        qt_pager(QT_MOLOCH_2);
  1643. +                        You_feel("strange energies envelop %s.",
  1644. +                                 the(xname(obj)));
  1645. +                        obj->spe = 1;
  1646. +                        u.uhave.amulet = 1;
  1647. +                        break;
  1648. +                    }
  1649. +                    if (!Blind)
  1650. +                        pline_The("altar glows for a moment.");
  1651. +                    /* nothing happens */
  1652. +                    break;
  1653. +                }
  1654. +                if (high_altar) {
  1655. +                    /* messages yoinked from pray.c */
  1656. +                    You("sense a conflict between %s and %s.",
  1657. +                        align_gname(A_NONE), a_gname());
  1658. +                    if (obj->spe && altar_align == inf_align(1)) {
  1659. +                        You_feel("the power of %s increase.",
  1660. +                                 align_gname(A_NONE));
  1661. +                    } else {
  1662. +                        pline("%s feel the power of %s decrease.",
  1663. +                              u.ualign.type == A_NONE ? "Unluckily, you"
  1664. +                                                      : "You",
  1665. +                              align_gname(A_NONE));
  1666. +                        godvoice(altar_align, "So, mortal!  You dare "
  1667. +                                              "desecrate my High Temple!");
  1668. +                        god_zaps_you(altar_align);
  1669. +                        break;
  1670. +                    }
  1671. +                }
  1672. +                levl[u.ux][u.uy].altarmask &= AM_SHRINE;
  1673. +                levl[u.ux][u.uy].altarmask |= AM_NONE;
  1674. +                if (!Blind)
  1675. +                    pline_The("altar glows %s.", hcolor(NH_RED));
  1676. +                if (!high_altar) {
  1677. +                    /* the Idol does all the work for you,
  1678. +                     * so you don't get a luck increase;
  1679. +                     * but you don't get a hostile minion, either */
  1680. +                    struct monst *pri = findpriest(temple_occupied(u.urooms));
  1681. +                    if (pri && mon_aligntyp(pri) != A_NONE)
  1682. +                        angry_priest();
  1683. +                } else {
  1684. +                    /* At this point, the player must be an Infidel.
  1685. +                     * Should we still check for opposite alignment?
  1686. +                     * Currently, Moloch doesn't care. */
  1687. +                    adjalign(10);
  1688. +                    u.uachieve.ascended = 1;
  1689. +                    pline1("A sinister laughter echoes through the temple, "
  1690. +                           "and you're bathed in darkness...");
  1691. +                    godvoice(A_NONE, "My pawn, thou hast done well!");
  1692. +                    display_nhwindow(WIN_MESSAGE, FALSE);
  1693. +                    verbalize("In return for thy service, "
  1694. +                              "I grant thee a part of My domain!");
  1695. +                    You("ascend to the status of Demon %s...",
  1696. +                        flags.female ? "Lady" : "Lord");
  1697. +                    done(ASCENDED);
  1698. +                }
  1699. +            } else {
  1700. +                obj->age = 0; /* will be set below */
  1701. +                use_figurine(&obj);
  1702. +            }
  1703. +            break;
  1704.          }
  1705.      } else {
  1706.          long eprop = (u.uprops[oart->inv_prop].extrinsic ^= W_ARTI),
  1707. @@ -1931,6 +2033,12 @@ boolean loseit;    /* whether to drop it if hero can longer touch it */
  1708.  {
  1709.      struct obj *obj = *objp;
  1710.  
  1711. +    /* allow hero in silver-hating form to try to perform invocation ritual */
  1712. +    if (obj->otyp == BELL_OF_OPENING
  1713. +        && invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
  1714. +        return 1;
  1715. +    }
  1716. +
  1717.      if (touch_artifact(obj, &youmonst)) {
  1718.          char buf[BUFSZ];
  1719.          int dmg = 0, tmp;
  1720. diff --git a/src/attrib.c b/src/attrib.c
  1721. index 028eebf..94ba766 100644
  1722. --- a/src/attrib.c
  1723. +++ b/src/attrib.c
  1724. @@ -41,6 +41,11 @@ static const struct innate {
  1725.                   { 15, &(HWarning), "sensitive", "" },
  1726.                   { 0, 0, 0, 0 } },
  1727.  
  1728. +  inf_abil[] = { { 1, &(HFire_resistance), "", "" },
  1729. +                 { 15, &(HWarning), "sensitive", "" },
  1730. +                 { 20, &(HShock_resistance), "inured", "softened" },
  1731. +                 { 0, 0, 0, 0 } },
  1732. +
  1733.    kni_abil[] = { { 7, &(HFast), "quick", "slow" }, { 0, 0, 0, 0 } },
  1734.  
  1735.    mon_abil[] = { { 1, &(HFast), "", "" },
  1736. @@ -101,6 +106,15 @@ static const struct innate {
  1737.                   { 1, &HPoison_resistance, "", "" },
  1738.                   { 0, 0, 0, 0 } },
  1739.  
  1740. +  dem_abil[] = { { 1, &HInfravision, "", "" },
  1741. +                 { 1, &HFire_resistance, "", "" },
  1742. +                 { 1, &HPoison_resistance, "", "" },
  1743. +                 { 1, &HDrain_resistance, "", "" },
  1744. +                 { 1, &HSee_invisible, "", "" },
  1745. +                 { 1, &HFlying, "", "" },
  1746. +                 /* also inediate */
  1747. +                 { 0, 0, 0, 0 } },
  1748. +
  1749.    hum_abil[] = { { 0, 0, 0, 0 } };
  1750.  
  1751.  STATIC_DCL void NDECL(exerper);
  1752. @@ -706,6 +720,7 @@ int r;
  1753.          { PM_BARBARIAN, bar_abil },
  1754.          { PM_CAVEMAN, cav_abil },
  1755.          { PM_HEALER, hea_abil },
  1756. +        { PM_INFIDEL, inf_abil },
  1757.          { PM_KNIGHT, kni_abil },
  1758.          { PM_MONK, mon_abil },
  1759.          { PM_PRIEST, pri_abil },
  1760. @@ -747,6 +762,9 @@ long frommask;
  1761.          case PM_ORC:
  1762.              abil = orc_abil;
  1763.              break;
  1764. +        case PM_DEMON:
  1765. +            abil = dem_abil;
  1766. +            break;
  1767.          case PM_HUMAN:
  1768.              abil = hum_abil;
  1769.              break;
  1770. @@ -800,6 +818,8 @@ int propidx;
  1771.          return FROM_LYCN;
  1772.      if (propidx == FAST && Very_fast)
  1773.          return FROM_NONE; /* can't become very fast innately */
  1774. +    if (propidx == FLYING && (BFlying & W_ARMOR))
  1775. +        return FROM_NONE; /* not from form, as that is blocked */
  1776.      if ((innateness = innately(&u.uprops[propidx].intrinsic)) != FROM_NONE)
  1777.          return innateness;
  1778.      if (propidx == JUMPING && Role_if(PM_KNIGHT)
  1779. diff --git a/src/bones.c b/src/bones.c
  1780. index da0de0f..f431a49 100644
  1781. --- a/src/bones.c
  1782. +++ b/src/bones.c
  1783. @@ -504,7 +504,7 @@ struct obj *corpse;
  1784.         character started out as, same as topten and logfile entries */
  1785.      Sprintf(newbones->who, "%s-%.3s-%.3s-%.3s-%.3s", plname, urole.filecode,
  1786.              urace.filecode, genders[flags.female].filecode,
  1787. -            aligns[1 - u.ualign.type].filecode);
  1788. +            aligns[u.ualign.type == A_NONE ? 3 : 1 - u.ualign.type].filecode);
  1789.      formatkiller(newbones->how, sizeof newbones->how, how, TRUE);
  1790.      Strcpy(newbones->when, yyyymmddhhmmss(when));
  1791.      /* final resting place, used to decide when bones are discovered */
  1792. diff --git a/src/botl.c b/src/botl.c
  1793. index 4c7dbf3..f841d63 100644
  1794. --- a/src/botl.c
  1795. +++ b/src/botl.c
  1796. @@ -84,9 +84,10 @@ do_statusline1()
  1797.              ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS),
  1798.              ACURR(A_CHA));
  1799.      Sprintf(nb = eos(nb),
  1800. -            (u.ualign.type == A_CHAOTIC)
  1801. -                ? "  Chaotic"
  1802. -                : (u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
  1803. +            (u.ualign.type == A_NONE) ? "  Unaligned"
  1804. +                : (u.ualign.type == A_CHAOTIC) ? "  Chaotic"
  1805. +                    : (u.ualign.type == A_NEUTRAL) ? "  Neutral"
  1806. +                        : "  Lawful");
  1807.  #ifdef SCORE_ON_BOTL
  1808.      if (flags.showscore)
  1809.          Sprintf(nb = eos(nb), " S:%ld", botl_score());
  1810. @@ -623,11 +624,13 @@ bot_via_windowport()
  1811.      blstats[idx][BL_CH].a.a_int = ACURR(A_CHA);
  1812.  
  1813.      /* Alignment */
  1814. -    Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_CHAOTIC)
  1815. -                                          ? "Chaotic"
  1816. -                                          : (u.ualign.type == A_NEUTRAL)
  1817. -                                               ? "Neutral"
  1818. -                                               : "Lawful");
  1819. +    Strcpy(blstats[idx][BL_ALIGN].val, (u.ualign.type == A_NONE)
  1820. +                                           ? "Unaligned"
  1821. +                                           : (u.ualign.type == A_CHAOTIC)
  1822. +                                               ? "Chaotic"
  1823. +                                               : (u.ualign.type == A_NEUTRAL)
  1824. +                                                   ? "Neutral"
  1825. +                                                   : "Lawful");
  1826.  
  1827.      /* Score */
  1828.      blstats[idx][BL_SCORE].a.a_long =
  1829. diff --git a/src/cmd.c b/src/cmd.c
  1830. index 6b28524..2148827 100644
  1831. --- a/src/cmd.c
  1832. +++ b/src/cmd.c
  1833. @@ -1833,7 +1833,7 @@ int unused_mode UNUSED;
  1834.  int final;
  1835.  {
  1836.      const char *role_titl, *rank_titl;
  1837. -    int innategend, difgend, difalgn;
  1838. +    int innategend, difgend, difalgn, difrace;
  1839.      char buf[BUFSZ], tmpbuf[BUFSZ];
  1840.  
  1841.      /* note that if poly'd, we need to use u.mfemale instead of flags.female
  1842. @@ -1911,12 +1911,14 @@ int final;
  1843.         trailing "and" on all three aligned entries but looks too verbose] */
  1844.      Sprintf(buf, " who %s opposed by", !final ? "is" : "was");
  1845.      if (u.ualign.type != A_LAWFUL)
  1846. -        Sprintf(eos(buf), " %s (%s) and", align_gname(A_LAWFUL),
  1847. -                align_str(A_LAWFUL));
  1848. +        Sprintf(eos(buf), " %s (%s)%s", align_gname(A_LAWFUL),
  1849. +                align_str(A_LAWFUL),
  1850. +                (u.ualign.type != A_NONE) ? " and" : ",");
  1851.      if (u.ualign.type != A_NEUTRAL)
  1852.          Sprintf(eos(buf), " %s (%s)%s", align_gname(A_NEUTRAL),
  1853.                  align_str(A_NEUTRAL),
  1854. -                (u.ualign.type != A_CHAOTIC) ? " and" : "");
  1855. +                (u.ualign.type == A_NONE) ? ", and" /* oxford comma */
  1856. +                : (u.ualign.type != A_CHAOTIC) ? " and" : "");
  1857.      if (u.ualign.type != A_CHAOTIC)
  1858.          Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC),
  1859.                  align_str(A_CHAOTIC));
  1860. @@ -1931,12 +1933,26 @@ int final;
  1861.      difalgn = (((u.ualign.type != u.ualignbase[A_CURRENT]) ? 1 : 0)
  1862.                 + ((u.ualignbase[A_CURRENT] != u.ualignbase[A_ORIGINAL])
  1863.                    ? 2 : 0));
  1864. +    difrace = urace.malenum != races[flags.initrace].malenum;
  1865.      if (difalgn & 1) { /* have temporary alignment so report permanent one */
  1866.          Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT]));
  1867.          you_are(buf, "");
  1868.          difalgn &= ~1; /* suppress helm from "started out <foo>" message */
  1869.      }
  1870. -    if (difgend || difalgn) { /* sex change or perm align change or both */
  1871. +    if (difrace) { /* permanent race change (Inf crowning) */
  1872. +        buf[0] = '\0';
  1873. +        if (difalgn) {
  1874. +            Strcat(buf, align_str(u.ualignbase[A_ORIGINAL]));
  1875. +            Strcat(buf, " ");
  1876. +        }
  1877. +        if (difgend) {
  1878. +            Strcat(buf, genders[flags.initgend].adj);
  1879. +            Strcat(buf, " ");
  1880. +        }
  1881. +        Strcat(buf, races[flags.initrace].noun);
  1882. +        Sprintf(buf, " You started out as %s.", an(buf));
  1883. +        enlght_out(buf);
  1884. +    } else if (difgend || difalgn) { /* sex change or perm align change */
  1885.          Sprintf(buf, " You started out %s%s%s.",
  1886.                  difgend ? genders[flags.initgend].adj : "",
  1887.                  (difgend && difalgn) ? " and " : "",
  1888. @@ -2494,6 +2510,25 @@ int final;
  1889.              enl_msg("You ", "fall", "fell", " asleep uncontrollably", buf);
  1890.          }
  1891.      }
  1892. +    /* In case the player missed the "urge to perform a sacrifice",
  1893. +     * put a reminder here. */
  1894. +    if (u.ualign.type == A_NONE) {
  1895. +        long due = moves - context.next_moloch_offering;
  1896. +        if (due < 0) {
  1897. +            if (wizard) {
  1898. +                Sprintf(buf, "%ld turns until your next "
  1899. +                        "mandatory sacrifice to ", -due);
  1900. +                you_have(buf, u_gname());
  1901. +            }
  1902. +        } else {
  1903. +            if (wizard && due > 0)
  1904. +                Sprintf(buf, "%ld turns late for your "
  1905. +                        "next sacrifice to ", due);
  1906. +            else
  1907. +                Strcpy(buf, "due for a sacrifice to ");
  1908. +            you_are(buf, u_gname());
  1909. +        }
  1910. +    }
  1911.      /* hunger/nutrition */
  1912.      if (Hunger) {
  1913.          if (magic || cause_known(HUNGER))
  1914. @@ -2624,9 +2659,11 @@ int final;
  1915.      enlght_out(final ? "Final Attributes:" : "Current Attributes:");
  1916.  
  1917.      if (u.uevent.uhand_of_elbereth) {
  1918. -        static const char *const hofe_titles[3] = { "the Hand of Elbereth",
  1919. +        static const char *const hofe_titles[4] = { "the Hand of Elbereth",
  1920.                                                      "the Envoy of Balance",
  1921. -                                                    "the Glory of Arioch" };
  1922. +                                                    "the Glory of Arioch",
  1923. +                                                    "the Emissary of Moloch"
  1924. +                                                  };
  1925.          you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1], "");
  1926.      }
  1927.  
  1928. @@ -2795,7 +2832,7 @@ int final;
  1929.          BLevitation = save_BLev;
  1930.      }
  1931.      /* actively flying handled earlier as a status condition */
  1932. -    if (BFlying) { /* flight is blocked */
  1933. +    if (BFlying && !Flying) { /* flight is blocked */
  1934.          long save_BFly = BFlying;
  1935.  
  1936.          BFlying = 0L;
  1937. @@ -2817,7 +2854,9 @@ int final;
  1938.                               ? if_surroundings_permitted
  1939.                               /* two or more of levitation, surroundings,
  1940.                                  and being trapped in the floor */
  1941. -                             : " if circumstances permitted",
  1942. +                             : (save_BFly == W_ARM)
  1943. +                                ? " if your wings weren't confined"
  1944. +                                : " if circumstances permitted",
  1945.                      "");
  1946.          }
  1947.          BFlying = save_BFly;
  1948. diff --git a/src/do.c b/src/do.c
  1949. index 8bbed39..f2e748c 100644
  1950. --- a/src/do.c
  1951. +++ b/src/do.c
  1952. @@ -569,7 +569,7 @@ const char *word;
  1953.              Norep("You cannot %s %s you are wearing.", word, something);
  1954.          return FALSE;
  1955.      }
  1956. -    if (obj->otyp == LOADSTONE && obj->cursed) {
  1957. +    if (obj->otyp == LOADSTONE && cursed(obj, TRUE)) {
  1958.          /* getobj() kludge sets corpsenm to user's specified count
  1959.             when refusing to split a stack of cursed loadstones */
  1960.          if (*word) {
  1961. @@ -914,7 +914,8 @@ int retry;
  1962.                  if (cnt < otmp->quan) {
  1963.                      if (welded(otmp)) {
  1964.                          ; /* don't split */
  1965. -                    } else if (otmp->otyp == LOADSTONE && otmp->cursed) {
  1966. +                    } else if (otmp->otyp == LOADSTONE
  1967. +                               && cursed(otmp, TRUE)) {
  1968.                          /* same kludge as getobj(), for canletgo()'s use */
  1969.                          otmp->corpsenm = (int) cnt; /* don't split */
  1970.                      } else {
  1971. @@ -1295,10 +1296,12 @@ boolean at_stairs, falling, portal;
  1972.       *   -1   11.46  12.50  12.5
  1973.       *   -2    5.21   4.17   0.0
  1974.       *   -3    2.08   0.0    0.0
  1975. +     *
  1976. +     *   Infidels (unaligned) are spared from the mysterious force.
  1977.       */
  1978.      if (Inhell && up && u.uhave.amulet && !newdungeon && !portal
  1979.          && (dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz) - 3)) {
  1980. -        if (!rn2(4)) {
  1981. +        if (u.ualign.type != A_NONE && !rn2(4)) {
  1982.              int odds = 3 + (int) u.ualign.type,   /* 2..4 */
  1983.                  diff = odds <= 1 ? 0 : rn2(odds); /* paranoia */
  1984.  
  1985. @@ -1707,7 +1710,8 @@ final_level()
  1986.      create_mplayers(rn1(4, 3), TRUE);
  1987.  
  1988.      /* create a guardian angel next to player, if worthy */
  1989. -    gain_guardian_angel();
  1990. +    if (u.ualign.type != A_NONE)
  1991. +        gain_guardian_angel();
  1992.  }
  1993.  
  1994.  static char *dfr_pre_msg = 0,  /* pline() before level change */
  1995. diff --git a/src/do_wear.c b/src/do_wear.c
  1996. index b48c69d..789eff7 100644
  1997. --- a/src/do_wear.c
  1998. +++ b/src/do_wear.c
  1999. @@ -414,7 +414,7 @@ Helmet_on(VOID_ARGS)
  2000.             by hero falling onto a polymorph trap or into water (emergency
  2001.             disrobe) or maybe lava (probably not, helm isn't 'organic') */
  2002.          uchangealign((u.ualign.type != A_NEUTRAL)
  2003. -                         ? -u.ualign.type
  2004. +                         ? -sgn(u.ualign.type)
  2005.                           : (uarmh->o_id % 2) ? A_CHAOTIC : A_LAWFUL,
  2006.                       1);
  2007.          /* makeknown(HELM_OF_OPPOSITE_ALIGNMENT); -- below, after Tobjnam() */
  2008. @@ -696,6 +696,7 @@ Armor_on(VOID_ARGS)
  2009.       */
  2010.      if (uarm) /* no known instances of !uarm here but play it safe */
  2011.          uarm->known = 1; /* suit's +/- evident because of status line AC */
  2012. +    check_wings(FALSE);
  2013.      return 0;
  2014.  }
  2015.  
  2016. @@ -705,6 +706,7 @@ Armor_off(VOID_ARGS)
  2017.      context.takeoff.mask &= ~W_ARM;
  2018.      setworn((struct obj *) 0, W_ARM);
  2019.      context.takeoff.cancelled_don = FALSE;
  2020. +    check_wings(FALSE);
  2021.      return 0;
  2022.  }
  2023.  
  2024. @@ -720,9 +722,44 @@ Armor_gone()
  2025.      context.takeoff.mask &= ~W_ARM;
  2026.      setnotworn(uarm);
  2027.      context.takeoff.cancelled_don = FALSE;
  2028. +    check_wings(FALSE);
  2029.      return 0;
  2030.  }
  2031.  
  2032. +/* Some monster forms' flight is blocked by most body armor. */
  2033. +void
  2034. +check_wings(silent)
  2035. +boolean silent; /* we assume a wardrobe change if false */
  2036. +{
  2037. +    static struct obj *last_worn_armor;
  2038. +    boolean old_flying = Flying;
  2039. +
  2040. +    BFlying &= ~W_ARM;
  2041. +    if (!big_wings(raceptr(&youmonst)))
  2042. +        return;
  2043. +
  2044. +    if (!uarm) {
  2045. +        if (!silent && Flying && !old_flying)
  2046. +            You("spread your wings and take flight.");
  2047. +    } else if (Is_dragon_scales(uarm)) {
  2048. +        if (!silent && uarm != last_worn_armor)
  2049. +            You("arrange the scales around your wings.");
  2050. +    } else if (uarm->otyp == LEATHER_JACKET) {
  2051. +        if (!silent && uarm != last_worn_armor)
  2052. +            pline1("This jacket seems to have holes for wings.");
  2053. +    } else {
  2054. +        BFlying |= W_ARM;
  2055. +        if (!silent)
  2056. +            You("fold your wings under your suit.");
  2057. +    }
  2058. +
  2059. +    if (uarm)
  2060. +        last_worn_armor = uarm;
  2061. +
  2062. +    if (Flying != old_flying)
  2063. +        context.botl = TRUE;
  2064. +}
  2065. +
  2066.  STATIC_OVL void
  2067.  Amulet_on()
  2068.  {
  2069. @@ -1546,31 +1583,35 @@ doremring()
  2070.  
  2071.  /* Check if something worn is cursed _and_ unremovable. */
  2072.  int
  2073. -cursed(otmp)
  2074. +cursed(otmp, silent)
  2075.  struct obj *otmp;
  2076. +boolean silent;
  2077.  {
  2078.      if (!otmp) {
  2079.          impossible("cursed without otmp");
  2080.          return 0;
  2081.      }
  2082. -    /* Curses, like chickens, come home to roost. */
  2083. -    if ((otmp == uwep) ? welded(otmp) : (int) otmp->cursed) {
  2084. -        boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
  2085. -                              || otmp->otyp == LENSES || otmp->quan > 1L);
  2086. -
  2087. -        /* might be trying again after applying grease to hands */
  2088. -        if (Glib && otmp->bknown
  2089. -            /* for weapon, we'll only get here via 'A )' */
  2090. -            && (uarmg ? (otmp == uwep)
  2091. -                      : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
  2092. -            pline("Despite your slippery %s, you can't.",
  2093. -                  fingers_or_gloves(TRUE));
  2094. -        else
  2095. -            You("can't.  %s cursed.", use_plural ? "They are" : "It is");
  2096. -        set_bknown(otmp, 1);
  2097. +    /* Inf are immune to curses. */
  2098. +    if (Role_if(PM_INFIDEL) || !otmp->cursed || otmp == uwep && !welded(otmp))
  2099. +        return 0;
  2100. +    if (silent)
  2101.          return 1;
  2102. -    }
  2103. -    return 0;
  2104. +
  2105. +    /* Curses, like chickens, come home to roost. */
  2106. +    boolean use_plural = (is_boots(otmp) || is_gloves(otmp)
  2107. +                          || otmp->otyp == LENSES || otmp->quan > 1L);
  2108. +
  2109. +    /* might be trying again after applying grease to hands */
  2110. +    if (Glib && otmp->bknown
  2111. +        /* for weapon, we'll only get here via 'A )' */
  2112. +        && (uarmg ? (otmp == uwep)
  2113. +            : ((otmp->owornmask & (W_WEP | W_RING)) != 0)))
  2114. +        pline("Despite your slippery %s, you can't.",
  2115. +              fingers_or_gloves(TRUE));
  2116. +    else
  2117. +        You("can't.  %s cursed.", use_plural ? "They are" : "It is");
  2118. +    set_bknown(otmp, 1);
  2119. +    return 1;
  2120.  }
  2121.  
  2122.  int
  2123. @@ -1581,7 +1622,7 @@ struct obj *otmp;
  2124.      int delay = -objects[otmp->otyp].oc_delay;
  2125.      const char *what = 0;
  2126.  
  2127. -    if (cursed(otmp))
  2128. +    if (cursed(otmp, FALSE))
  2129.          return 0;
  2130.      /* this used to make assumptions about which types of armor had
  2131.         delays and which didn't; now both are handled for all types */
  2132. @@ -1938,7 +1979,7 @@ struct obj *obj;
  2133.                       gloves_simple_name(uarmg));
  2134.                  return 1; /* always uses move */
  2135.              }
  2136. -            if (uarmg && uarmg->cursed) {
  2137. +            if (uarmg && cursed(uarmg, TRUE)) {
  2138.                  res = !uarmg->bknown;
  2139.                  set_bknown(uarmg, 1);
  2140.                  You("cannot remove your %s to put on the ring.", c_gloves);
  2141. @@ -2159,9 +2200,9 @@ glibr()
  2142.      boolean leftfall, rightfall, wastwoweap = FALSE;
  2143.      const char *otherwep = 0, *thiswep, *which, *hand;
  2144.  
  2145. -    leftfall = (uleft && !uleft->cursed
  2146. +    leftfall = (uleft && !cursed(uleft, TRUE)
  2147.                  && (!uwep || !welded(uwep) || !bimanual(uwep)));
  2148. -    rightfall = (uright && !uright->cursed && (!welded(uwep)));
  2149. +    rightfall = (uright && !cursed(uright, TRUE) && (!welded(uwep)));
  2150.      if (!uarmg && (leftfall || rightfall) && !nolimbs(youmonst.data)) {
  2151.          /* changed so cursed rings don't fall off, GAN 10/30/86 */
  2152.          Your("%s off your %s.",
  2153. @@ -2280,13 +2321,13 @@ int otyp;
  2154.          /* reasons ring can't be removed match those checked by select_off();
  2155.             limbless case has extra checks because ordinarily it's temporary */
  2156.          if (nolimbs(youmonst.data) && uamul
  2157. -            && uamul->otyp == AMULET_OF_UNCHANGING && uamul->cursed)
  2158. +            && uamul->otyp == AMULET_OF_UNCHANGING && cursed(uamul, TRUE))
  2159.              return uamul;
  2160.          if (welded(uwep) && (ring == uright || bimanual(uwep)))
  2161.              return uwep;
  2162. -        if (uarmg && uarmg->cursed)
  2163. +        if (uarmg && cursed(uarmg, TRUE))
  2164.              return uarmg;
  2165. -        if (ring->cursed)
  2166. +        if (cursed(ring, TRUE))
  2167.              return ring;
  2168.          /* normally outermost layer is processed first, but slippery gloves
  2169.             wears off quickly so uncurse ring itself before handling those */
  2170. @@ -2331,7 +2372,7 @@ register struct obj *otmp;
  2171.          if (welded(uwep) && (otmp == uright || bimanual(uwep))) {
  2172.              Sprintf(buf, "free a weapon %s", body_part(HAND));
  2173.              why = uwep;
  2174. -        } else if (uarmg && (uarmg->cursed || Glib)) {
  2175. +        } else if (uarmg && (cursed(uarmg, TRUE) || Glib)) {
  2176.              Sprintf(buf, "take off your %s%s",
  2177.                      Glib ? "slippery " : "", gloves_simple_name(uarmg));
  2178.              why = !Glib ? uarmg : &glibdummy;
  2179. @@ -2371,10 +2412,10 @@ register struct obj *otmp;
  2180.      /* special suit and shirt checks */
  2181.      if (otmp == uarm || otmp == uarmu) {
  2182.          why = 0; /* the item which prevents disrobing */
  2183. -        if (uarmc && uarmc->cursed) {
  2184. +        if (uarmc && cursed(uarmc, TRUE)) {
  2185.              Sprintf(buf, "remove your %s", cloak_simple_name(uarmc));
  2186.              why = uarmc;
  2187. -        } else if (otmp == uarmu && uarm && uarm->cursed) {
  2188. +        } else if (otmp == uarmu && uarm && cursed(uarm, TRUE)) {
  2189.              Sprintf(buf, "remove your %s", c_suit);
  2190.              why = uarm;
  2191.          } else if (welded(uwep) && bimanual(uwep)) {
  2192. @@ -2395,7 +2436,7 @@ register struct obj *otmp;
  2193.          ; /* some items can be removed even when cursed */
  2194.      } else {
  2195.          /* otherwise, this is fundamental */
  2196. -        if (cursed(otmp))
  2197. +        if (cursed(otmp, FALSE))
  2198.              return 0;
  2199.      }
  2200.  
  2201. @@ -2442,7 +2483,7 @@ do_takeoff()
  2202.  
  2203.      context.takeoff.mask |= I_SPECIAL; /* set flag for cancel_doff() */
  2204.      if (doff->what == W_WEP) {
  2205. -        if (!cursed(uwep)) {
  2206. +        if (!cursed(uwep, FALSE)) {
  2207.              setuwep((struct obj *) 0);
  2208.              You("are empty %s.", body_part(HANDED));
  2209.              u.twoweap = FALSE;
  2210. @@ -2456,46 +2497,46 @@ do_takeoff()
  2211.          You("no longer have ammunition readied.");
  2212.      } else if (doff->what == WORN_ARMOR) {
  2213.          otmp = uarm;
  2214. -        if (!cursed(otmp))
  2215. +        if (!cursed(otmp, FALSE))
  2216.              (void) Armor_off();
  2217.      } else if (doff->what == WORN_CLOAK) {
  2218.          otmp = uarmc;
  2219. -        if (!cursed(otmp))
  2220. +        if (!cursed(otmp, FALSE))
  2221.              (void) Cloak_off();
  2222.      } else if (doff->what == WORN_BOOTS) {
  2223.          otmp = uarmf;
  2224. -        if (!cursed(otmp))
  2225. +        if (!cursed(otmp, FALSE))
  2226.              (void) Boots_off();
  2227.      } else if (doff->what == WORN_GLOVES) {
  2228.          otmp = uarmg;
  2229. -        if (!cursed(otmp))
  2230. +        if (!cursed(otmp, FALSE))
  2231.              (void) Gloves_off();
  2232.      } else if (doff->what == WORN_HELMET) {
  2233.          otmp = uarmh;
  2234. -        if (!cursed(otmp))
  2235. +        if (!cursed(otmp, FALSE))
  2236.              (void) Helmet_off();
  2237.      } else if (doff->what == WORN_SHIELD) {
  2238.          otmp = uarms;
  2239. -        if (!cursed(otmp))
  2240. +        if (!cursed(otmp, FALSE))
  2241.              (void) Shield_off();
  2242.      } else if (doff->what == WORN_SHIRT) {
  2243.          otmp = uarmu;
  2244. -        if (!cursed(otmp))
  2245. +        if (!cursed(otmp, FALSE))
  2246.              (void) Shirt_off();
  2247.      } else if (doff->what == WORN_AMUL) {
  2248.          otmp = uamul;
  2249. -        if (!cursed(otmp))
  2250. +        if (!cursed(otmp, FALSE))
  2251.              Amulet_off();
  2252.      } else if (doff->what == LEFT_RING) {
  2253.          otmp = uleft;
  2254. -        if (!cursed(otmp))
  2255. +        if (!cursed(otmp, FALSE))
  2256.              Ring_off(uleft);
  2257.      } else if (doff->what == RIGHT_RING) {
  2258.          otmp = uright;
  2259. -        if (!cursed(otmp))
  2260. +        if (!cursed(otmp, FALSE))
  2261.              Ring_off(uright);
  2262.      } else if (doff->what == WORN_BLINDF) {
  2263. -        if (!cursed(ublindf))
  2264. +        if (!cursed(ublindf, FALSE))
  2265.              Blindf_off(ublindf);
  2266.      } else {
  2267.          impossible("do_takeoff: taking off %lx", doff->what);
  2268. @@ -2795,7 +2836,7 @@ boolean only_if_known_cursed; /* ignore covering unless known to be cursed */
  2269.          "need to take off %s to %s %s.";
  2270.      char buf[BUFSZ];
  2271.      boolean anycovering = !only_if_known_cursed; /* more comprehensible... */
  2272. -#define BLOCKSACCESS(x) (anycovering || ((x)->cursed && (x)->bknown))
  2273. +#define BLOCKSACCESS(x) (anycovering || (cursed((x), TRUE) && (x)->bknown))
  2274.  
  2275.      if (!obj || !obj->owornmask)
  2276.          return FALSE; /* not inaccessible */
  2277. diff --git a/src/dog.c b/src/dog.c
  2278. index 5c50eb6..feccd33 100644
  2279. --- a/src/dog.c
  2280. +++ b/src/dog.c
  2281. @@ -75,10 +75,16 @@ boolean quietly;
  2282.      struct permonst *pm;
  2283.      struct monst *mtmp = 0;
  2284.      int chance, trycnt = 100;
  2285. +    boolean idol = otmp && otmp->oartifact == ART_IDOL_OF_MOLOCH;
  2286.  
  2287.      do {
  2288.          if (otmp) { /* figurine; otherwise spell */
  2289.              int mndx = otmp->corpsenm;
  2290. +            if (idol) {
  2291. +                mndx = ndemon(A_NONE);
  2292. +                if (mndx == NON_PM) /* just in case */
  2293. +                    continue;
  2294. +            }
  2295.  
  2296.              pm = &mons[mndx];
  2297.              /* activating a figurine provides one way to exceed the
  2298. @@ -86,10 +92,14 @@ boolean quietly;
  2299.                 it has a special limit (erinys, Nazgul) */
  2300.              if ((mvitals[mndx].mvflags & G_EXTINCT)
  2301.                  && mbirth_limit(mndx) != MAXMONNO) {
  2302. -                if (!quietly)
  2303. +                if (!quietly) {
  2304.                      /* have just been given "You <do something with>
  2305.                         the figurine and it transforms." message */
  2306. -                    pline("... into a pile of dust.");
  2307. +                    if (!idol)
  2308. +                        pline("... into a pile of dust.");
  2309. +                    else if (!Blind)
  2310. +                        pline_The("cloud disperses.");
  2311. +                }
  2312.                  break; /* mtmp is null */
  2313.              }
  2314.          } else if (!rn2(3)) {
  2315. @@ -103,10 +113,16 @@ boolean quietly;
  2316.              }
  2317.          }
  2318.  
  2319. -        mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER | NO_MINVENT);
  2320. +        mtmp = makemon(pm, x, y, MM_EDOG | MM_IGNOREWATER
  2321. +                                 | (!idol * NO_MINVENT));
  2322.          if (otmp && !mtmp) { /* monster was genocided or square occupied */
  2323. -            if (!quietly)
  2324. -                pline_The("figurine writhes and then shatters into pieces!");
  2325. +            if (!quietly) {
  2326. +                if (!idol)
  2327. +                    pline_The("figurine writhes and then shatters "
  2328. +                              "into pieces!");
  2329. +                else if (!Blind)
  2330. +                    pline_The("cloud disperses.");
  2331. +            }
  2332.              break;
  2333.          }
  2334.      } while (!mtmp && --trycnt > 0);
  2335. @@ -114,6 +130,14 @@ boolean quietly;
  2336.      if (!mtmp)
  2337.          return (struct monst *) 0;
  2338.  
  2339. +    if (idol && !quietly && !Blind) {
  2340. +        pline_The("mist coagulates into the shape of %s%s.",
  2341. +                  x_monnam(mtmp, ARTICLE_A, (char *) 0, SUPPRESS_IT
  2342. +                           | SUPPRESS_INVISIBLE | SUPPRESS_SADDLE
  2343. +                           | SUPPRESS_NAME, FALSE),
  2344. +                  canspotmon(mtmp) ? "" : " and vanishes");
  2345. +    }
  2346. +
  2347.      if (is_pool(mtmp->mx, mtmp->my) && minliquid(mtmp))
  2348.          return (struct monst *) 0;
  2349.  
  2350. @@ -134,7 +158,7 @@ boolean quietly;
  2351.              }
  2352.          }
  2353.          /* if figurine has been named, give same name to the monster */
  2354. -        if (has_oname(otmp))
  2355. +        if (has_oname(otmp) && !idol)
  2356.              mtmp = christen_monst(mtmp, ONAME(otmp));
  2357.      }
  2358.      set_malign(mtmp); /* more alignment changes */
  2359. @@ -551,6 +575,19 @@ long nmv; /* number of moves */
  2360.          m_unleash(mtmp, FALSE);
  2361.      }
  2362.  
  2363. +    /* maybe pick up the abandoned Amulet */
  2364. +    if (mtmp->data == &mons[PM_AGENT] && !mtmp->mpeaceful
  2365. +        && !mon_has_amulet(mtmp) && rn2(imv + 1) > 300) {
  2366. +        struct obj *otmp;
  2367. +        for (otmp = level.objlist; otmp; otmp = otmp->nobj)
  2368. +            if (otmp->otyp == AMULET_OF_YENDOR
  2369. +                || otmp->otyp == FAKE_AMULET_OF_YENDOR) {
  2370. +                obj_extract_self(otmp);
  2371. +                (void) mpickobj(mtmp, otmp);
  2372. +                break;
  2373. +            }
  2374. +    }
  2375. +
  2376.      /* recover lost hit points */
  2377.      if (!regenerates(mtmp->data))
  2378.          imv /= 20;
  2379. @@ -923,7 +960,7 @@ register struct obj *obj;
  2380.          /* monsters with conflicting structures cannot be tamed */
  2381.          || mtmp->isshk || mtmp->isgd || mtmp->ispriest || mtmp->isminion
  2382.          || is_covetous(mtmp->data) || is_human(mtmp->data)
  2383. -        || (is_demon(mtmp->data) && !is_demon(youmonst.data))
  2384. +        || (is_demon(mtmp->data) && !is_demon(raceptr(&youmonst)))
  2385.          || (obj && dogfood(mtmp, obj) >= MANFOOD))
  2386.          return FALSE;
  2387.  
  2388. diff --git a/src/dothrow.c b/src/dothrow.c
  2389. index c1a415a..d3ffd8f 100644
  2390. --- a/src/dothrow.c
  2391. +++ b/src/dothrow.c
  2392. @@ -115,6 +115,7 @@ int shotlimit;
  2393.          /* some roles don't get a volley bonus until becoming expert */
  2394.          weakmultishot = (Role_if(PM_WIZARD) || Role_if(PM_PRIEST)
  2395.                           || (Role_if(PM_HEALER) && skill != P_KNIFE)
  2396. +                         || (Role_if(PM_INFIDEL) && skill != P_DAGGER)
  2397.                           || (Role_if(PM_TOURIST) && skill != -P_DART)
  2398.                           /* poor dexterity also inhibits multishot */
  2399.                           || Fumbling || ACURR(A_DEX) <= 6);
  2400. @@ -1804,7 +1805,7 @@ register struct monst *mon;
  2401.  register struct obj *obj;
  2402.  {
  2403.      char buf[BUFSZ];
  2404. -    boolean is_buddy = sgn(mon->data->maligntyp) == sgn(u.ualign.type);
  2405. +    boolean is_buddy = sgn(mon->data->maligntyp) == u.ualign.type;
  2406.      boolean is_gem = objects[obj->otyp].oc_material == GEMSTONE;
  2407.      int ret = 0;
  2408.      static NEARDATA const char nogood[] = " is not interested in your junk.";
  2409. diff --git a/src/dungeon.c b/src/dungeon.c
  2410. index 27b7481..1eedd62 100644
  2411. --- a/src/dungeon.c
  2412. +++ b/src/dungeon.c
  2413. @@ -1173,7 +1173,8 @@ boolean at_stairs;
  2414.          /* Taking an up dungeon branch. */
  2415.          /* KMH -- Upwards branches are okay if not level 1 */
  2416.          /* (Just make sure it doesn't go above depth 1) */
  2417. -        if (!u.uz.dnum && u.uz.dlevel == 1 && !u.uhave.amulet)
  2418. +        if (!u.uz.dnum && u.uz.dlevel == 1
  2419. +            && !(u.uhave.amulet && u.uachieve.amulet))
  2420.              done(ESCAPED);
  2421.          else
  2422.              goto_level(&sstairs.tolev, at_stairs, FALSE, FALSE);
  2423. @@ -2998,8 +2999,11 @@ boolean printdun;
  2424.              else
  2425.                  ADDNTOBUF("temple", mptr->feat.ntemple);
  2426.  
  2427. -            /* only print out altar's god if they are all to your god */
  2428. -            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type)
  2429. +            /* only print out altar's god if they are all to your god
  2430. +             * For Infidels, only print Moloch if there's exactly one altar;
  2431. +             * this is a technical resriction (i.e. I'm too lazy to fix it) */
  2432. +            if (Amask2align(Msa2amask(mptr->feat.msalign)) == u.ualign.type
  2433. +                && (u.ualign.type != A_NONE || mptr->feat.naltar == 1))
  2434.                  Sprintf(eos(buf), " to %s", align_gname(u.ualign.type));
  2435.          }
  2436.          ADDNTOBUF("throne", mptr->feat.nthrone);
  2437. diff --git a/src/eat.c b/src/eat.c
  2438. index 5e2aa1a..8ca11ae 100644
  2439. --- a/src/eat.c
  2440. +++ b/src/eat.c
  2441. @@ -2797,10 +2797,7 @@ gethungry()
  2442.         will need to wear an Amulet of Unchanging so still burn a small
  2443.         amount of nutrition in the 'moves % 20' ring/amulet check below */
  2444.      if ((!Unaware || !rn2(10)) /* slow metabolic rate while asleep */
  2445. -        && (carnivorous(youmonst.data)
  2446. -            || herbivorous(youmonst.data)
  2447. -            || metallivorous(youmonst.data))
  2448. -        && !Slow_digestion)
  2449. +        && !inediate(raceptr(&youmonst)) && !Slow_digestion)
  2450.          u.uhunger--; /* ordinary food consumption */
  2451.  
  2452.      if (moves % 2) { /* odd turns */
  2453. diff --git a/src/end.c b/src/end.c
  2454. index 4df88ce..fa02d50 100644
  2455. --- a/src/end.c
  2456. +++ b/src/end.c
  2457. @@ -754,7 +754,7 @@ time_t when; /* date+time at end of game */
  2458.  
  2459.      /* character name and basic role info */
  2460.      Sprintf(pbuf, "%s, %s %s %s %s", plname,
  2461. -            aligns[1 - u.ualign.type].adj,
  2462. +            aligns[u.ualign.type == A_NONE ? 3 : 1 - u.ualign.type].adj,
  2463.              genders[flags.female].adj,
  2464.              urace.adj,
  2465.              (flags.female && urole.name.f) ? urole.name.f : urole.name.m);
  2466. @@ -925,6 +925,8 @@ struct obj *list; /* inventory or container contents */
  2467.          } else if (obj->oartifact) {
  2468.              continue;
  2469.          } else if (obj->oclass == AMULET_CLASS) {
  2470. +            if (Role_if(PM_INFIDEL) && obj->otyp == AMULET_OF_YENDOR)
  2471. +                continue; /* starting inventory */
  2472.              i = obj->otyp - FIRST_AMULET;
  2473.              if (!amulets[i].count) {
  2474.                  amulets[i].count = obj->quan;
  2475. @@ -1464,7 +1466,10 @@ int how;
  2476.      }
  2477.  #endif
  2478.      if (u.uhave.amulet) {
  2479. -        Strcat(killer.name, " (with the Amulet)");
  2480. +        if (!Role_if(PM_INFIDEL)) /* redundant for Inf */
  2481. +            Strcat(killer.name, " (with the Amulet)");
  2482. +        else if (u.uachieve.amulet)
  2483. +            Strcat(killer.name, " (with the Idol)");
  2484.      } else if (how == ESCAPED) {
  2485.          if (Is_astralevel(&u.uz)) /* offered Amulet to wrong deity */
  2486.              Strcat(killer.name, " (in celestial disgrace)");
  2487. @@ -1478,7 +1483,9 @@ int how;
  2488.                  ? (const char *) ((flags.female && urole.name.f)
  2489.                      ? urole.name.f
  2490.                      : urole.name.m)
  2491. -                : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2492. +                : Role_if(PM_INFIDEL) /* can only ascend via Moloch */
  2493. +                 ? (const char *) (flags.female ? "Demon Lady" : "Demon Lord")
  2494. +                 : (const char *) (flags.female ? "Demigoddess" : "Demigod"));
  2495.      dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
  2496.      dump_forward_putstr(endwin, 0, "", done_stopprint);
  2497.  
  2498. diff --git a/src/engrave.c b/src/engrave.c
  2499. index b001855..975b538 100644
  2500. --- a/src/engrave.c
  2501. +++ b/src/engrave.c
  2502. @@ -431,7 +431,8 @@ int
  2503.  freehand()
  2504.  {
  2505.      return (!uwep || !welded(uwep)
  2506. -            || (!bimanual(uwep) && (!uarms || !uarms->cursed)));
  2507. +            || (!bimanual(uwep)
  2508. +                && (!uarms || !cursed(uarms, TRUE))));
  2509.  }
  2510.  
  2511.  static NEARDATA const char styluses[] = { ALL_CLASSES, ALLOW_NONE,
  2512. @@ -504,7 +505,7 @@ doengrave()
  2513.      maxelen = BUFSZ - 1;
  2514.      if (oep)
  2515.          oetype = oep->engr_type;
  2516. -    if (is_demon(youmonst.data) || youmonst.data->mlet == S_VAMPIRE)
  2517. +    if (is_demon(raceptr(&youmonst)) || youmonst.data->mlet == S_VAMPIRE)
  2518.          type = ENGR_BLOOD;
  2519.  
  2520.      /* Can the adventurer engrave at all? */
  2521. diff --git a/src/exper.c b/src/exper.c
  2522. index 9b96b5c..fc4cf1e 100644
  2523. --- a/src/exper.c
  2524. +++ b/src/exper.c
  2525. @@ -32,6 +32,7 @@ int en;
  2526.      case PM_WIZARD:
  2527.          return (2 * en);
  2528.      case PM_HEALER:
  2529. +    case PM_INFIDEL:
  2530.      case PM_KNIGHT:
  2531.          return ((3 * en) / 2);
  2532.      case PM_BARBARIAN:
  2533. diff --git a/src/explode.c b/src/explode.c
  2534. index 31ba7c7..3f933b1 100644
  2535. --- a/src/explode.c
  2536. +++ b/src/explode.c
  2537. @@ -185,7 +185,7 @@ int expltype;
  2538.                  case AD_DISN:
  2539.                      explmask[i][j] = (olet == WAND_CLASS)
  2540.                                           ? !!(nonliving(youmonst.data)
  2541. -                                              || is_demon(youmonst.data))
  2542. +                                              || is_demon(raceptr(&youmonst)))
  2543.                                           : !!Disint_resistance;
  2544.                      break;
  2545.                  case AD_ELEC:
  2546. diff --git a/src/hack.c b/src/hack.c
  2547. index 79fe740..da4bd69 100644
  2548. --- a/src/hack.c
  2549. +++ b/src/hack.c
  2550. @@ -2012,7 +2012,7 @@ invocation_message()
  2551.              Sprintf(buf, "under your %s", makeplural(body_part(FOOT)));
  2552.  
  2553.          You_feel("a strange vibration %s.", buf);
  2554. -        u.uevent.uvibrated = 1;
  2555. +        u.uachieve.vibrating_square = 1;
  2556.          if (otmp && otmp->spe == 7 && otmp->lamplit)
  2557.              pline("%s %s!", The(xname(otmp)),
  2558.                    Blind ? "throbs palpably" : "glows with a strange light");
  2559. @@ -2053,7 +2053,7 @@ switch_terrain()
  2560.          /* [minor bug: we don't know whether this is beginning flight or
  2561.             resuming it; that could be tracked so that this message could
  2562.             be adjusted to "resume flying", but isn't worth the effort...] */
  2563. -        if (Flying)
  2564. +        if (Flying && !was_flying)
  2565.              You("start flying.");
  2566.      }
  2567.      if ((!Levitation ^ was_levitating) || (!Flying ^ was_flying))
  2568. diff --git a/src/invent.c b/src/invent.c
  2569. index 7e7e3b2..d14dae2 100644
  2570. --- a/src/invent.c
  2571. +++ b/src/invent.c
  2572. @@ -813,7 +813,8 @@ struct obj *obj;
  2573.          if (u.uhave.amulet)
  2574.              impossible("already have amulet?");
  2575.          u.uhave.amulet = 1;
  2576. -        u.uachieve.amulet = 1;
  2577. +        if (!Role_if(PM_INFIDEL))
  2578. +            u.uachieve.amulet = 1;
  2579.      } else if (obj->otyp == CANDELABRUM_OF_INVOCATION) {
  2580.          if (u.uhave.menorah)
  2581.              impossible("already have candelabrum?");
  2582. @@ -834,6 +835,8 @@ struct obj *obj;
  2583.              if (u.uhave.questart)
  2584.                  impossible("already have quest artifact?");
  2585.              u.uhave.questart = 1;
  2586. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2587. +                u.uhave.amulet = 1;
  2588.              artitouch(obj);
  2589.          }
  2590.          set_artifact_intrinsic(obj, 1, W_ART);
  2591. @@ -1028,7 +1031,8 @@ const char *drop_fmt, *drop_arg, *hold_msg;
  2592.              drop_arg = strcpy(buf, drop_arg);
  2593.  
  2594.          obj = addinv(obj);
  2595. -        if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE || !obj->cursed)
  2596. +        if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE
  2597. +                                     || !cursed(obj, TRUE))
  2598.                                      && near_capacity() > prev_encumbr)) {
  2599.              /* undo any merge which took place */
  2600.              if (obj->quan > oquan)
  2601. @@ -1132,6 +1136,8 @@ struct obj *obj;
  2602.              if (!u.uhave.questart)
  2603.                  impossible("don't have quest artifact?");
  2604.              u.uhave.questart = 0;
  2605. +            if (Role_if(PM_INFIDEL) && obj->spe)
  2606. +                u.uhave.amulet = 0;
  2607.          }
  2608.          set_artifact_intrinsic(obj, 0, W_ART);
  2609.      }
  2610. @@ -1181,6 +1187,7 @@ register struct obj *obj;
  2611.      boolean update_map;
  2612.  
  2613.      if (obj->otyp == AMULET_OF_YENDOR
  2614. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
  2615.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  2616.          || obj->otyp == BELL_OF_OPENING
  2617.          || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  2618. @@ -1393,7 +1400,7 @@ boolean
  2619.  splittable(obj)
  2620.  struct obj *obj;
  2621.  {
  2622. -    return !((obj->otyp == LOADSTONE && obj->cursed)
  2623. +    return !((obj->otyp == LOADSTONE && cursed(obj, TRUE))
  2624.               || (obj == uwep && welded(uwep)));
  2625.  }
  2626.  
  2627. @@ -1601,10 +1608,11 @@ register const char *let, *word;
  2628.               || (!strncmp(word, "rub on the stone", 16)
  2629.                   && *let == GEM_CLASS && otmp->dknown
  2630.                   && objects[otyp].oc_name_known)
  2631. -             /* suppress corpses on astral, amulets elsewhere */
  2632. +             /* suppress corpses on astral (or sanctum), amulets elsewhere */
  2633.               || (!strcmp(word, "sacrifice")
  2634.                   /* (!astral && amulet) || (astral && !amulet) */
  2635. -                 && (!Is_astralevel(&u.uz) ^ (otmp->oclass != AMULET_CLASS)))
  2636. +                 && ((!Is_astralevel(&u.uz) && !Is_sanctum(&u.uz))
  2637. +                     ^ (otmp->oclass != AMULET_CLASS)))
  2638.               /* suppress container being stashed into */
  2639.               || (!strcmp(word, "stash") && !ck_bag(otmp))
  2640.               /* worn armor (shirt, suit) covered by worn armor (suit, cloak)
  2641. @@ -1820,7 +1828,7 @@ register const char *let, *word;
  2642.              /* don't split a stack of cursed loadstones */
  2643.              if (splittable(otmp))
  2644.                  otmp = splitobj(otmp, cnt);
  2645. -            else if (otmp->otyp == LOADSTONE && otmp->cursed)
  2646. +            else if (otmp->otyp == LOADSTONE && cursed(otmp, TRUE))
  2647.                  /* kludge for canletgo()'s can't-drop-this message */
  2648.                  otmp->corpsenm = (int) cnt;
  2649.          }
  2650. diff --git a/src/makemon.c b/src/makemon.c
  2651. index 3145ad6..cd6b0c1 100644
  2652. --- a/src/makemon.c
  2653. +++ b/src/makemon.c
  2654. @@ -185,7 +185,7 @@ register struct monst *mtmp;
  2655.              (void) mongets(mtmp, (mm != PM_ETTIN) ? BOULDER : CLUB);
  2656.          break;
  2657.      case S_HUMAN:
  2658. -        if (is_mercenary(ptr)) {
  2659. +        if (is_mercenary(ptr) || mm == PM_TEMPLAR) {
  2660.              w1 = w2 = 0;
  2661.              switch (mm) {
  2662.              case PM_WATCHMAN:
  2663. @@ -204,6 +204,7 @@ register struct monst *mtmp;
  2664.                  break;
  2665.              case PM_CAPTAIN:
  2666.              case PM_WATCH_CAPTAIN:
  2667. +            case PM_TEMPLAR:
  2668.                  w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
  2669.                  break;
  2670.              default:
  2671. @@ -266,11 +267,20 @@ register struct monst *mtmp;
  2672.          } else if (mm == PM_NINJA) { /* extra quest villains */
  2673.              (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
  2674.              (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
  2675. +        } else if (mm == PM_CHAMPION) {
  2676. +            (void) mongets(mtmp, rn2(2) ? TWO_HANDED_SWORD : BATTLE_AXE);
  2677. +            (void) mongets(mtmp, rn2(3) ? RING_MAIL : CHAIN_MAIL);
  2678. +        } else if (mm == PM_AGENT) {
  2679. +            (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : DAGGER);
  2680. +            if (!rn2(3))
  2681. +                (void) mongets(mtmp, LEATHER_ARMOR);
  2682. +            (void) mongets(mtmp, POT_INVISIBILITY);
  2683.          } else if (ptr->msound == MS_GUARDIAN) {
  2684.              /* quest "guardians" */
  2685.              switch (mm) {
  2686.              case PM_STUDENT:
  2687.              case PM_ATTENDANT:
  2688. +            case PM_CULTIST:
  2689.              case PM_ABBOT:
  2690.              case PM_ACOLYTE:
  2691.              case PM_GUIDE:
  2692. @@ -588,7 +598,7 @@ register struct monst *mtmp;
  2693.       */
  2694.      switch (ptr->mlet) {
  2695.      case S_HUMAN:
  2696. -        if (is_mercenary(ptr)) {
  2697. +        if (is_mercenary(ptr) || monsndx(ptr) == PM_TEMPLAR) {
  2698.              register int mac;
  2699.  
  2700.              switch (monsndx(ptr)) {
  2701. @@ -613,6 +623,9 @@ register struct monst *mtmp;
  2702.              case PM_WATCH_CAPTAIN:
  2703.                  mac = -2;
  2704.                  break;
  2705. +            case PM_TEMPLAR:
  2706. +                mac = -3;
  2707. +                break;
  2708.              default:
  2709.                  impossible("odd mercenary %d?", monsndx(ptr));
  2710.                  mac = 0;
  2711. @@ -655,6 +668,10 @@ register struct monst *mtmp;
  2712.              } else if (ptr == &mons[PM_WATCHMAN]) {
  2713.                  if (rn2(3)) /* most watchmen carry a whistle */
  2714.                      (void) mongets(mtmp, TIN_WHISTLE);
  2715. +            } else if (ptr == &mons[PM_TEMPLAR]) {
  2716. +                if (rn2(3)) /* being in a holy order has its benefits */
  2717. +                    (void) mongets(mtmp, rn2(4) ? POT_HEALING
  2718. +                                                : POT_EXTRA_HEALING);
  2719.              } else if (ptr == &mons[PM_GUARD]) {
  2720.                  /* if hero teleports out of a vault while being confronted
  2721.                     by the vault's guard, there is a shrill whistling sound,
  2722. @@ -695,6 +712,22 @@ register struct monst *mtmp;
  2723.              mkmonmoney(mtmp, (long) rn1(10, 20));
  2724.          } else if (quest_mon_represents_role(ptr, PM_MONK)) {
  2725.              (void) mongets(mtmp, rn2(11) ? ROBE : CLOAK_OF_MAGIC_RESISTANCE);
  2726. +        } else if (ptr == &mons[PM_PREACHER_OF_MOLOCH]) {
  2727. +            (void) mongets(mtmp, QUARTERSTAFF);
  2728. +            (void) mongets(mtmp, rn2(3) ? ROBE : CLOAK_OF_PROTECTION);
  2729. +        } else if (ptr == &mons[PM_PALADIN]) {
  2730. +            otmp = mksobj(MORNING_STAR, FALSE, FALSE);
  2731. +            otmp->blessed = otmp->oerodeproof = 1;
  2732. +            otmp->spe = rn1(3, 3);
  2733. +            (void) mpickobj(mtmp, otmp);
  2734. +            /* the Paladin wears no helmet
  2735. +             * because she looks cooler without a helmet */
  2736. +            (void) mongets(mtmp, LEATHER_GLOVES);
  2737. +            (void) mongets(mtmp, SHIELD_OF_REFLECTION);
  2738. +            (void) mongets(mtmp, LEATHER_CLOAK);
  2739. +            (void) mongets(mtmp, CRYSTAL_PLATE_MAIL);
  2740. +            (void) mongets(mtmp, HIGH_BOOTS);
  2741. +            (void) mongets(mtmp, POT_SPEED);
  2742.          }
  2743.          break;
  2744.      case S_NYMPH:
  2745. @@ -1269,7 +1302,7 @@ int mmflags;
  2746.              mtmp->mpeaceful = FALSE;
  2747.          break;
  2748.      case S_UNICORN:
  2749. -        if (is_unicorn(ptr) && sgn(u.ualign.type) == sgn(ptr->maligntyp))
  2750. +        if (is_unicorn(ptr) && u.ualign.type == sgn(ptr->maligntyp))
  2751.              mtmp->mpeaceful = TRUE;
  2752.          break;
  2753.      case S_BAT:
  2754. @@ -1365,6 +1398,13 @@ int mmflags;
  2755.                                ? !eminp->renegade
  2756.                                : eminp->renegade;
  2757.      }
  2758. +    /* these monsters are normally affiliated with a deity */
  2759. +    if ((mndx == PM_PALADIN || mndx == PM_TEMPLAR || mndx == PM_CHAMPION
  2760. +         || mndx == PM_AGENT) && !(mmflags & MM_EMIN)) {
  2761. +        newemin(mtmp);
  2762. +        mtmp->isminion = 1;
  2763. +        EMIN(mtmp)->min_align = sgn(ptr->maligntyp);
  2764. +    }
  2765.      set_malign(mtmp); /* having finished peaceful changes */
  2766.      if (anymon && !(mmflags & MM_NOGRP)) {
  2767.          if ((ptr->geno & G_SGROUP) && rn2(2)) {
  2768. @@ -2007,7 +2047,11 @@ register struct permonst *ptr;
  2769.  
  2770.      if (always_peaceful(ptr))
  2771.          return TRUE;
  2772. -    if (always_hostile(ptr))
  2773. +    /* Major demons will sometimes be peaceful to unaligned Infidels.
  2774. +     * They must pass this 50% check, then the 50% check for chaotics
  2775. +     * being non-hostile to unaligned, then the usual check for coaligned.
  2776. +     * For crowned Infidels, the last two checks are bypassed. */
  2777. +    if (always_hostile(ptr) && (ual != A_NONE || !is_demon(ptr) || rn2(2)))
  2778.          return FALSE;
  2779.      if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
  2780.          return TRUE;
  2781. @@ -2024,8 +2068,12 @@ register struct permonst *ptr;
  2782.      if (sgn(mal) != sgn(ual))
  2783.          return FALSE;
  2784.  
  2785. -    /* Negative monster hostile to player with Amulet. */
  2786. -    if (mal < A_NEUTRAL && u.uhave.amulet)
  2787. +    /* Not all chaotics support Moloch.  This goes especially for elves. */
  2788. +    if (ual == A_NONE && (is_elf(ptr) || rn2(2)))
  2789. +        return FALSE;
  2790. +
  2791. +    /* Chaotic monsters hostile to players with Amulet, except Infidels. */
  2792. +    if (mal < A_NEUTRAL && u.uhave.amulet && ual != A_NONE)
  2793.          return FALSE;
  2794.  
  2795.      /* minions are hostile to players that have strayed at all */
  2796. @@ -2070,7 +2118,7 @@ struct monst *mtmp;
  2797.              mal *= 5;
  2798.      }
  2799.  
  2800. -    coaligned = (sgn(mal) == sgn(u.ualign.type));
  2801. +    coaligned = (sgn(mal) == u.ualign.type);
  2802.      if (mtmp->data->msound == MS_LEADER) {
  2803.          mtmp->malign = -20;
  2804.      } else if (mal == A_NONE) {
  2805. @@ -2078,12 +2126,16 @@ struct monst *mtmp;
  2806.              mtmp->malign = 0;
  2807.          else
  2808.              mtmp->malign = 20; /* really hostile */
  2809. +        if (u.ualign.type == A_NONE)
  2810. +            mtmp->malign -= 20; /* reverse */
  2811.      } else if (always_peaceful(mtmp->data)) {
  2812.          int absmal = abs(mal);
  2813. -        if (mtmp->mpeaceful)
  2814. -            mtmp->malign = -3 * max(5, absmal);
  2815. -        else
  2816. +        if (!mtmp->mpeaceful)
  2817.              mtmp->malign = 3 * max(5, absmal); /* renegade */
  2818. +        else if (u.ualign.type == A_NONE)
  2819. +            mtmp->malign = 0; /* Moloch doesn't mind */
  2820. +        else
  2821. +            mtmp->malign = -3 * max(5, absmal);
  2822.      } else if (always_hostile(mtmp->data)) {
  2823.          int absmal = abs(mal);
  2824.          if (coaligned)
  2825. diff --git a/src/mcastu.c b/src/mcastu.c
  2826. index 1b2fb63..3c1402a 100644
  2827. --- a/src/mcastu.c
  2828. +++ b/src/mcastu.c
  2829. @@ -377,7 +377,7 @@ int spellnum;
  2830.      switch (spellnum) {
  2831.      case MGC_DEATH_TOUCH:
  2832.          pline("Oh no, %s's using the touch of death!", mhe(mtmp));
  2833. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  2834. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  2835.              You("seem no deader than before.");
  2836.          } else if (!Antimagic && rn2(mtmp->m_lev) > 12) {
  2837.              if (Hallucination) {
  2838. diff --git a/src/mhitu.c b/src/mhitu.c
  2839. index 849ddb1..cbb24de 100644
  2840. --- a/src/mhitu.c
  2841. +++ b/src/mhitu.c
  2842. @@ -589,7 +589,7 @@ register struct monst *mtmp;
  2843.      /*  Special demon handling code */
  2844.      if ((mtmp->cham == NON_PM) && is_demon(mdat) && !range2
  2845.          && mtmp->data != &mons[PM_BALROG] && mtmp->data != &mons[PM_SUCCUBUS]
  2846. -        && mtmp->data != &mons[PM_INCUBUS])
  2847. +        && mtmp->data != &mons[PM_INCUBUS] && mtmp->data != &mons[PM_DEMON])
  2848.          if (!mtmp->mcan && !rn2(13))
  2849.              (void) msummon(mtmp);
  2850.  
  2851. diff --git a/src/minion.c b/src/minion.c
  2852. index 4277b45..f2c780d 100644
  2853. --- a/src/minion.c
  2854. +++ b/src/minion.c
  2855. @@ -225,13 +225,21 @@ boolean talk;
  2856.  
  2857.  #define Athome (Inhell && (mtmp->cham == NON_PM))
  2858.  
  2859. -/* returns 1 if it won't attack. */
  2860. +/*
  2861. + * returns 1 if mtmp won't attack.
  2862. + * note: if already talked to mtmp, he won't speak on his own;
  2863. + * but, if chatted again, he still may demand a bribe.
  2864. + * this can occur if mtmp is magically pacified,
  2865. + * thus, in this case, initiative is punishable.
  2866. + */
  2867.  int
  2868.  demon_talk(mtmp)
  2869.  register struct monst *mtmp;
  2870.  {
  2871.      long cash, demand, offer;
  2872.  
  2873. +    mtmp->mstrategy &= ~STRAT_APPEARMSG; /* only talk once */
  2874. +
  2875.      if (uwep && uwep->oartifact == ART_EXCALIBUR) {
  2876.          pline("%s looks very angry.", Amonnam(mtmp));
  2877.          mtmp->mpeaceful = mtmp->mtame = 0;
  2878. @@ -257,18 +265,17 @@ register struct monst *mtmp;
  2879.          mtmp->minvis = mtmp->perminvis = 0;
  2880.          if (wasunseen && canspotmon(mtmp)) {
  2881.              pline("%s appears before you.", Amonnam(mtmp));
  2882. -            mtmp->mstrategy &= ~STRAT_APPEARMSG;
  2883.          }
  2884.          newsym(mtmp->mx, mtmp->my);
  2885.      }
  2886. -    if (youmonst.data->mlet == S_DEMON) { /* Won't blackmail their own. */
  2887. +    if (is_demon(raceptr(&youmonst))) { /* Won't blackmail their own. */
  2888.          if (!Deaf)
  2889.              pline("%s says, \"Good hunting, %s.\"", Amonnam(mtmp),
  2890.                    flags.female ? "Sister" : "Brother");
  2891.          else if (canseemon(mtmp))
  2892.              pline("%s says something.", Amonnam(mtmp));
  2893. -        if (!tele_restrict(mtmp))
  2894. -            (void) rloc(mtmp, TRUE);
  2895. +        display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
  2896. +        (void) rloc(mtmp, TRUE);
  2897.          return 1;
  2898.      }
  2899.      cash = money_cnt(invent);
  2900. diff --git a/src/mon.c b/src/mon.c
  2901. index 4f0a13d..72a7089 100644
  2902. --- a/src/mon.c
  2903. +++ b/src/mon.c
  2904. @@ -2463,7 +2463,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2905.      if (is_human(mdat)
  2906.          && (!always_hostile(mdat) && mtmp->malign <= 0)
  2907.          && (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD)
  2908. -        && u.ualign.type != A_CHAOTIC) {
  2909. +        && u.ualign.type > A_CHAOTIC) {
  2910.          HTelepat &= ~INTRINSIC;
  2911.          change_luck(-2);
  2912.          You("murderer!");
  2913. @@ -2472,7 +2472,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2914.      }
  2915.      if ((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame)
  2916.          change_luck(-1);
  2917. -    if (is_unicorn(mdat) && sgn(u.ualign.type) == sgn(mdat->maligntyp)) {
  2918. +    if (is_unicorn(mdat) && u.ualign.type == sgn(mdat->maligntyp)) {
  2919.          change_luck(-5);
  2920.          You_feel("guilty...");
  2921.      }
  2922. @@ -2500,7 +2500,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2923.          /* cancel divine protection for killing your priest */
  2924.          if (p_coaligned(mtmp))
  2925.              u.ublessed = 0;
  2926. -        if (mdat->maligntyp == A_NONE)
  2927. +        else if (mdat->maligntyp == A_NONE)
  2928.              adjalign((int) (ALIGNLIM / 4)); /* BIG bonus */
  2929.      } else if (mtmp->mtame) {
  2930.          adjalign(-15); /* bad!! */
  2931. @@ -2509,7 +2509,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
  2932.              You_hear("the rumble of distant thunder...");
  2933.          else
  2934.              You_hear("the studio audience applaud!");
  2935. -    } else if (mtmp->mpeaceful)
  2936. +    } else if (mtmp->mpeaceful && u.ualign.type != A_NONE)
  2937.          adjalign(-5);
  2938.  
  2939.      /* malign was already adjusted for u.ualign.type and randomization */
  2940. @@ -2743,7 +2743,9 @@ struct monst *mtmp;
  2941.      }
  2942.      rloc_to(mtmp, mm.x, mm.y);
  2943.      if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
  2944. -        mtmp->mstrategy &= ~STRAT_APPEARMSG; /* one chance only */
  2945. +        /* nb: we're reusing this STRAT for the bribe offer tracking */
  2946. +        if (!mtmp->mpeaceful || mtmp->data->msound != MS_BRIBE)
  2947. +            mtmp->mstrategy &= ~STRAT_APPEARMSG; /* one chance only */
  2948.          if (!couldspot && canspotmon(mtmp))
  2949.              pline("%s suddenly %s!", Amonnam(mtmp),
  2950.                    !Blind ? "appears" : "arrives");
  2951. @@ -2896,7 +2898,6 @@ boolean via_attack;
  2952.          /* only hypocritical if monster is vulnerable to Elbereth (or
  2953.             peaceful--not vulnerable but attacking it is hypocritical) */
  2954.          && (onscary(u.ux, u.uy, mtmp) || mtmp->mpeaceful)) {
  2955. -        You_feel("like a hypocrite.");
  2956.          /* AIS: Yes, I know alignment penalties and bonuses aren't balanced
  2957.             at the moment. This is about correct relative to other "small"
  2958.             penalties; it should be fairly large, as attacking while standing
  2959. @@ -2905,7 +2906,11 @@ boolean via_attack;
  2960.             it's intentionally larger than the 1s and 2s that are normally
  2961.             given for this sort of thing. */
  2962.          /* reduce to 3 (average) when alignment is already very low */
  2963. -        adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2964. +        if (u.ualign.type != A_NONE) {
  2965. +            You_feel("like a hypocrite.");
  2966. +            adjalign((u.ualign.record > 5) ? -5 : -rnd(5));
  2967. +        } else
  2968. +            You_feel("wily."); /* no alignment penalty */
  2969.  
  2970.          if (!Blind)
  2971.              pline("The engraving beneath you fades.");
  2972. @@ -2924,7 +2929,7 @@ boolean via_attack;
  2973.              adjalign(-5); /* very bad */
  2974.          else
  2975.              adjalign(2);
  2976. -    } else
  2977. +    } else if (u.ualign.type != A_NONE)
  2978.          adjalign(-1); /* attacking peaceful monsters is bad */
  2979.      if (couldsee(mtmp->mx, mtmp->my)) {
  2980.          if (humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd)
  2981. @@ -3002,7 +3007,8 @@ boolean via_attack;
  2982.                                 perhaps reduce tameness? */
  2983.                          } else {
  2984.                              mon->mpeaceful = 0;
  2985. -                            adjalign(-1);
  2986. +                            if (u.ualign.type != A_NONE)
  2987. +                                adjalign(-1);
  2988.                              if (!exclaimed)
  2989.                                  pline("%s gets angry!", Monnam(mon));
  2990.                          }
  2991. diff --git a/src/mondata.c b/src/mondata.c
  2992. index fae34e8..7d20930 100644
  2993. --- a/src/mondata.c
  2994. +++ b/src/mondata.c
  2995. @@ -97,7 +97,7 @@ boolean
  2996.  resists_drli(mon)
  2997.  struct monst *mon;
  2998.  {
  2999. -    struct permonst *ptr = mon->data;
  3000. +    struct permonst *ptr = raceptr(mon); /* handle demonic race */
  3001.      struct obj *wep;
  3002.  
  3003.      if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
  3004. @@ -421,8 +421,7 @@ register struct permonst *ptr;
  3005.      return (boolean) (bigmonst(ptr)
  3006.                        || (ptr->msize > MZ_SMALL && !humanoid(ptr))
  3007.                        /* special cases of humanoids that cannot wear suits */
  3008. -                      || ptr == &mons[PM_MARILITH]
  3009. -                      || ptr == &mons[PM_WINGED_GARGOYLE]);
  3010. +                      || ptr == &mons[PM_MARILITH]);
  3011.  }
  3012.  
  3013.  /* creature sticks other creatures it hits */
  3014. @@ -1077,7 +1076,7 @@ int montyp1, montyp2;
  3015.   * Returns correct pointer for non-polymorphed and polymorphed
  3016.   * player.  It does not return a pointer to player role character.
  3017.   */
  3018. -const struct permonst *
  3019. +struct permonst *
  3020.  raceptr(mtmp)
  3021.  struct monst *mtmp;
  3022.  {
  3023. diff --git a/src/monmove.c b/src/monmove.c
  3024. index cd6ca98..3160e00 100644
  3025. --- a/src/monmove.c
  3026. +++ b/src/monmove.c
  3027. @@ -344,6 +344,14 @@ int *inrange, *nearby, *scared;
  3028.                      || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
  3029.          *scared = 1;
  3030.          monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
  3031. +        if (u.ualign.type == A_NONE && !context.coward
  3032. +            && sengr_at("Elbereth", seescaryx, seescaryy, TRUE)) {
  3033. +            /* Followers of Moloch aren't supposed
  3034. +             * to hide behind other gods. */
  3035. +            You_feel("like a coward.");
  3036. +            context.coward = TRUE; /* once per move */
  3037. +            adjalign(-5);
  3038. +        }
  3039.      } else
  3040.          *scared = 0;
  3041.  }
  3042. @@ -468,24 +476,30 @@ register struct monst *mtmp;
  3043.      /* Demonic Blackmail! */
  3044.      if (nearby && mdat->msound == MS_BRIBE && mtmp->mpeaceful && !mtmp->mtame
  3045.          && !u.uswallow) {
  3046. -        if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
  3047. -            pline("%s whispers at thin air.",
  3048. -                  cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
  3049. -
  3050. -            if (is_demon(youmonst.data)) {
  3051. -                /* "Good hunting, brother" */
  3052. -                if (!tele_restrict(mtmp))
  3053. +        if (mtmp->mstrategy & STRAT_APPEARMSG) {
  3054. +            if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
  3055. +                pline("%s whispers at thin air.",
  3056. +                      cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
  3057. +                mtmp->mstrategy &= ~STRAT_APPEARMSG;
  3058. +
  3059. +                if (is_demon(raceptr(&youmonst))) {
  3060. +                    /* "Good hunting, brother" */
  3061. +                    display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
  3062.                      (void) rloc(mtmp, TRUE);
  3063. -            } else {
  3064. -                mtmp->minvis = mtmp->perminvis = 0;
  3065. -                /* Why?  For the same reason in real demon talk */
  3066. -                pline("%s gets angry!", Amonnam(mtmp));
  3067. -                mtmp->mpeaceful = 0;
  3068. -                set_malign(mtmp);
  3069. -                /* since no way is an image going to pay it off */
  3070. -            }
  3071. -        } else if (demon_talk(mtmp))
  3072. -            return 1; /* you paid it off */
  3073. +                } else {
  3074. +                    mtmp->minvis = mtmp->perminvis = 0;
  3075. +                    /* Why?  For the same reason in real demon talk */
  3076. +                    pline("%s gets angry!", Amonnam(mtmp));
  3077. +                    mtmp->mpeaceful = 0;
  3078. +                    set_malign(mtmp);
  3079. +                    /* since no way is an image going to pay it off */
  3080. +                }
  3081. +            } else if (demon_talk(mtmp))
  3082. +                return 1; /* you paid it off */
  3083. +        } else { /* either let the player pass, or pacified somehow */
  3084. +            (void) rloc(mtmp, TRUE); /* either way no bribe demands */
  3085. +            return 0;
  3086. +        }
  3087.      }
  3088.  
  3089.      /* the watch will look around and see if you are up to no good :-) */
  3090. @@ -927,6 +941,9 @@ register int after;
  3091.                      > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
  3092.              appr = -1;
  3093.  
  3094. +        if (monsndx(ptr) == PM_AGENT && mon_has_amulet(mtmp))
  3095. +            appr = -1; /* objective secured, retreat */
  3096. +
  3097.          if (!should_see && can_track(ptr)) {
  3098.              register coord *cp;
  3099.  
  3100. diff --git a/src/monst.c b/src/monst.c
  3101. index 6b8a5f7..de919f5 100644
  3102. --- a/src/monst.c
  3103. +++ b/src/monst.c
  3104. @@ -2139,6 +2139,27 @@ struct permonst _mons2[] = {
  3105.          M1_HUMANOID | M1_POIS | M1_REGEN | M1_OMNIVORE,
  3106.          M2_NOPOLY | M2_WERE | M2_HOSTILE | M2_HUMAN | M2_COLLECT,
  3107.          M3_INFRAVISIBLE, 6, CLR_ORANGE),
  3108. +    /* Only generated when playing as Infidel.
  3109. +     * Has emin, so always appears as a "champion of [deity]".
  3110. +     * Note: the difficulty is purposefully lowered. */
  3111. +    MON("champion", S_HUMAN, LVL(12, 12, 6, 10, 0), (G_NOGEN | G_NOHELL | 2),
  3112. +        A(ATTK(AT_WEAP, AD_PHYS, 2, 6), ATTK(AT_WEAP, AD_PHYS, 2, 6), NO_ATTK,
  3113. +          NO_ATTK, NO_ATTK, NO_ATTK),
  3114. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_POISON, 0,
  3115. +        M1_HUMANOID | M1_OMNIVORE,
  3116. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_NASTY | M2_STRONG | M2_COLLECT,
  3117. +        M3_INFRAVISIBLE, 6, CLR_GRAY),
  3118. +    /* Only generated when playing as Infidel.
  3119. +     * Has emin, so always appears as an "agent of [deity]".
  3120. +     * Note: the difficulty is purposefully lowered. */
  3121. +    MON("agent", S_HUMAN, LVL(6, 18, 10, 10, -7), (G_NOGEN | G_NOHELL | 3),
  3122. +        A(ATTK(AT_WEAP, AD_SAMU, 1, 4), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  3123. +          ATTK(AT_CLAW, AD_SAMU, 1, 1), ATTK(AT_CLAW, AD_SAMU, 1, 1),
  3124. +          NO_ATTK, NO_ATTK),
  3125. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  3126. +        M1_HUMANOID | M1_OMNIVORE | M1_TPORT,
  3127. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STALK | M2_STRONG | M2_COLLECT,
  3128. +        M3_INFRAVISIBLE, 6, CLR_BLACK),
  3129.      MON("elf", S_HUMAN, LVL(10, 12, 10, 2, -3), G_NOGEN, /* for corpses */
  3130.          A(ATTK(AT_WEAP, AD_PHYS, 1, 8), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  3131.            NO_ATTK),
  3132. @@ -2607,6 +2628,14 @@ struct permonst _mons2[] = {
  3133.          SIZ(1500, 400, MS_DJINNI, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  3134.          M1_HUMANOID | M1_FLY | M1_POIS, M2_NOPOLY | M2_STALK | M2_COLLECT,
  3135.          M3_INFRAVISIBLE, 8, CLR_YELLOW),
  3136. +    /* racial monster for crowned Infidels */
  3137. +    MON("demon", S_DEMON, LVL(10, 12, 10, 10, A_NONE), (G_NOGEN | G_NOCORPSE),
  3138. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_STNG, AD_DRST, 2, 4),
  3139. +          NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
  3140. +        SIZ(WT_HUMAN, 400, MS_GRUNT, MZ_HUMAN), MR_FIRE | MR_POISON, 0,
  3141. +        M1_HUMANOID | M1_FLY | M1_SEE_INVIS | M1_POIS,
  3142. +        M2_NOPOLY | M2_DEMON | M2_STALK | M2_HOSTILE | M2_COLLECT,
  3143. +        M3_INFRAVISIBLE | M3_INFRAVISION, 13, CLR_RED),
  3144.      /*
  3145.       * sea monsters
  3146.       */
  3147. @@ -2757,6 +2786,13 @@ struct permonst _mons2[] = {
  3148.          M1_HUMANOID | M1_OMNIVORE,
  3149.          M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  3150.          12, HI_DOMESTIC),
  3151. +    MON("infidel", S_HUMAN, LVL(10, 12, 10, 2, A_NONE), G_NOGEN,
  3152. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  3153. +          NO_ATTK),
  3154. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), MR_FIRE, 0,
  3155. +        M1_HUMANOID | M1_OMNIVORE,
  3156. +        M2_NOPOLY | M2_HUMAN | M2_STRONG | M2_COLLECT, M3_INFRAVISIBLE,
  3157. +        12, HI_DOMESTIC),
  3158.      MON("knight", S_HUMAN, LVL(10, 12, 10, 1, 3), G_NOGEN,
  3159.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  3160.            NO_ATTK, NO_ATTK, NO_ATTK),
  3161. @@ -2884,6 +2920,17 @@ struct permonst _mons2[] = {
  3162.          M2_NOPOLY | M2_HUMAN | M2_PNAME | M2_PEACEFUL | M2_STRONG | M2_MALE
  3163.              | M2_COLLECT | M2_MAGIC,
  3164.          M3_CLOSE | M3_INFRAVISIBLE, 22, HI_LORD),
  3165. +    /* apparently she should be a "preacheress" if female,
  3166. +     * but that word just sounds silly, imo */
  3167. +    MON("preacher of Moloch", S_HUMAN, LVL(20, 12, 0, 40, A_NONE),
  3168. +        (G_NOGEN | G_UNIQ),
  3169. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_MAGC, AD_CLRC, 0, 0), NO_ATTK,
  3170. +          NO_ATTK, NO_ATTK, NO_ATTK),
  3171. +        SIZ(WT_HUMAN, 400, MS_LEADER, MZ_HUMAN), MR_FIRE | MR_ELEC, 0,
  3172. +        M1_HUMANOID | M1_OMNIVORE,
  3173. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT
  3174. +            | M2_MAGIC,
  3175. +        M3_CLOSE | M3_INFRAVISIBLE, 23, CLR_RED),
  3176.      MON("King Arthur", S_HUMAN, LVL(20, 12, 0, 40, 20), (G_NOGEN | G_UNIQ),
  3177.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  3178.            NO_ATTK, NO_ATTK, NO_ATTK),
  3179. @@ -3026,6 +3073,18 @@ struct permonst _mons2[] = {
  3180.              | M2_HOSTILE | M2_NASTY | M2_MALE | M2_JEWELS | M2_COLLECT,
  3181.          M3_WANTSARTI | M3_WAITFORU | M3_INFRAVISION | M3_INFRAVISIBLE,
  3182.          23, CLR_GRAY),
  3183. +    /* Has emin, so always appears as the "Paladin of [deity]". */
  3184. +    MON("Paladin", S_HUMAN, LVL(24, 12, 0, 50, 20),
  3185. +        (G_NOGEN | G_UNIQ | G_NOCORPSE),
  3186. +        A(ATTK(AT_WEAP, AD_PHYS, 4, 4), ATTK(AT_WEAP, AD_STUN, 2, 6),
  3187. +          ATTK(AT_MAGC, AD_CLRC, 1, 8), ATTK(AT_CLAW, AD_SAMU, 1, 6),
  3188. +          NO_ATTK, NO_ATTK),
  3189. +        SIZ(WT_HUMAN, 400, MS_NEMESIS, MZ_HUMAN), MR_POISON | MR_STONE, 0,
  3190. +        M1_HUMANOID | M1_OMNIVORE | M1_SEE_INVIS,
  3191. +        M2_NOPOLY | M2_HUMAN | M2_MINION | M2_LORD | M2_STRONG | M2_FEMALE
  3192. +            | M2_STALK | M2_HOSTILE | M2_NASTY | M2_COLLECT | M2_MAGIC,
  3193. +        M3_WANTSARTI | M3_WANTSAMUL | M3_WAITFORU | M3_INFRAVISIBLE,
  3194. +        29, HI_GOLD),
  3195.      MON("Ixoth", S_DRAGON, LVL(15, 12, -1, 20, -14), (G_NOGEN | G_UNIQ),
  3196.          A(ATTK(AT_BREA, AD_FIRE, 8, 6), ATTK(AT_BITE, AD_PHYS, 4, 8),
  3197.            ATTK(AT_MAGC, AD_SPEL, 0, 0), ATTK(AT_CLAW, AD_PHYS, 2, 4),
  3198. @@ -3148,6 +3207,21 @@ struct permonst _mons2[] = {
  3199.          M1_HUMANOID | M1_OMNIVORE,
  3200.          M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  3201.          M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  3202. +    /* Has emin, so always appears as a "templar of [deity]". */
  3203. +    MON("templar", S_HUMAN, LVL(12, 10, 10, 20, 10), G_NOGEN,
  3204. +        A(ATTK(AT_WEAP, AD_PHYS, 3, 4), ATTK(AT_WEAP, AD_PHYS, 3, 4), NO_ATTK,
  3205. +          NO_ATTK, NO_ATTK, NO_ATTK),
  3206. +        SIZ(WT_HUMAN, 400, MS_HUMANOID, MZ_HUMAN), 0, 0,
  3207. +        M1_HUMANOID | M1_OMNIVORE,
  3208. +        M2_NOPOLY | M2_HUMAN | M2_HOSTILE | M2_STRONG | M2_COLLECT,
  3209. +        M3_INFRAVISIBLE, 14, CLR_BLUE),
  3210. +    MON("cultist", S_HUMAN, LVL(5, 12, 10, 10, A_NONE), G_NOGEN,
  3211. +        A(ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK,
  3212. +          NO_ATTK),
  3213. +        SIZ(WT_HUMAN, 400, MS_GUARDIAN, MZ_HUMAN), MR_FIRE, 0,
  3214. +        M1_HUMANOID | M1_OMNIVORE,
  3215. +        M2_NOPOLY | M2_HUMAN | M2_PEACEFUL | M2_STRONG | M2_COLLECT,
  3216. +        M3_INFRAVISIBLE, 7, HI_DOMESTIC),
  3217.      MON("page", S_HUMAN, LVL(5, 12, 10, 10, 3), G_NOGEN,
  3218.          A(ATTK(AT_WEAP, AD_PHYS, 1, 6), ATTK(AT_WEAP, AD_PHYS, 1, 6), NO_ATTK,
  3219.            NO_ATTK, NO_ATTK, NO_ATTK),
  3220. diff --git a/src/mplayer.c b/src/mplayer.c
  3221. index 2dba08e..b65f708 100644
  3222. --- a/src/mplayer.c
  3223. +++ b/src/mplayer.c
  3224. @@ -195,6 +195,16 @@ register boolean special;
  3225.              if (rn2(2))
  3226.                  shield = STRANGE_OBJECT;
  3227.              break;
  3228. +        case PM_INFIDEL:
  3229. +            if (!rn2(4))
  3230. +                weapon = CRYSKNIFE;
  3231. +            if (rn2(3))
  3232. +                cloak = CLOAK_OF_PROTECTION;
  3233. +            if (rn2(4))
  3234. +                helm = rn2(2) ? HELM_OF_BRILLIANCE : HELM_OF_TELEPATHY;
  3235. +            if (rn2(2))
  3236. +                shield = STRANGE_OBJECT;
  3237. +            break;
  3238.          case PM_KNIGHT:
  3239.              if (rn2(4))
  3240.                  weapon = LONG_SWORD;
  3241. diff --git a/src/muse.c b/src/muse.c
  3242. index 2dfb92f..6062690 100644
  3243. --- a/src/muse.c
  3244. +++ b/src/muse.c
  3245. @@ -2091,6 +2091,9 @@ struct obj *obj;
  3246.              return (boolean) !(nonliving(mon->data) || is_vampshifter(mon));
  3247.          if (typ == AMULET_OF_REFLECTION)
  3248.              return TRUE;
  3249. +        if (typ == AMULET_OF_YENDOR || typ == FAKE_AMULET_OF_YENDOR)
  3250. +            return (boolean) (mon->data == &mons[PM_AGENT]
  3251. +                              && !mon_has_amulet(mon));
  3252.          break;
  3253.      case TOOL_CLASS:
  3254.          if (typ == PICK_AXE)
  3255. diff --git a/src/pickup.c b/src/pickup.c
  3256. index 76f35aa..2bd0f65 100644
  3257. --- a/src/pickup.c
  3258. +++ b/src/pickup.c
  3259. @@ -2145,11 +2145,12 @@ register struct obj *obj;
  3260.          Norep("You cannot %s %s you are wearing.",
  3261.                Icebox ? "refrigerate" : "stash", something);
  3262.          return 0;
  3263. -    } else if ((obj->otyp == LOADSTONE) && obj->cursed) {
  3264. +    } else if ((obj->otyp == LOADSTONE) && cursed(obj, TRUE)) {
  3265.          set_bknown(obj, 1);
  3266.          pline_The("stone%s won't leave your person.", plur(obj->quan));
  3267.          return 0;
  3268.      } else if (obj->otyp == AMULET_OF_YENDOR
  3269. +               || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
  3270.                 || obj->otyp == CANDELABRUM_OF_INVOCATION
  3271.                 || obj->otyp == BELL_OF_OPENING
  3272.                 || obj->otyp == SPE_BOOK_OF_THE_DEAD) {
  3273. diff --git a/src/polyself.c b/src/polyself.c
  3274. index b053091..48e5898 100644
  3275. --- a/src/polyself.c
  3276. +++ b/src/polyself.c
  3277. @@ -42,8 +42,10 @@ void
  3278.  set_uasmon()
  3279.  {
  3280.      struct permonst *mdat = &mons[u.umonnum];
  3281. +    struct permonst *racedat; /* for infravision, flying */
  3282.  
  3283.      set_mon_data(&youmonst, mdat);
  3284. +    racedat = raceptr(&youmonst);
  3285.  
  3286.  #define PROPSET(PropIndx, ON)                          \
  3287.      do {                                               \
  3288. @@ -81,7 +83,7 @@ set_uasmon()
  3289.      PROPSET(SEE_INVIS, perceives(mdat));
  3290.      PROPSET(TELEPAT, telepathic(mdat));
  3291.      /* note that Infravision uses mons[race] rather than usual mons[role] */
  3292. -    PROPSET(INFRAVISION, infravision(Upolyd ? mdat : &mons[urace.malenum]));
  3293. +    PROPSET(INFRAVISION, infravision(racedat));
  3294.      PROPSET(INVIS, pm_invisible(mdat));
  3295.      PROPSET(TELEPORT, can_teleport(mdat));
  3296.      PROPSET(TELEPORT_CONTROL, control_teleport(mdat));
  3297. @@ -89,7 +91,10 @@ set_uasmon()
  3298.      /* floating eye is the only 'floater'; it is also flagged as a 'flyer';
  3299.         suppress flying for it so that enlightenment doesn't confusingly
  3300.         show latent flight capability always blocked by levitation */
  3301. -    PROPSET(FLYING, (is_flyer(mdat) && !is_floater(mdat)));
  3302. +    /* this property also checks race instead of role */
  3303. +    PROPSET(FLYING, (is_flyer(racedat) && !is_floater(racedat)));
  3304. +    if (!restoring) /* if loading, defer wings check until we have a steed */
  3305. +        check_wings(TRUE);
  3306.      PROPSET(SWIMMING, is_swimmer(mdat));
  3307.      /* [don't touch MAGICAL_BREATHING here; both Amphibious and Breathless
  3308.         key off of it but include different monster forms...] */
  3309. diff --git a/src/potion.c b/src/potion.c
  3310. index c6dffc5..1ce301e 100644
  3311. --- a/src/potion.c
  3312. +++ b/src/potion.c
  3313. @@ -648,8 +648,9 @@ register struct obj *otmp;
  3314.              break;
  3315.          }
  3316.          unkn++;
  3317. -        if (is_undead(youmonst.data) || is_demon(youmonst.data)
  3318. -            || u.ualign.type == A_CHAOTIC) {
  3319. +        if (is_undead(youmonst.data) || is_demon(raceptr(&youmonst))
  3320. +            || u.ualign.type <= A_CHAOTIC) {
  3321. +            int dice = (u.ualign.type == A_NONE) ? 4 : 2;
  3322.              if (otmp->blessed) {
  3323.                  pline("This burns like %s!", hliquid("acid"));
  3324.                  exercise(A_CON, FALSE);
  3325. @@ -660,11 +661,11 @@ register struct obj *otmp;
  3326.                          you_unwere(FALSE);
  3327.                      set_ulycn(NON_PM); /* cure lycanthropy */
  3328.                  }
  3329. -                losehp(Maybe_Half_Phys(d(2, 6)), "potion of holy water",
  3330. +                losehp(Maybe_Half_Phys(d(dice, 6)), "potion of holy water",
  3331.                         KILLED_BY_AN);
  3332.              } else if (otmp->cursed) {
  3333.                  You_feel("quite proud of yourself.");
  3334. -                healup(d(2, 6), 0, 0, 0);
  3335. +                healup(d(dice, 6), 0, 0, 0);
  3336.                  if (u.ulycn >= LOW_PM && !Upolyd)
  3337.                      you_were();
  3338.                  exercise(A_CON, TRUE);
  3339. @@ -961,7 +962,7 @@ register struct obj *otmp;
  3340.          if (otmp->cursed) {
  3341.              unkn++;
  3342.              /* they went up a level */
  3343. -            if ((ledger_no(&u.uz) == 1 && u.uhave.amulet)
  3344. +            if ((ledger_no(&u.uz) == 1 && u.uhave.amulet && u.uachieve.amulet)
  3345.                  || Can_rise_up(u.ux, u.uy, &u.uz)) {
  3346.                  const char *riseup = "rise up, through the %s!";
  3347.  
  3348. diff --git a/src/pray.c b/src/pray.c
  3349. index 79369fc..7fcfd8d 100644
  3350. --- a/src/pray.c
  3351. +++ b/src/pray.c
  3352. @@ -3,6 +3,7 @@
  3353.  /* NetHack may be freely redistributed.  See license for details. */
  3354.  
  3355.  #include "hack.h"
  3356. +#include "qtext.h"
  3357.  
  3358.  STATIC_PTR int NDECL(prayer_done);
  3359.  STATIC_DCL struct obj *NDECL(worst_cursed_item);
  3360. @@ -12,8 +13,6 @@ STATIC_DCL void FDECL(angrygods, (ALIGNTYP_P));
  3361.  STATIC_DCL void FDECL(at_your_feet, (const char *));
  3362.  STATIC_DCL void NDECL(gcrownu);
  3363.  STATIC_DCL void FDECL(pleased, (ALIGNTYP_P));
  3364. -STATIC_DCL void FDECL(godvoice, (ALIGNTYP_P, const char *));
  3365. -STATIC_DCL void FDECL(god_zaps_you, (ALIGNTYP_P));
  3366.  STATIC_DCL void FDECL(fry_by_god, (ALIGNTYP_P, BOOLEAN_P));
  3367.  STATIC_DCL void FDECL(gods_angry, (ALIGNTYP_P));
  3368.  STATIC_DCL void FDECL(gods_upset, (ALIGNTYP_P));
  3369. @@ -22,7 +21,8 @@ STATIC_DCL boolean FDECL(water_prayer, (BOOLEAN_P));
  3370.  STATIC_DCL boolean FDECL(blocked_boulder, (int, int));
  3371.  
  3372.  /* simplify a few tests */
  3373. -#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) && (obj)->cursed)
  3374. +#define Cursed_obj(obj, typ) ((obj) && (obj)->otyp == (typ) \
  3375. +                              && cursed(obj, TRUE))
  3376.  
  3377.  /*
  3378.   * Logic behind deities and altars and such:
  3379. @@ -50,7 +50,7 @@ static const char *godvoices[] = {
  3380.  /* values calculated when prayer starts, and used when completed */
  3381.  static aligntyp p_aligntyp;
  3382.  static int p_trouble;
  3383. -static int p_type; /* (-1)-3: (-1)=really naughty, 3=really good */
  3384. +static int p_type; /* (-2)-3: (-1)=really naughty, 3=really good */
  3385.  
  3386.  #define PIOUS 20
  3387.  #define DEVOUT 14
  3388. @@ -221,10 +221,11 @@ in_trouble()
  3389.          if (welded(uwep))
  3390.              return TROUBLE_UNUSEABLE_HANDS;
  3391.          if (Upolyd && nohands(youmonst.data)
  3392. -            && (!Unchanging || ((otmp = unchanger()) != 0 && otmp->cursed)))
  3393. +            && (!Unchanging || ((otmp = unchanger()) != 0
  3394. +                                && cursed(otmp, TRUE))))
  3395.              return TROUBLE_UNUSEABLE_HANDS;
  3396.      }
  3397. -    if (Blindfolded && ublindf->cursed)
  3398. +    if (Blindfolded && cursed(ublindf, TRUE))
  3399.          return TROUBLE_CURSED_BLINDFOLD;
  3400.  
  3401.      /*
  3402. @@ -274,6 +275,14 @@ worst_cursed_item()
  3403.  {
  3404.      register struct obj *otmp;
  3405.  
  3406. +    /* Infidels are immune to curses, but a cursed luckstone is still bad */
  3407. +    if (Role_if(PM_INFIDEL)) {
  3408. +        for (otmp = invent; otmp; otmp = otmp->nobj)
  3409. +            if (confers_luck(otmp) && otmp->cursed)
  3410. +                return otmp;
  3411. +        return (struct obj *) 0;
  3412. +    }
  3413. +
  3414.      /* if strained or worse, check for loadstone first */
  3415.      if (near_capacity() >= HVY_ENCUMBER) {
  3416.          for (otmp = invent; otmp; otmp = otmp->nobj)
  3417. @@ -452,7 +461,7 @@ int trouble;
  3418.              if (!Unchanging) {
  3419.                  Your("shape becomes uncertain.");
  3420.                  rehumanize(); /* "You return to {normal} form." */
  3421. -            } else if ((otmp = unchanger()) != 0 && otmp->cursed) {
  3422. +            } else if ((otmp = unchanger()) != 0 && cursed(otmp, TRUE)) {
  3423.                  /* otmp is an amulet of unchanging */
  3424.                  goto decurse;
  3425.              }
  3426. @@ -497,7 +506,7 @@ int trouble;
  3427.          if (otmp == uarmg && Glib) {
  3428.              make_glib(0);
  3429.              Your("%s are no longer slippery.", gloves_simple_name(uarmg));
  3430. -            if (!otmp->cursed)
  3431. +            if (!cursed(otmp, TRUE))
  3432.                  break;
  3433.          }
  3434.          if (!Blind || (otmp == ublindf && Blindfolded_only)) {
  3435. @@ -578,7 +587,7 @@ int trouble;
  3436.   * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
  3437.   * Divine wrath, dungeon walls, and armor follow the same principle.
  3438.   */
  3439. -STATIC_OVL void
  3440. +void
  3441.  god_zaps_you(resp_god)
  3442.  aligntyp resp_god;
  3443.  {
  3444. @@ -767,14 +776,18 @@ gcrownu()
  3445.      boolean already_exists, in_hand;
  3446.      short class_gift;
  3447.      int sp_no;
  3448. +    xchar maxint, maxwis;
  3449.  #define ok_wep(o) ((o) && ((o)->oclass == WEAPON_CLASS || is_weptool(o)))
  3450.  
  3451.      HSee_invisible |= FROMOUTSIDE;
  3452.      HFire_resistance |= FROMOUTSIDE;
  3453. -    HCold_resistance |= FROMOUTSIDE;
  3454. -    HShock_resistance |= FROMOUTSIDE;
  3455. -    HSleep_resistance |= FROMOUTSIDE;
  3456.      HPoison_resistance |= FROMOUTSIDE;
  3457. +    if (u.ualign.type != A_NONE) {
  3458. +        /* demons don't get all the intrinsics */
  3459. +        HCold_resistance |= FROMOUTSIDE;
  3460. +        HShock_resistance |= FROMOUTSIDE;
  3461. +        HSleep_resistance |= FROMOUTSIDE;
  3462. +    }
  3463.      godvoice(u.ualign.type, (char *) 0);
  3464.  
  3465.      class_gift = STRANGE_OBJECT;
  3466. @@ -815,6 +828,23 @@ gcrownu()
  3467.                     || class_gift != STRANGE_OBJECT) ? "take lives"
  3468.                    : "steal souls");
  3469.          break;
  3470. +    case A_NONE:
  3471. +        u.uevent.uhand_of_elbereth = 4;
  3472. +        verbalize("I shall reshape thee in Mine image, "
  3473. +                  "so that thou mayest bathe the world in My fire!");
  3474. +        class_gift = SPE_FIREBALL; /* no special weapon */
  3475. +        if (Upolyd)
  3476. +            rehumanize(); /* return to human/orcish form -- not a demon yet */
  3477. +        pline1("Wings sprout from your back and you grow a barbed tail!");
  3478. +        maxint = urace.attrmax[A_INT];
  3479. +        maxwis = urace.attrmax[A_WIS];
  3480. +        urace = race_demon;
  3481. +        /* mental faculties are not changed by demonization */
  3482. +        urace.attrmax[A_INT] = maxint;
  3483. +        urace.attrmax[A_WIS] = maxwis;
  3484. +        set_uasmon();
  3485. +        retouch_equipment(2); /* silver */
  3486. +        break;
  3487.      }
  3488.  
  3489.      if (objects[class_gift].oc_class == SPBOOK_CLASS) {
  3490. @@ -892,6 +922,9 @@ gcrownu()
  3491.              discover_artifact(ART_STORMBRINGER);
  3492.          break;
  3493.      }
  3494. +    case A_NONE:
  3495. +        /* nothing to do */
  3496. +        break;
  3497.      default:
  3498.          obj = 0; /* lint */
  3499.          break;
  3500. @@ -1016,7 +1049,43 @@ aligntyp g_align;
  3501.          case 0:
  3502.              break;
  3503.          case 1:
  3504. -            if (uwep && (welded(uwep) || uwep->oclass == WEAPON_CLASS
  3505. +            if (g_align == A_NONE) {
  3506. +                /* Moloch doesn't deal with blessings, but a cursed weapon is
  3507. +                 * pointless even to Inf; curse (and repair) armor instead */
  3508. +                static struct obj **const armor[] = { &uarm, &uarmc, &uarmh,
  3509. +                                                      &uarms, &uarmg, &uarmf,
  3510. +                                                      &uarmu };
  3511. +                int idx, worn;
  3512. +                struct obj *chosen;
  3513. +                boolean eroded;
  3514. +                /* I don't want to use some_armor() because
  3515. +                 * it doesn't pick covered shirts or suits */
  3516. +                for (idx = 0, worn = 0; idx < SIZE(armor); idx++)
  3517. +                    if (*armor[idx] && !rn2(++worn))
  3518. +                        chosen = *armor[idx];
  3519. +                if (!worn)
  3520. +                    break;
  3521. +                eroded = chosen->oeroded || chosen->oeroded2;
  3522. +                if (!chosen->cursed) {
  3523. +                    if (Blind)
  3524. +                        You_feel("the power of %s over %s.", u_gname(),
  3525. +                                 yname(chosen));
  3526. +                    else
  3527. +                        pline(eroded ? "%s %s and %s now as good as new."
  3528. +                                     : "%s %s.",
  3529. +                              Yobjnam2(chosen, "glow"),
  3530. +                              hcolor(chosen->blessed ? "brown" : NH_BLACK),
  3531. +                              otense(chosen, "are"));
  3532. +                    if (chosen->blessed)
  3533. +                        unbless(chosen);
  3534. +                    else
  3535. +                        curse(chosen);
  3536. +                } else if (eroded)
  3537. +                    pline("%s as good as new!",
  3538. +                          Yobjnam2(chosen, Blind ? "feel" : "look"));
  3539. +                if (eroded)
  3540. +                    chosen->oeroded = chosen->oeroded2 = 0;
  3541. +            } else if (uwep && (welded(uwep) || uwep->oclass == WEAPON_CLASS
  3542.                           || is_weptool(uwep))) {
  3543.                  char repair_buf[BUFSZ];
  3544.  
  3545. @@ -1079,7 +1148,8 @@ aligntyp g_align;
  3546.                      u.uevent.uheard_tune++;
  3547.                      break;
  3548.                  } else if (u.uevent.uheard_tune < 2) {
  3549. -                    You_hear("a divine music...");
  3550. +                    You_hear("%s music...", g_align == A_NONE ? "an infernal"
  3551. +                                                              : "a divine");
  3552.                      pline("It sounds like:  \"%s\".", tune);
  3553.                      u.uevent.uheard_tune++;
  3554.                      break;
  3555. @@ -1088,7 +1158,9 @@ aligntyp g_align;
  3556.              /*FALLTHRU*/
  3557.          case 2:
  3558.              if (!Blind)
  3559. -                You("are surrounded by %s glow.", an(hcolor(NH_GOLDEN)));
  3560. +                You("are surrounded by %s glow.", an(hcolor(g_align == A_NONE
  3561. +                                                            ? "crimson"
  3562. +                                                            : NH_GOLDEN)));
  3563.              /* if any levels have been lost (and not yet regained),
  3564.                 treat this effect like blessed full healing */
  3565.              if (u.ulevel < u.ulevelmax) {
  3566. @@ -1128,19 +1200,32 @@ aligntyp g_align;
  3567.              if (Blind)
  3568.                  You_feel("the power of %s.", u_gname());
  3569.              else
  3570. -                You("are surrounded by %s aura.", an(hcolor(NH_LIGHT_BLUE)));
  3571. +                You("are surrounded by %s aura.", an(hcolor(g_align != A_NONE
  3572. +                                                            ? NH_LIGHT_BLUE
  3573. +                                                            : "dark gray")));
  3574. +            /* Gods recognise that Inf benefit from wearing cursed armor;
  3575. +             * Moloch goes further and actively unblesses all armor */
  3576.              for (otmp = invent; otmp; otmp = otmp->nobj) {
  3577. -                if (otmp->cursed
  3578. +                boolean moloch = g_align == A_NONE
  3579. +                                 && otmp->oclass == ARMOR_CLASS;
  3580. +                if (moloch && otmp->blessed || !moloch && otmp->cursed
  3581. +                    && !(Role_if(PM_INFIDEL) && (otmp->owornmask & W_ARMOR))
  3582. +                    /* avoid Moloch undoing his own work */
  3583. +                    && !(g_align == A_NONE && otmp->otyp == POT_WATER)
  3584.                      && (otmp != uarmh /* [see worst_cursed_item()] */
  3585.                          || uarmh->otyp != HELM_OF_OPPOSITE_ALIGNMENT)) {
  3586.                      if (!Blind) {
  3587. -                        pline("%s %s.", Yobjnam2(otmp, "softly glow"),
  3588. -                              hcolor(NH_AMBER));
  3589. +                        pline("%s%s %s.", g_align != A_NONE ? "softly " : "",
  3590. +                              Yobjnam2(otmp, "glow"),
  3591. +                              hcolor(moloch ? "brown" : NH_AMBER));
  3592.                          iflags.last_msg = PLNMSG_OBJ_GLOWS;
  3593.                          otmp->bknown = 1; /* ok to bypass set_bknown() */
  3594.                          ++any;
  3595.                      }
  3596. -                    uncurse(otmp);
  3597. +                    if (moloch)
  3598. +                        unbless(otmp);
  3599. +                    else
  3600. +                        uncurse(otmp);
  3601.                  }
  3602.              }
  3603.              if (any)
  3604. @@ -1259,7 +1344,7 @@ boolean bless_water;
  3605.      return (boolean) (changed > 0L);
  3606.  }
  3607.  
  3608. -STATIC_OVL void
  3609. +void
  3610.  godvoice(g_align, words)
  3611.  aligntyp g_align;
  3612.  const char *words;
  3613. @@ -1357,6 +1442,9 @@ dosacrifice()
  3614.      if (otmp->otyp == CORPSE) {
  3615.          register struct permonst *ptr = &mons[otmp->corpsenm];
  3616.          struct monst *mtmp;
  3617. +        /* is this a conversion attempt? */
  3618. +        boolean to_other_god =  ugod_is_angry() && !your_race(ptr)
  3619. +                                && u.ualign.type != altaralign;
  3620.  
  3621.          /* KMH, conduct */
  3622.          u.uconduct.gnostic++;
  3623. @@ -1367,29 +1455,45 @@ dosacrifice()
  3624.          if (rider_corpse_revival(otmp, FALSE))
  3625.              return 1;
  3626.  
  3627. -        if (otmp->corpsenm == PM_ACID_BLOB
  3628. +        if (otmp->corpsenm == PM_ACID_BLOB || your_race(ptr)
  3629.              || (monstermoves <= peek_at_iced_corpse_age(otmp) + 50)) {
  3630.              value = mons[otmp->corpsenm].difficulty + 1;
  3631. +            /* Not demons--no demon corpses */
  3632. +            if (is_undead(ptr) && u.ualign.type > A_CHAOTIC)
  3633. +                value += 1;
  3634. +            if (is_unicorn(ptr))
  3635. +                value += 3;
  3636. +            if (uwep && uwep->oartifact == ART_SECESPITA)
  3637. +                value += value / 2;
  3638.              if (otmp->oeaten)
  3639.                  value = eaten_stat(value, otmp);
  3640. +            /* even cross-aligned sacrifices will count,
  3641. +             * as long as they're ultimately to Moloch */
  3642. +            if (u.ualign.type == A_NONE && !to_other_god) {
  3643. +                long new_timeout = moves + value * 500;
  3644. +                if (context.next_moloch_offering < new_timeout)
  3645. +                    context.next_moloch_offering = new_timeout;
  3646. +            }
  3647.          }
  3648.  
  3649.          if (your_race(ptr)) {
  3650. -            if (is_demon(youmonst.data)) {
  3651. +            if (is_demon(raceptr(&youmonst))) {
  3652.                  You("find the idea very satisfying.");
  3653.                  exercise(A_WIS, TRUE);
  3654. -            } else if (u.ualign.type != A_CHAOTIC) {
  3655. +            } else if (u.ualign.type > A_CHAOTIC) {
  3656.                  pline("You'll regret this infamous offense!");
  3657.                  exercise(A_WIS, FALSE);
  3658.              }
  3659.  
  3660.              if (highaltar
  3661. -                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)) {
  3662. +                && (altaralign != A_CHAOTIC || u.ualign.type != A_CHAOTIC)
  3663. +                && (altaralign != A_NONE || u.ualign.type != A_NONE)) {
  3664.                  goto desecrate_high_altar;
  3665.              } else if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
  3666.                  /* curse the lawful/neutral altar */
  3667.                  pline_The("altar is stained with %s blood.", urace.adj);
  3668. -                levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
  3669. +                levl[u.ux][u.uy].altarmask = u.ualign.type == A_NONE
  3670. +                                             ? AM_NONE : AM_CHAOTIC;
  3671.                  angry_priest();
  3672.              } else {
  3673.                  struct monst *dmon;
  3674. @@ -1409,7 +1513,7 @@ dosacrifice()
  3675.                  } else {
  3676.                      /* either you're chaotic or altar is Moloch's or both */
  3677.                      pline_The("blood covers the altar!");
  3678. -                    change_luck(altaralign == A_NONE ? -2 : 2);
  3679. +                    change_luck(altaralign == u.ualign.type ? 2 : -2);
  3680.                      demonless_msg = "blood coagulates";
  3681.                  }
  3682.                  if ((pm = dlord(altaralign)) != NON_PM
  3683. @@ -1433,7 +1537,7 @@ dosacrifice()
  3684.                      pline_The("%s.", demonless_msg);
  3685.              }
  3686.  
  3687. -            if (u.ualign.type != A_CHAOTIC) {
  3688. +            if (u.ualign.type > A_CHAOTIC) {
  3689.                  adjalign(-5);
  3690.                  u.ugangr += 3;
  3691.                  (void) adjattrib(A_WIS, -1, TRUE);
  3692. @@ -1449,17 +1553,17 @@ dosacrifice()
  3693.              return 1;
  3694.          } else if (has_omonst(otmp)
  3695.                     && (mtmp = get_mtraits(otmp, FALSE)) != 0
  3696. -                   && mtmp->mtame) {
  3697. +                   && mtmp->mtame
  3698. +                   /* Moloch is OK with sacrificing pets,
  3699. +                    * but make sure we're offering to him */
  3700. +                   && (u.ualign.type != A_NONE || to_other_god)) {
  3701.                  /* mtmp is a temporary pointer to a tame monster's attributes,
  3702.                   * not a real monster */
  3703.              pline("So this is how you repay loyalty?");
  3704.              adjalign(-3);
  3705.              value = -1;
  3706.              HAggravate_monster |= FROMOUTSIDE;
  3707. -        } else if (is_undead(ptr)) { /* Not demons--no demon corpses */
  3708. -            if (u.ualign.type != A_CHAOTIC)
  3709. -                value += 1;
  3710. -        } else if (is_unicorn(ptr)) {
  3711. +        } else if (is_unicorn(ptr) && value /* fresh */) {
  3712.              int unicalign = sgn(ptr->maligntyp);
  3713.  
  3714.              if (unicalign == altaralign) {
  3715. @@ -1479,7 +1583,7 @@ dosacrifice()
  3716.                  else
  3717.                      You_feel("you are thoroughly on the right path.");
  3718.                  adjalign(5);
  3719. -                value += 3;
  3720. +                /* value += 3; -- now applied above */
  3721.              } else if (unicalign == u.ualign.type) {
  3722.                  /* When sacrificing unicorn of your alignment to altar not of
  3723.                   * your alignment, your god gets angry and it's a conversion.
  3724. @@ -1491,7 +1595,7 @@ dosacrifice()
  3725.                   * and different from the altar's.  It's an ordinary (well,
  3726.                   * with a bonus) sacrifice on a cross-aligned altar.
  3727.                   */
  3728. -                value += 3;
  3729. +                /* value += 3; -- now applied above */
  3730.              }
  3731.          }
  3732.      } /* corpse */
  3733. @@ -1499,7 +1603,7 @@ dosacrifice()
  3734.      if (otmp->otyp == AMULET_OF_YENDOR) {
  3735.          if (!highaltar) {
  3736.   too_soon:
  3737. -            if (altaralign == A_NONE && Inhell)
  3738. +            if (altaralign == A_NONE && u.ualign.type != A_NONE && Inhell)
  3739.                  /* hero has left Moloch's Sanctum so is in the process
  3740.                     of getting away with the Amulet (outside of Gehennom,
  3741.                     fall through to the "ashamed" feedback) */
  3742. @@ -1510,7 +1614,9 @@ dosacrifice()
  3743.                              ? "homesick"
  3744.                              /* if on track, give a big hint */
  3745.                              : (altaralign == u.ualign.type)
  3746. -                               ? "an urge to return to the surface"
  3747. +                               ? (Role_if(PM_INFIDEL)
  3748. +                                  ? "an urge to descend deeper"
  3749. +                                  : "an urge to return to the surface")
  3750.                                 /* else headed towards celestial disgrace */
  3751.                                 : "ashamed");
  3752.              return 1;
  3753. @@ -1526,6 +1632,33 @@ dosacrifice()
  3754.              You("offer the Amulet of Yendor to %s...", a_gname());
  3755.              if (altaralign == A_NONE) {
  3756.                  /* Moloch's high altar */
  3757. +                if (Role_if(PM_INFIDEL)) {
  3758. +                    /* Infidels still have an ascension run,
  3759. +                     * they just carry a different McGuffin */
  3760. +                    u.uevent.ascended = 0;
  3761. +                    u.uachieve.amulet = 1;
  3762. +                    otmp = find_quest_artifact(1 << OBJ_INVENT);
  3763. +                    godvoice(A_NONE, (char *) 0);
  3764. +                    if (!otmp)
  3765. +                        qt_pager(QT_MOLOCH_1);
  3766. +                    else {
  3767. +                        qt_pager(QT_MOLOCH_2);
  3768. +                        if (otmp->where == OBJ_CONTAINED) {
  3769. +                            /* the Idol cannot be contained now,
  3770. +                             * so we have to remove it */
  3771. +                            obj_extract_self(otmp);
  3772. +                            (void) hold_another_object(otmp, "Oops!",
  3773. +                                                       (const char *) 0,
  3774. +                                                       (const char *) 0);
  3775. +                        }
  3776. +                        You_feel("strange energies envelop %s.",
  3777. +                                 the(xname(otmp)));
  3778. +                        otmp->spe = 1;
  3779. +                        if (otmp->where == OBJ_INVENT)
  3780. +                            u.uhave.amulet = 1;
  3781. +                    }
  3782. +                    return 1;
  3783. +                }
  3784.                  if (u.ualign.record > -99)
  3785.                      u.ualign.record = -99;
  3786.                  /*[apparently shrug/snarl can be sensed without being seen]*/
  3787. @@ -1582,8 +1715,10 @@ dosacrifice()
  3788.              if (Deaf)
  3789.                  pline("Oh, no."); /* didn't hear thunderclap */
  3790.              change_luck(-3);
  3791. -            adjalign(-1);
  3792. -            u.ugangr += 3;
  3793. +            if (u.ualign.type != A_NONE) {
  3794. +                adjalign(-1);
  3795. +                u.ugangr += 3;
  3796. +            }
  3797.              value = -3;
  3798.          }
  3799.      } /* fake Amulet */
  3800. @@ -1617,9 +1752,10 @@ dosacrifice()
  3801.          if (u.ualign.type != altaralign) {
  3802.              /* Is this a conversion ? */
  3803.              /* An unaligned altar in Gehennom will always elicit rejection. */
  3804. +            /* Infidels will also never be accepted. */
  3805.              if (ugod_is_angry() || (altaralign == A_NONE && Inhell)) {
  3806.                  if (u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL]
  3807. -                    && altaralign != A_NONE) {
  3808. +                    && altaralign != A_NONE && !Role_if(PM_INFIDEL)) {
  3809.                      You("have a strong feeling that %s is angry...",
  3810.                          u_gname());
  3811.                      consume_offering(otmp);
  3812. @@ -1644,7 +1780,11 @@ dosacrifice()
  3813.                  consume_offering(otmp);
  3814.                  You("sense a conflict between %s and %s.", u_gname(),
  3815.                      a_gname());
  3816. -                if (rn2(8 + u.ulevel) > 5) {
  3817. +                if (rn2(8 + u.ulevel) > 5
  3818. +                    /* Infidels have difficulty converting altars. */
  3819. +                    && !(u.ualign.type == A_NONE
  3820. +                         && !(Role_if(PM_INFIDEL) && u.uhave.questart)
  3821. +                         && depth(&u.uz) < depth(&valley_level) && rn2(5))) {
  3822.                      struct monst *pri;
  3823.                      You_feel("the power of %s increase.", u_gname());
  3824.                      exercise(A_WIS, TRUE);
  3825. @@ -1659,9 +1799,11 @@ dosacrifice()
  3826.                          pline_The("altar glows %s.",
  3827.                                    hcolor((u.ualign.type == A_LAWFUL)
  3828.                                              ? NH_WHITE
  3829. -                                            : u.ualign.type
  3830. -                                               ? NH_BLACK
  3831. -                                               : (const char *) "gray"));
  3832. +                                            : u.ualign.type == A_NONE
  3833. +                                                ? NH_RED
  3834. +                                                : u.ualign.type
  3835. +                                                    ? NH_BLACK
  3836. +                                                    : (const char *) "gray"));
  3837.  
  3838.                      if (rnl(u.ulevel) > 6 && u.ualign.record > 0
  3839.                          && rnd(u.ualign.record) > (3 * ALIGNLIM) / 4)
  3840. @@ -1686,8 +1828,9 @@ dosacrifice()
  3841.          consume_offering(otmp);
  3842.          /* OK, you get brownie points. */
  3843.          if (u.ugangr) {
  3844. -            u.ugangr -= ((value * (u.ualign.type == A_CHAOTIC ? 2 : 3))
  3845. -                         / MAXVALUE);
  3846. +            u.ugangr -= ((value * (u.ualign.type == A_NONE ? 3
  3847. +                                   : u.ualign.type == A_CHAOTIC ? 4 : 6))
  3848. +                         / (MAXVALUE * 2));
  3849.              if (u.ugangr < 0)
  3850.                  u.ugangr = 0;
  3851.              if (u.ugangr != saved_anger) {
  3852. @@ -1719,7 +1862,7 @@ dosacrifice()
  3853.              adjalign(value);
  3854.              You_feel("partially absolved.");
  3855.          } else if (u.ublesscnt > 0) {
  3856. -            u.ublesscnt -= ((value * (u.ualign.type == A_CHAOTIC ? 500 : 300))
  3857. +            u.ublesscnt -= ((value * (u.ualign.type <= A_CHAOTIC ? 500 : 300))
  3858.                              / MAXVALUE);
  3859.              if (u.ublesscnt < 0)
  3860.                  u.ublesscnt = 0;
  3861. @@ -1799,7 +1942,7 @@ boolean praying; /* false means no messages should be given */
  3862.      p_aligntyp = on_altar() ? a_align(u.ux, u.uy) : u.ualign.type;
  3863.      p_trouble = in_trouble();
  3864.  
  3865. -    if (is_demon(youmonst.data) && (p_aligntyp != A_CHAOTIC)) {
  3866. +    if (is_demon(raceptr(&youmonst)) && (p_aligntyp > A_CHAOTIC)) {
  3867.          if (praying)
  3868.              pline_The("very idea of praying to a %s god is repugnant to you.",
  3869.                        p_aligntyp ? "lawful" : "neutral");
  3870. @@ -1830,13 +1973,16 @@ boolean praying; /* false means no messages should be given */
  3871.      }
  3872.  
  3873.      if (is_undead(youmonst.data) && !Inhell
  3874. -        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && !rn2(10))))
  3875. +        && (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && praying
  3876. +                                       && !rn2(10))))
  3877.          p_type = -1;
  3878. -    /* Note:  when !praying, the random factor for neutrals makes the
  3879. -       return value a non-deterministic approximation for enlightenment.
  3880. -       This case should be uncommon enough to live with... */
  3881.  
  3882. -    return !praying ? (boolean) (p_type == 3 && !Inhell) : TRUE;
  3883. +    if (p_aligntyp == A_NONE && !on_altar()
  3884. +        && depth(&u.uz) < depth(&valley_level)
  3885. +        && !(Role_if(PM_INFIDEL) && u.uhave.questart) && praying && rn2(5))
  3886. +        p_type = -2; /* Moloch can't hear you */
  3887. +
  3888. +    return praying || p_type == 3 && (!Inhell || u.ualign.type == A_NONE);
  3889.  }
  3890.  
  3891.  /* #pray commmand */
  3892. @@ -1870,10 +2016,13 @@ dopray()
  3893.      nomovemsg = "You finish your prayer.";
  3894.      afternmv = prayer_done;
  3895.  
  3896. -    if (p_type == 3 && !Inhell) {
  3897. +    if (p_type == 3 && (!Inhell || u.ualign.type == A_NONE)) {
  3898.          /* if you've been true to your god you can't die while you pray */
  3899.          if (!Blind)
  3900. -            You("are surrounded by a shimmering light.");
  3901. +            You("are surrounded by %s %s.",
  3902. +                u.ualign.type == A_NONE ? an(hcolor(NH_BLACK))
  3903. +                                        : "a shimmering",
  3904. +                u.ualign.type == A_NONE ? "mist" : "light");
  3905.          u.uinvulnerable = TRUE;
  3906.      }
  3907.  
  3908. @@ -1899,7 +2048,13 @@ prayer_done() /* M. Stephenson (1.0.3b) */
  3909.          exercise(A_CON, FALSE);
  3910.          return 1;
  3911.      }
  3912. -    if (Inhell) {
  3913. +    if (p_type == -2) {
  3914. +        pline("Unfortunately, this close to the surface %s can't hear you.",
  3915. +              align_gname(alignment));
  3916. +        /* no further effects */
  3917. +        return 0;
  3918. +    }
  3919. +    if (Inhell && u.ualign.type != A_NONE) {
  3920.          pline("Since you are in Gehennom, %s can't help you.",
  3921.                align_gname(alignment));
  3922.          /* haltingly aligned is least likely to anger */
  3923. @@ -1929,7 +2084,7 @@ prayer_done() /* M. Stephenson (1.0.3b) */
  3924.      } else {
  3925.          /* coaligned */
  3926.          if (on_altar())
  3927. -            (void) water_prayer(TRUE);
  3928. +            (void) water_prayer(alignment != A_NONE);
  3929.          pleased(alignment); /* nice */
  3930.      }
  3931.      return 1;
  3932. @@ -1977,7 +2132,7 @@ doturn()
  3933.          return (u.uconduct.gnostic == 1);
  3934.      }
  3935.      if ((u.ualign.type != A_CHAOTIC
  3936. -         && (is_demon(youmonst.data) || is_undead(youmonst.data)))
  3937. +         && (is_demon(raceptr(&youmonst)) || is_undead(youmonst.data)))
  3938.          || u.ugangr > 6) { /* "Die, mortal!" */
  3939.          pline("For some reason, %s seems to ignore you.", Gname);
  3940.          aggravate();
  3941. @@ -2211,6 +2366,9 @@ aligntyp alignment;
  3942.      const char *gnam, *result = "god";
  3943.  
  3944.      switch (alignment) {
  3945. +    case A_NONE:
  3946. +        gnam = Moloch;
  3947. +        break;
  3948.      case A_LAWFUL:
  3949.          gnam = urole.lgod;
  3950.          break;
  3951. @@ -2229,6 +2387,23 @@ aligntyp alignment;
  3952.      return result;
  3953.  }
  3954.  
  3955. +/* return an alignment from a (lawful, neutral, chaotic) permutation
  3956. + * randomly chosen at game start; only relevant to Infidels */
  3957. +aligntyp
  3958. +inf_align(num)
  3959. +int num; /* 1..3 */
  3960. +{
  3961. +    aligntyp first, other;
  3962. +    first = context.inf_aligns % 3 - 1;
  3963. +    if (num == 1)
  3964. +        return first;
  3965. +    other = (context.inf_aligns + num) % 2;
  3966. +    if (other <= first)
  3967. +        other--;
  3968. +    return other;
  3969. +
  3970. +}
  3971. +
  3972.  void
  3973.  altar_wrath(x, y)
  3974.  register int x, y;
  3975. diff --git a/src/priest.c b/src/priest.c
  3976. index ab20a8d..e9cfb62 100644
  3977. --- a/src/priest.c
  3978. +++ b/src/priest.c
  3979. @@ -4,6 +4,7 @@
  3980.  
  3981.  #include "hack.h"
  3982.  #include "mfndpos.h"
  3983. +#include "qtext.h"
  3984.  
  3985.  /* these match the categorizations shown by enlightenment */
  3986.  #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
  3987. @@ -253,7 +254,7 @@ boolean sanctum; /* is it the seat of the high priest? */
  3988.  
  3989.          /* now his/her goodies... */
  3990.          if (sanctum && EPRI(priest)->shralign == A_NONE
  3991. -            && on_level(&sanctum_level, &u.uz)) {
  3992. +            && on_level(&sanctum_level, &u.uz) && !Role_if(PM_INFIDEL)) {
  3993.              (void) mongets(priest, AMULET_OF_YENDOR);
  3994.          }
  3995.          /* 2 to 4 spellbooks */
  3996. @@ -391,7 +392,7 @@ int roomno;
  3997.  {
  3998.      struct monst *priest, *mtmp;
  3999.      struct epri *epri_p;
  4000. -    boolean shrined, sanctum, can_speak;
  4001. +    boolean shrined, sanctum, can_speak, call_guards;
  4002.      long *this_time, *other_time;
  4003.      const char *msg1, *msg2;
  4004.      char buf[BUFSZ];
  4005. @@ -408,6 +409,7 @@ int roomno;
  4006.          sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
  4007.                     && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  4008.          can_speak = (priest->mcanmove && !priest->msleeping);
  4009. +        call_guards = FALSE;
  4010.          if (can_speak && !Deaf && moves >= epri_p->intone_time) {
  4011.              unsigned save_priest = priest->ispriest;
  4012.  
  4013. @@ -425,11 +427,20 @@ int roomno;
  4014.              epri_p->enter_time = 0L;
  4015.          }
  4016.          msg1 = msg2 = 0;
  4017. -        if (sanctum && Is_sanctum(&u.uz)) {
  4018. +        if ((sanctum && Is_sanctum(&u.uz) || u.ualign.type == A_NONE)
  4019. +            && !p_coaligned(priest)) {
  4020. +            /* either a non-Infidel in the Sanctum, or an Infidel in any
  4021. +             * non-Moloch temple; either way, the priest is not happy */
  4022.              if (priest->mpeaceful) {
  4023.                  /* first time inside */
  4024. -                msg1 = "Infidel, you have entered Moloch's Sanctum!";
  4025. -                msg2 = "Be gone!";
  4026. +                if (u.ualign.type == A_NONE) {
  4027. +                    msg1 = "Begone, infidel!";
  4028. +                    msg2 = "This place is barred for your cult!";
  4029. +                    call_guards = in_town(priest->mx, priest->my);
  4030. +                } else {
  4031. +                    msg1 = "Infidel, you have entered Moloch's Sanctum!";
  4032. +                    msg2 = "Be gone!";
  4033. +                }
  4034.                  priest->mpeaceful = 0;
  4035.                  /* became angry voluntarily; no penalty for attacking him */
  4036.                  set_malign(priest);
  4037. @@ -448,6 +459,11 @@ int roomno;
  4038.                  verbalize1(msg2);
  4039.              epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
  4040.          }
  4041. +        /* for Infidels, visiting the Minetown temple is a very bad idea */
  4042. +        if (call_guards) {
  4043. +            pline("%s calls for guards!", Monnam(priest));
  4044. +            (void) angry_guards(FALSE);
  4045. +        }
  4046.          if (!sanctum) {
  4047.              if (!shrined || !p_coaligned(priest)
  4048.                  || u.ualign.record <= ALGN_SINNED) {
  4049. @@ -549,7 +565,8 @@ register struct monst *priest;
  4050.  
  4051.      /* priests don't chat unless peaceful and in their own temple */
  4052.      if (!inhistemple(priest) || !priest->mpeaceful
  4053. -        || !priest->mcanmove || priest->msleeping) {
  4054. +        || !priest->mcanmove || priest->msleeping
  4055. +        || u.ualign.type == A_NONE && !coaligned) {
  4056.          static const char *cranky_msg[3] = {
  4057.              "Thou wouldst have words, eh?  I'll give thee a word or two!",
  4058.              "Talk?  Here is what I have to say!",
  4059. @@ -576,7 +593,19 @@ register struct monst *priest;
  4060.          return;
  4061.      }
  4062.      if (!money_cnt(invent)) {
  4063. -        if (coaligned && !strayed) {
  4064. +        if (Role_if(PM_INFIDEL) && u.uachieve.amulet
  4065. +            && priest->data == &mons[PM_HIGH_PRIEST] && Is_sanctum(&u.uz)) {
  4066. +            /* give a hint about the correct high altar */
  4067. +            aligntyp saved_align = u.ualignbase[A_ORIGINAL];
  4068. +            uchar saved_godgend = quest_status.godgend;
  4069. +            /* a hack for displaying a different god's name in the message */
  4070. +            u.ualignbase[A_ORIGINAL] = inf_align(3);
  4071. +            /* "god"[3] == 0; "goddess"[3] != 0 */
  4072. +            quest_status.godgend = !!align_gtitle(inf_align(3))[3];
  4073. +            qt_pager(QT_MOLOCH_3);
  4074. +            u.ualignbase[A_ORIGINAL] = saved_align;
  4075. +            quest_status.godgend = saved_godgend;
  4076. +        } else if (coaligned && !strayed) {
  4077.              long pmoney = money_cnt(priest->minvent);
  4078.              if (pmoney > 0L) {
  4079.                  /* Note: two bits is actually 25 cents.  Hmm. */
  4080. diff --git a/src/quest.c b/src/quest.c
  4081. index df4b831..c245ef1 100644
  4082. --- a/src/quest.c
  4083. +++ b/src/quest.c
  4084. @@ -219,9 +219,22 @@ finish_quest(obj)
  4085.  struct obj *obj; /* quest artifact; possibly null if carrying Amulet */
  4086.  {
  4087.      struct obj *otmp;
  4088. -
  4089. -    if (u.uhave.amulet) { /* unlikely but not impossible */
  4090. -        qt_pager(QT_HASAMULET);
  4091. +    aligntyp saved_align;
  4092. +    uchar saved_godgend;
  4093. +
  4094. +    if (u.uachieve.amulet) { /* unlikely but not impossible */
  4095. +        if (Role_if(PM_INFIDEL)) {
  4096. +            saved_align = u.ualignbase[A_ORIGINAL];
  4097. +            saved_godgend = quest_status.godgend;
  4098. +            /* a hack for displaying a different god's name in the message */
  4099. +            u.ualignbase[A_ORIGINAL] = inf_align(2);
  4100. +            /* "god"[3] == 0; "goddess"[3] != 0 */
  4101. +            quest_status.godgend = !!align_gtitle(inf_align(2))[3];
  4102. +            qt_pager(QT_HASAMULET);
  4103. +            u.ualignbase[A_ORIGINAL] = saved_align;
  4104. +            quest_status.godgend = saved_godgend;
  4105. +        } else
  4106. +            qt_pager(QT_HASAMULET);
  4107.          /* leader IDs the real amulet but ignores any fakes */
  4108.          if ((otmp = carrying(AMULET_OF_YENDOR)) != 0)
  4109.              fully_identify_obj(otmp);
  4110. @@ -255,7 +268,7 @@ chat_with_leader()
  4111.       */
  4112.      if (Qstat(got_thanks)) {
  4113.          /* Rule 1: You've gone back with/without the amulet. */
  4114. -        if (u.uhave.amulet)
  4115. +        if (u.uachieve.amulet)
  4116.              finish_quest((struct obj *) 0);
  4117.  
  4118.          /* Rule 2: You've gone back before going for the amulet. */
  4119. diff --git a/src/questpgr.c b/src/questpgr.c
  4120. index 5c04c6c..3bd8b65 100644
  4121. --- a/src/questpgr.c
  4122. +++ b/src/questpgr.c
  4123. @@ -599,7 +599,7 @@ void
  4124.  com_pager(msgnum)
  4125.  int msgnum;
  4126.  {
  4127. -    struct qtmsg *qt_msg;
  4128. +    struct qtmsg *qt_msg, *alt_qt_msg;
  4129.  
  4130.      if (skip_pager(TRUE))
  4131.          return;
  4132. @@ -609,6 +609,10 @@ int msgnum;
  4133.          return;
  4134.      }
  4135.  
  4136. +    /* optional alternate game start message; currently only Inf use it */
  4137. +    if (msgnum == 1 && (alt_qt_msg = msg_in(qt_list.chrole, QT_ALTSTART)))
  4138. +        qt_msg = alt_qt_msg;
  4139. +
  4140.      (void) dlb_fseek(msg_file, qt_msg->offset, SEEK_SET);
  4141.      if (qt_msg->delivery == 'p')
  4142.          deliver_by_pline(qt_msg);
  4143. diff --git a/src/read.c b/src/read.c
  4144. index aaa3341..f3bc78a 100644
  4145. --- a/src/read.c
  4146. +++ b/src/read.c
  4147. @@ -1118,6 +1118,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
  4148.                  uncurse(otmp);
  4149.              otmp->known = 1;
  4150.              setworn(otmp, W_ARM);
  4151. +            check_wings(TRUE);
  4152.              if (otmp->unpaid)
  4153.                  alter_cost(otmp, 0L); /* shop bill */
  4154.              break;
  4155. @@ -2150,7 +2151,9 @@ do_class_genocide()
  4156.                          /* non-leader/nemesis/guardian role-specific monster
  4157.                             */
  4158.                          && (i != PM_NINJA /* nuisance */
  4159. -                            || Role_if(PM_SAMURAI))) {
  4160. +                            || Role_if(PM_SAMURAI))
  4161. +                        && (i != PM_TEMPLAR && i != PM_CHAMPION
  4162. +                            && i != PM_AGENT || Role_if(PM_INFIDEL))) {
  4163.                          boolean named, uniq;
  4164.  
  4165.                          named = type_is_pname(&mons[i]) ? TRUE : FALSE;
  4166. diff --git a/src/restore.c b/src/restore.c
  4167. index 8c8703b..6d5608a 100644
  4168. --- a/src/restore.c
  4169. +++ b/src/restore.c
  4170. @@ -596,11 +596,11 @@ unsigned int *stuckid, *steedid;
  4171.      mread(fd, (genericptr_t) &sysflags, sizeof(struct sysflag));
  4172.  #endif
  4173.  
  4174. -    role_init(); /* Reset the initial role, race, gender, and alignment */
  4175.  #ifdef AMII_GRAPHICS
  4176.      amii_setpens(amii_numcolors); /* use colors from save file */
  4177.  #endif
  4178.      mread(fd, (genericptr_t) &u, sizeof(struct you));
  4179. +    role_init(); /* Reset the initial role, race, gender, and alignment */
  4180.  
  4181.  #define ReadTimebuf(foo)                   \
  4182.      mread(fd, (genericptr_t) timebuf, 14); \
  4183. @@ -694,6 +694,8 @@ unsigned int *stuckid, *steedid;
  4184.          mread(fd, (genericptr_t) stuckid, sizeof *stuckid);
  4185.      if (u.usteed)
  4186.          mread(fd, (genericptr_t) steedid, sizeof *steedid);
  4187. +    restlevelstate(*stuckid, *steedid);
  4188. +    check_wings(TRUE); /* we need usteed for the flight check */
  4189.      mread(fd, (genericptr_t) pl_character, sizeof pl_character);
  4190.  
  4191.      mread(fd, (genericptr_t) pl_fruit, sizeof pl_fruit);
  4192. @@ -817,7 +819,6 @@ register int fd;
  4193.          restoring = FALSE;
  4194.          return 0;
  4195.      }
  4196. -    restlevelstate(stuckid, steedid);
  4197.  #ifdef INSURANCE
  4198.      savestateinlock();
  4199.  #endif
  4200. diff --git a/src/role.c b/src/role.c
  4201. index f263609..a1336d9 100644
  4202. --- a/src/role.c
  4203. +++ b/src/role.c
  4204. @@ -192,6 +192,47 @@ const struct Role roles[] = {
  4205.        A_WIS,
  4206.        SPE_CURE_SICKNESS,
  4207.        -4 },
  4208. +    { { "Infidel", 0 },
  4209. +      { { "Apostate", 0 },
  4210. +        { "Heathen", 0 },
  4211. +        { "Heretic", 0 },
  4212. +        { "Idolater", "Idolatress" },
  4213. +        { "Cultist", 0 },
  4214. +        { "Splanchomancer", 0 },
  4215. +        { "Maleficus", "Malefica" },
  4216. +        { "Demonologist", 0 },
  4217. +        { "Heresiarch", 0 } },
  4218. +      0, 0, 0, /* uses a random role's pantheon */
  4219. +      "Inf",
  4220. +      "the Hidden Temple",
  4221. +      "the Howling Forest",
  4222. +      PM_INFIDEL,
  4223. +      NON_PM,
  4224. +      PM_HOMUNCULUS,
  4225. +      PM_PREACHER_OF_MOLOCH,
  4226. +      PM_CULTIST,
  4227. +      PM_PALADIN,
  4228. +      PM_AGENT,
  4229. +      PM_CHAMPION,
  4230. +      S_DOG,
  4231. +      S_UNICORN,
  4232. +      ART_IDOL_OF_MOLOCH,                         /* actually unaligned */
  4233. +      MH_HUMAN | MH_ORC | ROLE_MALE | ROLE_FEMALE | ROLE_CHAOTIC,
  4234. +      /* Str Int Wis Dex Con Cha */
  4235. +      { 7, 7, 10, 7, 7, 7 },
  4236. +      { 20, 10, 25, 15, 20, 10 },
  4237. +      /* Init   Lower  Higher */
  4238. +      { 10, 0, 0, 8, 1, 0 }, /* Hit points */
  4239. +      { 4, 3, 0, 1, 0, 2 },
  4240. +      10, /* Energy */
  4241. +      10,
  4242. +      3,
  4243. +      1,
  4244. +      2,
  4245. +      10,
  4246. +      A_WIS,
  4247. +      SPE_FIREBALL,
  4248. +      -4 },
  4249.      { { "Knight", 0 },
  4250.        { { "Gallant", 0 },
  4251.          { "Esquire", 0 },
  4252. @@ -725,6 +766,29 @@ const struct Race races[] = {
  4253.      { 0, 0, 0, 0 }
  4254.  };
  4255.  
  4256. +/* Special race for crowned Infidels. */
  4257. +struct Race race_demon = {
  4258. +    "demon",
  4259. +    "demonic",
  4260. +    "demonkind",
  4261. +    "Dem",
  4262. +    { 0, 0 },
  4263. +    PM_DEMON,
  4264. +    NON_PM,
  4265. +    NON_PM,
  4266. +    NON_PM,
  4267. +    MH_DEMON | ROLE_MALE | ROLE_FEMALE, /* not available at start */
  4268. +    MH_DEMON,
  4269. +    MH_DEMON,
  4270. +    MH_HUMAN | MH_ELF | MH_DWARF | MH_GNOME,
  4271. +    /*  Str    Int Wis Dex Con Cha */
  4272. +    { 3, 3, 3, 3, 3, 3 },
  4273. +    { STR18(100), 18, 18, 20, 20, 18 }, /* max Int & Wis are variable */
  4274. +    /* Init   Lower  Higher */
  4275. +    { 8, 0, 0, 8, 4, 0 }, /* Hit points */
  4276. +    { 4, 0, 6, 0, 6, 0 }  /* Energy */
  4277. +};
  4278. +
  4279.  /* The player's race, created at runtime from initial
  4280.   * choices.  This may be munged in role_init().
  4281.   */
  4282. @@ -786,6 +850,16 @@ int rolenum;
  4283.      return (boolean) (rolenum >= 0 && rolenum < SIZE(roles) - 1);
  4284.  }
  4285.  
  4286. +/* Inf are listed as chaotic above, but actually are unaligned. */
  4287. +int
  4288. +special_alignment(rolenum, alignnum)
  4289. +int rolenum, alignnum;
  4290. +{
  4291. +    if (validrole(rolenum) && roles[rolenum].malenum == PM_INFIDEL)
  4292. +        return 3; /* aligns[unaligned] */
  4293. +    return alignnum;
  4294. +}
  4295. +
  4296.  int
  4297.  randrole(for_display)
  4298.  boolean for_display;
  4299. @@ -1503,12 +1577,12 @@ int buflen, rolenum, racenum, gendnum, alignnum;
  4300.          if ((racenum >= 0) && (aligncount > 1)) {
  4301.              if (donefirst)
  4302.                  Strcat(buf, " ");
  4303. -            Strcat(buf, aligns[alignnum].adj);
  4304. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  4305.              donefirst = TRUE;
  4306.          } else {
  4307.              if (donefirst)
  4308.                  Strcat(buf, " ");
  4309. -            Strcat(buf, aligns[alignnum].adj);
  4310. +            Strcat(buf, aligns[special_alignment(rolenum, alignnum)].adj);
  4311.              donefirst = TRUE;
  4312.          }
  4313.      } else {
  4314. @@ -1800,6 +1874,7 @@ winid where;
  4315.              a = 2; /* alings[chaotic] */
  4316.          /* [c never forces gender] */
  4317.      }
  4318. +    a = special_alignment(r, a); /* special case (Infidel) */
  4319.      /* [g and a don't constrain anything sufficiently
  4320.         to narrow something done to a single choice] */
  4321.  
  4322. @@ -1935,6 +2010,7 @@ boolean preselect;
  4323.                  a = 1; /* aligns[neutral] */
  4324.              else if (allowmask == AM_CHAOTIC)
  4325.                  a = 2; /* aligns[chaotic] */
  4326. +            a = special_alignment(r, a); /* special case (Infidel) */
  4327.              if (a >= 0)
  4328.                  constrainer = "role";
  4329.          }
  4330. @@ -2010,7 +2086,7 @@ boolean preselect;
  4331.  void
  4332.  role_init()
  4333.  {
  4334. -    int alignmnt;
  4335. +    int alignmnt, malignmnt;
  4336.      struct permonst *pm;
  4337.  
  4338.      /* Strip the role letter out of the player name.
  4339. @@ -2049,11 +2125,21 @@ role_init()
  4340.      if (!validalign(flags.initrole, flags.initrace, flags.initalign))
  4341.          /* Pick a random alignment */
  4342.          flags.initalign = randalign(flags.initrole, flags.initrace);
  4343. -    alignmnt = aligns[flags.initalign].value;
  4344. +    /* Infidels are actually unaligned */
  4345. +    flags.initalign = special_alignment(flags.initrole, flags.initalign);
  4346. +    alignmnt = malignmnt = aligns[flags.initalign].value;
  4347. +    if (alignmnt != A_NONE)
  4348. +        malignmnt *= 3;
  4349.  
  4350.      /* Initialize urole and urace */
  4351.      urole = roles[flags.initrole];
  4352. -    urace = races[flags.initrace];
  4353. +    if (u.uevent.uhand_of_elbereth == 4) { /* crowned as a demon */
  4354. +        urace = race_demon;
  4355. +        /* mental faculties are not changed by demonization */
  4356. +        urace.attrmax[A_INT] = races[flags.initrace].attrmax[A_INT];
  4357. +        urace.attrmax[A_WIS] = races[flags.initrace].attrmax[A_WIS];
  4358. +    } else
  4359. +        urace = races[flags.initrace];
  4360.  
  4361.      /* Fix up the quest leader */
  4362.      if (urole.ldrnum != NON_PM) {
  4363. @@ -2061,7 +2147,7 @@ role_init()
  4364.          pm->msound = MS_LEADER;
  4365.          pm->mflags2 |= (M2_PEACEFUL);
  4366.          pm->mflags3 |= M3_CLOSE;
  4367. -        pm->maligntyp = alignmnt * 3;
  4368. +        pm->maligntyp = malignmnt;
  4369.          /* if gender is random, we choose it now instead of waiting
  4370.             until the leader monster is created */
  4371.          quest_status.ldrgend =
  4372. @@ -2074,7 +2160,7 @@ role_init()
  4373.      if (urole.guardnum != NON_PM) {
  4374.          pm = &mons[urole.guardnum];
  4375.          pm->mflags2 |= (M2_PEACEFUL);
  4376. -        pm->maligntyp = alignmnt * 3;
  4377. +        pm->maligntyp = malignmnt;
  4378.      }
  4379.  
  4380.      /* Fix up the quest nemesis */
  4381. @@ -2091,6 +2177,14 @@ role_init()
  4382.                                     : is_male(pm) ? 0 : (rn2(100) < 50);
  4383.      }
  4384.  
  4385. +    /* Enable special Inf enemies */
  4386. +    if (Role_if(PM_INFIDEL)) {
  4387. +        if (urole.enemy1num != NON_PM)
  4388. +            mons[urole.enemy1num].geno &= ~G_NOGEN;
  4389. +        if (urole.enemy2num != NON_PM)
  4390. +            mons[urole.enemy2num].geno &= ~G_NOGEN;
  4391. +    }
  4392. +
  4393.      /* Fix up the god names */
  4394.      if (flags.pantheon == -1) {             /* new game */
  4395.          flags.pantheon = flags.initrole;    /* use own gods */
  4396. diff --git a/src/shk.c b/src/shk.c
  4397. index 6772da4..91c75f8 100644
  4398. --- a/src/shk.c
  4399. +++ b/src/shk.c
  4400. @@ -4776,7 +4776,7 @@ boolean altusage; /* used as a verbalized exclamation:  \"Cad! ...\" */
  4401.  {
  4402.      const char *res = 0;
  4403.  
  4404. -    switch (is_demon(youmonst.data) ? 3 : poly_gender()) {
  4405. +    switch (is_demon(raceptr(&youmonst)) ? 3 : poly_gender()) {
  4406.      case 0:
  4407.          res = "cad";
  4408.          break;
  4409. diff --git a/src/sp_lev.c b/src/sp_lev.c
  4410. index 2c5628f..4817839 100644
  4411. --- a/src/sp_lev.c
  4412. +++ b/src/sp_lev.c
  4413. @@ -1624,6 +1624,14 @@ struct mkroom *croom;
  4414.          && (Race_if(PM_DWARF) || Race_if(PM_GNOME)) && rn2(3))
  4415.          pm = (struct permonst *) 0;
  4416.  
  4417. +    /* Make Sanctum monsters more friendly to Infidels */
  4418. +    if (u.ualign.type == A_NONE && Is_sanctum(&u.uz) && m->peaceful == 0)
  4419. +        m->peaceful = 1;
  4420. +    /* OTOH, the Astral shouldn't be easy; but the multitude of
  4421. +     * renegade minions of Moloch is still silly */
  4422. +    if (Role_if(PM_INFIDEL) && Is_astralevel(&u.uz) && amask == AM_NONE)
  4423. +        amask = Align2amask(rn1(3, -1));
  4424. +
  4425.      if (pm) {
  4426.          int loc = pm_to_humidity(pm);
  4427.          /* If water-liking monster, first try is without DRY */
  4428. diff --git a/src/spell.c b/src/spell.c
  4429. index 9cbb9a4..e489ffa 100644
  4430. --- a/src/spell.c
  4431. +++ b/src/spell.c
  4432. @@ -54,6 +54,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  4433.   *      Bar abhor magic (Conan finds it "interferes with his animal instincts")
  4434.   *      Cav are ignorant to magic
  4435.   *      Hea are very aware of healing magic through medical research
  4436. + *      Inf learned a lot of black magic from their cult
  4437.   *      Kni are moderately aware of healing from Paladin training
  4438.   *      Mon use magic to attack and defend in lieu of weapons and armor
  4439.   *      Pri are very aware of healing magic through theological research
  4440. @@ -74,6 +75,7 @@ STATIC_DCL boolean FDECL(spell_aim_step, (genericptr_t, int, int));
  4441.   *      Bar fugue/berserker (SPE_HASTE_SELF)
  4442.   *      Cav born to dig (SPE_DIG)
  4443.   *      Hea to heal (SPE_CURE_SICKNESS)
  4444. + *      Inf to channel hellfire (SPE_FIREBALL)
  4445.   *      Kni to turn back evil (SPE_TURN_UNDEAD)
  4446.   *      Mon to preserve their abilities (SPE_RESTORE_ABILITY)
  4447.   *      Pri to bless (SPE_REMOVE_CURSE)
  4448. @@ -946,14 +948,18 @@ boolean atme;
  4449.         the attempt may fail due to lack of energy after the draining, in
  4450.         which case a turn will be used up in addition to the energy loss */
  4451.      if (u.uhave.amulet && u.uen >= energy) {
  4452. -        You_feel("the amulet draining your energy away.");
  4453. +        You_feel("the %s draining your energy away.",
  4454. +                 Role_if(PM_INFIDEL) && u.uachieve.amulet ? "idol"
  4455. +                                                          : "amulet");
  4456.          /* this used to be 'energy += rnd(2 * energy)' (without 'res'),
  4457.             so if amulet-induced cost was more than u.uen, nothing
  4458.             (except the "don't have enough energy" message) happened
  4459.             and player could just try again (and again and again...);
  4460.             now we drain some energy immediately, which has a
  4461.             side-effect of not increasing the hunger aspect of casting */
  4462. -        u.uen -= rnd(2 * energy);
  4463. +        /* GREATLY reduced for Inf since they have to deal
  4464. +         * with the Amulet for the entire game */
  4465. +        u.uen -= rnd(Role_if(PM_INFIDEL) ? energy / 2 : 2 * energy);
  4466.          if (u.uen < 0)
  4467.              u.uen = 0;
  4468.          context.botl = 1;
  4469. @@ -1741,6 +1747,25 @@ int spell;
  4470.      if (uarmf && is_metallic(uarmf))
  4471.          splcaster += uarmfbon;
  4472.  
  4473. +    /* Infidels have a special penalty for wearing blessed armor. */
  4474. +    if (Role_if(PM_INFIDEL)) {
  4475. +        static struct obj **const armor[] = { &uarm, &uarmc, &uarmh, &uarms,
  4476. +                                              &uarmg, &uarmf, &uarmu };
  4477. +        int penalty = 0;
  4478. +        int i;
  4479. +
  4480. +        for (i = 0; i < SIZE(armor); i++) {
  4481. +            if (!*armor[i])
  4482. +                continue;
  4483. +            if ((*armor[i])->blessed)
  4484. +                penalty += 2;
  4485. +            else if ((*armor[i])->cursed)
  4486. +                penalty--;
  4487. +        }
  4488. +        if (penalty > 0)
  4489. +            splcaster += penalty;
  4490. +    }
  4491. +
  4492.      if (spellid(spell) == urole.spelspec)
  4493.          splcaster += urole.spelsbon;
  4494.  
  4495. diff --git a/src/steal.c b/src/steal.c
  4496. index 86933c7..961c756 100644
  4497. --- a/src/steal.c
  4498. +++ b/src/steal.c
  4499. @@ -539,14 +539,12 @@ struct monst *mtmp;
  4500.         if hero has more than one, choose randomly so that player
  4501.         can't use inventory ordering to influence the theft */
  4502.      for (n = 0, obj = invent; obj; obj = obj->nobj)
  4503. -        if (any_quest_artifact(obj))
  4504. -            ++n, otmp = obj;
  4505. -    if (n > 1) {
  4506. -        n = rnd(n);
  4507. -        for (otmp = invent; otmp; otmp = otmp->nobj)
  4508. -            if (any_quest_artifact(otmp) && !--n)
  4509. -                break;
  4510. -    }
  4511. +        if ((any_quest_artifact(obj)
  4512. +             /* agents haven't actualy seen the Idol (or Moloch) before */
  4513. +             || monsndx(mtmp->data) == PM_AGENT && obj->otyp == FIGURINE
  4514. +                && is_demon(&mons[obj->corpsenm]))
  4515. +            && !rn2(++n))
  4516. +            otmp = obj;
  4517.  
  4518.      if (!otmp) {
  4519.          /* if we didn't find any quest arifact, find another valuable item */
  4520. diff --git a/src/teleport.c b/src/teleport.c
  4521. index 23af60a..27a86cd 100644
  4522. --- a/src/teleport.c
  4523. +++ b/src/teleport.c
  4524. @@ -842,12 +842,25 @@ level_tele()
  4525.  
  4526.                  newlevel.dnum = destdnum;
  4527.                  newlevel.dlevel = destlev;
  4528. -                if (In_endgame(&newlevel) && !In_endgame(&u.uz)) {
  4529. +                if (In_endgame(&newlevel) && !In_endgame(&u.uz)
  4530. +                    && !u.uhave.amulet) {
  4531.                      struct obj *amu;
  4532.  
  4533. -                    if (!u.uhave.amulet
  4534. -                        && (amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE))
  4535. -                               != 0) {
  4536. +                    if (!Role_if(PM_INFIDEL)) {
  4537. +                        amu = mksobj(AMULET_OF_YENDOR, TRUE, FALSE);
  4538. +                    } else if (amu = find_quest_artifact(1 << OBJ_INVENT)) {
  4539. +                        obj_extract_self(amu); /* may be contained */
  4540. +                        amu->spe = 1;
  4541. +                    } else {
  4542. +                        const char *idol = artiname(ART_IDOL_OF_MOLOCH);
  4543. +                        amu = mksobj(FIGURINE, TRUE, FALSE);
  4544. +                        artifact_exists(amu, idol, TRUE);
  4545. +                        new_oname(amu, strlen(idol) + 1);
  4546. +                        Strcpy(ONAME(amu), idol);
  4547. +                        amu->spe = 1;
  4548. +                    }
  4549. +
  4550. +                    if (amu) {
  4551.                          /* ordinarily we'd use hold_another_object()
  4552.                             for something like this, but we don't want
  4553.                             fumbling or already full pack to interfere */
  4554. diff --git a/src/topten.c b/src/topten.c
  4555. index 7515c35..71cb614 100644
  4556. --- a/src/topten.c
  4557. +++ b/src/topten.c
  4558. @@ -374,7 +374,8 @@ int how;
  4559.              (long) ubirthday, XLOG_SEP, (long) urealtime.finish_time);
  4560.      Fprintf(rfile, "%cgender0=%s%calign0=%s", XLOG_SEP,
  4561.              genders[flags.initgend].filecode, XLOG_SEP,
  4562. -            aligns[1 - u.ualignbase[A_ORIGINAL]].filecode);
  4563. +            aligns[u.ualignbase[A_ORIGINAL] == A_NONE ? 3
  4564. +                   : 1 - u.ualignbase[A_ORIGINAL]].filecode);
  4565.      Fprintf(rfile, "%cflags=0x%lx", XLOG_SEP, encodexlogflags());
  4566.      Fprintf(rfile, "\n");
  4567.  #undef XLOG_SEP
  4568. @@ -552,7 +553,8 @@ time_t when;
  4569.      copynchars(t0->plrole, urole.filecode, ROLESZ);
  4570.      copynchars(t0->plrace, urace.filecode, ROLESZ);
  4571.      copynchars(t0->plgend, genders[flags.female].filecode, ROLESZ);
  4572. -    copynchars(t0->plalign, aligns[1 - u.ualign.type].filecode, ROLESZ);
  4573. +    copynchars(t0->plalign, aligns[u.ualign.type == A_NONE ? 3
  4574. +                                   : 1 - u.ualign.type].filecode, ROLESZ);
  4575.      copynchars(t0->name, plname, NAMSZ);
  4576.      formatkiller(t0->death, sizeof t0->death, how, TRUE);
  4577.      t0->birthdate = yyyymmdd(ubirthday);
  4578. @@ -834,8 +836,12 @@ boolean so;
  4579.              *bp = (t1->deathdnum == astral_level.dnum) ? '\0' : ' ';
  4580.          second_line = FALSE;
  4581.      } else if (!strncmp("ascended", t1->death, 8)) {
  4582. -        Sprintf(eos(linebuf), "ascended to demigod%s-hood",
  4583. -                (t1->plgend[0] == 'F') ? "dess" : "");
  4584. +        if (roles[str2role(t1->plrole)].malenum == PM_INFIDEL)
  4585. +            Sprintf(eos(linebuf), "ascended to demon-%s-hood",
  4586. +                    (t1->plgend[0] == 'F') ? "lady" : "lord");
  4587. +        else
  4588. +            Sprintf(eos(linebuf), "ascended to demigod%s-hood",
  4589. +                    (t1->plgend[0] == 'F') ? "dess" : "");
  4590.          second_line = FALSE;
  4591.      } else {
  4592.          if (!strncmp(t1->death, "quit", 4)) {
  4593. diff --git a/src/trap.c b/src/trap.c
  4594. index b6db811..d8f251e 100644
  4595. --- a/src/trap.c
  4596. +++ b/src/trap.c
  4597. @@ -3713,10 +3713,10 @@ boolean *lostsome;
  4598.                   * in removing them + loadstone and other cursed stuff
  4599.                   * for obvious reasons.
  4600.                   */
  4601. -                if (!((obj->otyp == LOADSTONE && obj->cursed) || obj == uamul
  4602. -                      || obj == uleft || obj == uright || obj == ublindf
  4603. -                      || obj == uarm || obj == uarmc || obj == uarmg
  4604. -                      || obj == uarmf || obj == uarmu
  4605. +                if (!((obj->otyp == LOADSTONE && cursed(obj, TRUE))
  4606. +                      || obj == uamul || obj == uleft || obj == uright
  4607. +                      || obj == ublindf || obj == uarm || obj == uarmc
  4608. +                      || obj == uarmg || obj == uarmf || obj == uarmu
  4609.                        || (obj->cursed && (obj == uarmh || obj == uarms))
  4610.                        || welded(obj)))
  4611.                      otmp = obj;
  4612. diff --git a/src/u_init.c b/src/u_init.c
  4613. index 77e7445..fef07ea 100644
  4614. --- a/src/u_init.c
  4615. +++ b/src/u_init.c
  4616. @@ -21,6 +21,7 @@ STATIC_DCL boolean FDECL(restricted_spell_discipline, (int));
  4617.  #define UNDEF_TYP 0
  4618.  #define UNDEF_SPE '\177'
  4619.  #define UNDEF_BLESS 2
  4620. +#define CURSED 3
  4621.  
  4622.  /*
  4623.   *      Initial inventory for the various roles.
  4624. @@ -70,6 +71,19 @@ static struct trobj Healer[] = {
  4625.      { APPLE, 0, FOOD_CLASS, 5, 0 },
  4626.      { 0, 0, 0, 0, 0 }
  4627.  };
  4628. +static struct trobj Infidel[] = {
  4629. +    { AMULET_OF_YENDOR, 0, AMULET_CLASS, 1, 0 },
  4630. +    { DAGGER, 1, WEAPON_CLASS, 1, 0 },
  4631. +    { LEATHER_JACKET, 1, ARMOR_CLASS, 1, CURSED },
  4632. +    { CLOAK_OF_PROTECTION, 0, ARMOR_CLASS, 1, CURSED },
  4633. +    { POT_WATER, 0, POTION_CLASS, 3, CURSED },
  4634. +    { SPE_DRAIN_LIFE, 0, SPBOOK_CLASS, 1, 0 },
  4635. +    { UNDEF_TYP, UNDEF_SPE, SPBOOK_CLASS, 1, 0 },
  4636. +    { FIRE_HORN, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  4637. +    { MAGIC_MARKER, UNDEF_SPE, TOOL_CLASS, 1, 0 },
  4638. +    { 0, 0, 0, 0, 0 }
  4639. +
  4640. +};
  4641.  static struct trobj Knight[] = {
  4642.      { LONG_SWORD, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  4643.      { LANCE, 1, WEAPON_CLASS, 1, UNDEF_BLESS },
  4644. @@ -324,6 +338,31 @@ static const struct def_skill Skill_H[] = {
  4645.      { P_BARE_HANDED_COMBAT, P_BASIC },
  4646.      { P_NONE, 0 }
  4647.  };
  4648. +static const struct def_skill Skill_Inf[] = {
  4649. +    { P_DAGGER, P_EXPERT },
  4650. +    { P_KNIFE, P_EXPERT },
  4651. +    { P_SHORT_SWORD, P_SKILLED },
  4652. +    { P_BROAD_SWORD, P_BASIC },
  4653. +    { P_SCIMITAR, P_SKILLED },
  4654. +    { P_SABER, P_BASIC },
  4655. +    { P_CLUB, P_BASIC },
  4656. +    { P_HAMMER, P_BASIC },
  4657. +    { P_QUARTERSTAFF, P_SKILLED },
  4658. +    { P_POLEARMS, P_SKILLED },
  4659. +    { P_SPEAR, P_BASIC },
  4660. +    { P_TRIDENT, P_BASIC },
  4661. +    { P_SLING, P_BASIC },
  4662. +    { P_CROSSBOW, P_SKILLED },
  4663. +    { P_DART, P_BASIC },
  4664. +    { P_WHIP, P_SKILLED },
  4665. +    { P_ATTACK_SPELL, P_EXPERT },
  4666. +    { P_DIVINATION_SPELL, P_SKILLED },
  4667. +    { P_ENCHANTMENT_SPELL, P_BASIC },
  4668. +    { P_CLERIC_SPELL, P_EXPERT },
  4669. +    { P_BARE_HANDED_COMBAT, P_SKILLED },
  4670. +    { P_RIDING, P_SKILLED },
  4671. +    { P_NONE, 0 }
  4672. +};
  4673.  static const struct def_skill Skill_K[] = {
  4674.      { P_DAGGER, P_BASIC },
  4675.      { P_KNIFE, P_BASIC },
  4676. @@ -701,6 +740,12 @@ u_init()
  4677.          knows_object(POT_FULL_HEALING);
  4678.          skill_init(Skill_H);
  4679.          break;
  4680. +    case PM_INFIDEL:
  4681. +        u.umoney0 = rn1(251, 250);
  4682. +        ini_inv(Infidel);
  4683. +        knows_object(SCR_CHARGING); /* that's what the marker is for */
  4684. +        skill_init(Skill_Inf);
  4685. +        break;
  4686.      case PM_KNIGHT:
  4687.          ini_inv(Knight);
  4688.          knows_class(WEAPON_CLASS);
  4689. @@ -927,6 +972,9 @@ int otyp;
  4690.      case PM_HEALER:
  4691.          skills = Skill_H;
  4692.          break;
  4693. +    case PM_INFIDEL:
  4694. +        skills = Skill_Inf;
  4695. +        break;
  4696.      case PM_KNIGHT:
  4697.          skills = Skill_K;
  4698.          break;
  4699. @@ -1014,6 +1062,8 @@ register struct trobj *trop;
  4700.                     || (otyp == SCR_ENCHANT_WEAPON && Role_if(PM_MONK))
  4701.                     /* wizard patch -- they already have one */
  4702.                     || (otyp == SPE_FORCE_BOLT && Role_if(PM_WIZARD))
  4703. +                   /* same for infidels */
  4704. +                   || (otyp == SPE_DRAIN_LIFE && Role_if(PM_INFIDEL))
  4705.                     /* powerful spells are either useless to
  4706.                        low level players or unbalancing; also
  4707.                        spells in restricted skill categories */
  4708. @@ -1086,8 +1136,8 @@ register struct trobj *trop;
  4709.                  obj->cknown = obj->lknown = 1;
  4710.                  obj->otrapped = 0;
  4711.              }
  4712. -            obj->cursed = 0;
  4713. -            if (obj->opoisoned && u.ualign.type != A_CHAOTIC)
  4714. +            obj->cursed = (trop->trbless == CURSED);
  4715. +            if (obj->opoisoned && u.ualign.type > A_CHAOTIC)
  4716.                  obj->opoisoned = 0;
  4717.              if (obj->oclass == WEAPON_CLASS || obj->oclass == TOOL_CLASS) {
  4718.                  obj->quan = (long) trop->trquan;
  4719. @@ -1096,10 +1146,14 @@ register struct trobj *trop;
  4720.                         && obj->otyp != FLINT) {
  4721.                  obj->quan = 1L;
  4722.              }
  4723. +            if (Role_if(PM_INFIDEL) && obj->oclass == ARMOR_CLASS) {
  4724. +                /* Infidels are used to playing with fire */
  4725. +                obj->oerodeproof = 1;
  4726. +            }
  4727.              if (trop->trspe != UNDEF_SPE)
  4728.                  obj->spe = trop->trspe;
  4729.              if (trop->trbless != UNDEF_BLESS)
  4730. -                obj->blessed = trop->trbless;
  4731. +                obj->blessed = (trop->trbless == 1);
  4732.          }
  4733.          /* defined after setting otyp+quan + blessedness */
  4734.          obj->owt = weight(obj);
  4735. diff --git a/src/uhitm.c b/src/uhitm.c
  4736. index 2eedb18..4d3e8ef 100644
  4737. --- a/src/uhitm.c
  4738. +++ b/src/uhitm.c
  4739. @@ -20,7 +20,7 @@ STATIC_DCL int FDECL(explum, (struct monst *, struct attack *));
  4740.  STATIC_DCL void FDECL(start_engulf, (struct monst *));
  4741.  STATIC_DCL void NDECL(end_engulf);
  4742.  STATIC_DCL int FDECL(gulpum, (struct monst *, struct attack *));
  4743. -STATIC_DCL boolean FDECL(hmonas, (struct monst *));
  4744. +STATIC_DCL boolean FDECL(hmonas, (struct monst *, int, boolean));
  4745.  STATIC_DCL void FDECL(nohandglow, (struct monst *));
  4746.  STATIC_DCL boolean FDECL(shade_aware, (struct obj *));
  4747.  
  4748. @@ -438,7 +438,7 @@ register struct monst *mtmp;
  4749.      }
  4750.  
  4751.      if (Upolyd)
  4752. -        (void) hmonas(mtmp);
  4753. +        (void) hmonas(mtmp, NON_PM, TRUE);
  4754.      else
  4755.          (void) hitum(mtmp, youmonst.data->mattk);
  4756.      mtmp->mstrategy &= ~STRAT_WAITMASK;
  4757. @@ -641,6 +641,20 @@ struct attack *uattk;
  4758.          if (mhit)
  4759.              (void) passive(mon, uswapwep, mhit, malive, AT_WEAP, !uswapwep);
  4760.      }
  4761. +
  4762. +    /* your race may grant extra attacks */
  4763. +    if (!Upolyd && malive) {
  4764. +        int i;
  4765. +        int race = (flags.female && urace.femalenum != NON_PM)
  4766. +                   ? urace.femalenum : urace.malenum;
  4767. +        struct attack *attacks = mons[race].mattk;
  4768. +        for (i = 0; i < NATTK; i++) {
  4769. +            if (attacks[i].aatyp != AT_WEAP && attacks[i].aatyp != AT_NONE) {
  4770. +                malive = hmonas(mon, race, FALSE);
  4771. +                break;
  4772. +            }
  4773. +        }
  4774. +    }
  4775.      return malive;
  4776.  }
  4777.  
  4778. @@ -1327,6 +1341,16 @@ int dieroll;
  4779.                  pline("%s appears confused.", Monnam(mon));
  4780.          }
  4781.      }
  4782. +    if (DEADMONSTER(mon) && attacks(AD_DREN, obj)
  4783. +        && !nonliving(mdat) && u.uen < u.uenmax) {
  4784. +        int energy = mon->m_lev + 1;
  4785. +        energy += rn2(energy);
  4786. +        pline_The("ritual knife captures the evanescent life force.");
  4787. +        u.uen += energy;
  4788. +        if (u.uen > u.uenmax)
  4789. +            u.uen = u.uenmax;
  4790. +        context.botl = TRUE;
  4791. +    }
  4792.      if (unpoisonmsg)
  4793.          Your("%s %s no longer poisoned.", saved_oname,
  4794.               vtense(saved_oname, "are"));
  4795. @@ -1643,7 +1667,7 @@ int specialdmg; /* blessed and/or silver bonus against various things */
  4796.  
  4797.      if (is_demon(youmonst.data) && !rn2(13) && !uwep
  4798.          && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS
  4799. -        && u.umonnum != PM_BALROG) {
  4800. +        && u.umonnum != PM_BALROG && u.umonnum != PM_DEMON) {
  4801.          demonpet();
  4802.          return 0;
  4803.      }
  4804. @@ -2346,22 +2370,28 @@ boolean wouldhavehit;
  4805.  
  4806.  /* attack monster as a monster; returns True if mon survives */
  4807.  STATIC_OVL boolean
  4808. -hmonas(mon)
  4809. +hmonas(mon, as, weapon_attacks)
  4810.  register struct monst *mon;
  4811. +int as;
  4812. +boolean weapon_attacks; /* skip weapon attacks if false */
  4813.  {
  4814.      struct attack *mattk, alt_attk;
  4815.      struct obj *weapon, **originalweapon;
  4816. -    boolean altwep = FALSE, weapon_used = FALSE, odd_claw = TRUE;
  4817. +    boolean altwep = FALSE, weapon_used = !weapon_attacks, odd_claw = TRUE;
  4818.      int i, tmp, armorpenalty, sum[NATTK], nsum = 0, dhit = 0, attknum = 0;
  4819.      int dieroll, multi_claw = 0;
  4820. +    boolean was_polyd = Upolyd;
  4821.  
  4822.      /* with just one touch/claw/weapon attack, both rings matter;
  4823.         with more than one, alternate right and left when checking
  4824.         whether silver ring causes successful hit */
  4825.      for (i = 0; i < NATTK; i++) {
  4826.          sum[i] = 0;
  4827. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4828. -        if (mattk->aatyp == AT_WEAP
  4829. +        if (as != NON_PM)
  4830. +            mattk = &mons[as].mattk[i];
  4831. +        else
  4832. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4833. +        if (mattk->aatyp == AT_WEAP && weapon_attacks
  4834.              || mattk->aatyp == AT_CLAW || mattk->aatyp == AT_TUCH)
  4835.              ++multi_claw;
  4836.      }
  4837. @@ -2369,11 +2399,16 @@ register struct monst *mon;
  4838.  
  4839.      for (i = 0; i < NATTK; i++) {
  4840.          /* sum[i] = 0; -- now done above */
  4841. -        mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4842. +        if (as != NON_PM)
  4843. +            mattk = &mons[as].mattk[i];
  4844. +        else
  4845. +            mattk = getmattk(&youmonst, mon, i, sum, &alt_attk);
  4846.          weapon = 0;
  4847.          switch (mattk->aatyp) {
  4848.          case AT_WEAP:
  4849.              /* if (!uwep) goto weaponless; */
  4850. +            if (!weapon_attacks)
  4851. +                continue;
  4852.   use_weapon:
  4853.              odd_claw = !odd_claw; /* see case AT_CLAW,AT_TUCH below */
  4854.              /* if we've already hit with a two-handed weapon, we don't
  4855. @@ -2461,6 +2496,8 @@ register struct monst *mon;
  4856.          case AT_BUTT:
  4857.          case AT_TENT:
  4858.          /*weaponless:*/
  4859. +            if (!Upolyd && touch_petrifies(mon->data) && !Stone_resistance)
  4860. +                continue; /* switch off a racial attack if it would petrify */
  4861.              tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0,
  4862.                                     &attknum, &armorpenalty);
  4863.              dieroll = rnd(20);
  4864. @@ -2722,7 +2759,7 @@ register struct monst *mon;
  4865.             needed to defer this until after uswapwep->cursed check */
  4866.          if (DEADMONSTER(mon))
  4867.              break;
  4868. -        if (!Upolyd)
  4869. +        if (was_polyd && !Upolyd)
  4870.              break; /* No extra attacks if no longer a monster */
  4871.          if (multi < 0)
  4872.              break; /* If paralyzed while attacking, i.e. floating eye */
  4873. diff --git a/src/weapon.c b/src/weapon.c
  4874. index 1027409..573c050 100644
  4875. --- a/src/weapon.c
  4876. +++ b/src/weapon.c
  4877. @@ -1610,6 +1610,8 @@ const struct def_skill *class_skill;
  4878.      /* set skills for magic */
  4879.      if (Role_if(PM_HEALER) || Role_if(PM_MONK)) {
  4880.          P_SKILL(P_HEALING_SPELL) = P_BASIC;
  4881. +    } else if (Role_if(PM_INFIDEL)) {
  4882. +        P_SKILL(P_ATTACK_SPELL) = P_BASIC;
  4883.      } else if (Role_if(PM_PRIEST)) {
  4884.          P_SKILL(P_CLERIC_SPELL) = P_BASIC;
  4885.      } else if (Role_if(PM_WIZARD)) {
  4886. diff --git a/src/wield.c b/src/wield.c
  4887. index 18c276a..07b7ca3 100644
  4888. --- a/src/wield.c
  4889. +++ b/src/wield.c
  4890. @@ -64,6 +64,8 @@ STATIC_DCL int FDECL(ready_weapon, (struct obj *));
  4891.  /* used by welded(), and also while wielding */
  4892.  #define will_weld(optr) \
  4893.      ((optr)->cursed && (erodeable_wep(optr) || (optr)->otyp == TIN_OPENER))
  4894. +/* Infidels are immune to curses */
  4895. +#define will_weld_to_you(optr) (will_weld(optr) && !Role_if(PM_INFIDEL))
  4896.  
  4897.  /*** Functions that place a given item in a slot ***/
  4898.  /* Proper usage includes:
  4899. @@ -160,7 +162,7 @@ struct obj *wep;
  4900.      } else {
  4901.          /* Weapon WILL be wielded after this point */
  4902.          res++;
  4903. -        if (will_weld(wep)) {
  4904. +        if (will_weld_to_you(wep)) {
  4905.              const char *tmp = xname(wep), *thestr = "The ";
  4906.  
  4907.              if (strncmp(tmp, thestr, 4) && !strncmp(The(tmp), thestr, 4))
  4908. @@ -575,7 +577,7 @@ const char *verb; /* "rub",&c */
  4909.      } else {
  4910.          struct obj *oldwep = uwep;
  4911.  
  4912. -        if (will_weld(obj)) {
  4913. +        if (will_weld_to_you(obj)) {
  4914.              /* hope none of ready_weapon()'s early returns apply here... */
  4915.              (void) ready_weapon(obj);
  4916.          } else {
  4917. @@ -858,7 +860,7 @@ int
  4918.  welded(obj)
  4919.  register struct obj *obj;
  4920.  {
  4921. -    if (obj && obj == uwep && will_weld(obj)) {
  4922. +    if (obj && obj == uwep && will_weld_to_you(obj)) {
  4923.          set_bknown(obj, 1);
  4924.          return 1;
  4925.      }
  4926. diff --git a/src/wizard.c b/src/wizard.c
  4927. index b1dae1e..8b11152 100644
  4928. --- a/src/wizard.c
  4929. +++ b/src/wizard.c
  4930. @@ -66,7 +66,9 @@ amulet()
  4931.          return;
  4932.  #endif
  4933.      if ((((amu = uamul) != 0 && amu->otyp == AMULET_OF_YENDOR)
  4934. -         || ((amu = uwep) != 0 && amu->otyp == AMULET_OF_YENDOR))
  4935. +         || ((amu = uwep) != 0 && (amu->otyp == AMULET_OF_YENDOR
  4936. +                                   || amu->oartifact == ART_IDOL_OF_MOLOCH
  4937. +                                      && amu->spe)))
  4938.          && !rn2(15)) {
  4939.          for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
  4940.              if (ttmp->ttyp == MAGIC_PORTAL) {
  4941. @@ -106,7 +108,8 @@ register struct monst *mtmp;
  4942.      register struct obj *otmp;
  4943.  
  4944.      for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
  4945. -        if (otmp->otyp == AMULET_OF_YENDOR)
  4946. +        if (otmp->otyp == AMULET_OF_YENDOR
  4947. +            || otmp->oartifact == ART_IDOL_OF_MOLOCH && otmp->spe)
  4948.              return 1;
  4949.      return 0;
  4950.  }
  4951. @@ -247,7 +250,7 @@ register struct monst *mtmp;
  4952.  
  4953.      otyp = which_arti(mask);
  4954.      if (!mon_has_arti(mtmp, otyp)) {
  4955. -        if (you_have(mask))
  4956. +        if (you_have(mask) && !mtmp->mpeaceful)
  4957.              return STRAT(STRAT_PLAYER, u.ux, u.uy, mask);
  4958.          else if ((otmp = on_ground(otyp)))
  4959.              return STRAT(STRAT_GROUND, otmp->ox, otmp->oy, mask);
  4960. @@ -296,6 +299,12 @@ register struct monst *mtmp;
  4961.          break;
  4962.      }
  4963.  
  4964. +    /* Quest nemeses will always prioritize their treasure
  4965. +     * (important for the Infidel quest) */
  4966. +    if (mtmp->data->msound == MS_NEMESIS)
  4967. +        if ((strat = target_on(M3_WANTSARTI, mtmp)) != STRAT_NONE)
  4968. +            return strat;
  4969. +
  4970.      if (context.made_amulet)
  4971.          if ((strat = target_on(M3_WANTSAMUL, mtmp)) != STRAT_NONE)
  4972.              return strat;
  4973. @@ -397,8 +406,13 @@ register struct monst *mtmp;
  4974.          /*FALLTHRU*/
  4975.  
  4976.      case STRAT_NONE: /* harass */
  4977. -        if (!rn2(!mtmp->mflee ? 5 : 33))
  4978. -            mnexto(mtmp);
  4979. +        if (!rn2(!mtmp->mflee ? 5 : 33)) {
  4980. +            if (mtmp->mpeaceful && !mtmp->mtame
  4981. +                && !(mtmp->mstrategy & STRAT_APPEARMSG))
  4982. +                (void) rloc(mtmp, TRUE); /* summoned demon lords etc. */
  4983. +            else
  4984. +                mnexto(mtmp);
  4985. +        }
  4986.          return 0;
  4987.  
  4988.      default: /* kill, maim, pillage! */
  4989. @@ -484,7 +498,7 @@ aggravate()
  4990.              continue;
  4991.          if (in_w_tower != In_W_tower(mtmp->mx, mtmp->my, &u.uz))
  4992.              continue;
  4993. -        mtmp->mstrategy &= ~(STRAT_WAITFORU | STRAT_APPEARMSG);
  4994. +        mtmp->mstrategy &= ~STRAT_WAITFORU;
  4995.          mtmp->msleeping = 0;
  4996.          if (!mtmp->mcanmove && !rn2(5)) {
  4997.              mtmp->mfrozen = 0;
  4998. diff --git a/src/worn.c b/src/worn.c
  4999. index 1a966b7..db2b27d 100644
  5000. --- a/src/worn.c
  5001. +++ b/src/worn.c
  5002. @@ -578,6 +578,10 @@ boolean racialexception;
  5003.                  continue;
  5004.              if (racialexception && (racial_exception(mon, obj) < 1))
  5005.                  continue;
  5006. +            /* monsters won't sacrifice flight for AC */
  5007. +            if (big_wings(mon->data) && !Is_dragon_scales(obj)
  5008. +                && obj->otyp != LEATHER_JACKET)
  5009. +                continue;
  5010.              break;
  5011.          }
  5012.          if (obj->owornmask)
  5013. diff --git a/src/zap.c b/src/zap.c
  5014. index 1c7a5de..2784f34 100644
  5015. --- a/src/zap.c
  5016. +++ b/src/zap.c
  5017. @@ -1182,6 +1182,7 @@ struct obj *obj;
  5018.  int ochance, achance; /* percent chance for ordinary objects, artifacts */
  5019.  {
  5020.      if (obj->otyp == AMULET_OF_YENDOR
  5021. +        || Role_if(PM_INFIDEL) && is_quest_artifact(obj)
  5022.          || obj->otyp == SPE_BOOK_OF_THE_DEAD
  5023.          || obj->otyp == CANDELABRUM_OF_INVOCATION
  5024.          || obj->otyp == BELL_OF_OPENING
  5025. @@ -2446,7 +2447,7 @@ boolean ordinary;
  5026.  
  5027.      case WAN_DEATH:
  5028.      case SPE_FINGER_OF_DEATH:
  5029. -        if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  5030. +        if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  5031.              pline((obj->otyp == WAN_DEATH)
  5032.                        ? "The wand shoots an apparently harmless beam at you."
  5033.                        : "You seem no deader than before.");
  5034. @@ -3838,7 +3839,7 @@ xchar sx, sy;
  5035.                  (void) destroy_arm(uarmc);
  5036.              if (uarmu)
  5037.                  (void) destroy_arm(uarmu);
  5038. -        } else if (nonliving(youmonst.data) || is_demon(youmonst.data)) {
  5039. +        } else if (nonliving(youmonst.data) || is_demon(raceptr(&youmonst))) {
  5040.              shieldeff(sx, sy);
  5041.              You("seem unaffected.");
  5042.              break;
  5043. diff --git a/sys/amiga/Makefile.agc b/sys/amiga/Makefile.agc
  5044. index 47040b5..b13632e 100644
  5045. --- a/sys/amiga/Makefile.agc
  5046. +++ b/sys/amiga/Makefile.agc
  5047. @@ -228,6 +228,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  5048.     $(SLIB)Hea-strt.lev
  5049.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  5050.  
  5051. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  5052. +   $(SLIB)Inf-strt.lev
  5053. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  5054. +
  5055.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  5056.     $(SLIB)Kni-strt.lev
  5057.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  5058. @@ -264,7 +268,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  5059.     $(SLIB)Wiz-strt.lev
  5060.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  5061.  
  5062. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  5063. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  5064.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  5065.         $(VDFILES) $(WDFILES)
  5066.  
  5067. @@ -843,6 +847,10 @@ $(HDFILES1):   $(SLIB)Hea-goal.lev
  5068.  
  5069.  $(SLIB)Hea-goal.lev:   $(DAT)Healer.des $(SBIN)lev_comp
  5070.  
  5071. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  5072. +
  5073. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  5074. +
  5075.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  5076.  
  5077.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  5078. diff --git a/sys/amiga/Makefile.ami b/sys/amiga/Makefile.ami
  5079. index 14b1298..6fefee5 100644
  5080. --- a/sys/amiga/Makefile.ami
  5081. +++ b/sys/amiga/Makefile.ami
  5082. @@ -435,6 +435,10 @@ HDFILES1= $(SLIB)Hea-fila.lev $(SLIB)Hea-filb.lev $(SLIB)Hea-loca.lev \
  5083.     $(SLIB)Hea-strt.lev
  5084.  HDFILES= $(SLIB)Hea-goal.lev $(HDFILES1)
  5085.  
  5086. +IDFILES1= $(SLIB)Inf-fila.lev $(SLIB)Inf-filb.lev $(SLIB)Inf-loca.lev \
  5087. +   $(SLIB)Inf-strt.lev
  5088. +IDFILES= $(SLIB)Inf-goal.lev $(IDFILES1)
  5089. +
  5090.  KDFILES1= $(SLIB)Kni-fila.lev $(SLIB)Kni-filb.lev $(SLIB)Kni-loca.lev \
  5091.     $(SLIB)Kni-strt.lev
  5092.  KDFILES= $(SLIB)Kni-goal.lev $(KDFILES1)
  5093. @@ -471,7 +475,7 @@ WDFILES1= $(SLIB)Wiz-fila.lev $(SLIB)Wiz-filb.lev $(SLIB)Wiz-loca.lev \
  5094.     $(SLIB)Wiz-strt.lev
  5095.  WDFILES= $(SLIB)Wiz-goal.lev $(WDFILES1)
  5096.  
  5097. -XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(KDFILES) \
  5098. +XDFILES=   $(ADFILES) $(BDFILES) $(CDFILES) $(HDFILES) $(IDFILES) $(KDFILES) \
  5099.         $(MDFILES) $(PDFILES) $(RDFILES) $(RANFILES) $(SDFILES) $(TDFILES) \
  5100.         $(VDFILES) $(WDFILES)
  5101.  
  5102. @@ -1148,6 +1152,12 @@ $(SLIB)Hea-goal.lev: $(DAT)Healer.des $(SBIN)lev_comp
  5103.  #SFD_INSTEAD $(SBIN)lev_comp $(DAT)Healer.des
  5104.  #none
  5105.  
  5106. +$(IDFILES1):   $(SLIB)Inf-goal.lev
  5107. +
  5108. +$(SLIB)Inf-goal.lev:   $(DAT)Infidel.des $(SBIN)lev_comp
  5109. +#SFD_INSTEAD $(SBIN)lev_comp $(DAT)Infidel.des
  5110. +#none
  5111. +
  5112.  $(KDFILES1):   $(SLIB)Kni-goal.lev
  5113.  
  5114.  $(SLIB)Kni-goal.lev:   $(DAT)Knight.des $(SBIN)lev_comp
  5115. diff --git a/sys/mac/Files.r b/sys/mac/Files.r
  5116. index 3ea176e..a9b3d51 100644
  5117. --- a/sys/mac/Files.r
  5118. +++ b/sys/mac/Files.r
  5119. @@ -124,51 +124,56 @@ read 'File' (1116,"Hea-filb.lev") "Hea-filb.lev";
  5120.  read 'File' (1117,"Hea-goal.lev") "Hea-goal.lev";
  5121.  read 'File' (1118,"Hea-loca.lev") "Hea-loca.lev";
  5122.  read 'File' (1119,"Hea-strt.lev") "Hea-strt.lev";
  5123. -read 'File' (1120,"Kni-fila.lev") "Kni-fila.lev";
  5124. -read 'File' (1121,"Kni-filb.lev") "Kni-filb.lev";
  5125. -read 'File' (1122,"Kni-goal.lev") "Kni-goal.lev";
  5126. -read 'File' (1123,"Kni-loca.lev") "Kni-loca.lev";
  5127. -read 'File' (1124,"Kni-strt.lev") "Kni-strt.lev";
  5128. -read 'File' (1125,"Mon-fila.lev") "Mon-fila.lev";
  5129. -read 'File' (1126,"Mon-filb.lev") "Mon-filb.lev";
  5130. -read 'File' (1127,"Mon-goal.lev") "Mon-goal.lev";
  5131. -read 'File' (1128,"Mon-loca.lev") "Mon-loca.lev";
  5132. -read 'File' (1129,"Mon-strt.lev") "Mon-strt.lev";
  5133. -read 'File' (1130,"Pri-fila.lev") "Pri-fila.lev";
  5134. -read 'File' (1131,"Pri-filb.lev") "Pri-filb.lev";
  5135. -read 'File' (1132,"Pri-goal.lev") "Pri-goal.lev";
  5136. -read 'File' (1133,"Pri-loca.lev") "Pri-loca.lev";
  5137. -read 'File' (1134,"Pri-strt.lev") "Pri-strt.lev";
  5138. -read 'File' (1135,"Ran-fila.lev") "Ran-fila.lev";
  5139. -read 'File' (1136,"Ran-filb.lev") "Ran-filb.lev";
  5140. -read 'File' (1137,"Ran-goal.lev") "Ran-goal.lev";
  5141. -read 'File' (1138,"Ran-loca.lev") "Ran-loca.lev";
  5142. -read 'File' (1139,"Ran-strt.lev") "Ran-strt.lev";
  5143. -read 'File' (1140,"Rog-fila.lev") "Rog-fila.lev";
  5144. -read 'File' (1141,"Rog-filb.lev") "Rog-filb.lev";
  5145. -read 'File' (1142,"Rog-goal.lev") "Rog-goal.lev";
  5146. -read 'File' (1143,"Rog-loca.lev") "Rog-loca.lev";
  5147. -read 'File' (1144,"Rog-strt.lev") "Rog-strt.lev";
  5148. -read 'File' (1145,"Sam-fila.lev") "Sam-fila.lev";
  5149. -read 'File' (1146,"Sam-filb.lev") "Sam-filb.lev";
  5150. -read 'File' (1147,"Sam-goal.lev") "Sam-goal.lev";
  5151. -read 'File' (1148,"Sam-loca.lev") "Sam-loca.lev";
  5152. -read 'File' (1149,"Sam-strt.lev") "Sam-strt.lev";
  5153. -read 'File' (1150,"Tou-fila.lev") "Tou-fila.lev";
  5154. -read 'File' (1151,"Tou-filb.lev") "Tou-filb.lev";
  5155. -read 'File' (1152,"Tou-goal.lev") "Tou-goal.lev";
  5156. -read 'File' (1153,"Tou-loca.lev") "Tou-loca.lev";
  5157. -read 'File' (1154,"Tou-strt.lev") "Tou-strt.lev";
  5158. -read 'File' (1155,"Val-fila.lev") "Val-fila.lev";
  5159. -read 'File' (1156,"Val-filb.lev") "Val-filb.lev";
  5160. -read 'File' (1157,"Val-goal.lev") "Val-goal.lev";
  5161. -read 'File' (1158,"Val-loca.lev") "Val-loca.lev";
  5162. -read 'File' (1159,"Val-strt.lev") "Val-strt.lev";
  5163. -read 'File' (1160,"Wiz-fila.lev") "Wiz-fila.lev";
  5164. -read 'File' (1161,"Wiz-filb.lev") "Wiz-filb.lev";
  5165. -read 'File' (1162,"Wiz-goal.lev") "Wiz-goal.lev";
  5166. -read 'File' (1163,"Wiz-loca.lev") "Wiz-loca.lev";
  5167. -read 'File' (1164,"Wiz-strt.lev") "Wiz-strt.lev";
  5168. +read 'File' (1120,"Inf-fila.lev") "Inf-fila.lev";
  5169. +read 'File' (1121,"Inf-filb.lev") "Inf-filb.lev";
  5170. +read 'File' (1122,"Inf-goal.lev") "Inf-goal.lev";
  5171. +read 'File' (1123,"Inf-loca.lev") "Inf-loca.lev";
  5172. +read 'File' (1124,"Inf-strt.lev") "Inf-strt.lev";
  5173. +read 'File' (1125,"Kni-fila.lev") "Kni-fila.lev";
  5174. +read 'File' (1126,"Kni-filb.lev") "Kni-filb.lev";
  5175. +read 'File' (1127,"Kni-goal.lev") "Kni-goal.lev";
  5176. +read 'File' (1128,"Kni-loca.lev") "Kni-loca.lev";
  5177. +read 'File' (1129,"Kni-strt.lev") "Kni-strt.lev";
  5178. +read 'File' (1130,"Mon-fila.lev") "Mon-fila.lev";
  5179. +read 'File' (1131,"Mon-filb.lev") "Mon-filb.lev";
  5180. +read 'File' (1132,"Mon-goal.lev") "Mon-goal.lev";
  5181. +read 'File' (1133,"Mon-loca.lev") "Mon-loca.lev";
  5182. +read 'File' (1134,"Mon-strt.lev") "Mon-strt.lev";
  5183. +read 'File' (1135,"Pri-fila.lev") "Pri-fila.lev";
  5184. +read 'File' (1136,"Pri-filb.lev") "Pri-filb.lev";
  5185. +read 'File' (1137,"Pri-goal.lev") "Pri-goal.lev";
  5186. +read 'File' (1138,"Pri-loca.lev") "Pri-loca.lev";
  5187. +read 'File' (1139,"Pri-strt.lev") "Pri-strt.lev";
  5188. +read 'File' (1140,"Ran-fila.lev") "Ran-fila.lev";
  5189. +read 'File' (1141,"Ran-filb.lev") "Ran-filb.lev";
  5190. +read 'File' (1142,"Ran-goal.lev") "Ran-goal.lev";
  5191. +read 'File' (1143,"Ran-loca.lev") "Ran-loca.lev";
  5192. +read 'File' (1144,"Ran-strt.lev") "Ran-strt.lev";
  5193. +read 'File' (1145,"Rog-fila.lev") "Rog-fila.lev";
  5194. +read 'File' (1146,"Rog-filb.lev") "Rog-filb.lev";
  5195. +read 'File' (1147,"Rog-goal.lev") "Rog-goal.lev";
  5196. +read 'File' (1148,"Rog-loca.lev") "Rog-loca.lev";
  5197. +read 'File' (1149,"Rog-strt.lev") "Rog-strt.lev";
  5198. +read 'File' (1150,"Sam-fila.lev") "Sam-fila.lev";
  5199. +read 'File' (1151,"Sam-filb.lev") "Sam-filb.lev";
  5200. +read 'File' (1152,"Sam-goal.lev") "Sam-goal.lev";
  5201. +read 'File' (1153,"Sam-loca.lev") "Sam-loca.lev";
  5202. +read 'File' (1154,"Sam-strt.lev") "Sam-strt.lev";
  5203. +read 'File' (1155,"Tou-fila.lev") "Tou-fila.lev";
  5204. +read 'File' (1156,"Tou-filb.lev") "Tou-filb.lev";
  5205. +read 'File' (1157,"Tou-goal.lev") "Tou-goal.lev";
  5206. +read 'File' (1158,"Tou-loca.lev") "Tou-loca.lev";
  5207. +read 'File' (1159,"Tou-strt.lev") "Tou-strt.lev";
  5208. +read 'File' (1160,"Val-fila.lev") "Val-fila.lev";
  5209. +read 'File' (1161,"Val-filb.lev") "Val-filb.lev";
  5210. +read 'File' (1162,"Val-goal.lev") "Val-goal.lev";
  5211. +read 'File' (1163,"Val-loca.lev") "Val-loca.lev";
  5212. +read 'File' (1164,"Val-strt.lev") "Val-strt.lev";
  5213. +read 'File' (1165,"Wiz-fila.lev") "Wiz-fila.lev";
  5214. +read 'File' (1166,"Wiz-filb.lev") "Wiz-filb.lev";
  5215. +read 'File' (1167,"Wiz-goal.lev") "Wiz-goal.lev";
  5216. +read 'File' (1168,"Wiz-loca.lev") "Wiz-loca.lev";
  5217. +read 'File' (1169,"Wiz-strt.lev") "Wiz-strt.lev";
  5218.  #else
  5219.  read 'File' (1000,"cmdhelp") ":dat:cmdhelp";
  5220.  read 'File' (1001,"help") ":dat:help";
  5221. @@ -253,49 +258,54 @@ read 'File' (1116,"Hea-filb.lev") ":lib:Hea-filb.lev";
  5222.  read 'File' (1117,"Hea-goal.lev") ":lib:Hea-goal.lev";
  5223.  read 'File' (1118,"Hea-loca.lev") ":lib:Hea-loca.lev";
  5224.  read 'File' (1119,"Hea-strt.lev") ":lib:Hea-strt.lev";
  5225. -read 'File' (1120,"Kni-fila.lev") ":lib:Kni-fila.lev";
  5226. -read 'File' (1121,"Kni-filb.lev") ":lib:Kni-filb.lev";
  5227. -read 'File' (1122,"Kni-goal.lev") ":lib:Kni-goal.lev";
  5228. -read 'File' (1123,"Kni-loca.lev") ":lib:Kni-loca.lev";
  5229. -read 'File' (1124,"Kni-strt.lev") ":lib:Kni-strt.lev";
  5230. -read 'File' (1125,"Mon-fila.lev") ":lib:Mon-fila.lev";
  5231. -read 'File' (1126,"Mon-filb.lev") ":lib:Mon-filb.lev";
  5232. -read 'File' (1127,"Mon-goal.lev") ":lib:Mon-goal.lev";
  5233. -read 'File' (1128,"Mon-loca.lev") ":lib:Mon-loca.lev";
  5234. -read 'File' (1129,"Mon-strt.lev") ":lib:Mon-strt.lev";
  5235. -read 'File' (1130,"Pri-fila.lev") ":lib:Pri-fila.lev";
  5236. -read 'File' (1131,"Pri-filb.lev") ":lib:Pri-filb.lev";
  5237. -read 'File' (1132,"Pri-goal.lev") ":lib:Pri-goal.lev";
  5238. -read 'File' (1133,"Pri-loca.lev") ":lib:Pri-loca.lev";
  5239. -read 'File' (1134,"Pri-strt.lev") ":lib:Pri-strt.lev";
  5240. -read 'File' (1135,"Ran-fila.lev") ":lib:Ran-fila.lev";
  5241. -read 'File' (1136,"Ran-filb.lev") ":lib:Ran-filb.lev";
  5242. -read 'File' (1137,"Ran-goal.lev") ":lib:Ran-goal.lev";
  5243. -read 'File' (1138,"Ran-loca.lev") ":lib:Ran-loca.lev";
  5244. -read 'File' (1139,"Ran-strt.lev") ":lib:Ran-strt.lev";
  5245. -read 'File' (1140,"Rog-fila.lev") ":lib:Rog-fila.lev";
  5246. -read 'File' (1141,"Rog-filb.lev") ":lib:Rog-filb.lev";
  5247. -read 'File' (1142,"Rog-goal.lev") ":lib:Rog-goal.lev";
  5248. -read 'File' (1143,"Rog-loca.lev") ":lib:Rog-loca.lev";
  5249. -read 'File' (1144,"Rog-strt.lev") ":lib:Rog-strt.lev";
  5250. -read 'File' (1145,"Sam-fila.lev") ":lib:Sam-fila.lev";
  5251. -read 'File' (1146,"Sam-filb.lev") ":lib:Sam-filb.lev";
  5252. -read 'File' (1147,"Sam-goal.lev") ":lib:Sam-goal.lev";
  5253. -read 'File' (1148,"Sam-loca.lev") ":lib:Sam-loca.lev";
  5254. -read 'File' (1149,"Sam-strt.lev") ":lib:Sam-strt.lev";
  5255. -read 'File' (1150,"Tou-fila.lev") ":lib:Tou-fila.lev";
  5256. -read 'File' (1151,"Tou-filb.lev") ":lib:Tou-filb.lev";
  5257. -read 'File' (1152,"Tou-goal.lev") ":lib:Tou-goal.lev";
  5258. -read 'File' (1153,"Tou-loca.lev") ":lib:Tou-loca.lev";
  5259. -read 'File' (1154,"Tou-strt.lev") ":lib:Tou-strt.lev";
  5260. -read 'File' (1155,"Val-fila.lev") ":lib:Val-fila.lev";
  5261. -read 'File' (1156,"Val-filb.lev") ":lib:Val-filb.lev";
  5262. -read 'File' (1157,"Val-goal.lev") ":lib:Val-goal.lev";
  5263. -read 'File' (1158,"Val-loca.lev") ":lib:Val-loca.lev";
  5264. -read 'File' (1159,"Val-strt.lev") ":lib:Val-strt.lev";
  5265. -read 'File' (1160,"Wiz-fila.lev") ":lib:Wiz-fila.lev";
  5266. -read 'File' (1161,"Wiz-filb.lev") ":lib:Wiz-filb.lev";
  5267. -read 'File' (1162,"Wiz-goal.lev") ":lib:Wiz-goal.lev";
  5268. -read 'File' (1163,"Wiz-loca.lev") ":lib:Wiz-loca.lev";
  5269. -read 'File' (1164,"Wiz-strt.lev") ":lib:Wiz-strt.lev";
  5270. +read 'File' (1120,"Inf-fila.lev") ":lib:Inf-fila.lev";
  5271. +read 'File' (1121,"Inf-filb.lev") ":lib:Inf-filb.lev";
  5272. +read 'File' (1122,"Inf-goal.lev") ":lib:Inf-goal.lev";
  5273. +read 'File' (1123,"Inf-loca.lev") ":lib:Inf-loca.lev";
  5274. +read 'File' (1124,"Inf-strt.lev") ":lib:Inf-strt.lev";
  5275. +read 'File' (1125,"Kni-fila.lev") ":lib:Kni-fila.lev";
  5276. +read 'File' (1126,"Kni-filb.lev") ":lib:Kni-filb.lev";
  5277. +read 'File' (1127,"Kni-goal.lev") ":lib:Kni-goal.lev";
  5278. +read 'File' (1128,"Kni-loca.lev") ":lib:Kni-loca.lev";
  5279. +read 'File' (1129,"Kni-strt.lev") ":lib:Kni-strt.lev";
  5280. +read 'File' (1130,"Mon-fila.lev") ":lib:Mon-fila.lev";
  5281. +read 'File' (1131,"Mon-filb.lev") ":lib:Mon-filb.lev";
  5282. +read 'File' (1132,"Mon-goal.lev") ":lib:Mon-goal.lev";
  5283. +read 'File' (1133,"Mon-loca.lev") ":lib:Mon-loca.lev";
  5284. +read 'File' (1134,"Mon-strt.lev") ":lib:Mon-strt.lev";
  5285. +read 'File' (1135,"Pri-fila.lev") ":lib:Pri-fila.lev";
  5286. +read 'File' (1136,"Pri-filb.lev") ":lib:Pri-filb.lev";
  5287. +read 'File' (1137,"Pri-goal.lev") ":lib:Pri-goal.lev";
  5288. +read 'File' (1138,"Pri-loca.lev") ":lib:Pri-loca.lev";
  5289. +read 'File' (1139,"Pri-strt.lev") ":lib:Pri-strt.lev";
  5290. +read 'File' (1140,"Ran-fila.lev") ":lib:Ran-fila.lev";
  5291. +read 'File' (1141,"Ran-filb.lev") ":lib:Ran-filb.lev";
  5292. +read 'File' (1142,"Ran-goal.lev") ":lib:Ran-goal.lev";
  5293. +read 'File' (1143,"Ran-loca.lev") ":lib:Ran-loca.lev";
  5294. +read 'File' (1144,"Ran-strt.lev") ":lib:Ran-strt.lev";
  5295. +read 'File' (1145,"Rog-fila.lev") ":lib:Rog-fila.lev";
  5296. +read 'File' (1146,"Rog-filb.lev") ":lib:Rog-filb.lev";
  5297. +read 'File' (1147,"Rog-goal.lev") ":lib:Rog-goal.lev";
  5298. +read 'File' (1148,"Rog-loca.lev") ":lib:Rog-loca.lev";
  5299. +read 'File' (1149,"Rog-strt.lev") ":lib:Rog-strt.lev";
  5300. +read 'File' (1150,"Sam-fila.lev") ":lib:Sam-fila.lev";
  5301. +read 'File' (1151,"Sam-filb.lev") ":lib:Sam-filb.lev";
  5302. +read 'File' (1152,"Sam-goal.lev") ":lib:Sam-goal.lev";
  5303. +read 'File' (1153,"Sam-loca.lev") ":lib:Sam-loca.lev";
  5304. +read 'File' (1154,"Sam-strt.lev") ":lib:Sam-strt.lev";
  5305. +read 'File' (1155,"Tou-fila.lev") ":lib:Tou-fila.lev";
  5306. +read 'File' (1156,"Tou-filb.lev") ":lib:Tou-filb.lev";
  5307. +read 'File' (1157,"Tou-goal.lev") ":lib:Tou-goal.lev";
  5308. +read 'File' (1158,"Tou-loca.lev") ":lib:Tou-loca.lev";
  5309. +read 'File' (1159,"Tou-strt.lev") ":lib:Tou-strt.lev";
  5310. +read 'File' (1160,"Val-fila.lev") ":lib:Val-fila.lev";
  5311. +read 'File' (1161,"Val-filb.lev") ":lib:Val-filb.lev";
  5312. +read 'File' (1162,"Val-goal.lev") ":lib:Val-goal.lev";
  5313. +read 'File' (1163,"Val-loca.lev") ":lib:Val-loca.lev";
  5314. +read 'File' (1164,"Val-strt.lev") ":lib:Val-strt.lev";
  5315. +read 'File' (1165,"Wiz-fila.lev") ":lib:Wiz-fila.lev";
  5316. +read 'File' (1166,"Wiz-filb.lev") ":lib:Wiz-filb.lev";
  5317. +read 'File' (1167,"Wiz-goal.lev") ":lib:Wiz-goal.lev";
  5318. +read 'File' (1168,"Wiz-loca.lev") ":lib:Wiz-loca.lev";
  5319. +read 'File' (1169,"Wiz-strt.lev") ":lib:Wiz-strt.lev";
  5320.  #endif
  5321. diff --git a/sys/msdos/Makefile.BC b/sys/msdos/Makefile.BC
  5322. index ce0756a..5476f58 100644
  5323. --- a/sys/msdos/Makefile.BC
  5324. +++ b/sys/msdos/Makefile.BC
  5325. @@ -718,7 +718,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  5326.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  5327.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  5328.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  5329. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  5330. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  5331.  
  5332.  #
  5333.  # Utility Objects.
  5334. @@ -976,6 +976,7 @@ $(DAT)\sp_lev.tag: $(U)utility.tag $(SPLEVDES)
  5335.     $(U)lev_comp barb.des
  5336.     $(U)lev_comp caveman.des
  5337.     $(U)lev_comp healer.des
  5338. +   $(U)lev_comp infidel.des
  5339.     $(U)lev_comp knight.des
  5340.     $(U)lev_comp monk.des
  5341.     $(U)lev_comp priest.des
  5342. diff --git a/sys/msdos/Makefile.GCC b/sys/msdos/Makefile.GCC
  5343. index 4693bda..579f11a 100644
  5344. --- a/sys/msdos/Makefile.GCC
  5345. +++ b/sys/msdos/Makefile.GCC
  5346. @@ -1016,7 +1016,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  5347.     $(DAT)/caveman.des   $(DAT)/healer.des   $(DAT)/knight.des \
  5348.     $(DAT)/monk.des      $(DAT)/priest.des   $(DAT)/ranger.des \
  5349.     $(DAT)/rogue.des     $(DAT)/samurai.des  $(DAT)/tourist.des \
  5350. -   $(DAT)/valkyrie.des  $(DAT)/wizard.des
  5351. +   $(DAT)/valkyrie.des  $(DAT)/wizard.des $(DAT)/infidel.des
  5352.     @$(subst /,\,cd $(DAT))
  5353.     @$(subst /,\,$(U)lev_comp bigroom.des)
  5354.     @$(subst /,\,$(U)lev_comp castle.des)
  5355. @@ -1033,6 +1033,7 @@ $(O)sp_lev.tag: $(O)utility.tag \
  5356.     @$(subst /,\,$(U)lev_comp barb.des)
  5357.     @$(subst /,\,$(U)lev_comp caveman.des)
  5358.     @$(subst /,\,$(U)lev_comp healer.des)
  5359. +   @$(subst /,\,$(U)lev_comp infidel.des)
  5360.     @$(subst /,\,$(U)lev_comp knight.des)
  5361.     @$(subst /,\,$(U)lev_comp monk.des)
  5362.     @$(subst /,\,$(U)lev_comp priest.des)
  5363. diff --git a/sys/msdos/Makefile.MSC b/sys/msdos/Makefile.MSC
  5364. index b7d827a..b605dcc 100644
  5365. --- a/sys/msdos/Makefile.MSC
  5366. +++ b/sys/msdos/Makefile.MSC
  5367. @@ -148,7 +148,7 @@ SPLEVDES = $(DAT)\Arch.des $(DAT)\Barb.des $(DAT)\bigroom.des \
  5368.     $(DAT)\mines.des $(DAT)\oracle.des $(DAT)\Priest.des \
  5369.     $(DAT)\Ranger.des $(DAT)\Rogue.des $(DAT)\Samurai.des \
  5370.     $(DAT)\Tourist.des $(DAT)\tower.des $(DAT)\Valkyrie.des \
  5371. -   $(DAT)\Wizard.des $(DAT)\yendor.des
  5372. +   $(DAT)\Wizard.des $(DAT)\yendor.des $(DAT)\Infidel.des
  5373.  
  5374.  VGAOBJ      = vidvga.o
  5375.  
  5376. @@ -428,6 +428,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(SPLEVDES)
  5377.     $(U)lev_comp barb.des
  5378.     $(U)lev_comp caveman.des
  5379.     $(U)lev_comp healer.des
  5380. +   $(U)lev_comp infidel.des
  5381.     $(U)lev_comp knight.des
  5382.     $(U)lev_comp monk.des
  5383.     $(U)lev_comp priest.des
  5384. @@ -973,6 +974,11 @@ nhdat: $(U)dlb_main.exe $(DAT)\data $(DAT)\oracles $(DAT)\options \
  5385.     echo HEA-GOAL.LEV  >>dlb.lst
  5386.     echo HEA-LOCA.LEV  >>dlb.lst
  5387.     echo HEA-STRT.LEV  >>dlb.lst
  5388. +   echo INF-FILA.LEV  >>dlb.lst
  5389. +   echo INF-FILB.LEV  >>dlb.lst
  5390. +   echo INF-GOAL.LEV  >>dlb.lst
  5391. +   echo INF-LOCA.LEV  >>dlb.lst
  5392. +   echo INF-STRT.LEV  >>dlb.lst
  5393.     echo JUIBLEX.LEV   >>dlb.lst
  5394.     echo KNI-FILA.LEV  >>dlb.lst
  5395.     echo KNI-FILB.LEV  >>dlb.lst
  5396. diff --git a/sys/os2/Makefile.os2 b/sys/os2/Makefile.os2
  5397. index 4afcf0f..9ddaad5 100644
  5398. --- a/sys/os2/Makefile.os2
  5399. +++ b/sys/os2/Makefile.os2
  5400. @@ -1280,6 +1280,7 @@ AFILES = $(GAMEDIR)\Arc-goal.lev
  5401.  BFILES = $(GAMEDIR)\Bar-goal.lev
  5402.  CFILES = $(GAMEDIR)\Cav-goal.lev
  5403.  HFILES = $(GAMEDIR)\Hea-goal.lev
  5404. +IFILES = $(GAMEDIR)\Inf-goal.lev
  5405.  KFILES = $(GAMEDIR)\Kni-goal.lev
  5406.  MFILES = $(GAMEDIR)\Mon-goal.lev
  5407.  PFILES = $(GAMEDIR)\Pri-goal.lev
  5408. @@ -1290,7 +1291,7 @@ TFILES = $(GAMEDIR)\Tou-goal.lev
  5409.  VFILES = $(GAMEDIR)\Val-goal.lev
  5410.  WFILES = $(GAMEDIR)\Wiz-goal.lev
  5411.  
  5412. -XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(KFILES) $(MFILES) \
  5413. +XFILES = $(AFILES) $(BFILES) $(CFILES) $(HFILES) $(IFILES) $(KFILES) $(MFILES) \
  5414.      $(PFILES) $(RANFILES) $(RFILES) $(SFILES) $(TFILES) $(VFILES) $(WFILES)
  5415.  
  5416.  spec_lev : $(GAMEDIR)\astral.lev $(GAMEDIR)\bigrm-1.lev $(GAMEDIR)\castle.lev \
  5417. @@ -1389,6 +1390,8 @@ $(CFILES) : $(DAT)\Caveman.des $(TEMP)\lev_comp.exe
  5418.     $(MAKEB) QQ=Cav QF=Caveman do_quest
  5419.  $(HFILES) : $(DAT)\Healer.des $(TEMP)\lev_comp.exe
  5420.     $(MAKEB) QQ=Hea QF=Healer do_quest
  5421. +$(IFILES) : $(DAT)\Infidel.des $(TEMP)\lev_comp.exe
  5422. +   $(MAKEB) QQ=Inf QF=Infidel do_quest
  5423.  $(KFILES) : $(DAT)\Knight.des $(TEMP)\lev_comp.exe
  5424.     $(MAKEB) QQ=Kni QF=Knight do_quest
  5425.  $(MFILES) : $(DAT)\Monk.des $(TEMP)\lev_comp.exe
  5426. diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat
  5427. index 00f6043..c6bb10d 100644
  5428. --- a/sys/unix/Makefile.dat
  5429. +++ b/sys/unix/Makefile.dat
  5430. @@ -145,11 +145,12 @@ spec_levs: ../util/lev_comp \
  5431.  quest_levs: ../util/lev_comp \
  5432.     Arch.des Barb.des Caveman.des Healer.des Knight.des Monk.des \
  5433.     Priest.des Ranger.des Rogue.des Samurai.des Tourist.des Valkyrie.des \
  5434. -   Wizard.des
  5435. +   Wizard.des Infidel.des
  5436.     ../util/lev_comp Arch.des
  5437.     ../util/lev_comp Barb.des
  5438.     ../util/lev_comp Caveman.des
  5439.     ../util/lev_comp Healer.des
  5440. +   ../util/lev_comp Infidel.des
  5441.     ../util/lev_comp Knight.des
  5442.     ../util/lev_comp Monk.des
  5443.     ../util/lev_comp Priest.des
  5444. diff --git a/sys/unix/NetHack.xcodeproj/project.pbxproj b/sys/unix/NetHack.xcodeproj/project.pbxproj
  5445. index fdee884..d0db85a 100644
  5446. --- a/sys/unix/NetHack.xcodeproj/project.pbxproj
  5447. +++ b/sys/unix/NetHack.xcodeproj/project.pbxproj
  5448. @@ -1310,6 +1310,7 @@
  5449.                 "$(NH_DAT_DIR)/Barb.des",
  5450.                 "$(NH_DAT_DIR)/Caveman.des",
  5451.                 "$(NH_DAT_DIR)/Healer.des",
  5452. +               "$(NH_DAT_DIR)/Infidel.des",
  5453.                 "$(NH_DAT_DIR)/Knight.des",
  5454.                 "$(NH_DAT_DIR)/Monk.des",
  5455.                 "$(NH_DAT_DIR)/Priest.des",
  5456. @@ -1328,7 +1329,7 @@
  5457.             );
  5458.             runOnlyForDeploymentPostprocessing = 0;
  5459.             shellPath = /bin/sh;
  5460. -           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";
  5461. +           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";
  5462.         };
  5463.         317E7C4E21A3697300F6E4E5 /* Build options and headers */ = {
  5464.             isa = PBXShellScriptBuildPhase;
  5465. @@ -1472,6 +1473,11 @@
  5466.                 "$(NH_DAT_DIR)/Hea-goal.lev",
  5467.                 "$(NH_DAT_DIR)/Hea-loca.lev",
  5468.                 "$(NH_DAT_DIR)/Hea-strt.lev",
  5469. +               "$(NH_DAT_DIR)/Inf-fila.lev",
  5470. +               "$(NH_DAT_DIR)/Inf-filb.lev",
  5471. +               "$(NH_DAT_DIR)/Inf-goal.lev",
  5472. +               "$(NH_DAT_DIR)/Inf-loca.lev",
  5473. +               "$(NH_DAT_DIR)/Inf-strt.lev",
  5474.                 "$(NH_DAT_DIR)/Kni-fila.lev",
  5475.                 "$(NH_DAT_DIR)/Kni-filb.lev",
  5476.                 "$(NH_DAT_DIR)/Kni-goal.lev",
  5477. diff --git a/sys/vms/Makefile.dat b/sys/vms/Makefile.dat
  5478. index e74eb95..dea0fb8 100644
  5479. --- a/sys/vms/Makefile.dat
  5480. +++ b/sys/vms/Makefile.dat
  5481. @@ -31,7 +31,7 @@ VARDAT    = data.;,rumors.;,quest.dat;,oracles.;,options.;,\
  5482.  DUNGEON = dungeon.;
  5483.  X11TILES= x11tiles.;
  5484.  # note: the level lists need to be space separated for use as-is by $(LEVCOMP)
  5485. -QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Knight.des \
  5486. +QUESTLEVS = Arch.des Barb.des Caveman.des Healer.des Infidel.des Knight.des \
  5487.     Monk.des Priest.des Ranger.des Rogue.des Samurai.des Tourist.des \
  5488.     Valkyrie.des Wizard.des
  5489.  SPECLEVS  = bigroom.des castle.des endgame.des gehennom.des knox.des \
  5490. diff --git a/sys/vms/install.com b/sys/vms/install.com
  5491. index 09f6f83..5172e41 100755
  5492. --- a/sys/vms/install.com
  5493. +++ b/sys/vms/install.com
  5494. @@ -45,7 +45,7 @@ $ spec_input = "bigroom.des castle.des endgame.des " -
  5495.            + "gehennom.des knox.des medusa.des mines.des " -
  5496.            + "oracle.des sokoban.des tower.des yendor.des"
  5497.  $  qstl_files = "%%%-GOAL.LEV,%%%-FIL%.LEV,%%%-LOCA.LEV,%%%-STRT.LEV"
  5498. -$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des " -
  5499. +$  qstl_input = "Arch.des Barb.des Caveman.des Healer.des Infidel.des " -
  5500.            + "Knight.des Monk.des Priest.des Ranger.des Rogue.des " -
  5501.            + "Samurai.des Tourist.des Wizard.des Valkyrie.des"
  5502.  $  dngn_files = "DUNGEON."
  5503. diff --git a/sys/wince/bootstrp.mak b/sys/wince/bootstrp.mak
  5504. index 5d92dc7..dcd3a46 100644
  5505. --- a/sys/wince/bootstrp.mak
  5506. +++ b/sys/wince/bootstrp.mak
  5507. @@ -244,7 +244,8 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  5508.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  5509.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  5510.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  5511. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  5512. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  5513. +   $(DAT)\infidel.des
  5514.     cd $(DAT)
  5515.     $(U)lev_comp bigroom.des
  5516.     $(U)lev_comp castle.des
  5517. @@ -261,6 +262,7 @@ $(O)sp_lev.tag:  $(DAT)\bigroom.des  $(DAT)\castle.des \
  5518.     $(U)lev_comp barb.des
  5519.     $(U)lev_comp caveman.des
  5520.     $(U)lev_comp healer.des
  5521. +   $(U)lev_comp infidel.des
  5522.     $(U)lev_comp knight.des
  5523.     $(U)lev_comp monk.des
  5524.     $(U)lev_comp priest.des
  5525. diff --git a/sys/winnt/Makefile.msc b/sys/winnt/Makefile.msc
  5526. index 8bd5086..5e172cf 100644
  5527. --- a/sys/winnt/Makefile.msc
  5528. +++ b/sys/winnt/Makefile.msc
  5529. @@ -711,7 +711,8 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  5530.     $(DAT)\caveman.des $(DAT)\healer.des   $(DAT)\knight.des \
  5531.     $(DAT)\monk.des    $(DAT)\priest.des   $(DAT)\ranger.des \
  5532.     $(DAT)\rogue.des   $(DAT)\samurai.des  $(DAT)\sokoban.des \
  5533. -   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des
  5534. +   $(DAT)\tourist.des $(DAT)\valkyrie.des $(DAT)\wizard.des \
  5535. +        $(DAT)\infidel.des
  5536.     cd $(DAT)
  5537.     $(U)levcomp bigroom.des
  5538.     $(U)levcomp castle.des
  5539. @@ -728,6 +729,7 @@ $(O)sp_lev.tag: $(O)utility.tag $(DAT)\bigroom.des  $(DAT)\castle.des \
  5540.     $(U)levcomp barb.des
  5541.     $(U)levcomp caveman.des
  5542.     $(U)levcomp healer.des
  5543. +   $(U)levcomp infidel.des
  5544.     $(U)levcomp knight.des
  5545.     $(U)levcomp monk.des
  5546.     $(U)levcomp priest.des
  5547. diff --git a/util/lev_main.c b/util/lev_main.c
  5548. index 8bcfc83..15a487f 100644
  5549. --- a/util/lev_main.c
  5550. +++ b/util/lev_main.c
  5551. @@ -250,7 +250,8 @@ char **argv;
  5552.          ":dat:Wizard.des",  ":dat:bigroom.des",  ":dat:castle.des",
  5553.          ":dat:endgame.des", ":dat:gehennom.des", ":dat:knox.des",
  5554.          ":dat:medusa.des",  ":dat:mines.des",    ":dat:oracle.des",
  5555. -        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des"
  5556. +        ":dat:sokoban.des", ":dat:tower.des",    ":dat:yendor.des",
  5557. +        ":dat:Infidel.des"
  5558.      };
  5559.  
  5560.      argc = SIZE(mac_argv);
  5561. diff --git a/win/X11/winstat.c b/win/X11/winstat.c
  5562. index 0aecdf1..596fed0 100644
  5563. --- a/win/X11/winstat.c
  5564. +++ b/win/X11/winstat.c
  5565. @@ -1228,7 +1228,8 @@ long new_value;
  5566.              Strcpy(buf,
  5567.                     (new_value == A_CHAOTIC)
  5568.                         ? "Chaotic"
  5569. -                       : (new_value == A_NEUTRAL) ? "Neutral" : "Lawful");
  5570. +                       : (new_value == A_NEUTRAL) ? "Neutral"
  5571. +                       : (new_value == A_LAWFUL) ? "Lawful" : "Unaligned");
  5572.          } else {
  5573.              Sprintf(buf, "%ld", new_value);
  5574.          }
  5575. diff --git a/win/share/monsters.txt b/win/share/monsters.txt
  5576. index f2b81fc..e5f12b3 100644
  5577. --- a/win/share/monsters.txt
  5578. +++ b/win/share/monsters.txt
  5579. @@ -5081,6 +5081,44 @@ Z = (195, 195, 195)
  5580.    ................
  5581.    ................
  5582.  }
  5583. +# tile 266 (champion)
  5584. +{
  5585. +  ................
  5586. +  ................
  5587. +  .......CCA......
  5588. +  ......CCCCA.....
  5589. +  ......LFLFA.....
  5590. +  ......LLLLA.....
  5591. +  ......AKKA......
  5592. +  .....RTKKRS.AAA.
  5593. +  ....LTJTRSRLAAA.
  5594. +  ....LRTJTRSLAAA.
  5595. +  ....LLLLJLLLAAA.
  5596. +  .....RTRTJSPPAA.
  5597. +  ......RTRSJPPPA.
  5598. +  ......LAAPPJPPA.
  5599. +  .....LLA.PPPJA..
  5600. +  ..........PPA...
  5601. +}
  5602. +# tile 267 (agent)
  5603. +{
  5604. +  ................
  5605. +  ................
  5606. +  .......LLA......
  5607. +  ......LLLLA.....
  5608. +  ......APAPA.....
  5609. +  ......LLLLA.....
  5610. +  ......ALLA......
  5611. +  .....TSAARR.AAA.
  5612. +  ....TTSSRRRRAAA.
  5613. +  ....TATSSRARAAA.
  5614. +  ....LATTSSALAAA.
  5615. +  ......TSTRAAAAA.
  5616. +  ......TSSRAAAA..
  5617. +  .....TSSARRA.A..
  5618. +  .....RRR.RRR....
  5619. +  ................
  5620. +}
  5621.  # tile 266 (elf)
  5622.  {
  5623.    ................
  5624. @@ -6107,6 +6145,25 @@ Z = (195, 195, 195)
  5625.    .........IFED...
  5626.    ................
  5627.  }
  5628. +# tile 320 (demon)
  5629. +{
  5630. +  ................
  5631. +  .....O....O.....
  5632. +  .....OOSSOO.....
  5633. +  ...C..TTTTA.C...
  5634. +  ...C..FDFDA.C...
  5635. +  ..CDD.DDDDADDC..
  5636. +  ..CDDDADDADDDC..
  5637. +  ..CDDCKAAKJDDCA.
  5638. +  ..DDCKKKJJJJDDA.
  5639. +  ..DDKACKJJAJDDA.
  5640. +  ..DADACJKJADADA.
  5641. +  ..DA..CJKJDAADA.
  5642. +  ......CJJKDDDA..
  5643. +  .....KCJAJJADDO.
  5644. +  .....CJJ.JKJ....
  5645. +  ................
  5646. +}
  5647.  # tile 320 (jellyfish)
  5648.  {
  5649.    ................
  5650. @@ -6487,6 +6544,25 @@ Z = (195, 195, 195)
  5651.    ................
  5652.    ................
  5653.  }
  5654. +# tile 340 (infidel)
  5655. +{
  5656. +  ................
  5657. +  ................
  5658. +  .......SSA......
  5659. +  ......TTTTA.....
  5660. +  ......DLDLA.....
  5661. +  C.C.C.LLLLA.....
  5662. +  DCDCD.ALLA......
  5663. +  .DCD.CKAAKJ.AAA.
  5664. +  ..D.CKKKJJJJAAA.
  5665. +  ..LCKACKJJAJAAA.
  5666. +  .....ACJKJALAAA.
  5667. +  ......CJKJAAAAA.
  5668. +  ......CJJKAAAA..
  5669. +  .....KCJAJJA.A..
  5670. +  .....CJJ.JKJ....
  5671. +  ................
  5672. +}
  5673.  # tile 340 (knight)
  5674.  {
  5675.    ................
  5676. @@ -6791,6 +6867,25 @@ Z = (195, 195, 195)
  5677.    .LCCCCCCCDA.....
  5678.    ................
  5679.  }
  5680. +# tile 356 (preacher of Moloch)
  5681. +{
  5682. +  .INI............
  5683. +  IIIII.KDDK......
  5684. +  .ICI.KDAADK.....
  5685. +  ..C..DIAIAD.....
  5686. +  ..LD.DAAAAD.....
  5687. +  .DLLD.DAADJDK...
  5688. +  .DCLADDDDJDDDK..
  5689. +  ..CAADDJJDDDDDK.
  5690. +  ..CDDDDJDDJDDD.A
  5691. +  ..C..DDJDDLJDAAA
  5692. +  ..C..DDJDLLDAAAA
  5693. +  ..C..KDJDDDJAAAA
  5694. +  ..C..KDJDDDJAAAA
  5695. +  ..C.ADDJDDDJAAA.
  5696. +  ..CADDDJJDDDAA..
  5697. +  ................
  5698. +}
  5699.  # tile 356 (King Arthur)
  5700.  {
  5701.    ................
  5702. @@ -7057,6 +7152,25 @@ Z = (195, 195, 195)
  5703.    ....CJJJCLAAAAAA
  5704.    ..LLLLL.LLLLLAA.
  5705.  }
  5706. +# tile 370 (Paladin)
  5707. +{
  5708. +  ................
  5709. +  ................
  5710. +  .......HH.......
  5711. +  ......HHHH......
  5712. +  .....HLBLBH.....
  5713. +  .....HLLLLH.....
  5714. +  .....HALLAHAAAA.
  5715. +  ....NHNAAMHMAAA.
  5716. +  .PK.LNBNMBMLAAA.
  5717. +  .P.KL.NMBMALAAA.
  5718. +  .P..K..BMAALAA..
  5719. +  .P...KBMBMAAAA..
  5720. +  .B....MAAMAA.A..
  5721. +  BPB..JJA.JJA....
  5722. +  .B..............
  5723. +  ................
  5724. +}
  5725.  # tile 370 (Ixoth)
  5726.  {
  5727.    ....O......O....
  5728. @@ -7304,6 +7418,44 @@ Z = (195, 195, 195)
  5729.    ................
  5730.    ................
  5731.  }
  5732. +# tile 383 (templar)
  5733. +{
  5734. +  ................
  5735. +  ................
  5736. +  .......BPA......
  5737. +  ...N..BPPPA.....
  5738. +  ...N..PEEPA.....
  5739. +  ...N..PLLPA.....
  5740. +  ...N..ALNANO.O..
  5741. +  ...N.BBANNNOOOA.
  5742. +  ..CCCPPPNPPPPOA.
  5743. +  ...LPABPNPNPPOA.
  5744. +  ...C...PNPPPPOA.
  5745. +  ......BP.NPPOAA.
  5746. +  ......BPAPNOA...
  5747. +  .....PPA.PPA....
  5748. +  ................
  5749. +  ................
  5750. +}
  5751. +# tile 384 (cultist)
  5752. +{
  5753. +  ................
  5754. +  ................
  5755. +  .......LLA......
  5756. +  ......LLLLA.....
  5757. +  ......DLDLA.....
  5758. +  ......LLLLA.....
  5759. +  .....DALLAD.....
  5760. +  .L...CDAADJ.AAA.
  5761. +  LLLCCDCDDJDKAAA.
  5762. +  LLLACCDJJDDKKAAA
  5763. +  .CAACDCJDDDLKKA.
  5764. +  .CCCDCDJDDLLKAA.
  5765. +  ....CDDJDKDKAA..
  5766. +  ...ADDDJKDKDAA..
  5767. +  ..ADCDDJJKDK....
  5768. +  ................
  5769. +}
  5770.  # tile 383 (page)
  5771.  {
  5772.    ................
  5773. diff --git a/win/tty/wintty.c b/win/tty/wintty.c
  5774. index d7ffec6..d5c18bb 100644
  5775. --- a/win/tty/wintty.c
  5776. +++ b/win/tty/wintty.c
  5777. @@ -929,6 +929,7 @@ tty_player_selection()
  5778.       */
  5779.      getconfirmation = (picksomething && pick4u != 'a' && !flags.randomall);
  5780.      while (getconfirmation) {
  5781. +        int real_algn = special_alignment(ROLE, ALGN);
  5782.          tty_clear_nhwindow(BASE_WINDOW);
  5783.          role_selection_prolog(ROLE_NONE, BASE_WINDOW);
  5784.          win = create_nhwindow(NHW_MENU);
  5785. @@ -941,7 +942,7 @@ tty_player_selection()
  5786.              Sprintf(plbuf, " %s", genders[GEND].adj);
  5787.          else
  5788.              *plbuf = '\0'; /* omit redundant gender */
  5789. -        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[ALGN].adj, plbuf,
  5790. +        Sprintf(pbuf, "%s, %s%s %s %s", plname, aligns[real_algn].adj, plbuf,
  5791.                  races[RACE].adj,
  5792.                  (GEND == 1 && roles[ROLE].name.f) ? roles[ROLE].name.f
  5793.                                                    : roles[ROLE].name.m);
  5794. diff --git a/win/win32/vs2017/files.props b/win/win32/vs2017/files.props
  5795. index 483ec1e..5a12ab8 100644
  5796. --- a/win/win32/vs2017/files.props
  5797. +++ b/win/win32/vs2017/files.props
  5798. @@ -35,6 +35,7 @@
  5799.      <Desfiles Include = "endgame.des"/>
  5800.      <Desfiles Include = "gehennom.des"/>
  5801.      <Desfiles Include = "healer.des"/>
  5802. +    <Desfiles Include = "infidel.des"/>
  5803.      <Desfiles Include = "knight.des"/>
  5804.      <Desfiles Include = "knox.des"/>
  5805.      <Desfiles Include = "medusa.des"/>
  5806. @@ -128,6 +129,11 @@
  5807.      <Levfiles Include = "hea-goal.lev"/>
  5808.      <Levfiles Include = "hea-loca.lev"/>
  5809.      <Levfiles Include = "hea-strt.lev"/>
  5810. +    <Levfiles Include = "inf-fila.lev"/>
  5811. +    <Levfiles Include = "inf-filb.lev"/>
  5812. +    <Levfiles Include = "inf-goal.lev"/>
  5813. +    <Levfiles Include = "inf-loca.lev"/>
  5814. +    <Levfiles Include = "inf-strt.lev"/>
  5815.      <Levfiles Include = "kni-fila.lev"/>
  5816.      <Levfiles Include = "kni-filb.lev"/>
  5817.      <Levfiles Include = "kni-goal.lev"/>
Add Comment
Please, Sign In to add comment